This may be more information then you wanted, but here's what I've done to do my VBOs
When I first create an object/model:
void Objects::ReserveVBOs(void){ // Vertex glGenBuffersARB(1, &VertexName); glBindBufferARB(GL_ARRAY_BUFFER, VertexName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 3 * sizeof(float), pVertex, GL_DYNAMIC_DRAW); // Color glGenBuffersARB(1, &ColorName); glBindBufferARB(GL_ARRAY_BUFFER, ColorName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 4 * sizeof(unsigned char), pColor, GL_DYNAMIC_DRAW); // Normal glGenBuffersARB(1, &NormalName); glBindBufferARB(GL_ARRAY_BUFFER, NormalName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 3 * sizeof(float), pNormal, GL_DYNAMIC_DRAW); // Texture glGenBuffersARB(1, &TexCoordName); glBindBufferARB(GL_ARRAY_BUFFER, TexCoordName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 2 * sizeof(float), pTexCoord, GL_DYNAMIC_DRAW); // Points glGenBuffersARB(1, &Points.VBOName); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Points.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Points.IndexCurrentSize * sizeof(unsigned int), Points.pIndex, GL_DYNAMIC_DRAW); // Lines glGenBuffersARB(1, &Lines.VBOName); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Lines.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Lines.IndexCurrentSize * sizeof(unsigned int), Lines.pIndex, GL_DYNAMIC_DRAW); // Triangles glGenBuffersARB(1, &Triangles.VBOName); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Triangles.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Triangles.IndexCurrentSize * sizeof(unsigned int), Triangles.pIndex, GL_DYNAMIC_DRAW); // Quads glGenBuffersARB(1, &Quads.VBOName); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Quads.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Quads.IndexCurrentSize * sizeof(unsigned int), Quads.pIndex, GL_DYNAMIC_DRAW);}
Whenever I update the data in my object/model, I do this to update my VBOs:
void Objects::UpdateVBOs(void){ // Vertex glBindBufferARB(GL_ARRAY_BUFFER, VertexName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 3 * sizeof(float), pVertex, GL_DYNAMIC_DRAW); // Color glBindBufferARB(GL_ARRAY_BUFFER, ColorName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 4 * sizeof(unsigned char), pColor, GL_DYNAMIC_DRAW); // Normal glBindBufferARB(GL_ARRAY_BUFFER, NormalName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 3 * sizeof(float), pNormal, GL_DYNAMIC_DRAW); // Texture glBindBufferARB(GL_ARRAY_BUFFER, TexCoordName); glBufferDataARB(GL_ARRAY_BUFFER, VertexCurrentSize * 2 * sizeof(float), pTexCoord, GL_DYNAMIC_DRAW); // Points glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Points.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Points.IndexCurrentSize * sizeof(unsigned int), Points.pIndex, GL_DYNAMIC_DRAW); // Lines glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Lines.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Lines.IndexCurrentSize * sizeof(unsigned int), Lines.pIndex, GL_DYNAMIC_DRAW); // Triangles glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Triangles.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Triangles.IndexCurrentSize * sizeof(unsigned int), Triangles.pIndex, GL_DYNAMIC_DRAW); // Quads glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Quads.VBOName); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Quads.IndexCurrentSize * sizeof(unsigned int), Quads.pIndex, GL_DYNAMIC_DRAW);}
And when I want to draw, I do this:
// Bind the vertex data glBindBufferARB(GL_ARRAY_BUFFER, VertexName); glVertexPointer(3, GL_FLOAT, 0, 0); // Bind the color data glBindBufferARB(GL_ARRAY_BUFFER, ColorName); glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0); // Bind the normal data glBindBufferARB(GL_ARRAY_BUFFER, NormalName); glNormalPointer(GL_FLOAT, 0, 0); // Bind the texture data glBindBufferARB(GL_ARRAY_BUFFER, TexCoordName); glTexCoordPointer(2, GL_FLOAT, 0, 0); // Draw the Points if (Points.IndexCurrentSize > 0) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Points.VBOName); glDrawRangeElements(GL_POINTS, 0, Points.IndexCurrentSize, Points.IndexCurrentSize, GL_UNSIGNED_INT, NULL); } // Draw the Lines if (Lines.IndexCurrentSize > 0) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Lines.VBOName); glDrawRangeElements(GL_LINES, 0, Lines.IndexCurrentSize, Lines.IndexCurrentSize, GL_UNSIGNED_INT, NULL); } // Draw the Triangles if (Triangles.IndexCurrentSize > 0) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Triangles.VBOName); glDrawRangeElements(GL_TRIANGLES, 0, Triangles.IndexCurrentSize, Triangles.IndexCurrentSize, GL_UNSIGNED_INT, NULL); } // Draw the Quads if (Quads.IndexCurrentSize > 0) { glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Quads.VBOName); glDrawRangeElements(GL_QUADS, 0, Quads.IndexCurrentSize, Quads.IndexCurrentSize, GL_UNSIGNED_INT, NULL); }
You can modify the call to glDrawRangeElements() to draw only portions of the VBO by changing the 4th parameter to the number of verticies you want to draw (in the example above, you can see all the verticies are drawn) and changing the last parameter to a buffer offset. Here's an example of how I do that case:
glDrawRangeElements(GL_TRIANGLES, 0, Triangles.IndexCurrentSize, (size * 3), GL_UNSIGNED_INT, BUFFER_OFFSET((start * 3) * sizeof(unsigned int)));
where BUFFER_OFFSET is #define BUFFER_OFFSET(i) ((char *)NULL + (i)). 'size' is the number of triangles to draw, 'start' is the triangle to begin drawing from.
Hope this helps. VBOs gave (and sometimes still give) me a lot of trouble to get working the first time.