2011-08-26 143 views
22

我已经看到了很多关于这个主题的资料,但是我发现的例子和我很难理解正确的过程有一些差异。希望有人能告诉我,如果我在正确的轨道上。我还应该提到我在OS X Snow Leopard和Xcode 3的最新版本上这样做。设置OpenGL多个渲染目标

为了举例,假设我要写入两个目标,一个用于正常,一个用于颜色。要做到这一点,我创建一个帧缓冲和绑定两个纹理它,以及一个深度纹理:

glGenFramebuffersEXT(1, &mFBO); 
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); 

glGenTextures(1, &mTexColor); 
glBindTexture(GL_TEXTURE_2D, mTexColor); 
//<texture params> 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexColor, 0); 

glGenTextures(1, &mTexNormal); 
glBindTexture(GL_TEXTURE_2D, mTexNormal); 
//<Texture params> 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mTexNormal, 0); 

glGenTextures(1, &mTexDepth); 
glBindTexture(GL_TEXTURE_2D, mTexDepth); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); 
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, mTexDepth, 0); 

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) 

在渲染之前,我会再次绑定的帧缓冲,然后执行:

GLenum buffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; 
glDrawBuffers(2, buffers); 

这意味着进一步的调用会引起我的帧缓冲区。 (我认为?)

然后,我会设置我的着色器并绘制场景。在我的顶点着色器中,我会像往常一样处理法线/位置/颜色,并将数据传递给片段着色器。该片段然后会做这样的事情:

gl_FragData[0] = OutputColor; 
gl_FragData[1] = OutputNormal; 

在这一点上,我应该有两个纹理;一个来自所有渲染对象的颜色和一个带法线的颜色。这一切是否正确?我现在应该可以像使用其他任何其他纹理一样使用这些纹理,比如说将它们渲染为全屏四边形,对吧?

回答

10

听起来很合理。这确实是通常的做法。如果不需要深度数据作为纹理进行进一步处理,还可以使用渲染缓冲区作为附件,但纹理也应该可以正常工作。

完成所有设置后,您还可以使用glCheckFramebufferStatusEXT来查看帧缓冲区在当前配置下是否有效,但代码看起来不错。如果你没有问题,这只是为了保证,那么请放心,你在正确的轨道上,否则告诉我们什么是错的。

+0

感谢您的回答!这更多的只是一个保证类型的问题,以确保我没有分配我不需要的东西,而且订单看起来没问题。将使用渲染缓冲而不是纹理提供任何性能优势? – TaylorP

+0

@Tlorlor我不知道,可能不会。 –

+2

我知道这是一个老问题。但是,是的,与使用纹理相比,使用渲染缓冲区会获得更好的性能。由于渲染缓冲区可以利用更优化的数据存储方式和处理绘制操作的过程。 – Vallentin