优化iPhone OpenGL ES填充率

时间:2010-05-07 01:35:26

标签: iphone performance optimization opengl-es rendering

我在iPhone上有一个Open GL ES游戏。我的帧率非常糟糕,大约20fps。在iPhone 3G上使用Xcode OpenGL ES性能工具,它显示:

渲染器利用率:95%至99%

Tiler利用率:~27%

我正在绘制大量非常大的图像并进行大量混合。如果我减少绘制的图像数量,帧速率从大约20到大约40,尽管性能工具结果保持不变(渲染器仍然是最大值)。我认为我受限于iPhone 3G的填充率,但我不确定。

我的问题是:如何更准确地确定瓶颈在哪里?这是我最大的问题,我只是不知道一直在做什么。如果它是填充物,除了画得少之外,还有什么可以改进的吗?

我正在使用纹理地图集。我试图最小化图像绑定,虽然它并不总是可能的(绘制顺序,并非所有东西都适合一个1024x1024纹理等)。我做的每一帧10个图像绑定。这似乎很合理,但我可能会弄错。

我正在使用顶点数组和glDrawArrays。我真的没有很多几何形状。如果需要,我可以尝试更精确。每个图像都是2个三角形,我尝试批量处理是可能的,尽管经常(可能有一半的时间)图像是用单独的glDrawArrays调用绘制的。除了图像,我还有大约60个三角形的几何图形在~6个glDrawArrays调用中呈现。我经常在调用glDrawArrays之前进行glTranslate。

它会改善帧率以切换到VBO吗?我不认为这是一个巨大的几何形状,但也许它由于其他原因更快?

是否有一些需要注意的事情会降低性能?例如,我应该避免使用glTranslate,glColor4g等吗?

我每帧使用3个位置的glScissor。每次使用都包含2个glScissor调用,一个用于设置,一个用于将其重置为原来的状态。我不知道这里是否会产生很大的性能影响。

如果我使用PVRTC,它能否更快地渲染?目前我的所有图片都是GL_RGBA。我没有记忆问题。

我的全屏纹理之一是256x256。使用480x320会更好吗,这样手机不需要进行任何缩放吗?纹理尺寸是否还有其他一般性能建议?

以下是按照以下顺序对我正在绘制的内容进行粗略概述:

1)切换到透视矩阵。 2)绘制全屏背景图像 3)绘制半透明的全屏图像(这个具有滚动纹理)。 4)画几个精灵。 5)切换到ortho矩阵。 6)画几个精灵。 7)切换到透视矩阵。 8)绘制精灵和一些其他纹理几何。 9)切换到ortho矩阵。 10)绘制几个精灵(例如,游戏HUD)。

步骤1-6绘制一堆背景资料。 8绘制了大部分游戏内容。 10绘制HUD。

正如你所看到的,有很多层,其中一些全屏,一些精灵相当大(屏幕的1/4)。这些图层使用半透明,所以我必须按照从前到后的顺序绘制它们。由于需要在正视和其他视角中绘制各种层,因此进一步复杂化。

如果需要,我很乐意提供其他信息。提前感谢您对我的问题的任何性能提示或一般建议!

修改

我添加了一些日志记录,看看我正在做多少glDrawArrays调用,以及有多少数据。我每帧做大约20次glDrawArray调用。通常,这些中约有1到6个具有大约40个顶点。其余的调用通常只有2个顶点(一个图像)。我只是使用glVertexPointer和glTexCoordPointer。

7 个答案:

答案 0 :(得分:7)

鉴于渲染器利用率基本上为100%,这表明瓶颈是填充,纹理化和混合像素。旨在优化顶点处理(VBO和顶点格式)或CPU使用(绘制调用批处理)的技术可能没有帮助,因为它们不会加速像素处理。

最好的办法是减少填充的像素数量,同时查看不同的纹理格式,以便更好地利用第一代设备上可用的非常有限的内存带宽。尽可能使用PVRTC纹理,否则优先使用16位未压缩纹理。

答案 1 :(得分:3)

