DrawingGL 1.1

glDrawElements

Draws primitives using an index buffer to choose which vertices to use.

Signature

void glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);

How it works

Instead of reading vertices in order, the GPU reads count indices from the element buffer stored in the bound VAO, and fetches the vertex each index points to. A cube needs only 8 unique vertices plus 36 small indices, instead of 36 full vertices.

The GPU also caches recently transformed vertices, so reused indices are nearly free.

GL_TRIANGLES0123456 vertices → 2 trianglesGL_TRIANGLE_STRIP0123456 vertices → 4 trianglesGL_TRIANGLE_FAN0123456 vertices → 4 triangles
The same six vertices (0 to 5) in the three triangle modes. GL_TRIANGLES takes them three at a time; GL_TRIANGLE_STRIP makes a triangle from each new vertex and the two before it; GL_TRIANGLE_FAN joins every pair to vertex 0.

Parameters

modeGLenum

Primitive type.

Common values

GL_TRIANGLES
Every 3 vertices form one triangle. The default choice.
GL_TRIANGLE_STRIP
Each new vertex forms a triangle with the previous two.
GL_TRIANGLE_FAN
All triangles share the first vertex.
GL_LINES / GL_LINE_STRIP / GL_LINE_LOOP
Line segments.
GL_POINTS
One point per vertex.
countGLsizei

Number of INDICES to read.

typeGLenum

Type of each index in the element buffer.

Common values

GL_UNSIGNED_INT
32-bit — safe default.
GL_UNSIGNED_SHORT
16-bit — up to 65 535 vertices, half the memory.
GL_UNSIGNED_BYTE
8-bit — up to 255 vertices.
indicesconst void *

Byte offset into the element buffer, cast to void*. Usually 0.

Tips & pitfalls

  • type must match the actual C++ type of your index array: unsigned int ↔ GL_UNSIGNED_INT.

  • If nothing is drawn, check that the EBO was bound while the VAO was bound.

Errors

When the call is invalid it does nothing and sets an error, which glGetError returns:

GL_INVALID_ENUM
type is not one of the three unsigned types.
GL_INVALID_OPERATION
No VAO bound, or no program in use.

Example

example.cpp
1unsigned int indices[] = { 0, 1, 3,   1, 2, 3 }; // quad = 2 triangles
2glBindVertexArray(vao);
3glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
4glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
5
6glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
Official Khronos documentation