512x512纹理在iPhone上造成巨大的GPU压力,尽管平铺

时间:2009-05-16 14:45:09

标签: iphone performance opengl-es textures

我在iPhone上测试我的简单OpenGL ES实现(2D游戏),并且在使用分析器时我注意到高渲染利用率。这些是事实:

  • 我以60fps的速度显示只有一个预加载的大纹理 512x512像素),渲染利用率约为40%。
  • 我的纹理使用GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA混合,我正在使用的唯一GL功能
  • 我试图让纹理更小并平铺没有区别
  • 我正在使用1024x1024像素的PNG纹理图集

我觉得很奇怪,这个一个纹理导致如此强烈的GPU使用。

这是预料到的吗?我做错了什么?

编辑:我的代码:

// OpenGL setup is identical to OpenGL ES template
// initState is called to setup
// timer is initialized, drawView is called by the timer

- (void) initState
{
    //usual init declarations have been omitted here        
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA);     
    glEnableClientState (GL_VERTEX_ARRAY);
    glVertexPointer     (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].x);          
    glEnableClientState (GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer   (2,GL_FLOAT,sizeof(Vertex),&allVertices[0].tx);     
    glEnableClientState (GL_COLOR_ARRAY);
    glColorPointer      (4,GL_UNSIGNED_BYTE,sizeof(Vertex),&allVertices[0].r);    
}    
- (void) drawView
{       
    [EAGLContext setCurrentContext:context];
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity();

    GLfloat width  = backingWidth /2.f; 
    GLfloat height = backingHeight/2.f; 

    glOrthof(-width, width, -height, height, -1.f, 1.f);
    glMatrixMode(GL_MODELVIEW);
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);       
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);       
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];      
    [self checkGLError];        
}

编辑:我做了一些改进,但没有人设法降低渲染利用率。我将纹理划分为32x32的部分,将坐标和纹理坐标的类型从GLfloat更改为GLshort,并为退化三角形添加了额外的顶点。

更新如下:

INITSTATE:     (顶点和纹理指针现在是GL_SHORT)

glMatrixMode(GL_TEXTURE);
glScalef(1.f / 1024.f, 1.f / 1024.f, 1.f / 1024.f);
glMatrixMode(GL_MODELVIEW);
glScalef(1.f / 16.f, 1.f/ 16.f, 1.f/ 16.f);

drawView函数:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 1536); //(16*16 parts * 6 vertices)  

5 个答案:

答案 0 :(得分:1)

我正在编写一个应用程序,它使用GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA在2D环境中相互显示五个512x512纹理,我可以得到大约14fps。你真的需要60fps吗?对于一场比赛,我认为24-30会好的。此外,如果可能的话,使用PVR纹理压缩。有一个例子,它包含在SDK中。

答案 1 :(得分:1)

  1. 我希望你不要忘记在你不需要的时候禁用GL_BLEND
  2. 您可以尝试内存带宽优化 - 使用16 bpp格式或PVRTC。恕我直言你的纹理大小纹理缓存根本没有帮助。
  3. 不要忘记你的帧缓冲被iPhone UI用作纹理。如果它被创建为32位RGBA,它将再次进行alpha混合。为获得最佳性能,16位565帧缓冲器是最好的(但图形质量会受到影响)。
  4. 我不知道所有细节,例如缓存大小,但是,我认为,纹理像素在上传到视频内存时已经被调配,并且三角形被PVR瓦片引擎分割。因此,您自己的分裂似乎是多余的。

    最后。这只是一款移动低功耗GPU,不适用于大屏幕和高填充率。 Alpha混合成本很高,可能是PowerVR芯片的3-4倍差异。

答案 2 :(得分:0)

Read this post.

对于iPhone来说,512x512可能有点过于乐观了。

编辑:

我假设您已经阅读过此内容,但如果不是check Apples guide to optimal OpenGl ES performance on iPhone.

答案 3 :(得分:0)

究竟是什么问题?
你得到了你的60fps,这是丝般光滑的。

谁在乎渲染利用率是否为40%?

答案 4 :(得分:0)

问题可能是因为iPhone的纹理缓存大小。它可能只是归结为每个三角形,四边形或三角形上有多少纹理,具体取决于您设置状态的方式。

试试这个:细分四边形并重复测试。因此,如果你是1个四边形,那么它是4.然后是16.依此类推,看看是否有帮助。关键是减少每个基元引用的实际像素数。

当纹理缓存被烧毁时,硬件会将纹理查找从主存储器扫描到为每个像素的纹理缓冲区留出的任何vram。这可能会迅速扼杀性能。

或者 - 我完全错了,因为我真的不知道iPhone硬件,而且我也知道PVR芯片与我以前相比是一个奇怪的野兽(PS2,PSP)。仍然是一个简单的尝试尝试,我很好奇,如果它有帮助。