Indices, glDrawElements and/or 其他绘制大顶点数组的方法
Indicies, glDrawElements and/or other methods of drawing big vertex arrays
我正在尝试显示一个等值面,它是使用移动立方体算法构建的,我想它会生成一组三角形。然而,我在图形编程方面是一个完全的业余爱好者,而且我正在努力理解有效绘制它们的几种方法。
我的想法是使用诸如 glVertexPointer-glDrawElement 构造之类的方法在一个调用中将其全部绘制出来。但是,后者要求我知道索引,而我显然不知道它们。此外,我实际上并不确定它们的用途:我认为它们只是一个,呃,索引,驱动程序使用它们的顺序以及通过排除多次出现的相同顶点来节省内存的方法.
那么,我对指数目的的看法是否正确?解决我的问题的正确方法是什么?
如果你想一次调用绘制一个大东西,你可以通过提供绘图函数来实现 2 件事:
顶点数组
这是一个顶点数组,您猜对了。 3D 坐标 space。它们不必按任何特定顺序排列。
索引数组
这是顶点数组中的索引数组。
该数组告诉您的驱动程序顶点的顺序(什么与什么相连)。
你应该上传所有顶点,然后将它们变成索引数组中的三角形。
如果您不需要索引,那么...不要使用索引!是的,如果多次使用同一个顶点,它们可以用来提高渲染效率。但它们完全是可选的。
在没有索引的情况下渲染时使用的绘图调用是 glDrawArrays()
。这将根据传递给绘制调用的基元类型,以自然顺序使用顶点缓冲区中的顶点。例如,使用 GL_TRIANGLES
,它将在缓冲区中绘制一个顶点位于 (0, 1, 2) 位置的三角形,一个顶点位于 (3, 4, 5) 的三角形,等等
所以在你的等值面算法中,你可以在每次生成三角形时简单地计算 3 个顶点,并将它们附加到最终存储在顶点缓冲区中的顶点列表中。然后用glDrawArrays(GL_TRIANGLES, ...)
画出整个东西,就这样了。
现在,在覆盖一个表面的网格中,相同的顶点平均由大约 6 个三角形共享(查看常规网格以了解该数字是如何得出的)。因此,如果您为每个三角形分别生成顶点,您将拥有大约 6 次相同的顶点,从而导致大量不必要的内存使用和顶点处理时间。
这就是索引的用武之地。您可以使用的一种方法是,对于网格的每条边,您跟踪该边上的等值面顶点是否已创建,如果已创建则存储其索引。然后,任何时候在生成三角形时需要网格边的顶点,如果边还没有顶点,则创建一个新顶点(具有新索引),或者使用已创建顶点的索引。然后将生成的索引序列存储在索引缓冲区中,并使用 glDrawElements(GL_TRIANGLES, ...)
.
绘制
上面的一个小变化是你首先遍历所有网格边,计算与等值面相交的边的所有顶点,然后再次存储每个边的顶点索引。然后,当您迭代网格立方体以生成三角形时,您可以简单地从它的每个相交边获取顶点索引。
我正在尝试显示一个等值面,它是使用移动立方体算法构建的,我想它会生成一组三角形。然而,我在图形编程方面是一个完全的业余爱好者,而且我正在努力理解有效绘制它们的几种方法。
我的想法是使用诸如 glVertexPointer-glDrawElement 构造之类的方法在一个调用中将其全部绘制出来。但是,后者要求我知道索引,而我显然不知道它们。此外,我实际上并不确定它们的用途:我认为它们只是一个,呃,索引,驱动程序使用它们的顺序以及通过排除多次出现的相同顶点来节省内存的方法.
那么,我对指数目的的看法是否正确?解决我的问题的正确方法是什么?
如果你想一次调用绘制一个大东西,你可以通过提供绘图函数来实现 2 件事:
顶点数组
这是一个顶点数组,您猜对了。 3D 坐标 space。它们不必按任何特定顺序排列。
索引数组
这是顶点数组中的索引数组。 该数组告诉您的驱动程序顶点的顺序(什么与什么相连)。
你应该上传所有顶点,然后将它们变成索引数组中的三角形。
如果您不需要索引,那么...不要使用索引!是的,如果多次使用同一个顶点,它们可以用来提高渲染效率。但它们完全是可选的。
在没有索引的情况下渲染时使用的绘图调用是 glDrawArrays()
。这将根据传递给绘制调用的基元类型,以自然顺序使用顶点缓冲区中的顶点。例如,使用 GL_TRIANGLES
,它将在缓冲区中绘制一个顶点位于 (0, 1, 2) 位置的三角形,一个顶点位于 (3, 4, 5) 的三角形,等等
所以在你的等值面算法中,你可以在每次生成三角形时简单地计算 3 个顶点,并将它们附加到最终存储在顶点缓冲区中的顶点列表中。然后用glDrawArrays(GL_TRIANGLES, ...)
画出整个东西,就这样了。
现在,在覆盖一个表面的网格中,相同的顶点平均由大约 6 个三角形共享(查看常规网格以了解该数字是如何得出的)。因此,如果您为每个三角形分别生成顶点,您将拥有大约 6 次相同的顶点,从而导致大量不必要的内存使用和顶点处理时间。
这就是索引的用武之地。您可以使用的一种方法是,对于网格的每条边,您跟踪该边上的等值面顶点是否已创建,如果已创建则存储其索引。然后,任何时候在生成三角形时需要网格边的顶点,如果边还没有顶点,则创建一个新顶点(具有新索引),或者使用已创建顶点的索引。然后将生成的索引序列存储在索引缓冲区中,并使用 glDrawElements(GL_TRIANGLES, ...)
.
上面的一个小变化是你首先遍历所有网格边,计算与等值面相交的边的所有顶点,然后再次存储每个边的顶点索引。然后,当您迭代网格立方体以生成三角形时,您可以简单地从它的每个相交边获取顶点索引。