我正在使用OpenGL管道开发IOS游戏。我已经能够将我想要的图形渲染到屏幕上,但是,我打电话glDrawElements
太多次了,并且最终会遇到一些关于遇到性能问题的担忧。我的游戏中有几个静态元素,不需要在每个渲染周期渲染。有没有办法可以将静态元素渲染到一个帧缓冲区,将动态元素渲染到另一个帧缓冲区?
这是我尝试过的代码:
static BOOL renderThisFrameBuffer = YES;
if (renderThisFrameBuffer) {
glBindFramebuffer(GL_FRAMEBUFFER, interFrameBuffer);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
// Set up projection matrix
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * OpenGLView.frame.size.height / OpenGLView.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:50];
glUniformMatrix4fv(projectionUniform, 1, 0, projection.glMatrix);
glViewport(0, 0, OpenGLView.frame.size.width, OpenGLView.frame.size.height);
for (BoardSpace *boardSpace in spaceArray){
[boardSpace drawWithMatrix:modelView];
}
[context presentRenderbuffer:GL_RENDERBUFFER];
glBindFramebuffer(GL_FRAMEBUFFER, constFrameBuffer);
renderThisFrameBuffer = false;
}
在这种情况下,我之前创建了两个帧缓冲区:静态元素为interFrameBuffer
,动态元素为constFrameBuffer
。我错过了什么吗?
答案 0 :(得分:2)
应该可以。最直接的方法是将静态元素渲染到FBO一次。然后在每次重绘时,将静态FBO的内容复制到默认的帧缓冲区,然后在其上绘制动态元素。
ES 2.0的功能集是一种支持此功能的边界线。例如,您没有glBlitFramebuffer()
,这是将FBO内容复制到默认帧缓冲区的便捷方式。但是您可以使用简单的着色器程序进行复制,该程序通过顶点着色器中的坐标进行提供,并且仅在片段着色器中使用纹理样本操作。然后将渲染静态内容的纹理绑定到,并绘制一个大小为四的屏幕。
如果动态渲染需要静态渲染的深度缓冲区,则会变得更加棘手。例如,如果动态内容被静态内容遮挡,则会出现这种情况。在这种情况下,您还需要复制深度缓冲区。通过快速刷新我对规范的记忆,我没有看到任何可以在ES 2.0中实现这一点的东西。 glBlitFramebuffer()
不在那里。看起来ES 2.0不支持深度纹理。如果你想去那里,你将进入ES 3.0领域。
有了这一切,你显然希望确保它真的有助于你的表现。复制帧缓冲区不是免费的。如果它比渲染静态元素便宜,它只会得到回报。在做出决定之前,两种方法的基准测试肯定是有条理的。