Opengl es opengles中的高效绘图方法

Opengl es opengles中的高效绘图方法,opengl-es,webgl,Opengl Es,Webgl,在我的应用程序中,我通过OpenGL ES Api绘制了很多立方体。所有立方体的尺寸都相同,只是它们位于不同的空间坐标上。我可以想出两种画它们的方法,但我不确定哪一种是最有效的。我不是OpenGL专家,所以我决定在这里提问 方法1,这就是我现在使用的:因为所有的立方体都是相同的维度,所以我只计算一次顶点缓冲区、索引缓冲区、法线缓冲区和颜色缓冲区。在刷新场景的过程中,我检查了所有立方体,对同一组缓冲区执行bufferData(),然后使用Dropelements()调用绘制立方体的三角形网格。由于

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

方法1,这就是我现在使用的:因为所有的立方体都是相同的维度,所以我只计算一次顶点缓冲区、索引缓冲区、法线缓冲区和颜色缓冲区。在刷新场景的过程中,我检查了所有立方体,对同一组缓冲区执行bufferData(),然后使用Dropelements()调用绘制立方体的三角形网格。由于每个立方体位于不同的位置,因此在绘制之前,我将转换mvMatrix。为每个多维数据集执行bufferData()和DrawerElements()。在这种方法中,我可能会通过不每次计算缓冲区来节省大量内存。但是我做了很多关于抽屉元素()的调用

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

我使用OpenGL的经验非常有限,从性能的角度来看,我不知道上面哪种方法更好


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

我实现了方法2,它以压倒性优势获胜。大量记忆的负面影响似乎只是我的想象。事实上,垃圾收集器在方法2中只被调用了一次,而在方法1中被调用了4-5次

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


阅读“OpenGL ES 2.0编程指南”第6章中的“顶点缓冲区对象”一节,了解如何使用它们

我提出以下方法:

装载时:

  • 生成坐标缓冲区(用于一个多维数据集)并将其加载到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)


  • 我知道这个问题已经得到了回答,但我认为值得指出关于WebGL优化的Google IO演示:


    从本质上讲,他们讨论了这个完全相同的问题(许多相同的形状和不同的颜色/位置),并讨论了一些优化这样一个场景的好方法(他们的也是动态的!)

    我不知道答案,但在没有答案的两天后,我怀疑你最好的方法是尝试实现方法2并运行一些性能测试。是的,我也这么认为。我会发布我的发现。首先,你不需要重复“gl”。例如,它只是gl.DrawArray。第二,OpenGL ES没有glTranslate或任何其他矩阵函数。第三,您基本上描述了海报“方法1”,这实际上是两种方法中速度较慢的一种。(但它是否更好实际上取决于程序的需要)作为WebGL中的一般规则:更少的绘制调用===更快。如果你的立方体是静态的或很少移动(比如说,Minecraft景观)是的,一个单一的静态缓冲区是一个不错的选择。我不会过分强调所涉及的内存使用。多维数据集非常轻量级。您是如何将所有多维数据集数据发送到tue GPU,以便您可以在单个抽屉元素调用中绘制的?“动态”有点牵强-对象位置是预先确定的(
    x=sin(time)
    etc)所以一切都可以在GPU上计算。没有场景图,网格也不会改变。不过这是一次有用的谈话。