2013-01-08 146 views
1

我正在开发opengl 2.1和opengl es 2.0。我想实现整个场景的景深效果。我知道如何为具有着色器的单个模型执行此操作,但这需要所有模型都具有相同代码的着色器。有没有办法检索最终场景深度和颜色缓冲区并将其存储到纹理中,以便我可以再次使用DOF着色器使用它们?或者这是一个坏主意?编辑] 终于搞定了。绘制第一个电话时检索最终场景z缓冲区和颜色缓冲区

glGenFramebuffers(1, &frameBuffer_); 
glGenTextures(1, &colorBuffer_); 
glGenTextures(1, &depthBuffer_); 
//glGenRenderbuffers(1, &depthBuffer_); 

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer_); 

glBindTexture(GL_TEXTURE_2D, colorBuffer_); 
glTexImage2D(
    GL_TEXTURE_2D, 
    0, 
    GL_RGBA, 
    width, 
    height, 
    0, 
    GL_RGBA, 
    GL_UNSIGNED_BYTE, 
    NULL); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glFramebufferTexture2D(
    GL_FRAMEBUFFER, 
    GL_COLOR_ATTACHMENT0, 
    GL_TEXTURE_2D, colorBuffer_, 0); 

glBindTexture(GL_TEXTURE_2D, depthBuffer_); 
glTexImage2D(
    GL_TEXTURE_2D, 
    0, 
    GL_DEPTH24_STENCIL8, 
    width, 
    height, 
    0, 
    GL_DEPTH_STENCIL, 
    GL_UNSIGNED_INT_24_8, 
    NULL); 

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glFramebufferTexture2D(
    GL_FRAMEBUFFER, 
    GL_DEPTH_ATTACHMENT, 
    GL_TEXTURE_2D, depthBuffer_, 0); 

//glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer_); 
//glRenderbufferStorage(
// GL_RENDERBUFFER, 
// GL_DEPTH_COMPONENT24, 
// width, 
// height); 
//glFramebufferRenderbuffer(
// GL_FRAMEBUFFER, 
// GL_DEPTH_ATTACHMENT, 
// GL_RENDERBUFFER, depthBuffer_); 

GLenum status; 
status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); 
switch(status) { 
case GL_FRAMEBUFFER_COMPLETE: 
    // Success. 
break; 
case GL_FRAMEBUFFER_UNSUPPORTED: 
    LOGE("Frame buffer format not supported."); 
break; 
default: 
    LOGE("Framebuffer Error."); 
} 

后来: 初始化代码看起来像这样

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer_); 

渲染的场景,然后调用:

glBindFramebuffer(GL_FRAMEBUFFER, 0); 

现在什么都可以在这里使用呈现depthBuffer_或colorBuffer_作为OpengGL纹理句柄。

+3

扩展最小工作的例子,我相信你可以使用EXT或ARB功能在2.1接入帧缓冲对象(宗教组织)查看

https://github.com/datenwolf/codesamples/tree/master/samples/OpenGL/minimalfbo

。他们甚至可能被提升为核心,我不记得了。 如果可以,那么只需将所有内容呈现给FBO即可。将纹理附加到GL_COLOR_ATTACHMENT0和GL_DEPTH_STENCIL_ATTACHMENT。然后,将FBO作为纹理绑定并在其上运行着色器。 – Aeluned

+0

如何将FBO作为纹理进行绑定? – SMart

回答

3

使用framebuffer对象。它们是OpenGL-ES-2的一部分,可作为OpenGL-2.1的扩展(支持良好)。

使用在桌面上的OpenGL 2.x的

+0

谢谢,我的色彩缓冲区现在可以工作。但我仍然不知道如何使用深度缓冲区。现在,当我使用颜色缓冲区渲染平面并尝试使用gl_FragCoord.z时,我总是得到0.0f。这是因为它应该是如果没有FBO,因为飞机就在相机前面。但是我需要gl_FragCoord.z值作为FBO渲染的场景,就好像根本没有飞机一样。我不知道该怎么做。我是否需要调用一些将FBO深度缓冲区复制到当前默认缓冲区的其他方法?我有什么意义吗? – SMart

+1

使用深度纹理而不是渲染缓冲区。然后将深度纹理绑定到第二个纹理单元并从中读取。 – datenwolf

+0

你能给我一个代码的例子吗?我像这样添加颜色缓冲区:glBindTexture(GL_TEXTURE_2D,colorBuffer_);它的工作原理,所以我尝试了glBindTexture(GL_TEXTURE_2D,depthBuffer_);不幸的是,这增加了一些其他纹理,这绝对不是深度。我如何将depthBuffer_添加为纹理? – SMart