WebGL Elements

In many situations, one vertex is used by many primitives. Using drawArrays() requires repeating the vertex coordinates each time we need it.

Elements provide an indirection layer over vertex data, a way to use indices of vertices instead of vertex data themselves. This allows sharing of data for vertices.

For example,

// a pentagon made of triangles:
const elementVertexData = new Float32Array([
    0.0,      0.0,
    0.0       1.0,
    0.95106,  0.30902,
    0.58779,  -.80902,
    -.58779,  -.80902,
    -.95106,  0.30902,
]);
const elementIndexData = [
    0, 1, 2,
    0, 2, 3,
    0, 3, 4,
    0, 4, 5,
    0, 5, 1,
];

Now, let's bind arrayVertexBuffer to the target gl.ARRAY_BUFFER.

elementVertexBuffer can be bound to another target gl.ELEMENT_ARRAY_BUFFER.

const arrayVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, arrayVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, arrayVertexBuffer, gl.STATIC_DRAW);

const elementVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementVertexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, elementIndexData);

Once gl.ELEMENT_ARRAY_BUFFER is bound, we can use gl.drawElements (it will throw if there's no buffer bound to gl.ELEMENT_ARRAY_BUFFER):

gl.drawElements(gl.TRIANGLES, elementIndexData.length, gl.UNSIGNED_BYTE, 0);

Downsides: more round-trips to GPU.