我对在 OpenGL 中使用纹理三角形网格绘制全屏背景时所看到的糟糕性能感到非常困惑:仅绘制背景而没有其他内容,使用最基本的着色器时最高可达 40 fps,而使用最基本的着色器则最高可达 50 fps使用默认管道。
虽然 40 fps 看起来并不算太糟糕,但在此基础上添加其他任何内容都会导致 fps 下降,并且考虑到我需要在此基础上绘制 100-200 个其他网格,我最终得到了微不足道的 15 fps根本无法使用。
我已将相关代码隔离到可用的 XCode 项目中 here ,但其本质是规范的纹理贴图示例:
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat texCoords[] = {
0.125, 1.0,
0.875, 1.0,
0.125, 0.0,
0.875, 0.0
};
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
if ([context API] == kEAGLRenderingAPIOpenGLES2) {
// Use shader program.
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
glBindTexture(GL_TEXTURE_2D, texture);
// Update attribute values.
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
glEnableVertexAttribArray(ATTRIB_TEXCOORD);
} else {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable( GL_TEXTURE_2D );
glBindTexture(GL_TEXTURE_2D, texture);
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
顶点着色器:
attribute lowp vec4 position;
attribute lowp vec2 tex;
varying lowp vec2 texCoord;
uniform float translate;
void main()
{
gl_Position = position;
texCoord = tex;
}
片段着色器:
varying lowp vec2 texCoord;
uniform sampler2D texture;
void main()
{
gl_FragColor = texture2D(texture, texCoord);
}
将矩形大小除以二会使帧速率加倍,因此渲染时间显然取决于绘图在屏幕上占用的空间。这完全有道理,但对我来说没有意义的是,似乎不可能以超过 15 fps 的速度用 OpenGL 纹理映射网格覆盖整个屏幕。
但是有数百款游戏可以做到这一点,所以这是可能的,我一定做错了什么,但它是什么?
最佳答案
不幸的是,我现在只有 iPad 2 来测试这个(我的 iPad 1 测试设备坐在家里),而且它的片段处理速度快得离谱。它的帧速率被固定在 60 FPS,在您的日志记录中理论帧速率为 1400。
但是,我使用 OpenGL ES 驱动程序和时间分析器仪器以及酷炫的新 OpenGL ES 分析器(Xcode 4 附带)通过 Instruments 运行了它。 OpenGL ES 分析器的结果如下所示:
查看 OpenGL ES 驱动程序中的 Tiler 使用统计数据显示,Tiler 几乎没有被使用,但渲染器有一些使用(同样,在我的 iPad 2 上只有 5%)。这表明针对几何图形使用 VBO 和索引的建议可能对您没有多大帮助。
最突出的是关于冗余调用的警告:
您不断绑定(bind)帧缓冲区并设置每一帧的视口(viewport),根据 Time Profiler,这占应用程序中工作负载的 10%。注释掉该行
[(EAGLView *)self.view setFramebuffer];
在我的 iPad 2 上,在帧绘制开始附近,理论帧速率从 1400 FPS 跃升至 27000 FPS(顺便说一句,您可能应该 measure using milliseconds for your rendering )。
同样,这是我在 iPad 2 中真正强大的 GPU 上运行的测试,但您应该能够在原始 iPad 或任何其他设备上重复这些类似的步骤,以验证此性能瓶颈并可能突出显示其他性能瓶颈。我发现新的 OpenGL ES 分析器在解决与着色器相关的性能问题方面非常方便。
关于iphone - 全屏背景纹理与 OpenGL 性能问题 (iPad),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5594951/