【问题标题】:OpenGL ES2.0 glReadPixels() read data from renderbuffer through framebufferOpenGL ES2.0 glReadPixels() 通过帧缓冲区从渲染缓冲区读取数据
【发布时间】:2013-09-13 09:04:06
【问题描述】:

我在 Android 上使用 opengl es2.0 进行离屏处理。

我创建了一个渲染缓冲区,并将其附加到帧缓冲区 FBO,在渲染到 FBO 后,我尝试通过 getReadPixels() 方法从该 FBO 获取像素。但我一无所获。

代码如下:

GLuint resultFBO;// FBO
    GLuint rboId;  //render buffer id
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, image_width, image_height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

glGenFramebuffers(1, &resultFBO);
glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
        GL_RENDERBUFFER, rboId);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_COMPLETE) {
    //LOGH("Single FBO setup successfully.");
} else {
    LOGH("Problem in setup FBO texture: %d .", status);
}

//After render to the FBO 
glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);
glReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, imageSetData);

【问题讨论】:

  • 有什么理由将 16 位深度缓冲区读入 ubyte 数组?
  • @ChristianRau 我在调用 glRenderbufferStorage 时尝试使用 GL_DEPTH_COMPONENT,但这会因错误而失败。
  • 好吧,那又怎样? GL_DEPTH_COMPONENT16 可能是个好主意,但为什么要将它读入 ubyte 数组呢?
  • 顺便问一下,"nothing"到底是什么?您如何检查imageSetData 的内容以及它实际包含的内容(因为它不能包含“nothing”)?
  • @ChristianRau 实际上在我将数据传输到 imageSetData 之后,我会在屏幕上显示它。以前我渲染到纹理,并使用 getReadPixels(),我可以获取并查看图像。现在我要渲染到渲染缓冲区,getReadPixels() 方法不会将任何数据传输到我的 imageSetData。

标签: android opengl-es-2.0


【解决方案1】:

您不能在 OpenGL ES 2.0 中从 GL_DEPTH_COMPONENT 转换为 glReadPixels()。仅来自颜色缓冲区。请参阅 API 参考 here。


void glReadPixels(  GLint x,
    GLint y,
    GLsizei width,
    GLsizei height,
    GLenum format,
    GLenum type,
    GLvoid * data);

格式
指定像素数据的格式。接受以下符号值:GL_ALPHA、GL_RGB 和 GL_RGBA


解决方法 1:如果精度不是那么重要,您可以改为将深度写入 8 位颜色通道之一。

解决方法 2:您可以通过将浮点数打包到 vec4 中来将深度写入 RGBA 通道:例如参见 this SO thread。

解决方法3:您可以尝试OES_depth_texture 扩展,如果支持,则改为渲染到深度纹理。

【讨论】:

  • 但是当我需要通过FBO渲染到渲染缓冲区时,当我为渲染缓冲区分配内存时,我使用glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, image_width, image_height); 这里我使用GL_DEPTH_COMMPNET16,所以我认为我不能使用GL_RGB读取像素。你怎么看?
  • 我链接到一个线程,该线程解释了如何将深度浮点数打包到 RGBA vec4 中。
  • 您好,感谢您的重播,我可以再问您一个问题吗?关于着色器的精度,我的代码在 openg GL 的桌面版本上运行良好,但是当我移植到 Android 时,我发现结果图像中有一些伪影,白色变成绿色,我在桌面上使用 RGB32 格式,但我在Android上使用RGB格式(每个通道8位),这是问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-26
  • 1970-01-01
  • 2011-09-04
  • 2014-07-08
相关资源
最近更新 更多