Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 什么时候应该使用OpenGL顶点的索引数组?_Arrays_Opengl_Vertex_Indexed - Fatal编程技术网

Arrays 什么时候应该使用OpenGL顶点的索引数组?

Arrays 什么时候应该使用OpenGL顶点的索引数组?,arrays,opengl,vertex,indexed,Arrays,Opengl,Vertex,Indexed,我试图弄清楚什么时候应该使用OpenGL顶点的索引数组,使用gl[Multi]DrawElements等绘制,什么时候应该使用连续的顶点数组,使用gl[Multi]DrawArray绘制 (更新:我得到的回复一致认为应该始终使用索引顶点。) 我已经在这个问题上反复讨论了好几次,所以我将概述我目前的理解,希望有人能告诉我,我现在终于或多或少正确了,或者指出我仍然存在的误解。具体来说,我有三个结论,用黑体字表示。如果他们错了,请改正 一个简单的例子是,如果我的几何体由网格组成,以形成曲面。在这种情况

我试图弄清楚什么时候应该使用OpenGL顶点的索引数组,使用gl[Multi]DrawElements等绘制,什么时候应该使用连续的顶点数组,使用gl[Multi]DrawArray绘制

更新:我得到的回复一致认为应该始终使用索引顶点。)

我已经在这个问题上反复讨论了好几次,所以我将概述我目前的理解,希望有人能告诉我,我现在终于或多或少正确了,或者指出我仍然存在的误解。具体来说,我有三个结论,用黑体字表示。如果他们错了,请改正

一个简单的例子是,如果我的几何体由网格组成,以形成曲面。在这种情况下,网格中的顶点对于每个顶点的三角形都具有相同的属性(位置、法线、颜色、纹理坐标等)。

这使我得出结论:

1。对于接缝较少的几何体,索引阵列是一大优势。

始终遵循规则1,但以下情况除外:

对于非常“块状”的几何体,其中每条边代表一条接缝,索引数组的好处不太明显。以简单立方体为例,尽管每个顶点用于三个不同的面,但我们不能在它们之间共享顶点,因为对于单个顶点,每个面上的曲面法线(以及可能的其他东西,如颜色和纹理坐标)将不同。因此,我们需要显式地在数组中引入冗余顶点位置,以便同一位置可以多次用于不同的法线等。这意味着索引数组的使用较少

e、 g.渲染立方体的单个面时:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2
(这可以单独考虑,因为此面和所有相邻面之间的接缝意味着这些顶点不能在面之间共享)

如果使用GL_三角形_扇(或_条)渲染,则立方体的每个面都可以这样渲染:

verts  = [v0, v1, v2, v3]
colors = [c0, c0, c0, c0]
normal = [n0, n0, n0, n0]
添加索引不允许我们简化这一点

由此我得出结论:

2。当渲染所有接缝或大部分接缝的几何体时,当使用GL_三角形_条带或_扇时,我不应该使用索引数组,而应该始终使用GL[Multi]DrawArrays。

更新:回复表明这一结论是错误的。尽管索引不允许我们在此处减小阵列的大小,但由于其他性能优势,仍应使用它们,如评论中所述)

规则2的唯一例外是:

使用GL_三角形(而不是条带或扇形)时,一半的顶点仍然可以重复使用两次,使用相同的法线和颜色等,因为每个立方体面都渲染为两个单独的三角形。同样,对于同一个立方体面:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2
如果没有索引,使用GL_三角形,数组将类似于:

verts =   [v0, v1, v2,  v2, v3, v0]
normals = [n0, n0, n0,  n0, n0, n0]
colors =  [c0, c0, c0,  c0, c0, c0]
由于顶点和法线通常各为3个浮点数,颜色通常为3个字节,因此,对于每个立方体面,大约:

verts   = 6 * 3 floats = 18 floats
normals = 6 * 3 floats = 18 floats
colors  = 6 * 3 bytes  = 18 bytes

= 36 floats and 18 bytes per cube face.
(我知道如果使用不同的类型,字节数可能会发生变化,确切数字仅供说明。)

有了索引,我们可以稍微简化一下,给出:

verts   = [v0, v1, v2, v3]     (4 * 3 = 12 floats)
normals = [n0, n0, n0, n0]     (4 * 3 = 12 floats)
colors  = [c0, c0, c0, c0]     (4 * 3 = 12 bytes)
indices = [0, 1, 2,  2, 3, 0]  (6 shorts)

= 24 floats + 12 bytes, and maybe 6 shorts, per cube face.
请参见在后一种情况下,顶点0和2如何使用两次,但在每个顶点、法线和颜色数组中仅表示一次。这听起来像是使用索引的小胜利,即使在每个几何体边都是接缝的极端情况下也是如此

这使我得出结论:

3。使用GL_三角形时,应始终使用索引数组,即使对于所有接缝的几何体也是如此。

如果我的结论是错误的,请用黑体字更正

由此我得出结论,当渲染所有接缝或大部分接缝的几何体时,当使用GL_TRIANGLE_STRIP或_FAN时,我不应该使用索引数组,而应该始终使用GL[Multi]DrawArray

不,原因很简单

你的结论是基于你分析了一个由两个三角形组成的四边形。无法使用索引数组简化使用三角形扇形/条形绘制的这两个三角形

但是试着考虑一个大的地形几何体。使用三角形扇形/条形图元将每个地形块绘制为四边形。例如:

图中的每个三角形条都有与相邻三角形条相同的所有顶点,使用索引可以压缩几何体定义,而不是为每个三角形条重复顶点


基本上,只要您可以与另一个图元共享一个图元的大多数顶点,使用索引绘制图元(三角形、扇形和条带)是非常有用的。

共享信息可以节省信息传输带宽,但这不是唯一的优势。实际索引数组允许:

  • 避免同步属于同一“概念”顶点(多次指定)的信息
  • 允许对单个顶点执行相同的着色器操作,而不是多次执行,每个顶点重复一次
  • 此外,结合使用三角形条带/扇形和索引允许应用程序压缩索引缓冲区,因为条带/扇形规格需要较少的索引(三角形始终需要每个面3个索引)
正如您所指定的,当一个顶点不能与另一个重合顶点共享与其关联的所有信息(颜色、纹理坐标等)时,就不能使用索引数组


为了完整性起见,几何体规范所需信息的大小并不是决定最佳渲染操作的唯一因素

事实上,基本体渲染的另一个基本因素是数据的缓存本地化。巴德尔