【问题标题】:OpenGL avoid calling glDrawElements multiple timesOpenGL 避免多次调用 glDrawElements
【发布时间】:2014-07-11 15:23:35
【问题描述】:

我正在将我们的图形从使用旧的固定流水线功能迁移到使用可编程流水线。我们最简单的模型只是空间中点的集合,其中每个点都可以用不同的形状表示。其中之一是立方体。

我的代码基于来自 OpenGL 超棒的立方体 example

在这个例子中,立方体被放置在一些随机的地方,而我将在空间中有一个固定的光照点。我想知道是否有办法将该列表传递给我的着色器,以便在每个点绘制一个立方体,而不是循环遍历列表并每次调用 glDrawElements。这是否值得麻烦(性能方面)?

PS 我们仅限于 OpenGL 3.3 功能。

【问题讨论】:

    标签: c++ opengl glsl opengl-3


    【解决方案1】:

    这是否值得麻烦(性能方面)?

    可能是的,但仍然尝试分析。

    你要找的是实例化渲染,看看glDrawElementsInstancedglVertexAttribDivisor

    您要做的是将通用立方体的 8 个顶点(以原点为中心)存储在一个缓冲区中,并将每个立方体中心的坐标存储在另一个顶点属性缓冲区中。

    然后您可以使用glDrawElementsInstanced 绘制 N 个立方体,从第一个缓冲区获取顶点,并使用存储在第二个缓冲区中的特定位置在着色器中转换它们。

    类似这样的:

    glVertexAttribPointer( vertexPositionIndex, /** Blah .. */ );
    glVertexAttribPointer( cubePositionIndex, /** Blah .. */ );
    glVertexAttribDivisor( cubePositionIndex, 1 ); // Advance one vertex attribute per instance
    
    glDrawElementsInstanced( GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices, NumberOfCubes );
    

    在您的顶点着色器中,您需要两个属性:

     vec3 vertexPosition; // The coordinates of a vertex of the generic cube
     vec3 cubePosition; // The coordinates of the center the specific cube being rendered
    
     // .... 
     vec3 vertex = vertexPosition + cubePosition;
    

    显然,您还可以有一个缓冲区来存储每个立方体的大小,或者另一个用于方向的缓冲区,这个想法保持不变。

    【讨论】:

    • 只是把它放在那里,也可以使用几何着色器(从 openGL 3.2 开始)来生成立方体,但它在性能方面可能不是一个很好的解决方案,尤其是对于大量的立方体。一个更老的例子(支持实例化)pixelnerve.com/v/2010/04/03/mass-cube-rendering
    【解决方案2】:

    在您的示例中,每个立方体每帧都使用自己的模型矩阵。 如果你想保持它,你需要多个 drawElements 调用。 如果某些立方体不移动(不需要每帧模型矩阵),您应该将这些立方体组合成一个 VBO。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2018-10-31
      • 2019-10-31
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多