当有许多重复顶点时,glDrawElements() 是不是比 glDrawArrays() 更有效?
Posted
技术标签:
【中文标题】当有许多重复顶点时,glDrawElements() 是不是比 glDrawArrays() 更有效?【英文标题】:Is glDrawElements() more efficient than glDrawArrays() when there are many duplicate vertices?当有许多重复顶点时,glDrawElements() 是否比 glDrawArrays() 更有效? 【发布时间】:2010-01-15 16:40:44 【问题描述】:我正试图从我的 iPhone OpenGL ES 应用程序中挤出一些性能提升。根据 Instruments 的说法,我的 tiler 利用率大部分时间都接近 100%,我的 FPS 大约是 24。我想让我的 FPS 超过 30。我可以通过从 GL_FLOAT 转换为 GL_SHORT 来实现,但这会带来一些目前对我来说相当艰巨的技术问题。我宁愿不去那里。
所以,我正在考虑从 glDrawArrays() 切换到 glDrawElements()。我有 35 个由 708 个顶点组成的网格,但其中很多顶点在面之间共享。我是纹理映射,但网格的颜色大多是均匀的。需要特殊纹理的面将保持原样。
假设我可以将顶点数减半。假设我还以对 iPhone 有意义的方式组织几何图形:例如,使用 Imagination Technologies PVRTTriStrip 工具。忽略索引数组的少量额外内存,这意味着我将内存带宽大致减少了一半,因此我应该会看到相当不错的性能提升。
这是真的,还是我遗漏或误解了什么?感谢您的建议。
【问题讨论】:
【参考方案1】:如果有人有兴趣,我继续尝试,没有 PVRTTriStrip 工具部分。所有测试均在 iPhone 3G 上完成。我能够将我的顶点从 708 缩小到 113。由于我不到 255,我使用 GLubyte 作为我的索引类型。所以,我从:
35 * (708 * 32) = ~774K
收件人:
35 * (113 * 32 + 708 * 1) = ~148K
这将我的总内存带宽减少到原来的 20% 以下。我的 FPS 增加到 ~34。所以,我看到 FPS 提高了大约 42%。总的来说,我很高兴。我认为还有更多的收获,但我现在有更大的鱼要炒。
此外,我过滤掉了一堆退化三角形(不是有用的三角形),使我的索引计数从 708 下降到 522。从那时起,我看到从我看到的 ~34 FPS 增加到 ~40 FPS。
【讨论】:
【参考方案2】:如果您在 Instruments (like I was) 中达到 100% 的 Tiler 利用率,那么您将受到几何体大小的限制。在我试图提高性能的所有事情中,我只注意到当我减小几何尺寸时帧速率显着提高。所以,是的,如果你可以消除一些被发送的顶点,你应该会看到性能的提升。
即使您说这很难做到,我还是强烈建议您将 GL_FLOAT 转换为 GL_SHORT,因为您会看到渲染速度大幅提升。我在我的应用程序中做到了这一点,对于我得到的回报来说,实施起来并不麻烦。
【讨论】:
哦,我完全同意你的看法。实际上我曾经让它工作过,但后来我开始实现一些新功能,而 GL_SHORT 转换给我带来了问题。我支持它以在新功能上取得进展;然后,当我重新添加它时,我发现了一层新的复杂性。如果我发现我需要挤出更多性能,这肯定是我尝试的下一件事。以上是关于当有许多重复顶点时,glDrawElements() 是不是比 glDrawArrays() 更有效?的主要内容,如果未能解决你的问题,请参考以下文章
OpenGL - glDrawElements vs 顶点数组对象
glDrawElements中的OpenGL SegFault
OpenGL- glDrawElements 只绘制第一个元素