2

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

绘制视图:

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

5 回答 5

1

我正在编写一个应用程序,它使用 GL_SRC_ALPHA、GL_ONE_MINUS_SRC_ALPHA 在 2D 环境中彼此叠加显示五个 512x512 纹理,我可以获得大约 14fps。你真的需要60fps吗?对于一场比赛,我认为24-30就可以了。此外,尽可能使用 PVR 纹理压缩。SDK 中包含一个示例。

于 2009-06-28T21:43:41.873 回答
1
  1. 我希望您在不需要时不要忘记禁用GL_BLEND它。
  2. 您可以尝试优化内存带宽 - 使用 16 bpp 格式或 PVRTC。恕我直言,您的纹理大小纹理缓存根本没有帮助。
  3. 不要忘记您的帧缓冲区正在被 iPhone UI 用作纹理。如果它被创建为 32 位 RGBA,它将再进行一次 alpha 混合。为了获得最佳性能,16 位 565 帧缓冲区是最好的(但图形质量会受到影响)。

我不知道所有细节,例如缓存大小,但是,我想,纹理像素在上传到视频内存时已经混合,三角形被 PVR 平铺引擎分割。因此,您自己的拆分似乎是多余的。

最后。这只是一个移动低功耗 GPU,不是为大屏幕和高填充率而设计的。Alpha 混合成本很高,可能是 PowerVR 芯片的 3-4 倍。

于 2009-12-02T11:46:26.263 回答
0

阅读这篇文章。

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

编辑:

我假设你已经阅读了这篇文章,但如果没有,请查看 Apples guide to best OpenGL ES performance on iPhone。

于 2009-05-16T15:02:17.170 回答
0

究竟是什么问题?
您将获得 60fps 的速度,如丝般顺滑。

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

于 2009-06-28T21:39:08.577 回答
0

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

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

当纹理缓存被炸毁时,硬件会将纹理查找从主内存转换到为每个像素的纹理缓冲区留出的任何 vram 中。这会很快杀死性能。

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

于 2009-06-28T21:53:33.477 回答