# Vertex lists

There is a significant overhead in using pyglet.graphics.draw and pyglet.graphics.draw_indexed due to pyglet interpreting and formatting the vertex data for the video device. Usually the data drawn in each frame (of an animation) is identical or very similar to the previous frame, so this overhead is unnecessarily repeated.

A VertexList is a list of vertices and their attributes, stored in an efficient manner that's suitable for direct upload to the video card. On newer video cards (supporting OpenGL 1.5 or later) the data is actually stored in video memory.

Create a VertexList for a set of attributes and initial data with pyglet.graphics.vertex_list. The following example creates a vertex list with the two coloured points used in the previous page:

    vertex_list = pyglet.graphics.vertex_list(2,
        ('v2i', (10, 15, 30, 35)),
        ('c3B', (0, 0, 255, 0, 255, 0))
    )

To draw the vertex list, call its VertexList.draw method:

    vertex_list.draw(pyglet.gl.GL_POINTS)

Note that the primitive mode is given to the draw method, not the vertex list constructor. Otherwise the vertex_list method takes the same arguments as pyglet.graphics.draw, including any number of vertex attributes.

Because vertex lists can reside in video memory, it is necessary to call the delete method to release video resources if the vertex list isn't going to be used any more (there's no need to do this if you're just exiting the process).

# Updating vertex data

The data in a vertex list can be modified. Each vertex attribute (including the vertex position) appears as an attribute on the VertexList object. The attribute names are given in the following table.

> Vertex attribute | Object attribute
> --- | ---
> Vertex position | `vertices`
> Color | `colors`
> Edge flag | `edge_flags`
> Fog coordinate | `fog_coords`
> Normal | `normals`
> Secondary color | `secondary_colors`
> Texture coordinate | `tex_coords`
> Generic attribute | Inaccessible

In the following example, the vertex positions of the vertex list are updated by replacing the `vertices` attribute:

    vertex_list.vertices = [20, 25, 40, 45]

The attributes can also be selectively updated in-place:

    vertex_list.vertices[:2] = [30, 35]

Similarly, the color attribute of the vertex can be updated:

    vertex_list.colors[:3] = [255, 0, 0]

For large vertex lists, updating only the modified vertices can have a perfomance benefit, especially on newer graphics cards.

Attempting to set the attribute list to a different size will cause an error (not necessarily immediately, either). To resize the vertex list, call VertexList.resize with the new vertex count. Be sure to fill in any newly uninitialised data after resizing the vertex list.

Since vertex lists are mutable, you may not necessarily want to initialise them with any particular data. You can specify just the format string in place of the `(format, data)` tuple in the data arguments vertex_list function. The following example creates a vertex list of 1024 vertices with positional, color, texture coordinate and normal attributes:

    vertex_list = pyglet.graphics.vertex_list(1024, 'v3f', 'c4B', 't2f', 'n3f')

# Data usage

By default, pyglet assumes vertex data will be updated less often than it is drawn, but more often than just during initialisation. You can override this assumption for each attribute by affixing a usage specification onto the end of the format string, detailed in the following table:

> Usage | Description
> --- | ---
> `"/static"` | Data is never or rarely modified after initialisation
> `"/dynamic"` | Data is occasionally modified (default)
> `"/stream"` | Data is updated every frame

In the following example a vertex list is created in which the positional data is expected to change every frame, but the color data is expected to remain relatively constant:

    vertex_list = pyglet.graphics.vertex_list(1024, 'v3f/stream', 'c4B/static')

The usage specification affects how pyglet lays out vertex data in memory, whether or not it's stored on the video card, and is used as a hint to OpenGL. Specifying a usage does not affect what operations are possible with a vertex list (a `static` attribute can still be modified), and may only have performance benefits on some hardware.

# Indexed vertex lists

IndexedVertexList performs the same role as VertexList, but for indexed vertices. Use pyglet.graphics.vertex_list_indexed to construct an indexed vertex list, and update the IndexedVertexList.indices sequence to change the indices.