2011-01-25 113 views
3

我正在为OpenGL ES 1.1中的iPhone开发游戏;在每个节点都有一个子节点列表的数据结构中,我有很多纹理四边形。因此,我从根部遍历结构,并对每个四边形进行渲染,然后对其子进行渲染,等等。优化OpenGL ES应用程序。我应该尽可能避免调用glVertexPointer吗?

问题是,对于每个四元组,我调用glVertexPointer来设置顶点。

  • 我应该避免为每个四元组调用它吗?例如只会提高性能一次?
  • glVertexPointer将顶点复制到GPU内存或者只保存指针?

尽量减少通话次数并不容易,因为每个节点可能有不同的四元组。我有相同的顶点数据相同的精灵,但我不一定渲染一个又一个,因为我可能正在绘制他们之间的一个不同的精灵。

感谢。

回答

10

glVertexPointer只保留指针,但在OpenGL驱动程序中发生状态更改并显式同步,因此成本相当高。通常当你说'这里是我的数据,请绘制'时,GPU开始绘制,并且继续与CPU上发生的任何事情同时进行,并且持续时间尽可能长。当你改变渲染状态时,它需要完成它在旧状态下所做的任何事情。所以通过每四次更改一次,您就可以有效地强制并发处理是连续的。因此,避免每个quad的glVertexPointer(大概是glDrawArrays或glDrawElements?)应该给你一个很大的好处。

立即优化是简单地保持数据结构中总共四元组的数量的计数,为至少具有该尺寸的顶点分配单个目标缓冲区,并让所有四边形将其几何体复制到目标缓冲区中比每次调用glVertexPointer。然后调用glVertexPointer和您的绘图调用(希望压缩一个调用),最后使用一个大数组。它在CPU方面成本更高一些,但并行性和缺乏重复的GPU/CPU同步会为您节省很多。虽然tip around于NDA当前的主题,但我强烈建议您看看Xcode 4测试版。 Apple的其他功能stated publicly to be present是OpenGL ES分析器。所以你可以很容易地比较方法。

要将数据复制到GPU,您需要使用顶点缓冲区对象。这意味着创建一个带有glGenBuffers的缓冲区,用glBufferData将数据推送到该缓冲区,然后发布一个地址为例如1的glVertexPointer。如果您上传的数据中的第一个字节是顶点的第一个字节,则为0。在ES 1.x中,您可以上传数据为GL_DYNAMIC_DRAW来标记您打算经常更新并经常从中抽取数据。如果你可以进入比上传更频繁的位置,这可能是值得的。

如果您曾经切换到ES 2.x也有GL_STREAM_DRAW,这可能值得调查,但与您的问题没有直接关系。我提到它,因为它可能会出现,如果你的谷歌的顶点缓冲区对象,可在桌面OpenGL。 ES 1.x的选项仅为GL_STATIC_DRAW和GL_DYNAMIC_DRAW。

我刚刚在一个iPad ES 1.x应用程序中使用了对象,每个对象都会改变每个帧,但是每个使用的渲染管线都会绘制两次。屏幕上只有五个这样的对象,每个顶点有40个,但是从初始实现切换到VBO实现会减少总处理时间的20%。

+0

+1很好的答案。 – 2011-01-25 16:05:31

相关问题