从GL_TEXTURE_EXTERNAL_OES读取Android像素

8
我正在尝试从绑定到GL_TEXTURE_EXTERNAL_OES的OpenGL纹理中读取像素/数据。
将纹理绑定到该目标的原因是,为了在Android上获取实时摄像头数据,需要从绑定到GL_TEXTURE_EXTERNAL_OES的OpenGL纹理创建SurfaceTexture。
由于Android使用OpenGL ES,我无法使用glGetTexImage()读取图像数据。
因此,我将目标绑定到FBO,然后使用readPixels()进行读取。这是我的代码:
    GLuint framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    //Attach 2D texture to this FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, cameraTexture, 0);
    status("glFramebufferTexture2D() returned error %d", glGetError());

但是出现错误1282(GL_INVALID_OPERATION),原因未知。

2个回答

2
我认为这可能是问题所在:
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_EXTERNAL_OES, cameraTexture, 0);

你不应该将cameraTexture附加到帧缓冲区,而是应该生成一个新的GL_TEXTURE_2D格式的纹理。

glGenTextures(1, mTextureHandle, 0);

glBindTexture(GL_TEXTURE_2D, mTextureHandle[0]);

...

cameraTexture是从SurfaceTexture获取的,它是用于渲染的源。这个新纹理是您应该渲染到的(稍后可能在渲染管道中使用)。然后执行以下操作:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, mTextureHandle[0], 0);

cameraTexture被绘制到帧缓冲的附加纹理中,使用一个简单的着色器程序来绘制,在着色器程序正在使用时绑定cameraTexture:

glBindTexture(GL_TEXTURE_EXTERNAL_OES, cameraTexture); 

1
这个答案提供了什么解决方案? - Léon Pelletier
1
我认为正确的解决方案需要将这两个答案结合起来,首先创建一个新的帧缓冲和一个新的纹理,并使用glFramebufferTexture2D,然后可以使用着色器将YUV数据绘制到帧缓冲中,最后可以通过glReadPixels读取。有点复杂! - Wilson Chen

1

GL_TEXTURE_EXTERNAL_OES 纹理目标通常处于 YUV 色彩空间,而 glReadPixels() 要求目标为 RGB。它可能不会自动执行色彩空间转换。但是,您可以在自己的片段着色器中进行转换,将 RGB 渲染到另一个纹理中,然后使用 glReadPixels() 读取该纹理。

OpenGL ES 中用于 YUV420 到 RGB 转换的纹理


3
这不太准确。在Android上,YUV到RGB的转换是自动进行的,并且发生在后台。请参见https://dev59.com/C6Xja4cB1Zd3GeqPNjV1 - tmm1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接