Tute: Vertex Buffer Objects

Download the base code that draws a sphere as points in immediate mode.

In this tutorial you will modify this code to draw using firstly vertex arrays and then vertex buffer objects (VBOs). Unlike immediate mode (gl begin/vertex/end), vertex arrays allow large amounts of geometry to be drawn with a single call. VBOs extend this functionality, storing the data on the GPU so no data transfer to the GPU is needed per-render.

The geometry data can be stored in a number of different ways:

Additionally, separate arrays can be given for each vertex attribute (normal, texture coordinate etc.) or the attributes can be interleaved. The latter can be faster as it improves cache coherency. Interleaved vertex data is beyond the scope of this tutorial.

Related Functions

glGenBuffers
glBindBuffer
glBufferData
glEnableClientState
glVertexPointer
glDrawArrays
glDrawElements

Note: It is important to know clearly what OpenGL is expecting as arguments to these functions. For example the size argument in glBufferData must match or OpenGL may over-read the given array. Also if invalid indices are given in glDrawElements or more geometry is drawn than is available, the program may simply crash, freeze or cause unpredictable errors. Checking for errors at each step can be very helpful.

Tasks

Vertex Arrays

  1. In the init() function, fill an array of floats which contain the positions of every vertex in a sphere (move the for loops from the display() function).
  2. Now in the display function, use glVertexPointer to tell OpenGL to draw from your array. Then call glEnableClientState and glDrawArrays, replacing the previous immediate mode method, to draw your vertices as GL_POINTS.
  3. In the init() function, fill another array of unsigned ints which index your vertices to draw quads or triangles. Replace glDrawArrays with glDrawElements, giving the index array.

    It may help to use glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) to view your sphere in wireframe and double check the indices array is correct.

VBOs

In order to render from video memory, the geometry must be copied across. The first step is to generate a unique handle to an OpenGL buffer. Then video memory must be allocated for this buffer and data copied accross (both with glBufferData) before it can be read during rendering.

  1. Generate a buffer handle with glGenBuffers and buffer your array of vertices, with glBindBuffer and glBufferData using GL_ARRAY_BUFFER as the target.

  2. Now instead of passing the array pointer to glVertexPointer, bind your GL_ARRAY_BUFFER buffer containing your vertices and give a buffer offset (in this case zero) as the glVertexPointer pointer. Test the VBO using glDrawArrays and GL_POINTS.

  3. Create another buffer handle for the indices array however this time buffer the data using GL_ELEMENT_ARRAY_BUFFER as the target. Use glDrawElements and give the buffer offset, zero, as the pointer. Remebering to bind the GL_ELEMENT_ARRAY_BUFFER before drawing.

    If you get stuck, this code gives a simple example of using indices and glDrawElements.