指示符,glDrawElements和/或其他绘制大顶点数组的方法



我正在尝试显示一个等值面,该等值面使用行进立方体算法构建,我想它会产生一组三角形。然而,我是一个完全的图形编程业余爱好者,我正在努力理解有效绘制它们的几种方法。

我想到的是使用glVertexPointer-glDrawElement构造在一次调用中绘制所有内容。不过,后者要求我知道指数,而我显然不知道它们。此外,我实际上并不完全确定它们的目的:我认为它们只是一个索引,是驱动程序使用它们的顺序,也是通过排除多次出现的相同顶点来节省内存的一种方式。

那么,我对指数目的的看法是否正确,解决问题的正确方法是什么?

如果您不需要索引,那么...不要使用索引!是的,如果多次使用同一顶点,它们可用于提高渲染效率。但它们完全是可选的。

在没有索引的情况下呈现时使用的绘制调用是 glDrawArrays() 。这将根据传递给 draw 调用的基元类型,以自然顺序使用顶点缓冲区中的顶点。例如,使用 GL_TRIANGLES ,它将绘制一个在缓冲区中的位置 (0, 1, 2) 具有顶点的三角形,一个具有顶点 (3, 4, 5) 的三角形,依此类推。

因此,在您的等值面算法中,您可以在每次生成三角形时简单地计算 3 个顶点,并将它们附加到最终存储在顶点缓冲区中的顶点列表中。然后用glDrawArrays(GL_TRIANGLES, ...)画出整个东西,仅此而已。

现在,在覆盖表面的网格中,相同的顶点平均由大约 6 个三角形共享(查看常规网格以了解此数字是如何得出的)。因此,如果为每个三角形分别生成顶点,则相同的顶点大约 6 次,从而导致大量不必要的内存使用和顶点处理时间。

这就是指数的用武之地。可以使用的一种方法是,对于格网的每个边,跟踪是否已创建边上的等值面顶点,如果已创建,则存储其索引。然后,每当在生成三角形时需要网格边的顶点时,如果边还没有顶点,则可以创建一个新顶点(带有新索引),或者使用已创建的顶点的索引。然后,将生成的索引序列存储在索引缓冲区中,并使用 glDrawElements(GL_TRIANGLES, ...) 绘制。

上述方法的一个小变化是,首先遍历所有网格边,计算与等值面相交的边的所有顶点,然后再次存储每个边的顶点索引。然后,当您迭代网格立方体以生成三角形时,您只需从其每个相交边缘获取顶点索引即可。

如果你想用一次调用画一个大东西,你可以通过提供绘图函数来做到这一点 2件事:

顶点数组

这是一个,你猜对了,顶点的数组。在 3D 空间中进行坐标。它们不必按任何特定顺序排列。

索引数组

这是顶点数组中的索引数组。此数组告诉驱动程序顶点的顺序(什么与什么连接)。

您应该上传所有顶点,然后将它们转换为索引数组中的三角形。

最新更新