在OpenGL ES中绘制的有效方法

时间:2010-10-02 15:25:38

标签: opengl-es webgl

在我的应用程序中,我通过OpenGL ES Api绘制了很多立方体。所有立方体都具有相同的尺寸,只有它们位于空间的不同坐标。我可以想到两种绘制它们的方法,但我不确定哪种方法最有效。我不是OpenGL专家,所以我决定在这里问。

方法1,这就是我现在使用的:由于所有立方体的尺寸相同,我只计算一次顶点缓冲区,索引缓冲区,普通缓冲区和颜色缓冲区。在刷新场景期间,我遍历所有立方体,对同一组缓冲区执行bufferData(),然后使用drawElements()调用绘制多维数据集的三角形网格。由于每个立方体位于不同的位置,我在绘制之前翻译mvMatrix。对每个多维数据集执行bufferData()和drawElements()。在这种方法中,我可能通过不每次计算缓冲区来节省大量内存。但我正在制作很多drawElements()调用。

方法2将:将所有立方体视为遍布场景的多边形集。计算每个多边形的顶点,索引,颜色,正常缓冲区(实际上是多边形内的三角形),并在单次调用bufferData()时将它们推送到图形卡内存。然后单击调用drawElements()绘制它们。这种方法的优点是,我只做一个bindBuffer和drawElements调用。缺点是,我使用大量内存来创建缓冲区。

我对OpenGL的经验是有限的,从性能的角度来看,不知道上述哪种方法更好。

我在WebGL应用程序中使用它,但它是一个通用的OpenGL ES问题。

3 个答案:

答案 0 :(得分:14)

我实施了方法2,它以压倒性优势获胜。高记忆的假设下行似乎只是我的想象力。事实上,垃圾收集器只在方法2中调用一次,而在方法1中调用了4-5次。

您的OpenGL场景可能与我的不同,但如果您到达此处寻找性能提示,则此问题的教训是:识别场景中不经常更改的部分。无论它们有多大,都将它们放在单个缓冲区集(VBO)中并上传到图形内存的次数最少。这就是VBO的用途。客户端(即您的应用程序)和显卡之间的内存带宽非常宝贵,您不希望经常无故地使用它。

阅读Ch。中的“顶点缓冲区对象”部分。 6“OpenGL ES 2.0编程指南”了解它们应该如何使用。 http://opengles-book.com/

答案 1 :(得分:5)

我知道这个问题已经得到解答,但我认为值得指出有关WebGL优化的Google IO演示文稿:

http://www.youtube.com/watch?v=rfQ8rKGTVlg

它们基本上涵盖了这个完全相同的问题(很多相同形状的不同颜色/位置),并谈论优化这种场景的一些好方法(他们也是动态的!)

答案 2 :(得分:-1)

我建议采用以下方法:

载入时:

  1. 生成坐标缓冲区(对于一个多维数据集)并将其加载到VBO(gl.glGenBuffersgl.glBindBuffer
  2. 平局:

    1. 绑定缓冲区(gl.glBindBuffer

    2. 绘制每个单元格(循环)

      2.1。将当前位置移动到当前多维数据集的中心(gl.glTranslatef(position.x, position.y, position.z

      2.2。绘制当前立方体(gl.glDrawArrays

      2.3。移回位置(gl.glTranslatef(-position.x, -position.y, -position.z)