全屏幕背景纹理与OpenGL性能问题(iPad)

Guy*_*lon 6 iphone textures opengl-es ipad opengl-es-2.0

我在使用OpenGL中使用纹理三角形网格绘制全屏幕背景时看到的糟糕表现让我感到困惑:使用最基本的着色器绘制背景并且没有其他任何内容以40 fps最大化,使用默认值使用50 fps管道.

虽然40 fps似乎并不太糟糕,但在其上添加任何其他内容会使fps下降,并且考虑到我需要在其上绘制100-200个其他网格,我最终得到的是一个微不足道的15 fps,这根本就不是可用.

我已将相关代码隔离到此处可用的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);
Run Code Online (Sandbox Code Playgroud)

顶点着色器:

attribute lowp vec4 position;
attribute lowp vec2 tex;

varying lowp vec2 texCoord;

uniform float translate;

void main()
{
    gl_Position = position;
    texCoord = tex;
}
Run Code Online (Sandbox Code Playgroud)

片段着色器:

varying lowp vec2   texCoord;
uniform sampler2D   texture;

void main()
{
    gl_FragColor = texture2D(texture, texCoord);
}
Run Code Online (Sandbox Code Playgroud)

将矩形大小除以2是帧速率的两倍,因此渲染时间显然取决于绘图在屏幕上占据的空间.这完全有道理,但对我来说没有意义的是,用超过15 fps的OpenGL纹理映射网格覆盖整个屏幕是不可能的.

然而,有数以百计的游戏在那里做,所以它是可能的,我必须做错事,但它是什么?

Bra*_*son 7

不幸的是,我所拥有的只是我的iPad 2来测试它(我的iPad 1测试单元坐在家里),并且它具有可笑的快速片段处理.它被固定在60 FPS,你的日志记录中有1400理论FPS.

但是,我使用OpenGL ES驱动程序和Time Profiler仪器以及酷炫的新OpenGL ES Analyzer(随Xcode 4提供)运行仪器.这就是OpenGL ES Analyzer的结果:

OpenGL ES分析器

查看OpenGL ES驱动程序中的Tiler Utilization统计信息,显示该窗口器几乎没有被使用,但渲染器有一些用处(同样,我的iPad 2上只有5%).这表明对几何体使用VBO和索引的建议可能对您没有多大帮助.

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

OpenGL ES冗余调用

您继续绑定帧缓冲区并每帧设置视口,根据Time Profiler,它占应用程序工作负载的10%.评论出来

[(EAGLView *)self.view setFramebuffer];
Run Code Online (Sandbox Code Playgroud)

在你的框架绘图开始附近导致理论帧率从我的iPad 2上的1400 FPS跳到27000 FPS(另外,你可能应该用毫秒来测量你的渲染).

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