Javascript 为什么gl.drawArrays不需要重新绑定而gl.drawElements需要重新绑定';T
嗨,伙计们,这些天我一直在学习webgl 有两个片段完成了相同的任务——画一个正方形。一个是对6个顶点使用gl.DrawArray,另一个是对4个顶点使用gl.drawElements 但是我注意到,当使用gl.drawArray时,我们可以在使用它之前解除绑定gl.ARRAY\u缓冲区,这并不重要。请参阅片段Javascript 为什么gl.drawArrays不需要重新绑定而gl.drawElements需要重新绑定';T,javascript,webgl,webgl2,Javascript,Webgl,Webgl2,嗨,伙计们,这些天我一直在学习webgl 有两个片段完成了相同的任务——画一个正方形。一个是对6个顶点使用gl.DrawArray,另一个是对4个顶点使用gl.drawElements 但是我注意到,当使用gl.drawArray时,我们可以在使用它之前解除绑定gl.ARRAY\u缓冲区,这并不重要。请参阅片段 function initBuffers() { /* V0 V3 (-0.5, 0.5, 0)
function initBuffers() {
/*
V0 V3
(-0.5, 0.5, 0) (0.5, 0.5, 0)
X---------------------X
| |
| |
| (0, 0) |
| |
| |
X---------------------X
V1 V2
(-0.5, -0.5, 0) (0.5, -0.5, 0)
*/
const vertices = [
// first triangle (V0, V1, V2)
-0.5, 0.5, 0,
-0.5, -0.5, 0,
0.5, -0.5, 0,
// second triangle (V0, V2, V3)
-0.5, 0.5, 0,
0.5, -0.5, 0,
0.5, 0.5, 0
];
// Setting up the VBO
squareVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(program.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(program.aVertexPosition);
// Clean
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
function draw() {
// Clear the scene
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.drawArrays(gl.TRIANGLES, 0, 6);
// Clean
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
在draw()之前调用initBuffers()
。请注意,在调用gl.drawArray
之前,我已经解除绑定了gl.ARRAY\u BUFFER
,它成功地绘制了正方形
但是,在使用gl.drawerelements时,我必须确保gl.ELEMENT\u ARRAY\u BUFFER
当前已绑定到正确的索引。e、 g
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
如果我使用gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,null)
就像我对gl.drawArray
所做的那样,我必须使用gl.bindBuffer(gl.ELEMENT\u ARRAY\u BUFFER,squareIndexBuffer)重新绑定它在调用gl.drawerelements
之前,此答案主要解释了这一点:
短版本为gl。drawArrays
仅使用属性。调用gl.vertexattributepointer
时,属性将缓冲区绑定到它们。在调用gl.verexattributepointer
时绑定的任何缓冲区都会复制到该属性的状态
属性本身是当前顶点数组对象(VAO)的状态,也是当前元素数组缓冲区的状态。VAO是WebGL1中的可选扩展,也是WebGL2的标准部分
再次参考此答案:以及此答案:您好,谢谢您的回复。我不太清楚您所说的绑定的缓冲区是什么意思。在您调用gl.verexattributepointer时,执行gl.ARRAY\u缓冲区会被复制到该属性的状态。
但是,我查看了您发布的那些链接,我觉得我已经掌握了窍门。如果我错了,请纠正我。之所以gl.drawArrays
不需要重新绑定,是因为gl.VertexAttributePointer
已在内部存储了arrayBuffer,以便我们可以直接使用。另一方面,gl.drawElements
具有全局元素ArrayBuffer,因此如果之前取消绑定它,则必须重新绑定它。请更正gl.drawArrays
。对于gl.drawerelements
元素阵列缓冲区是当前vertexArray
状态的一部分。在WebGL1中,只有一个全局顶点阵列,除非启用扩展名OES\u vertex\u array
。在WebGL2中,创建的顶点数组数量与创建的顶点数组数量相同(请参见gl.createVertexArray
,gl.bindVertexArray
)。顶点数组包含所有属性状态和elementArrayBuffer状态感谢您的回复!既然webgl2中可以有多个VAO来存储属性状态和elementArrayBuffer状态,那么我们需要区分哪个VAO存储哪个属性状态和哪个elementArrayBuffer状态吗?有办法检查吗?