iPad上的glDrawArrays()速度慢吗?

时间:2010-05-04 22:53:12

标签: performance optimization ipad opengl-es

我想知道如何使用OpenGLES 2.0加速我的iPad应用程序。目前,我们让每个可绘制对象都通过调用glDrawArrays()来绘制自己。混合模式已启用,我们确实需要它。如果不禁用blendmode,我们将如何提高此应用的性能?

例如,如果我们现在在整个屏幕上绘制3个纹理(1024x1024,256x512,256x512),应用程序只能获得15FPS,我觉得这真的很慢?我们做的事情是非常错的吗?我们的绘图代码(适用于每个drawable)如下:

- (void) draw {
    GLuint textureAvailable = 0;
    if(texture != nil){
        textureAvailable = 1;
    }

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture.name);

    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, vertices);
    glEnableVertexAttribArray(ATTRIB_VERTEX);

    glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, 1, 0, colorsWithMultipliedAlpha);
    glEnableVertexAttribArray(ATTRIB_COLOR);

    glVertexAttribPointer(ATTRIB_TEXTUREMAP, 2, GL_FLOAT, 1, 0, textureMapping);
    glEnableVertexAttribArray(ATTRIB_TEXTUREMAP);

    //Note that we are NOT using position.z here because that is only used to determine drawing order
    int *jnUniforms = JNOpenGLConstants::getInstance().uniforms;
    glUniform4f(jnUniforms[UNIFORM_TRANSLATE], position.x, position.y, 0.0, 0.0);
    glUniform4f(jnUniforms[UNIFORM_SCALE], scale.x, scale.y, 1.0, 1.0);
    glUniform1f(jnUniforms[UNIFORM_ROTATION], rotation);
    glUniform1i(jnUniforms[UNIFORM_TEXTURE_SAMPLE], 0);
    glUniform2f(jnUniforms[UNIFORM_TEXTURE_REPEAT], textureRepeat.x, textureRepeat.y);
    glUniform1i(jnUniforms[UNIFORM_TEXTURE_AVAILABLE], textureAvailable);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

我认为可行的优化不起作用:

  • 批量绘制几何体
    • 我只画了3个项目而且FPS是15,我不认为批量几何在这里会起作用,因为它是如此少量的绘图调用,如果我们杀了2就没关系这些电话中有3个。
  • 纹理图集
    • 同样,只绘制3个纹理。我想知道如果我们将这些转换为PVR是否重要(很多)?我没有调查过,但我必须承认我们现在正在加载大型PNG。有没有什么方法可以确定是否确实如此,或者更容易检查一下?

但请告诉我,如果我错了,我很高兴听到任何想法。

提议的解决方案

Mipmapped纹理

加载mipmapped纹理,这样做:

- (id) initWithUIImage: (UIImage * const) image {
    glGenTextures(1, &name);
    //JNLogString(@"Recieved name(%d), binding texture", name);
    glBindTexture(GL_TEXTURE_2D, name);

    //Set the needed parameters for the texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    //Load the image data into the texture

    glGenerateMipmap(GL_TEXTURE_2D);

    return self;
}

这似乎对我们的FPS没有任何作用,我认为这是因为我们的纹理已经大致达到它们在屏幕上呈现的大小,在大多数情况下甚至是1:1。

欢迎其他解决方案!我会尝试一下并在此处发布结果

2 个答案:

答案 0 :(得分:2)

如果您使用非常大的纹理,请尝试创建mipmap纹理。成本基本上是原始纹理内存的1/3。我认为在设置纹理时可以使用此调用创建它们。

glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

一些计算:如果您在15 Hz时有3个纹理2048x2048(最大尺寸),您将获得2048x2048x3x15 = 188,743,680 /秒的纹素吞吐量(如果它们完全显示,即缩小到屏幕分辨率),这大约是我们的值单glbenchmark.com查看单次填充率(173 Mtexel / sec)。但是如果你使用mipmap纹理,纹素的吞吐量应该更接近屏幕尺寸分辨率(1024x768),这应该是先前吞吐量的1/4。

答案 1 :(得分:2)

我的片段着色器中有一个分支。我虽然没有给它带来很多压力,但确实如此!无论如何,这就是整个问题,我删除了分支,现在我的FPS几乎翻了一倍。