查看Apple的Best Practices for Working with Texture Data的“Best Practices for Working with Vertex Data”和“OpenGL ES Programming Guide for iPhone OS”部分。他们强烈推荐(和其他人一样)使用PVRTC压缩纹理,因为它们可以提供比标准未压缩纹理8:1或16:1的压缩比。除了mipmapping之外,您似乎正在使用纹理图集进行其他推荐的优化。

您似乎不受几何限制,因为(正如我在this question中发现的)Tiler Utilization统计数据似乎表明几何尺寸造成了多大的瓶颈。然而,iPhone 3G S(以及第三代iPod touch和iPad)支持硬件加速的VBO,因此您可以尝试一下,看看它们如何影响性能。它们可能没有像压缩纹理那样有效,但它们并不难实现。

答案 2 :(得分:2)

(主要是)3G的大赢家也将是你正在使用的纹理过滤。检查您是否使用“TRILINEAR”过滤,并将其更改为“BILINEAR”。

确保按如下方式设置纹理:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

而不是这样:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

哈利

答案 3 :(得分:2)

我想补充一点,将Framebuffer支持更改为16位格式,而不是32位格式。

if ((self = [super initWithCoder:coder])) 
    {
    eaglLayer = (CAEAGLLayer *)self.layer;
    eaglLayer.opaque = YES;
    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                            [NSNumber numberWithBool:NO], 
                                            kEAGLDrawablePropertyRetainedBacking, 
                                            kEAGLColorFormatRGB565,  //kEAGLColorFormatRGBA8 = large frame buff 32bit  // kEAGLColorFormatRGB565 = 16bit frame buffer.
                                            kEAGLDrawablePropertyColorFormat, 
                                            nil];        
}

让我醒来的是XCode分析器。它一直抱怨使用大的帧缓冲区,最终我在我的init部分找到它。 http://developer.apple.com/library/ios/#documentation/iPhone/Reference/EAGLDrawable_Ref/EAGLDrawable/EAGLDrawable.html  。  这一次改变让我在iPad,Retina和iPod上的游戏达到了60 FPS。 我还没有用这个改变重新发布它们,因为我刚刚发现它3天前:)但我不认为我计划以60fps发布,30fps对于休闲游戏来说很好,而且我发现我的声音效果被削减了帧速率下降,所以重新采样,在另一个线程中播放sfx,或者其他解决方案,以便在我决定使用60fps时保持帧速率。
不要忘记丢弃不习惯的缓冲区显示..

if (fiOSver >= 4.0f) {
    const GLenum discards[]  = {GL_DEPTH_ATTACHMENT_OES};
    glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES,1,discards);
}

[m_oglContext presentRenderbuffer:GL_RENDERBUFFER_OES];

答案 4 :(得分:1)

在类似情况下(将2D冒险游戏移植到iPad)。我的3GS版本或多或少地锁定在60FPS,把它放在iPad上将它(和我的下巴)降低到20fps。

原来其中一个小问题是PVR卡讨厌GL_ALPHA_TEST;在PC上实际上有一些轻微的积极影响(尤其是在较旧的英特尔芯片上),但它们在iPhone上的填充率已经很高。将其更改为

 glDisable(GL_ALPHA_TEST);

让我立即100%提升FPS(最高40 FPS)。一行代码还不错.. :)

阿伦

答案 5 :(得分:0)

iPhone平台上最大的性能杀手是绘制调用和状态更改的数量。如果您正在进行超过20个绘制调用或状态更改,那么您将遇到性能障碍。

批处理和纹理地图集是你的朋友。

答案 6 :(得分:0)

根据我过去在旧windows移动设备上使用openGL ES的经验,处理速度约为600mhz 通常会降低渲染窗口的分辨率,从而提高渲染速度。

正如我最近的测试一样,我发现我需要进行性能监控,同时逐帧渲染,以收集当前性能和当前应用的分辨率可以显示的fps数量

我希望在运行游戏渲染引擎时保持监控算法代替渲染视图以平衡分辨率和帧速率是一种很好的做法。

取决于您想要的帧速率,您应该牺牲渲染视图分辨率,以便在大多数设备上执行最佳和降级,并具有不同的硬件和软件性能。

您可能需要像本文中所解释的那样手动控制分辨率。

http://www.david-amador.com/2010/09/setting-opengl-view-for-iphone-4-retina-hi-resolution/