优化OpenGL ES应用程序。我应该尽可能避免调用glVertexPointer吗?

时间:2011-01-25 14:24:06

标签: iphone optimization opengl-es

我正在开发一款适用于iPhone的OpenGL ES 1.1游戏;我在数据结构中有很多纹理四边形,其中每个节点都有一个子节点列表。所以我从根遍历结构,并对每个四边形进行渲染,然后对其子进行渲染等等。

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

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

尝试最小化调用次数并不容易,因为每个节点可能有不同的四边形。我有很多相同的精灵与相同的顶点数据,但我不一定渲染一个接一个,因为我可能在它们之间绘制不同的精灵。

感谢。

1 个答案:

答案 0 :(得分:10)

glVertexPointer只保留指针,但会导致OpenGL驱动程序的状态更改和显式同步,因此成本相当高。通常当你说'这是我的数据,请绘制'时,GPU开始绘图并继续与CPU上的任何内容并行执行,只要它可以。当您更改渲染状态时,它需要完成它在旧状态下执行的任何操作。因此,通过每个四元组更改一次,您可以有效地强制并发处理是连续的。因此,每个四边形避免glVertexPointer(可能是glDrawArrays或glDrawElements?)应该会给你带来很大的好处。

立即优化只是在数据结构中保持总数的数量,为至少大小的顶点分配单个目标缓冲区,并让所有四边形将其几何体复制到目标缓冲区而不是每次调用glVertexPointer。然后调用glVertexPointer和你的绘图调用(也希望只调用一个调用),最后一个大数组。它在CPU方面成本更高,但并行性和缺乏重复的GPU / CPU同步应该可以为您节省很多。

在围绕目前正在使用NDA的主题时,我强烈建议您查看Xcode 4测试版。 Apple拥有stated publicly to be present的其他功能是OpenGL ES分析器。所以你可以很容易地比较方法。

要将数据复制到GPU,您需要使用顶点缓冲区对象。这意味着创建一个glGenBuffers的缓冲区,用glBufferData将数据推送给它,然后发布一个地址为例如的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%。