2012-07-16 85 views
3

我有一个OpenGL的纹理,并希望能够读回一个像素的值,所以我可以在屏幕上显示它。如果纹理是一个普通的旧RGB纹理或类似,这是没有问题:我需要一个空的帧缓冲区对象,我已经躺在附近,质地重视COLOR0的帧缓冲,并呼吁:如何有效地从Depth Texture中读取像素?

glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, &c); 

其中c本质上是一个浮动[4]。

然而,当它是一种深度纹理,我得走了一条不同的代码路径,设置深度附件代替COLOR0,并呼吁:

glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &c); 

其中c为浮动。这适用于运行NVIDIA GeForce 580的Windows 7计算机,但在旧版2008 MacBook Pro上导致出现错误。具体来说,在将深度纹理附加到帧缓冲区之后,如果我调用glCheckFrameBufferStatus(GL_READ_BUFFER),则会得到GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER。

搜索OpenGL的文档后,我发现这条线,这似乎意味着,OpenGL的不支持从帧缓冲区的深度分量阅读,如果没有附色:

GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER is returned if GL_READ_BUFFER is not GL_NONE 
and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color 
attachment point named by GL_READ_BUFFER. 

果然如果我创建了一个临时颜色纹理并将其绑定到COLOR0,那么当我从深度纹理读取像素时不会发生错误。

通过此代码,每次创建临时纹理(编辑:或甚至一次,并使GPU内存受其束缚)通过此代码很烦人,并且可能很慢,所以我想知道是否有人知道另一种方式来读取单个像素从深度纹理? (当然,如果没有更好的方法,我会围绕一个纹理进行调整,以便在需要时调整大小,并仅将其用于临时颜色附件,但这看起来相当迂回)。

+0

“现在每次通过此代码创建临时纹理”为什么每次通过此代码创建临时纹理*?你为什么不一次性创建它,让它连接到FBO? – 2012-07-16 18:56:15

+0

I * do *继续说:“我将保留一个纹理,以便在需要时调整大小,并仅将其用于临时颜色附件。”我只是这样做,以测试是否可行。但是我说它的方式很混乱,所以我会改变它。谢谢。 – MikeMx7f 2012-07-16 19:28:07

回答

5

答案被包含在你的错误信息:

如果GL_READ_BUFFER不GL_NONE

这样做;将读取缓冲区设置为GL_NONE。用glReadBuffer。像这样:

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); //where fbo is your FBO. 
glReadBuffer(GL_NONE); 

这样,即使FBO只具有深度纹理,也是正确完成的。

+0

太棒了,它完美的作品。我知道我错过了一些东西,但我只是因为OpenGL规范很愚蠢而被拒绝了。 – MikeMx7f 2012-07-16 19:26:22