题
在我的应用程序中,我通过 OpenGL ES Api 绘制了很多立方体。所有立方体的尺寸相同,只是它们位于空间坐标不同。我可以想到两种绘制它们的方法,但我不确定哪一种是最有效的。我不是OpenGL专家,所以我决定在这里问。
方法一,我现在用的:由于所有立方体的尺寸相同,因此我仅计算一次顶点缓冲区、索引缓冲区、法线缓冲区和颜色缓冲区。在场景刷新期间,我遍历所有立方体,对同一组缓冲区执行 bufferData(),然后使用 drawElements() 调用绘制立方体的三角形网格。由于每个立方体位于不同的位置,因此我在绘制之前平移 mvMatrix。bufferData() 和drawElements() 对每个立方体执行。在这种方法中,我可能节省了大量内存,因为不必每次都计算缓冲区。但我进行了大量的drawElements()调用。
方法 2 是:将所有立方体视为分布在场景中的一组多边形。计算每个多边形(实际上是多边形内的三角形)的顶点、索引、颜色、法线缓冲区,并通过对 bufferData() 的单次调用将它们推送到显卡内存。然后通过一次调用drawElements()来绘制它们。这种方法的优点是,我只进行一次bindBuffer 和drawElements 调用。缺点是,我使用大量内存来创建缓冲区。
我对 OpenGL 的经验非常有限,从性能角度来看,不知道上述方法中哪一种更好。
我在 WebGL 应用程序中使用它,但这是一个通用的 OpenGL ES 问题。
解决方案
予实现的方法,2和它以压倒性获胜。高容量的内存的应该缺点似乎只有我的想象。事实上,垃圾收集器得到了在方法2中调用仅一次,而它是在方法1调用的4-5倍。
您OpenGL的情况可能与我的不同,但如果你在搜索的性能提示达到这里,从这个问题上的教训是:确定在场景中不经常更换的部件。不管他们有多大,把它们放在一个缓冲区集(维也纳组织),并上传到次显存最低数量。这是维也纳各组织是如何打算使用。客户端(即你的应用程序)和显卡之间的内存带宽是宝贵的,你不希望经常使用它没有道理。
读取部“顶点缓冲对象”在Ch中。 “OpenGL ES 2.0的编程指南”的第6,了解他们应该如何使用。 http://opengles-book.com/
其他提示
我知道这个问题已经回答了,但我认为这是值得指出的了解WebGL优化谷歌IO介绍:
http://www.youtube.com/watch?v=rfQ8rKGTVlg
它们覆盖,从本质上讲,这完全一样的问题,谈一些伟大的方式(用不同的颜色/位置具有相同形状的很多的),以优化这样的场面(和他们是动态的呢!)
我建议采用以下方法:
负载:
- 生成坐标缓冲区(针对一个立方体)并将其加载到 VBO 中(
gl.glGenBuffers
,gl.glBindBuffer
)
抽奖时:
绑定缓冲区(
gl.glBindBuffer
)绘制每个单元格(循环)
2.1.将当前位置移动到当前立方体的中心(
gl.glTranslatef(position.x, position.y, position.z
)2.2.绘制当前立方体(
gl.glDrawArrays
)2.3.向后移动位置 (
gl.glTranslatef(-position.x, -position.y, -position.z)
)