Best Use Of Vbos?

Started by
5 comments, last by Ahl 13 years, 3 months ago
I have my VBO code working right now but I'm wondering if there is a better way to go about it. I've read that loading all the information for a given model into one buffer is a good way. I've read that loading all models into one buffer and managing them through memory manipulation is a good way to go.

loading code:

glGenBuffersARB( 1, &VertexID ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, VertexID ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*3*sizeof(float), VertexData, GL_STATIC_DRAW_ARB ); // Load The Data


// Generate And Bind The Texture Coordinate Buffer
glGenBuffersARB( 1, &NormalID ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, NormalID ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB, NormalCount*2*sizeof(float), NormalData, GL_STATIC_DRAW_ARB ); // Load The Data

// Generate And Bind The Texture Coordinate Buffer
glGenBuffersARB( 1, &TexcoordID ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, TexcoordID ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB, TexCoordCount*2*sizeof(float), TexCoordData, GL_STATIC_DRAW_ARB ); // Load The Data


Rendering code:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f, 0.0f, -5.0f);

glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);

xrot += 0.005;
yrot += 0.005;
zrot += 0.005;

glColor3f(1.0, 1.0, 1.0);

glEnableClientState( GL_VERTEX_ARRAY ); // Enable Vertex Arrays
glEnableClientState( GL_NORMAL_ARRAY ); // Enable Normal Arrays
glEnableClientState( GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coord Arrays

if (MyModel->Vertexs == true)
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, MyModel->VertexID);
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL ); // Set The Vertex Pointer To The Vertex Buffer
}
if (MyModel->Normals == true)
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, MyModel->NormalID );
glNormalPointer( GL_FLOAT, 0, (char *) NULL ); // Set The Normal Pointer To The Normal Buffer
}
if (MyModel->TexCoords == true)
{
glBindBufferARB( GL_ARRAY_BUFFER_ARB, MyModel->TexcoordID );
glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL ); // Set The TexCoord Pointer To The TexCoord Buffer
}

glDrawArrays( GL_TRIANGLES, 0, MyModel->VertexCount ); // Draw All Of The Triangles At Once

glDisableClientState( GL_VERTEX_ARRAY ); // Disable Vertex Arrays
glDisableClientState( GL_NORMAL_ARRAY ); // Disable Normal Arrays
glDisableClientState( GL_TEXTURE_COORD_ARRAY ); // Disable Texture Coord Arrays
return TRUE;


It's mostly in it's present form for testing purposes as I'm just learning how to use them.

Thanks in advance.
Advertisement
Sure, but it won't necessarily give you a big perf improvement.
Here you go
http://www.opengl.org/wiki/VBO_-_just_examples

and also

http://www.opengl.org/wiki/Vertex_Buffer_Object
http://www.opengl.org/wiki/VBO_-_more
http://www.opengl.org/wiki/Vertex_Arrays
http://www.opengl.org/wiki/Vertex_Formats
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Just for S' and G's I'm trying sticking all the data for a given model in a single VBO like so:


bool Model::BuildVBO()
{
GLsizei VBOsize = (VertexCount*3 + NormalCount*3 + TexCoordCount*2) * sizeof(float);
glGenBuffersARB( 1, &VertexID );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, VertexID );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VBOsize, NULL, GL_STATIC_DRAW_ARB );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, NULL, VertexData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, NULL, NormalData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, NULL, TexCoordData );

return true;
}


then rendering it like so:

int DrawGLScene(Model *MyModel)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f, 0.0f, -5.0f);

glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
glRotatef(zrot, 0.0f, 0.0f, 1.0f);

xrot += 0.005;
yrot += 0.005;
zrot += 0.005;

glColor3f(1.0, 1.0, 1.0);

