2011-04-08 43 views
6

我对使用OpenGL中的纹理三角形网格绘制全屏幕背景时看到的糟糕表现感到困惑:只绘制背景而没有其他东西在使用最基本的着色器为40 fps,使用默认管道为50 fps。全屏幕背景纹理与OpenGL性能问题(iPad)

虽然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); 
} 

将矩形大小除以2渲染时间明显地取决于绘图在屏幕上显示的房地产。这是完全合理的,但对我来说没有意义的是,用OpenGL纹理映射网格覆盖整个屏幕看起来不可能超过15 fps。

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

+0

FWIW,您为什么在拨打相关电话后启用客户端状态的任何原因? (例如,在启用vert数组之前调用顶点指针) – 2011-04-08 15:21:29

+0

实际上,大多数代码都来自OpenGL ES iPad应用程序的默认模板,这并不意味着它是很好的代码,但只要它有效,我就不会问自己无论这种或那种方式是否有意义:-) – 2011-04-08 16:47:16

回答

7

不幸的是,我现在所拥有的就是我的iPad 2来测试它(我的iPad 1测试装置坐在家里),并且它具有快速的碎片处理能力。它被固定在60 FPS,在你的测井中有1400理论FPS。但是,我使用OpenGL ES驱动程序和Time Profiler仪器以及酷炫的新型OpenGL ES分析器(随Xcode 4一起提供)在仪器上运行。这是从的OpenGL ES分析的结果如下:

OpenGL ES Analyzer

综观了OpenGL ES驱动铺放器使用率统计显示几乎被所有使用的瓦工,但有一些使用的渲染器(再次,在我的iPad 2上只有5%)。这表明对于几何体使用VBOs和索引的建议可能对您没有太大帮助。

那伸出的一个是关于冗余呼叫警告:

OpenGL ES redundant calls

你留着结合帧缓存和设置视每一帧,而根据时间探查器占10%工作负载在您的应用程序。注释掉靠近你的框架拉制开始行

[(EAGLView *)self.view setFramebuffer]; 

引起了理论帧率跳从1400 FPS 27000 FPS在我的iPad 2(顺便说一句,你应该measure using milliseconds for your rendering)。

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

+0

“不幸的是,我所拥有的就是我的iPad 2,现在就测试它”。我想和你一样不幸:-)感谢您将测试应用程序放在iPad 2上!我从你的回答中看出,你看我画背景的方式没有错? – 2011-04-08 16:48:12

+0

@Guy - 我刚刚在我现在已经过时的iPad 1上试用了这款产品,而且我仍然获得60 FPS,即使在删除上面的多余呼叫之前,该旧硬件上的理论FPS也是1400。在你的Xcode构建设置中可能会有些问题,因为你的测试用例在我的硬件上运行的速度非常快。此外,这是在该硬件上使用iOS 4.3.1。如果你使用3.2,可能会变慢。 – 2011-04-09 00:47:50

+0

感谢一堆为了理智检查,我会进一步调查! – 2011-04-10 09:18:57

0

胡乱猜测下面,我没有任何的iPad体验:根据本benchmark

,你可以期望有关于纯填充率214fps,在背景的分辨率。

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

你的质感是“两种质感的非功率”吗?在这种情况下,您是否尝试从GL_TEXTURE_WRAP_*中删除GL_REPEAT,替换为GL_CLAMP(_TO_EDGE)?重复NPOT可能会在某些硬件上花费一些性能。

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

+0

图片没有2维度的权力,但我加载到一个512x512纹理,我也试过GL_NEAREST,但不是GL_CLAMP。会做,感谢指针。 – 2011-04-10 09:21:40