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