OpenGL,如何使用framebuffer中的depthbuffer作为通常的深度缓冲区

时间:2012-03-28 19:05:34

标签: opengl framebuffer depth-buffer

我有帧缓冲区,深度组件和4个颜色附件,4个纹理

我在其中绘制了一些内容并解除了缓冲区后,使用4个纹理进行片段着色器(延迟光照)。 后来我想在屏幕上绘制更多东西,使用我的帧缓冲区中的深度缓冲区,是否可能?

我尝试再次绑定framebuffer并指定glDrawBuffer(GL_FRONT),但它不起作用。

3 个答案:

答案 0 :(得分:10)

就像Nicol已经说过的那样,你不能直接使用FBO深度缓冲区作为默认帧缓冲区的深度缓冲区。

但是你可以使用EXT_framebuffer_blit扩展名将FBO的深度缓冲区复制到默认的帧缓冲区(自GL 3起应该是核心):

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, 
                  GL_DEPTH_BUFFER_BIT, GL_NEAREST);

如果不支持此扩展(我怀疑你已经拥有FBO),你可以使用FBO深度附件的深度纹理,并使用纹理四边形和一个简单的直通片段着色器将其渲染到默认的帧缓冲区写入gl_FragDepth。虽然这可能比只是轻轻一点慢。

答案 1 :(得分:9)

我刚刚经历过,当使用glBlitFramebuffer时,将深度缓冲区从渲染缓冲区复制到主(上下文提供的)深度缓冲区是非常不可靠的。只是因为你不能保证格式匹配。使用GL_DEPTH_COMPONENT24作为我的内部深度纹理格式只是在我的AMD Radeon 6950(最新驱动程序)上不起作用,因为Windows(或驱动程序)决定使用相当于GL_DEPTH24_STENCIL8作为我的前/后缓冲区的深度格式,尽管我没有请求任何模板精度(在像素格式描述符中将模板位设置为0)。当我使用GL_DEPTH24_STENCIL8作为我的帧缓冲区的深度纹理时,Blitting按预期工作,但我有这种格式的其他问题。第一次尝试在NVIDIA显卡上运行良好,所以我很确定我没有弄乱。

最好的(根据我的经验)是通过着色器进行复制:

Fragment-Program(又名Pixel-Shader)[GLSL]

#version 150

uniform sampler2D depthTexture;
in vec2 texCoords; //texture coordinates from vertex-shader

void main( void )
{
    gl_FragDepth = texture(depthTexture, texCoords).r;
}

用于复制的C ++代码如下所示:

glDepthMask(GL_TRUE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_DEPTH_TEST); //has to be enabled for some reason
glBindFramebuffer(GL_FRAMEBUFFER, 0);
depthCopyShader->Enable();
DrawFullscreenQuad(depthTextureIndex);

我知道这个帖子已经过时了,但这是我在搞问题时的第一个结果之一,所以我希望尽可能保持一致。

答案 2 :(得分:2)

您无法将图像(颜色或深度)附加到默认帧缓冲区。同样,您无法从默认帧缓冲区中获取图像并将它们附加到FBO。