Mystery Blue Lines Appear When Displaying Modified Pixels

As part of our project, we are accessing video camera RGB pixels and modifying them to set them to black if they meet certain conditions. This is done before calling GLTexImage2D to display the image as part of a live video feed on an Android device.

We are seeing blue lines appear in consistent locations running horizontally across the screen, and only in regions in which we have modified the pixels. We have checked to confirm that our code has not generated any blue pixels before GLTexImage2D is called, and so believe that this is something to do with that function in concert with the changes we made to the image.

Does anyone know what could be causing this? Any help is greatly appreciated.

-Cooper

On your texture, what are you using for:

  • GL internal format
  • GL external format
  • GL external type

The usual reason is you’re missing:

glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

The default is 4 (4 bytes). If you’re truly trying to access RGB8 pixels in tightly-packed rows, you’ll likely want 1 here.

See:

I believe that the internal and external formats are both RGBA, the output format is set as RGBA_8888 and the frame buffer is set using 4-byte-per-pixel RGBA.

In terms of GL external type, I’m not sure of that as I don’t see any references to it in the code. Where would you look to determine that?

-Cooper

Here is the line that specifies those types in our code:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, capture_width_, capture_height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

An update on this after further exploring -

We were able to remove the blue lines in the modified parts of our image that we set to black. This was done by setting the alpha (opacity) values of all of the filtered pixels to 0.

However, in parts of the image that are modified but are set to colors other than black, this fix is not working. When the alpha values are set to 0, the lines turn red in these regions, and when the values are set to 255 the lines turn blue again. Values between 0 and 255 are predictably on a spectrum from red to blue.

I am not sure if this may be an issue with the texture or glBlend - could OpenGL be blending between a red color “behind” the blue color, leading to a transparent pixel showing red and an opaque one showing blue?

We also attempted rebuilding and displaying the image in RGB, rather than RGBA, and this again shows the horizontal blue lines but this time on the entire image (assumedly because the image has been reconstructed to into a new data structure in order to convert it to RGB).

Here is the new glTexImage2D call with this implemented:

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, capture_width_, capture_height_, 0, GL_RGB, GL_UNSIGNED_BYTE, new_ptr);

Any help is appreciated,
Cooper

Couple things.

First, above you’re calling glTexImage2D() with two different internal formats:

  1. GL_RGBA8
  2. GL_RGB (unsized components)

You need to pick one and stick with it. GL_RGBA8 will probably be better from a rendering performance perspective than GL_RGB8. And GL_RGB8 will likely consume 4 bytes instead of 3 in memory anyway. However, if performance is not that important, pick either

Next, GL_RGB is an unsized internal format. You’re not saying how many bits you want for R, G, and B. You should do so. GL_RGB8 is probably want you’re looking for if you want RGB without alpha. Just be aware that when you upload tightly-packed RGB8 data to GL, you’re basically demanding that the driver reformat your texel data to fit its memory layout, which can cost you in upload performance.

At any rate, choose one of GL_RGBA8 or GL_RGB8.

Second, regardless of which you pick, every call to glTexImage2D() is freeing the old texture storage and allocating new texture storage, and additionally uploading new texel content to it (if the ptr provided is non-NULL). You should not do this. Allocate the texture once (e.g. with glTexImage2D() or better glTexStorage2D()) and then when you want to update the texels, use the “subload” texture call: glTexSubImage2D(). This does not free the old texture storage and allocate new. It merely uploads new content to the texture.

And finally as to your rendering artifact, you haven’t given any info on how you’re rendering that texture on the screen. While the problem could involve how you’re uploading the texel data to a GL texture (or your app uploading garbage texel data to GL), it’s more likely to be wrapped up in how you are rendering that texture onto the window. For instance, are you using GLSL shaders or fixed-function shading, what GL rasterization state is set at the time, what framebuffer format you’re using, which buffers of that framebuffer you’re clearing before rendering the texture, etcetc.