最好的方法是什么?如果我使用drawarrays,或者我使用drawelements?有什么不同的吗?
答案 0 :(得分:31)
对于两者,您向OpenGL传递一些包含顶点数据的缓冲区。
glDrawArrays基本上是“使用我之前给你的数据绘制这个连续的顶点范围”。 好:
为:
使用glDrawElements,传入包含要绘制的顶点索引的缓冲区。
好
为
我的建议是使用glDrawElements
答案 1 :(得分:6)
性能影响在iphone上可能类似,OpenGL ES Programming Guide for iOS建议使用三角形条带并通过退化三角形连接多个条带。
这个链接很好地说明了这个概念。通过这种方式,您可以重复使用一些顶点并仍然可以一步完成所有绘图。
为获得最佳性能,您的模型应使用glDrawArrays作为单个无索引三角形条提交,并尽可能少复制顶点。如果您的模型需要复制许多顶点(因为许多顶点由三角形共享,或者因为您的应用程序合并了许多较小的三角形条),您可以使用单独的索引缓冲区并调用glDrawElements获得更好的性能代替。有一个权衡:未编制索引的三角形条必须定期复制整个顶点,而索引三角形列表需要额外的索引内存,并增加查找顶点的开销。为获得最佳效果,请使用索引和未索引的三角形条测试模型,并使用速度最快的模型。
在可能的情况下,对顶点和索引数据进行排序,以便共享公共顶点的三角形在三角形条带中相互接近地绘制。图形硬件通常会缓存最近的顶点计算,因此引用的局部性可能允许硬件避免多次计算顶点。
缺点是您可能需要一个预处理步骤来对网格进行排序,以获得足够长的条带。 我还没有想出一个很好的算法,所以与GL_TRIANGLES相比,我不能给出任何性能或空格数。当然,这也高度依赖于你想要绘制的网格。
答案 2 :(得分:1)
实际上,您可以退化三角形条以创建连续条带,这样您就不必在使用glDrawArray时将其拆分。
我一直在使用glDrawElements和GL_TRIANGLES,但考虑使用glDrawArray而不是GL_TRIANGLE_STRIP。这样就不需要创建inidices矢量。
任何了解上述帖子中上面提到的顶点缓存事项的人都有?考虑glDrawElements / GL_TRIANGLE与glDrawArray / GL_TRIANGLE_STRIP之间的表现。
答案 3 :(得分:1)
接受的答案有点过时了。按照Jorn Horstmann的答案OpenGL ES Programming Guide for iOS中的文档链接,Apple描述如何使用DrawElements 使用“退化三角形”技巧,从而获得两全其美的效果。
使用DrawArrays通过将所有数据组合到单个GL调用DrawElements中,可以节省少量索引。 (你可以使用DrawArrays组合所有,但是任何“浪费的元素”都会浪费顶点,这些顶点比索引大得多,并且需要更多的渲染时间。)
这也意味着您不需要仔细考虑所有模型,无论它们中的大多数都可以渲染为最小数量的条带,还是它们太复杂。一个统一的解决方案,处理一切。 (但是尽可能尝试组织成条带,以最小化发送的数据,并最大化GPU重新使用最近缓存的顶点计算的可能性。)
BEST:使用GL_TRIANGLE_STRIP进行一次DrawElements调用,其中包含 所有 您的数据(每帧都在变化)。