glDrawElements在iOS上大量使用cpu

myr*_*yro 5 iphone opengl-es ipad ios opengl-es-2.0

硬件:iPad2软件:OpenGL ES 2.0 C++

glDrawElements似乎占用了大约25%的cpu.使CPU 18ms和GPU每帧10ms.

当我不使用索引缓冲区并使用glDrawArrays时,它会加速并且glDrawArrays大麦会显示在探查器上.其他一切都是一样的,glDrawArrays有更多的顶点因为我必须在没有索引缓冲区的情况下复制VBO中的顶点.

至今:

  • 这两种方法之间的状态变化几乎相同
  • 顶点结构是两个浮点数(8个字节).
  • indexbuffer是16bit(尝试32位)
  • 两个缓冲区的GL_SATIC_DRAW
  • 缓冲区在加载后不会改变
  • 相同的VBO和indexbuffer每帧渲染多次,具有不同的偏移和大小
  • 没有opengl错误

所以看起来它正在做某种类型的软件回退.但我无法弄清楚会导致OpenGL回退的原因.

Bry*_*yan 2

There are a few things that immediately jump to mind that might affect speed the way you describe.

其一,许多命令是被动发出的,以减少总线传输的数量。他们排队等待下一批传输。状态变化、纹理变化和类似的命令都会累积。绘制命令可能在一种情况下触发较大的传输,但在另一种情况下则不会,或者您在一种情况或另一种情况下触发更频繁的传输。另一方面,您的特定模型可能会更好地组织一个或另一个绘制调用。您需要查看它们有多大,它们是否重用索引值,以及它们是否针对渲染进行了优化或重新排序。glDrawArrays 可能需要传输更多数据,但如果您的模型很小,则开销可能不是太大问题。绘制频率变得很重要,因为您希望经常对调用进行排队以保持卡繁忙并让 CPU 执行其他工作,您不希望它只是累积在等待发送的命令缓冲区中,但它需要平衡,因为这些转移是有成本的。最重要的是,频繁索引的值在频繁重用时可以从缓存效果中受益,但是线性访问的数组在线性访问时可以从缓存效果中受益,因此您需要了解您的数据,因为不同类型的数据受益于不同的数据类型。方法。

就连苹果公司似乎也不确定该使用哪种方法。

直到 iOS7,该版本及更早版本的IOS OpenGL ES 编程指南写道:

为了获得最佳性能,您的模型应使用 glDrawArrays 作为单个无索引三角形带提交,并尽可能少地重复顶点。如果您的模型需要复制许多顶点(...),您可以使用单独的索引缓冲区并调用 glDrawElements 来获得更好的性能。...为了获得最佳结果,请使用索引和未索引的三角形条测试您的模型,并使用性能最快的一个。

但他们更新的适用于 iOS8的 iOS OpenGL ES 编程指南提供了相反的内容:

为了获得最佳性能,您的模型应作为单个索引三角形条提交。为了避免在顶点缓冲区中多次指定同一顶点的数据,请使用单独的索引缓冲区并使用 glDrawElements 函数绘制三角形带

在您的情况下,您似乎刚刚尝试了两种方法,并发现一种方法更适合您的数据。