, indexBuffer=None, attribDivisors=None, legacy=False)[source]

Create a Vertex Array object (VAO). VAOs store buffer binding states, reducing CPU overhead when drawing objects with vertex data stored in VBOs.

Define vertex attributes within a VAO state by passing a mapping for generic attribute indices and VBO buffers.

  • attribBuffers (dict) – Attributes and associated VBOs to add to the VAO state. Keys are vertex attribute pointer indices, values are VBO descriptors to define. Values can be tuples where the first value is the buffer descriptor, the second is the number of attribute components (int, either 2, 3 or 4), the third is the offset (int), and the last is whether to normalize the array (bool).

  • indexBuffer (VertexBufferInfo) – Optional index buffer.

  • attribDivisors (dict) – Attribute divisors to set. Keys are vertex attribute pointer indices, values are the number of instances that will pass between updates of an attribute. Setting attribute divisors is only permitted if legacy is False.

  • legacy (bool, optional) – Use legacy attribute pointer functions when setting the VAO state. This is for compatibility with older GL implementations. Key specified to attribBuffers must be GLenum types such as GL_VERTEX_ARRAY to indicate the capability to use.


Create a vertex array object and enable buffer states within it:

vao = createVAO({0: vertexPos, 1: texCoords, 2: vertexNormals})

Using an interleaved vertex buffer, all attributes are in the same buffer (vertexAttr). We need to specify offsets for each attribute by passing a buffer in a tuple with the second value specifying the offset:

# buffer with interleaved layout `00011222` per-attribute
vao = createVAO(
    {0: (vertexAttr, 3),            # size 3, offset 0
     1: (vertexAttr, 2, 3),         # size 2, offset 3
     2: (vertexAttr, 3, 5, True)})  # size 3, offset 5, normalize

You can mix interleaved and single-use buffers:

vao = createVAO(
    {0: (vertexAttr, 3, 0), 1: (vertexAttr, 3, 3), 2: vertexColors})

Specifying an optional index array, this is used for indexed drawing of primitives:

vao = createVAO({0: vertexPos}, indexBuffer=indices)

The returned VertexArrayInfo instance will have attribute isIndexed==True.

Drawing vertex arrays using a VAO, will use the indexBuffer if available:

# draw the array
drawVAO(vao, mode=GL.GL_TRIANGLES)

Use legacy attribute pointer bindings when building a VAO for compatibility with the fixed-function pipeline and older GLSL versions:

attribBuffers = {GL_VERTEX_ARRAY: vertexPos, GL_NORMAL_ARRAY: normals}
vao = createVAO(attribBuffers, legacy=True)

If you wish to used instanced drawing, you can specify attribute divisors this way:

vao = createVAO(
    {0: (vertexAttr, 3, 0), 1: (vertexAttr, 3, 3), 2: vertexColors},
    attribDivisors={2: 1})

Back to top