优化iPhone OpenGL ES填充率

优化iPhone OpenGL ES填充率,iphone,performance,optimization,opengl-es,rendering,Iphone,Performance,Optimization,Opengl Es,Rendering,我在iPhone上有一个opengles游戏。我的帧速率非常糟糕,大约20帧。在iPhone 3G上使用Xcode OpenGL ES性能工具显示: 渲染器利用率:95%到99% 瓦工利用率:~27% 我画了很多非常大的图像,有很多混合。如果减少绘制的图像数量,帧速率将从~20变为~40,尽管性能工具的结果保持不变(渲染器仍处于最大值)。我想我受到了iPhone 3G的填充率的限制,但我不确定 我的问题是:如何以更高的粒度确定瓶颈在哪里?这是我最大的问题,我只是不知道要花多少时间。如果是fill

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

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

瓦工利用率:~27%

我画了很多非常大的图像,有很多混合。如果减少绘制的图像数量,帧速率将从~20变为~40,尽管性能工具的结果保持不变(渲染器仍处于最大值)。我想我受到了iPhone 3G的填充率的限制,但我不确定

我的问题是:如何以更高的粒度确定瓶颈在哪里?这是我最大的问题,我只是不知道要花多少时间。如果是fillrate,除了少画画之外,我还有什么可以改进的吗

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

我使用的是顶点数组和gldraw数组。我真的不太懂几何学。如果需要的话,我可以试着更精确一些。每个图像是2个三角形,我尝试批处理这些事情是可能的,尽管通常(可能有一半的时间)图像是通过单独的GLDrawArray调用绘制的。除了这些图像,我还有大约60个三角形的几何体,它们在大约6个glDrawArrays调用中被渲染。我经常在调用gldrawArray之前进行glTranslate

切换到VBOs会提高帧率吗?我不认为这是一个巨大的几何量,但也许它是更快的其他原因

是否需要注意某些可能会降低性能的事情?我应该避免glTranslate、glColor4g等吗

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

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

我的一个全屏纹理是256x256。使用480x320是否更好,这样手机就不必进行任何缩放?对于纹理大小是否有其他一般性能建议

以下是我正在绘制的大致内容,顺序如下:

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

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

如您所见,有许多层,其中一些是全屏的,一些精灵相当大(屏幕的1/4)。层使用半透明,所以我必须从后向前顺序绘制它们。由于需要在ortho和透视图中绘制各种图层,这一点更加复杂

如有需要,我将乐意提供更多信息。提前感谢您提供有关我的问题的任何性能提示或一般建议

编辑:


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

iPhone平台上最大的性能杀手是抽签呼叫和状态更改的数量。如果您正在进行超过20次的绘制调用或状态更改,您将遇到性能问题

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

请查看苹果的“”和“”部分。他们强烈建议(和其他人一样)使用PVRTC压缩纹理,因为它们可以提供比标准未压缩纹理8:1或16:1的压缩比。除了mipmapping,您似乎正在使用纹理图集进行其他推荐的优化


您似乎没有受到几何体的限制,因为(正如我在中发现的)平铺机利用率统计数据似乎表明几何体大小造成了多大的瓶颈。然而,iphone3gs(以及第三代ipodtouch和iPad)支持硬件加速的vbo,因此您可以试一试,看看它们是如何影响性能的。它们可能没有压缩纹理的效果那么好,但实现起来并不困难。

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

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

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

结果发现其中一个小问题是PVR卡讨厌GL_ALPHA_测试;在个人电脑上,这实际上有轻微的积极影响(特别是在较旧的英特尔芯片上),但在iPhone上,这对fillrate来说是致命的。改成

 glDisable(GL_ALPHA_TEST);
给了我一个即时100%的提高,在FPS(高达40 FPS)。对于一行代码来说还不错:)

艾伦(Allan)

3G(主要用于)的一大胜利也将是您正在使用的纹理过滤。看看你
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);
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];        
}
if (fiOSver >= 4.0f) {
    const GLenum discards[]  = {GL_DEPTH_ATTACHMENT_OES};
    glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES,1,discards);
}

[m_oglContext presentRenderbuffer:GL_RENDERBUFFER_OES];