BGRA on iPhone glTexImage2D and glReadPixels

2019-04-15 11:19发布

Looking at the docs, I should be able to use BGRA for the internal format of a texture. I am supplying the texture with BGRA data (using GL_RGBA8_OES for glRenderbufferStorage as it seems BGRA there is not allowed). However, the following does not work:

glTexImage2D(GL_TEXTURE_2D, 0, **GL_BGRA**, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
...
glReadPixels(0, 0, w,h, GL_BGRA, GL_UNSIGNED_BYTE,buffer, 0);

While this gives me a black frame:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
...
glReadPixels(0, 0, w,h, **GL_BGRA**, GL_UNSIGNED_BYTE,buffer, 0);

And this does work, but the blues/reds are inverted (I supply BGRA data to the texture):

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
...
glReadPixels(0, 0, w,h, **GL_RGBA**, GL_UNSIGNED_BYTE,buffer, 0);

...why can't I just use BGRA throughout? I do notice that glRenderbufferStorage does not seem to accept any BGRA formats...I'm really confused. BGRA is the only suitable format my data is in, as it comes from the iphone's camera.

2条回答
Lonely孤独者°
2楼-- · 2019-04-15 11:39

My own looking around for OpenGL ES2 indicates that this works for the BGRA little endian native format under iOS. Here "pixels" points to a buffer of 32 bit BGRA that would come from a CGBitmapContextCreate() or grabbing the image data from out of a CGImageRef.

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels);

See the apple ext for this here. Good discussion of this issue here

查看更多
The star\"
3楼-- · 2019-04-15 11:46

The third parameter to glTexImage2D() is the number of color components in the texture, not the pixel ordering of the texture. You want to use GL_RGBA here, or it just won't work.

I don't believe GL_BGRA is supported by glReadPixels() on iOS devices as a color format. While providing pixel data to the textures in BGRA format is recommended by Apple when processing video image frames, I think you're fine in reading that back in RGBA format and then encoding that to disk, as you've described elsewhere.

If you want to see a sample project that takes camera video frames in BGRA, sends them to a texture, processes them using shaders, and then reads the resulting pixels back, you can check out the one I built here.

查看更多
登录 后发表回答