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

  • 我正在显示 只有一个预加载的大纹理 (512x512 像素)在 60fps 下,渲染利用率约为 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,并为退化三角形添加了额外的顶点。

更新内容是:

初始化状态:(顶点和纹理指针现在为 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)  
有帮助吗?

解决方案

阅读这篇文章。

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

编辑:

我假设你已经读过这篇文章,但如果没有 查看 Apple 的 iPhone 上最佳 OpenGL ES 性能指南。

其他提示

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

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

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

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

到底是什么问题呢?
您将获得 60 fps,如丝般流畅。

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

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

尝试这个:细分你的四边形并重复你的测试。因此,如果您是 1 个四边形,请将其改为 4 个。然后16。等等,看看是否有帮助。关键是减少每个基元引用的实际像素数。

当纹理缓存被耗尽时,硬件会将主内存中的纹理查找搅动到为纹理缓冲区预留的任何 vram 中 每个像素. 。这会很快降低性能。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top