我有一个这样的顶点缓冲区:

0.0, 0.0,
1.0, 0.0,
0.0, 0.6,
1.0, 0.6,
0.5, 1.0


我有以下索引缓冲区:

0, 2,
2, 4,
4, 3,
3, 2,
2, 1,
1, 0,
0, 3,
3, 1


我知道我要使用WebGL绘制gl.LINES,表示多个分隔的线段。

gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, indexBuffer);


似乎可以在WebGL的单个绘制调用中绘制多个线段。 br />
我能不能有人给我ELI5,什么是索引缓冲区?它与顶点缓冲区有什么关系?如何从我的原语生成索引缓冲区?

#1 楼


有人能给我ELI5吗?什么是索引缓冲区?它与顶点缓冲区有何关系?


您的顶点缓冲区包含X和Y坐标5顶点。它们是:

index |  X  |  Y
  0   | 0.0 | 0.0 
  1   | 1.0 | 0.0
  2   | 0.0 | 0.6
  3   | 1.0 | 0.6
  4   | 0.5 | 1.0


您的索引缓冲区包含有关在这些顶点之间绘制哪些线的信息。它使用顶点缓冲区中每个顶点的索引作为值。

由于要绘制线,因此索引缓冲区中的每对连续值都表示一个线段。例如,如果索引缓冲区以0, 2开头,则意味着在顶点数组的第0个顶点和第2个顶点之间绘制一条线,在这种情况下,这将绘制从[0.0, 0.0][0.0, 0.6]的一条线。

下图每对索引的颜色与它指示的线进行颜色协调:



同样,如果您绘制的是三角形而不是线条,则需要提供一个索引缓冲区,其中每个3个连续值表示顶点缓冲区中三个顶点的索引,例如

0, 1, 2,
2, 1, 3,
2, 3, 4,


#2 楼

如果您有这样一个顶点缓冲区:

var vertices = [
  0.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.5, 1.0, 0.0
]


并按原样绘制它:

// Create an empty buffer object
var vertex_buffer = gl.createBuffer();

// Bind appropriate array buffer to it
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

// Pass the vertex data to the buffer
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 5);


每个线段都需要两个专用坐标。使用上面定义的vertices,只能画两条线:



如果定义了以下索引:

var indices = [
  0, 2,
  2, 4,
  4, 3,
  3, 2,
  2, 1,
  1, 0,
  0, 3,
  3, 1
]


可以一次又一次地绘制与相同顶点相交的线。这减少了冗余。如果您绑定索引缓冲区并告诉GPU按照indecies数组中指定的顺序绘制连接顶点的线段:

var index_buffer = gl.createBuffer();

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);

gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

// draw geometry lines by indices
gl.drawElements(gl.LINES, 16, gl.UNSIGNED_SHORT, index_buffer);


无需重新定义就可以绘制更复杂的图形相同的顶点一遍又一遍。结果如下:



要获得没有索引的相同结果,顶点缓冲区应如下所示:

var vertices = [
  0.0, 0.0, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.5, 1.0, 0.0,
  0.5, 1.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  0.0, 0.6, 0.0,
  1.0, 0.0, 0.0,
  1.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  0.0, 0.0, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.6, 0.0,
  1.0, 0.0, 0.0
]

/* [...] */

// Draw the lines
gl.drawArrays(gl.LINES, 0, 16);

结果相同的图像:



请注意,存储顶点的冗余度很高。

评论


$ \ begingroup $
如果您打算立即回答自己的问题,请至少在问题中提及该问题,以免其他人浪费时间。
$ \ endgroup $
– Rottem
16年4月13日在12:50

$ \ begingroup $
每个好的问题都应该有2或3个好的答案。您没有浪费时间,我非常感谢您的努力。我需要此线程向项目合作伙伴解释逻辑,您的帖子将极大地帮助他。
$ \ endgroup $
–非洲
16年4月13日在12:53

$ \ begingroup $
@ 5chdn强烈建议自己回答。感谢您添加此答案。如果您在发布问题时心中有一个答案,则问题下方的复选框将使您能够在发布问题之前写下您的答案,因此两者都将同时出现。这只是为了让您知道它是否有用-您当然不需要这样做,并且在发布问题后的任何时间间隔内,仍然非常欢迎自助回答。
$ \ endgroup $
–trichoplax
16-4-16在9:48