Android OpenGL ES glDrawArrays or glDrawElements?
最佳方法是什么:如果我使用
对于这两者,您都向OpenGL传递了一些包含顶点数据的缓冲区。
glDrawArrays基本上是"使用我之前提供的数据绘制此连续范围的顶点"。
好:
- 您不需要建立索引缓冲区
坏:
- 如果将数据组织到GL_TRIANGLES中,则相邻三角形的顶点数据将重复。这显然是浪费的。
- 如果您使用GL_TRIANGLE_STRIP和GL_TRIANGLE_FAN尝试避免重复数据:效果并不理想,则必须为每个带钢和风扇进行一次渲染调用。 OpenGL调用很昂贵,应尽可能避免
使用glDrawElements,您传入包含要绘制的顶点的索引的缓冲区。
好
- 没有重复的顶点数据-您只需为不同的三角形索引相同的数据
- 您可以只使用GL_TRIANGLES并依靠顶点缓存来避免两次处理相同的数据-无需重新组织几何数据或将渲染分为多个调用
不良
- 索引缓冲区的内存开销
我的建议是使用glDrawElements
性能影响可能与iphone相似,《 iOS OpenGL ES编程指南》建议使用三角形条纹,并通过退化的三角形连接多个条纹。
该链接很好地说明了该概念。这样,您可以重用一些顶点,并且仍然可以一步完成所有绘图。
For best performance, your models should be submitted as a single unindexed triangle strip using glDrawArrays with as few duplicated vertices as possible. If your models require many vertices to be duplicated (because many vertices are shared by triangles that do not appear sequentially in the triangle strip or because your application merged many smaller triangle strips), you may obtain better performance using a separate index buffer and calling glDrawElements instead. There is a trade off: an unindexed triangle strip must periodically duplicate entire vertices, while an indexed triangle list requires additional memory for the indices and adds overhead to look up vertices. For best results, test your models using both indexed and unindexed triangle strips, and use the one that performs the fastest.
Where possible, sort vertex and index data so that that triangles that share common vertices are drawn reasonably close to each other in the triangle strip. Graphics hardware often caches recent vertex calculations, so locality of reference may allow the hardware to avoid calculating a vertex multiple times.
不利的一面是,您可能需要一个预处理步骤来对网格进行排序,以获得足够长的条带。
我还无法为此提出一个不错的算法,因此与GL_TRIANGLES相比,我无法给出任何性能或空间数字。当然,这也高度取决于您要绘制的网格。
接受的答案有些过时。遵循Jorn Horstmann的答案(iOS的OpenGL ES编程指南)中的doc链接,Apple描述了如何在DrawElements中使用"简并三角形"技巧,从而获得两全其美。
使用DrawArrays节省少量索引并不值得将所有数据组合到一个GL调用DrawElements中而节省下来。 (您可以使用DrawArrays合并所有元素,但是任何"浪费的元素"都将浪费顶点,这些顶点比索引大得多,并且还需要更多的渲染时间。)
这也意味着您不需要仔细考虑所有模型,就可以将大多数模型呈现为最小数量的条带还是它们过于复杂。一种统一的解决方案,可以处理所有问题。 (但是,请尽量将其组织成条带,以最大程度地减少发送的数据,并最大程度地提高GPU重复使用最近缓存的顶点计算的可能性。)
BEST:使用GL_TRIANGLE_STRIP的单个DrawElements调用,其中包含您的所有数据(每帧都在变化)。
实际上,您可以退化三角形条纹以创建连续的条纹,这样您就不必在使用glDrawArray时将其拆分。
我一直在使用glDrawElements和GL_TRIANGLES,但正在考虑将glDrawArray与GL_TRIANGLE_STRIP结合使用。这样就无需创建指令向量。
对其中一篇文章中提到的顶点缓存有更多了解的人吗?考虑glDrawElements / GL_TRIANGLE与glDrawArray / GL_TRIANGLE_STRIP之间的性能。