使用帧缓冲区将深度缓冲区渲染为纹理

时间:2012-09-22 18:03:34

标签: java c++ opengl jogl framebuffer

我正在使用JOGL,但这个问题一般适用于OpenGL。似乎存在类似的问题,但它们要么针对GLSL代码,要么与复制帧缓冲区的内容有关,要么是一般建议 - 使用帧缓冲对象而不是glCopyTexSubImage2D

问题

我正在做一些阴影贴图。如何使用帧缓冲对象将深度通道直接渲染到纹理?

请您发布一段初始化纹理和帧缓冲区对象的代码,以及在渲染场景之前初始化所有内容的代码吗?

目前,我使用glCopyTexSubImage2D。我像这样初始化纹理:

glGenTextures(1, &textureNo)
glBindTexture(GL_TEXTURE_2D, textureNo)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL)
glTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY)
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 2048, 2048, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, null)

然后我这样渲染:

glBindTexture(GL_TEXTURE_2D, textureNo)
glClear(GL_DEPTH_BUFFER_BIT)
drawScene()
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 2048, 2048)

并且这很好用,纹理最终保持场景的深度通道 - 这意味着我的投影和视图矩阵被正确设置以从光的角度查看场景。我想改用帧缓冲对象。

我需要更改以上内容才能使用帧缓冲区对象直接渲染到纹理?

编辑:

这是我尝试过的。我首先初始化了帧缓冲区对象:

glGenFramebuffers(1, &fbo)

然后我像这样渲染:

glBindFramebuffer(GL_FRAMEBUFFER, fbo)
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureNo, 0)
glBindTexture(GL_TEXTURE_2D, textureNo)
drawScene()

我已经确认上述内容适用于GL_RGBGL_COLOR_ATTACHMENT0类型的纹理,但它似乎不适用于GL_DEPTH_COMPONENT类型纹理和GL_DEPTH_ATTACHMENT - 深度通道不会渲染到上面的纹理textureNo中。

1 个答案:

答案 0 :(得分:4)

假设这是所有FBO设置代码,我看不到您调用glCheckFramebufferStatus的部分。你知道,这个函数会告诉你你的Framebuffer Object was incomplete,然后渲染它会失败。

具体来说,它会给你GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER​,因为你没有设置有效的绘图缓冲区。如果您不使用颜色附件,则需要使用glDrawBuffer将所有颜色缓冲区写入设置为GL_NONE

这是一个常见的FBO陷阱;你不会是第一个没有看到它的人。但这就是为什么修改FBO后总是检查glCheckFramebufferStatus至关重要。