【问题标题】:How to read a pixel from a Depth Texture efficiently?如何有效地从深度纹理中读取像素?
【发布时间】:2012-07-16 16:12:03
【问题描述】:

我有一个 OpenGL 纹理并希望能够读回单个像素的值,以便将其显示在屏幕上。如果纹理是常规的旧 RGB 纹理或类似的纹理,这没问题:我拿一个空的 Framebuffer Object 放在周围,将纹理附加到帧缓冲区上的 COLOR0 并调用:

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

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

但是,当它是深度纹理时,我必须走不同的代码路径,设置 DEPTH 附件而不是 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 内存被它占用)很烦人并且可能很慢,所以我想知道是否有人知道读取单个像素的另一种方法从深度纹理? (当然,如果没有更好的方法,我将保留一个纹理以在需要时调整大小,并仅将其用于临时颜色附件,但这似乎相当迂回)。

【问题讨论】:

  • "现在每次都通过这段代码创建一个临时纹理" 为什么要每次都通过这段代码创建一个临时纹理?为什么不直接创建一次并将其附加到 FBO?
  • 确实继续说“我将保留一个纹理以在需要时调整大小,并仅将其用于临时颜色附件。”我这样做只是为了测试它是否有效。但是我表达的方式令人困惑,所以我会改变它。谢谢。

标签: opengl


【解决方案1】:

答案包含在您的错误消息中:

如果 GL_READ_BUFFER 不是 GL_NONE

那就这样做吧;将读取缓冲区设置为GL_NONE。与glReadBuffer。像这样:

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

这样,FBO 就可以正确完成,即使它只有深度纹理。

【讨论】:

  • 太好了,效果很好。我知道我遗漏了一些东西,但我对这个答案半信半疑,只是因为 OpenGL 规范很愚蠢。
猜你喜欢
  • 2011-11-06
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 2013-11-22
  • 2019-08-29
相关资源
最近更新 更多