2013-01-08 45 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