OpenGL避免多次调用glDrawElements

时间:2014-07-11 15:23:36

标签: c++ opengl glsl opengl-3

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

我的代码基于OpenGL超级明星的example多维数据集。

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

PS我们仅限于OpenGL 3.3功能。

2 个答案:

答案 0 :(得分:5)

  

这是否值得麻烦(性能明智)?

可能是的,但尽管如此仍然试着说明。

您要找的是实例化渲染,请查看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;

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

答案 1 :(得分:0)

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