Iphone 带有OpenGL性能问题的全屏背景纹理(iPad)

Iphone 带有OpenGL性能问题的全屏背景纹理(iPad),iphone,ipad,opengl-es,textures,opengl-es-2.0,Iphone,Ipad,Opengl Es,Textures,Opengl Es 2.0,在OpenGL中使用带纹理的三角形网格绘制全屏背景时,我对所看到的糟糕性能感到非常困惑:使用最基本的着色器仅绘制背景,其他任何内容都不会以40 fps的速度最大化,使用默认管道以50 fps的速度最大化 虽然40fps看起来并不太糟糕,但是在上面添加任何其他东西都会使fps下降,并且考虑到我需要在上面绘制100-200个其他网格,我最终得到的是微不足道的15fps,这根本不可用 我已经将相关代码隔离到一个可用的XCode项目中,但其实质是规范的纹理贴图示例: static const GLflo

在OpenGL中使用带纹理的三角形网格绘制全屏背景时,我对所看到的糟糕性能感到非常困惑:使用最基本的着色器仅绘制背景,其他任何内容都不会以40 fps的速度最大化,使用默认管道以50 fps的速度最大化

虽然40fps看起来并不太糟糕,但是在上面添加任何其他东西都会使fps下降,并且考虑到我需要在上面绘制100-200个其他网格,我最终得到的是微不足道的15fps,这根本不可用

我已经将相关代码隔离到一个可用的XCode项目中,但其实质是规范的纹理贴图示例:

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);
}
将矩形大小除以2会使帧速率加倍,因此渲染时间显然取决于图形在屏幕上的实际位置。这完全有道理,但对我来说没有意义的是,用OpenGL纹理贴图网格以超过15 fps的速度覆盖整个屏幕似乎是不可能的


然而,有数百种游戏可以做到这一点,所以这是有可能的,我一定是做错了什么,但这是什么?

不幸的是,我现在只有我的iPad2来测试这一点(我的iPad1测试单元就在家里),而且它的碎片处理速度快得离谱。它被锁定在60 FPS,在你的日志中有1400 FPS的理论速度

然而,我使用OpenGL ES驱动程序和时间分析器工具,以及酷炫的新OpenGL ES分析器(随Xcode 4提供)在仪器中运行了它。这就是OpenGL ES Analyzer的结果:

查看OpenGL ES驱动程序中的瓷砖利用率统计数据可以看出,瓷砖几乎没有被使用,但渲染器有一些用处(同样,在我的iPad2上只有5%)。这表明对几何体使用VBO和索引的建议可能对您没有多大帮助

最突出的是关于冗余呼叫的警告:

您将继续绑定帧缓冲区并在每一帧设置视口,根据Time Profiler,这将占应用程序工作负载的10%。评论这句话

[(EAGLView *)self.view setFramebuffer];
在刚开始画框的时候,我的iPad2上的理论帧速率从1400 FPS跃升到27000 FPS(顺便说一句,你应该这样做)


同样,这是我在iPad2中真正强大的GPU上运行的测试,但你应该能够在原始的iPad或任何其他设备上重复这些类似的步骤,以验证这个性能瓶颈,并可能突出其他瓶颈。我发现新的OpenGL ES Analyzer在发现与着色器相关的性能问题方面非常方便。

以下是我的猜测,我没有任何iPad体验:

根据这一点,在背景分辨率下,纯填充率大约为214fps

您是否尝试禁用纹理,以检查您是否受到纹理的限制

你的纹理是“非二次幂纹理”吗?在这种情况下,您是否尝试用
GL\u夹具(\u到\u边缘)
替换
GL\u纹理包裹
中的
GL\u REPEAT
?重复NPOT可能会降低某些硬件的性能


最后,您还可以尝试将最小/最大筛选器设置为GL_NEAREST。

FWIW,您在进行相关调用后启用客户端状态的原因是什么?(例如,在启用vert数组之前调用vertex指针)实际上,大多数代码都来自OpenGL ES iPad应用程序的默认模板,这并不意味着它是好代码,但只要它能工作,我就不会问自己这样或那样做是否有意义:-)“不幸的是,我现在只有我的iPad 2来测试这个”。我想和你一样不幸:-)谢谢你在iPad2上测试应用程序!我从你的回答中得出结论,你认为我画背景的方式没有错吗?@Guy-我刚刚在我现在已经过时的iPad1上试用了这个方法,我仍然获得60 FPS,在删除上面多余的调用之前,旧硬件上的理论FPS为1400 FPS。在您的Xcode构建设置中可能存在一些问题,因为您的测试用例运行速度与在我的硬件上一样快。此外,这是在该硬件上使用iOS 4.3.1。如果你在3.2上,可能会慢一些。谢谢你的理智检查,我会进一步调查的!这张图片没有2维的能力,但我将其加载到512x512纹理中,我也尝试了GL_NEAREST,但没有GL_CLAMP。好的,谢谢你的指点。