Why use vertex array

The most obvious reason is that if an entity consist of many polygons , the adjacent polygons will share a lot of vertexes , if every polygons has it own vertexes, there will be a lot of redundant data.

The second reason is that dealing with every individual vertex separately are wasteful. Vertex arrays allows you to send vertex data in sets instead of individually.This can improve the performance. OpenGL can process an array of vertexes with just one function call.

VBO

Vertex has a disadvantage: the data is in client state , every time its referenced , it must be sent to server. VBO creates buffer object for vertex in high performance memory on the server side and provides same access functions to reference the arrays, which are used in vertex arrays, such as glVertexPointer(), glNormalPointer(), glTexCoordPointer(), etc.

Using VBO in OpenGL

Using VBO include allocating it, read or write it, feed to OpenGL and free it.

Allocate VBO. Using glGenBuffersARB to create a VBO:

 
GLuint id = 0xFFFF;
glGenBuffersARB( 1 , & id );
if ( id == 0xFFFF ) {
    Error("GenBuffersARB failed");
}
 

The first parameter tells OpenGL how many buffers to create, here we create one buffer, second parameter is the location to hold the id of created buffer. You will need this id to read or write the buffer.

Write the buffer, because the VBO is in server state, sometimes we call the action upload. First use glBindBufferARB to bind the buffer , each time you want to operate on a particular VBO, you need at first to bind it, this makes the buffer the active one. The data operations always works on the active buffer.

Then use glBufferDataARB or glBufferSubDataARB to upload the data.

 
glBindBufferedARB( GL_ARRAY_BUFFER_ARB, id );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, data, GL_STATIC_DRAW_ARB );
 

GL_ARRAY_BUFFER_ARB indicate the VBO will store vertex array data, to store indices array , using GL_ELEMENT_ARRAY_BUFFER_ARB.

 
void glBufferDataARB(GLenum target, GLsizei size, const void* data, GLenum usage)
 
usage:
  GL_STATIC_DRAW_ARB
  GL_STATIC_READ_ARB
  GL_STATIC_COPY_ARB
  GL_DYNAMIC_DRAW_ARB
  GL_DYNAMIC_READ_ARB
  GL_DYNAMIC_COPY_ARB
  GL_STREAM_DRAW_ARB
  GL_STREAM_READ_ARB
  GL_STREAM_COPY_ARB
 
 

usage indicate how the VBO will be used, GL_STATIC_DRAW_ARB means the data will not change, GL_DYNAMIC_DRAW_ARB means the data will be updated frequently. GL_STREAM_DRAW_ARB means data will be changed every frame.

Update VBO. The VBO may be allocated in SYSTEM memory or in video memory, so you have map the memory to your application's address space to change the data. Use glMapBufferARB:

 
glBindBufferedARB( GL_ARRAY_BUFFER_ARB, id );
float *ptr = (float*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB);
 
// If the GPU is working on the buffer, null is returned
// Only return a not null pointer, we can access the buffer
if(ptr) {
    // write  something into memory pointed by ptr.
 
    glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); 
}
 
 

Free VBO

To free the buffer , use glDeleteBuffersARB.

 
glDeleteBuffersARB( 1, & id);
 

Reference

OpenGL Vertex Buffer Object (VBO)

OpenGL Vertex Array