我正在将我们的图形从使用旧的固定管道功能迁移到使用可编程管道。我们最简单的模型只是空间中点的集合,其中每个点都可以用不同的形状表示。其中之一是立方体。
我的代码基于立方体 example来自 OpenGL 精湛。
在这个例子中,立方体被放置在有些随机的地方,而我将在空间中有固定点亮。我想知道是否有办法将该列表传递给我的着色器,以便在每个点绘制一个立方体,而不是循环遍历列表并每次调用 glDrawElements。这是否值得麻烦(性能方面)?
PS 我们仅限于 OpenGL 3.3 功能。
最佳答案
Is that even worth the trouble (performance wise)?
可能是的,但还是要尝试分析。
你要找的是实例化渲染,看看glDrawElementsInstanced和 glVertexAttribDivisor .
您要做的是将一个通用立方体(以原点为中心)的 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;
显然,您还可以有一个缓冲区来存储每个立方体的大小,或者另一个缓冲区来存储方向,这个想法是一样的。
关于c++ - OpenGL 避免多次调用 glDrawElements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24701223/