我需要有任意数量的传递,其中每个传递渲染到某种缓冲区,然后将其用作下一遍的输入纹理。
目前,每个缓冲区都由FBO实现,纹理附加到COLOR0。首先,我用
创建FBO(和里面的纹理)glGenTextures(1, texIds, 0);
glBindTexture(GL_TEXTURE_2D, texIds[0]);
// ... here goes the usual glTexParameterf stuff ...
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glGenFramebuffers(1, fboIds, 0);
glBindFramebuffer(GL_FRAMEBUFFER, fboIds[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texIds[0], 0);
然后每当我需要渲染到Buffer时,我都会调用
glBindFramebuffer(GL_FRAMEBUFFER, fboIds[0]);
每当我需要将Buffer的内容设置为下一遍的输入时,我就
glBindTexture(GL_TEXTURE_2D, texIds[0]);
一切正常。
问题在于我在众多来源中读到BindFramebuffer调用非常慢(刷新整个管道),特别是在我使用的OpenGL ES目标上。例如,SongHo Ahn明确表示
"(...)切换可连接帧缓冲的图像要快得多 在FBO之间切换。"
(http://www.songho.ca/opengl/gl_fbo.html)
因此我想改用只有1个帧缓冲区和许多纹理的设计;每次我需要渲染到Buffer时,我只会将给定的纹理附加到唯一的Framebuffer的COLOR0上。
你认为这是个好主意吗?或者也许一些完全不同的设计在这里最好 - RenderBuffers怎么样?答案 0 :(得分:1)
根据this NVIDIA presentation(第65页),您不应在一个FBO上交换附件:
“不要创建一个FBO,然后在其上交换附件。这 导致驱动程序中的大量验证,这反过来导致不良 性能“。
这是因为当您将新纹理附加到FBO的颜色附件时,OpenGL驱动程序必须检查附件是否正确以及FBO是否完整,如果经常这样做会非常昂贵。
还可以同时渲染多个颜色附件,但这仅适用于OpenGL ES 3.0 +。
但总的来说,问题的答案是不。您应该坚持使用多个FBO而不是更改其上的附件。
答案 1 :(得分:1)
另外(有点矛盾)与MarGenDo链接的NVidia演示文稿,这里是OpenGL.org official documentation的链接,似乎表明(部分)相反:
最好每次制作1个FBO并将纹理绑定到它上面 需要渲染到纹理? FBO本身不会占用太多内存。 它是一个状态向量对象。在性能方面,每次你 绑定,驱动程序需要验证占用CPU时间的状态。 从逻辑上讲,每个Render_To_Texture最好有1个FBO (RTT)。但是,已经发现,如果您的速度提高,您将获得速度提升 纹理大小相同,你可以使用1个FBO。如果你有10个 64x64的纹理和512x64的10个纹理构成2个FBO。 每组一名FBO。
答案 2 :(得分:1)
Leszek的评论必须纳入背景,以完成当前接受的答案。
如果正在使用< Opengl es 3.0,保持FBO附件相同并更改FBO总是更好。改变FBO的代价很高;没有必要逃脱它。更改底层资源只会带来更多额外工作。除了帧缓冲完整性之外,驱动程序还必须验证新纹理的渲染能力。
使用3.0+,可以附加多个纹理/渲染缓冲区,并有效地使用draw_buffer_attachment以最小的状态开销进行渲染。 FBO或GL_COLOR_BUFFER_ATTACHMENT根本不需要改变。