Javascript 为什么gl.drawArrays不需要重新绑定而gl.drawElements需要重新绑定';T

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)

嗨,伙计们,这些天我一直在学习webgl

有两个片段完成了相同的任务——画一个正方形。一个是对6个顶点使用gl.DrawArray,另一个是对4个顶点使用gl.drawElements

但是我注意到,当使用gl.drawArray时,我们可以在使用它之前解除绑定gl.ARRAY\u缓冲区,这并不重要。请参阅片段

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状态吗?有办法检查吗?