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

当我在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);
}

将矩形的大小除以帧速的两倍,所以渲染时间显然取决于绘图在屏幕上的实际占有面积。 这是完全合理的,但对我来说没有意义的是,用OpenGL纹理映射网格覆盖整个屏幕看起来不可能超过15 fps。

然而,现在有数百款游戏可以做到这一点,所以这是可能的,我必须做错事,但是它是什么?


不幸的是,我拥有的就是我的iPad 2,现在正在测试它(我的iPad 1测试装置正坐在家中),并且它的快速碎片处理速度非常快。 它被固定在60 FPS,在你的测井中有1400理论FPS。

但是,我使用OpenGL ES Driver和Time Profiler仪器以及新的OpenGL ES Analyzer(随Xcode 4一起提供)在仪器上运行。 这就是OpenGL ES分析器的结果:

OpenGL ES分析器

查看OpenGL ES驱动程序中的Tiler Utilization统计信息显示,根本没有使用tiler,但渲染器有一些用处(同样,我的iPad 2上只有5%)。 这表明对于几何体使用VBOs和索引的建议可能对您没有太大帮助。

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

OpenGL ES冗余呼叫

你保持绑定framebuffer并设置每个帧的视口,这根据时间分析器是占应用程序工作量的10%。 注释掉该行

[(EAGLView *)self.view setFramebuffer];

在画框开始附近导致理论帧速率在我的iPad 2上从1400 FPS跳到27000 FPS(另外,您应该使用毫秒进行渲染)。

再次,这是我在iPad 2上运行真正强大的GPU的测试,但您应该能够在原始iPad或任何其他设备上重复这些类似的步骤来验证此性能瓶颈并可能突出显示其他设备。 我发现新的OpenGL ES分析器在处理与着色器相关的性能问题时非常方便。


疯狂的猜测下面,我没有任何iPad的经验:

根据这个基准,在背景分辨率下,你可以预期纯填充率约为214fps。

你尝试禁用纹理,检查你是否受限于你的纹理?

你的纹理是“两种纹理的无力”吗? 在这种情况下,你有没有尝试删除GL_REPEATGL_TEXTURE_WRAP_* ,通过更换GL_CLAMP(_TO_EDGE) 重复NPOT可能会在某些硬件上花费一些性能。

最终,您可以尝试将最小/最大过滤器设置为GL_NEAREST。

链接地址: http://www.djcxy.com/p/33969.html

上一篇: Full screen background texture with OpenGL performance issue (iPad)

下一篇: Unable to Draw 3D (Frustum) on top of 2D (Ortho) in OpenGL