OpenGL ES/iPhone的性能和背景图片

7
我正在使用OpenGL ES为iPhone开发一个2D游戏,我想使用一张320x480位图作为持久背景。我的第一个想法是创建一个320x480的四边形,然后将代表背景的纹理映射到上面。所以...我创建了一个512x512的纹理,上面有一张320x480的图片,然后我将它映射到了320x480的四边形上。我在每帧都绘制这个背景,然后在其上绘制动画精灵。除了所有对象(背景+精灵)的绘制速度太慢之外,这种方法还可以。我进行了一些测试,发现我的减速在像素管道中。毫不奇怪,大型的背景图片是主要罪魁祸首。为了证明这一点,我删除了背景绘制,其他所有内容都渲染得非常快。 我正在寻求如何保持背景并提高性能的建议。以下是更多信息:
1)我目前正在模拟器上测试(仍在等待苹果授权)
2)背景是PVR纹理压缩到128k
3)我希望能够将这个背景缓存到颜色缓冲区中,但没有成功。这可能是由于我对OpenGL ES的经验不足,或者只是一个不起作用的愚蠢想法:)
4)我意识到并非总是需要刷新整个背景,只需刷新移动精灵覆盖部分的部分即可。我开始研究刷新(如有必要)背景的技术,无论是作为单独的纹理还是使用剪刀框,但这似乎不太优雅。
任何提示/建议将不胜感激...
谢谢。

你是在模拟器上运行还是在真机上运行的? - Cheery
6个回答

8
  1. 永远不要在模拟器上进行性能测试!
    与真实硬件的差异巨大,无论是正向还是反向。
  2. 如果每帧都绘制背景:
    不要清除帧缓冲区。背景将覆盖整个屏幕。
  3. 你真的需要一个背景纹理吗?
    考虑使用顶点颜色的渐变。
  4. 尝试使用2位模式的纹理。
  5. 关闭所有不需要的渲染步骤来绘制背景。
    例如:光照、混合、深度测试等。

如果您可以发布一些绘图代码,我们可以更容易地帮助您。


我现在只能在模拟器上运行,因为这是我目前所拥有的全部 ;) 仍在等待苹果。此外,我没有清除帧缓冲区,关闭了效果,并尝试了2位纹理(看起来很糟糕)。正如你建议的那样,我可能需要使用效果作为背景。我在很多游戏中都看到了这一点。谢谢。 - g-dog

5
如果你正在制作2D游戏,没有使用现有的库有什么原因吗?特别是对于iPhone来说,cocos2d可能值得一试。我无法回答关于如何自己解决问题的问题,但我可以说我已经用cocos2d做过你所说的事情(在全屏背景上放置精灵),而且效果非常好。(假设60 fps对你足够快)。你可能有你自己的理由来完成它,但如果你能的话,我强烈建议至少使用cocos2d进行快速原型设计,并看看它是否可以帮助你进展。(iPhone版本的详细信息和源代码在这里:http://code.google.com/p/cocos2d-iphone/

我更喜欢从头开始构建,以获得额外的控制度。话虽如此,我肯定会尝试一下cocoas2d。其中一个问题是,除了背景之外,我有10多个大精灵同时出现在屏幕上。你用cocoas2d做过类似的事情吗?谢谢。 - g-dog

3
感谢所有提供信息的人。所有的建议都在某种程度上帮助了我。
然而,我想澄清的是,这里的主要问题实际上是模拟器本身的行为(正如Andreas在他的回答中所暗示的)。一旦我能够将应用程序放到设备上,它的表现就好得多了。我之所以提到这一点,是因为在开发我的游戏之前,我看到了很多帖子,表明设备比模拟器慢得多。这在某些情况下可能是真的(例如一般的应用逻辑),但在我看来,动画(特别是3D变换)在设备上运行得更快。

1

我对OpenGL ES没有太多经验,但这个问题通常会出现。

你关于“颜色缓冲区”的想法是很好的直觉,本质上你想将背景作为帧缓冲区存储,并在绘制前直接加载到渲染缓冲区中。

在OpenGL中,使用帧缓冲对象(FBO)相当简单。不幸的是,我认为OpenGL ES不支持它们,但这可能是你开始寻找的地方。


很奇怪...OpenGL ES 1.0似乎支持帧缓冲对象扩展,但我无法确认iPhone上是否可用该扩展。我想我只能测试一下并发布我的发现。谢谢。 - g-dog
糟糕,澄清一下... 帧缓冲扩展得到支持。我需要测试的是创建第二个帧缓冲,然后将纹理附加到它上面。 - g-dog

0

你可以尝试使用VBO(顶点缓冲对象)来提高速度。教程在这里

此外,我刚刚看到自从OpenGL ES v1.1以来,有一个名为glDrawTex(绘制纹理)的函数,专门用于快速渲染游戏中的背景画面、位图字形和2D框架元素。


我已经在使用vbos了。我正在经历的瓶颈在像素管道中。通过消除所有纹理并仅呈现线框,我能够证明这一点。在这种配置下,应用程序运行非常快。谢谢... - g-dog

0
  1. 你可以使用类似于苹果GLPaint示例的帧缓冲对象。
  2. 使用纹理图集来最小化绘制调用的数量。您可以使用glTexCoordPointer设置纹理坐标,将每个图像映射到其正确的位置。记得设置顶点缓冲区。理想情况下,一个绘制调用将渲染整个2D场景。
  3. 尽可能避免启用/禁用状态。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接