glEnableClientState( GL_VERTEX_ARRAY ); // Enable Vertex Arrays
glEnableClientState( GL_NORMAL_ARRAY ); // Enable Normal Arrays
glEnableClientState( GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coord Arrays

glBindBufferARB( GL_ARRAY_BUFFER_ARB, MyModel->VertexID);
if (MyModel->Vertexs == true) glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
if (MyModel->Normals == true ) glNormalPointer( GL_FLOAT, 0, (char *) NULL );
if (MyModel->TexCoords == true) glTexCoordPointer( 2, GL_FLOAT, 0, (char *) NULL );

glDrawArrays( GL_TRIANGLES, 0, MyModel->VertexCount ); // Draw All Of The Triangles At Once

glDisableClientState( GL_VERTEX_ARRAY ); // Disable Vertex Arrays
glDisableClientState( GL_NORMAL_ARRAY ); // Disable Normal Arrays
glDisableClientState( GL_TEXTURE_COORD_ARRAY ); // Disable Texture Coord Arrays
return TRUE;
}


I get no errors but I also only get a blank screen. The model doesn't show. What am I doing wrong?
I may be wrong but from the code it looks to me like the glBufferSubData() calls are all writing in the same location (each call is overriding the data uploaded by the previous call).
Changing the VBO code to this:

bool Model::BuildVBO()
{
GLsizei VBOsize = (VertexCount*3 + NormalCount*3 + TexCoordCount*2) * sizeof(float);
glGenBuffersARB( 1, &VertexID );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, VertexID );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VBOsize, NULL, GL_STATIC_DRAW_ARB );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, VertexCount*3*sizeof(float), VertexData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, NormalCount*3*sizeof(float), NormalData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, TexCoordCount*2*sizeof(float), TexCoordData );

return true;
}

displays a totally scrambled model.

Changing the VBO code to this:

bool Model::BuildVBO()
{
GLsizei VBOsize = (VertexCount*3 + NormalCount*3 + TexCoordCount*2) * sizeof(float);
glGenBuffersARB( 1, &VertexID );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, VertexID );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VBOsize, NULL, GL_STATIC_DRAW_ARB );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, VertexCount*3*sizeof(float), VertexData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, NormalCount*3*sizeof(float), NormalData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, TexCoordCount*2*sizeof(float), TexCoordData );

return true;
}

displays a totally scrambled model.



I think you need to change the code above to:

bool Model::BuildVBO()
{
GLsizei VBOsize = (VertexCount*3 + NormalCount*3 + TexCoordCount*2) * sizeof(float);
glGenBuffersARB( 1, &VertexID );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, VertexID );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VBOsize, NULL, GL_STATIC_DRAW_ARB );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, VertexCount*3*sizeof(float), VertexData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*3*sizeof(float), NormalCount*3*sizeof(float), NormalData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*3*sizeof(float) + NormalCount*3*sizeof(float), TexCoordCount*2*sizeof(float), TexCoordData );

return true;
}



and in your drawing code:
glVertexPointer( 3, GL_FLOAT, 0, (char *) NULL );
glNormalPointer( GL_FLOAT, 0, (GLvoid *)(VertexCount*3*sizeof(float)) );
glTexCoordPointer( 2, GL_FLOAT, 0, (GLvoid *)(VertexCount*3*sizeof(float) + NormalCount*3*sizeof(float)) );

I think you need to change the code above to:

bool Model::BuildVBO()
{
GLsizei VBOsize = (VertexCount*3 + NormalCount*3 + TexCoordCount*2) * sizeof(float);
glGenBuffersARB( 1, &VertexID );
glBindBufferARB( GL_ARRAY_BUFFER_ARB, VertexID );
glBufferDataARB( GL_ARRAY_BUFFER_ARB, VBOsize, NULL, GL_STATIC_DRAW_ARB );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, NULL, VertexCount*3*sizeof(float), VertexData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*3*sizeof(float), NormalCount*3*sizeof(float), NormalData );
glBufferSubDataARB( GL_ARRAY_BUFFER_ARB, VertexCount*3*sizeof(float) + NormalCount*3*sizeof(float), TexCoordCount*2*sizeof(float), TexCoordData );

return true;
}



This was enough to fix the problem. Thank you very much. I have a much better understanding of how this works now.

This topic is closed to new replies.

Advertisement