Почему этот gl.drawElements нуждается в повторной привязке, а gl.drawArrays нет? - PullRequest
0 голосов
/ 29 января 2019

Привет, ребята, я изучал webgl в эти дни.

Есть два фрагмента, которые выполняют одно и то же - нарисовать квадрат.Один использует gl.drawArrays для 6 вершин, а другой использует gl.drawElements для 4 вершин.

Однако я заметил, что при использовании gl.drawArrays мы можем отсоединить gl.ARRAY_BUFFER перед его использованием, он неиметь значение.Смотрите фрагменты.

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);
    }

initBuffers() вызывается до draw().Заметьте, что здесь я уже отсоединяю gl.ARRAY_BUFFER перед вызовом gl.drawArrays, и он успешно рисует квадрат.

Однако при использовании gl.drawElements я должен убедиться, что gl.ELEMENT_ARRAY_BUFFER в настоящее время привязан к правильным индексам.например,

gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);

, если я использую gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);, как я сделал для gl.drawArrays, я должен перепривязать его с помощью gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer); перед вызовом gl.drawElements.

1 Ответ

0 голосов
/ 29 января 2019

Это в основном объясняется в этом ответе: https://stackoverflow.com/a/27164577/128511

Краткая версия gl.drawArrays использует только атрибуты.Атрибуты имеют буферы, связанные с ними при вызове gl.vertexAttribPointer.Какой бы буфер ни был связан, то gl.ARRAY_BUFFER во время вызова gl.verexAttribPointer копируется в состояние этого атрибута.

Сами атрибуты являются состоянием текущего объекта Vertex Array (VAO), как и текущий ELEMENT_ARRAY_BUFFER.VAO являются необязательным расширением в WebGL1 и стандартной частью WebGL2.

Снова обратитесь к этому ответу: https://stackoverflow.com/a/27164577/128511, а также к этому ответу: https://stackoverflow.com/a/50257695/128511

...