Anyone here using VBO's with .3ds files?

Started by
21 comments, last by MARS_999 18 years ago
MARS_999,
The simplest and easiest way is just dumping all vertices into vertex array as you mentioned and draw the triangles with glDrawArrays(). Let's say if a model has 10 triangles, then the total number of vertices will be 30 (some of them might be duplicated here) and the size of vertex coords array will be 90 because each vertex has x, y and z components:
GLfloat *vertices = new GLfloat[numTris * 3 * 3];

And draw the triangles with glDrawArrays(). It is identical on both VA and VBO mode:
glDrawArrays(GL_TRIANGLES, 0, numTris*3);

However, there may be many duplicated shared vertices in the above method. You may filter out the duplicated vertices and create an index array to access the associated vertex data with glDrawElements() or glDrawRangeElements(). By doing this way, the size of vertex array gets smaller, which means faster transferring data to OpenGL.
Advertisement
ok, thanks guys for the info. I will try to get to it this weekend. If not next week sometime. I will let you know if I get it working or not.
Ok, now I got VA running my .3ds files, but one question lets say I have 10 different model types and display all 10 but each type has 50each? Now can I use the same model object for the other 49 units? If so I am thinking I need to keep each unit with its own xyz data and other info like hitpoints ect... So if I know ahead of time that each model type is going to use the same texture for all 10 models types should I make the texture variable in the class static? How about the mesh data static also, so I am not wasting memory... Thanks Oh BTW would moving to VBO over VA give me much faster performance or would it be worth the time?
Quote:Original post by MARS_999
Ok, now I got VA running my .3ds files, but one question lets say I have 10 different model types and display all 10 but each type has 50each? Now can I use the same model object for the other 49 units? If so I am thinking I need to keep each unit with its own xyz data and other info like hitpoints ect...

Create one array for the entire model, set the pointers once (this is important because it's an expensive operation when using vertex buffers) and then call DrawElements (or DrawArrays or whatever method of dereferencing) as many times as required ...

Quote:Thanks Oh BTW would moving to VBO over VA give me much faster performance or would it be worth the time?

It'll typically take 10-15 minutes of work, and the performance increases can be upto 50% (that's what it was for me), so I say yes you should do it! [wink]
Quote:Original post by deavik
Quote:Original post by MARS_999
Ok, now I got VA running my .3ds files, but one question lets say I have 10 different model types and display all 10 but each type has 50each? Now can I use the same model object for the other 49 units? If so I am thinking I need to keep each unit with its own xyz data and other info like hitpoints ect...

Create one array for the entire model, set the pointers once (this is important because it's an expensive operation when using vertex buffers) and then call DrawElements (or DrawArrays or whatever method of dereferencing) as many times as required ...

Quote:Thanks Oh BTW would moving to VBO over VA give me much faster performance or would it be worth the time?

It'll typically take 10-15 minutes of work, and the performance increases can be upto 50% (that's what it was for me), so I say yes you should do it! [wink]


Ok I am trying to switch over my .3ds files to VBO's and here is what I have

void Model_3DS::SetupVBO(void){	glGenBuffers(2, vbo_buffers);	vboObjectSizeArrayVertices = sizeof(float) * totalVerts * 3;	vboObjectSizeArrayNormals = sizeof(float) * totalVerts * 3;	vboObjectSizeArrayTextCoords = sizeof(float) * totalVerts * 2;	glBindBuffer(GL_ARRAY_BUFFER, vbo_buffers[0]);	glBufferData(GL_ARRAY_BUFFER, vboObjectSizeArrayVertices + vboObjectSizeArrayNormals + vboObjectSizeArrayTextCoords, NULL, GL_STATIC_DRAW);	glBufferSubData(GL_ARRAY_BUFFER, 0, vboObjectSizeArrayVertices, Objects[0].Vertexes);    glBufferSubData(GL_ARRAY_BUFFER, vboObjectSizeArrayVertices, vboObjectSizeArrayNormals, Objects[0].Normals);	glBufferSubData(GL_ARRAY_BUFFER, vboObjectSizeArrayVertices + vboObjectSizeArrayNormals, vboObjectSizeArrayTextCoords, Objects[0].TexCoords);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_buffers[1]);	vboObjectSizeElement = sizeof(unsigned int) * 3;	glBufferData(GL_ELEMENT_ARRAY_BUFFER, vboObjectSizeElement, Objects[0].MatFaces[0].subFaces, GL_STATIC_DRAW);}//now to renderglBindBuffer(GL_ARRAY_BUFFER, vbo_buffers[0]);		glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));		glEnableClientState(GL_VERTEX_ARRAY);		glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(vboObjectSizeArrayVertices));		glEnableClientState(GL_NORMAL_ARRAY);				glActiveTextureARB(GL_TEXTURE0_ARB);		glClientActiveTextureARB(GL_TEXTURE0_ARB);		glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(vboObjectSizeArrayVertices + vboObjectSizeArrayNormals));		glEnableClientState(GL_TEXTURE_COORD_ARRAY);		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_buffers[1]);					glDrawElements(GL_TRIANGLES, Objects.MatFaces[j].numSubFaces, GL_UNSIGNED_INT, BUFFER_OFFSET(Objects.MatFaces[j].numSubFaces * sizeof(unsigned int)));	//shutdown vbos	glActiveTextureARB(GL_TEXTURE0_ARB);	glClientActiveTextureARB(GL_TEXTURE0_ARB);	glDisableClientState(GL_TEXTURE_COORD_ARRAY);	glDisableClientState(GL_NORMAL_ARRAY);	glDisableClientState(GL_VERTEX_ARRAY);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);	glBindBuffer(GL_ARRAY_BUFFER, 0);


and I crash... If I comment out the glDrawElements() I have no crashes... I am thinking I have the math wrong, I am don't think my setup code is wrong, just must be over bounds on some array?
You are most likely outside array bounds on your index array, because when a card deals with VBOs and it accesses outside an array, rather than crashing, you get a bogus vertex (thats my experience with NVIDIA drivers anyways)

cheers
-Dan
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
Quote:Original post by MARS_999
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_buffers[1]);
vboObjectSizeElement = sizeof(unsigned int) * 3;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vboObjectSizeElement, Objects[0].MatFaces[0].subFaces, GL_STATIC_DRAW);

I think you forgot to multiply by the number of triangles [grin].
Well I am not sure what variable I should be taking from the .3ds file format?
Shouldn't I be taking the total number of sub faces? I have a pointer to the subfaces and then a total number of the subfaces. I am taking number of subfaces * sizeof(unsigned int) and it loads and doesn't crash unless I use line mode, but the models are still render all wrong...

void Model_3DS::SetupVBO(void){	glGenBuffers(2, vbo_buffers);	vboObjectSizeArrayVertices = sizeof(float) * totalVerts * 3;	vboObjectSizeArrayNormals = sizeof(float) * totalVerts * 3;	vboObjectSizeArrayTextCoords = sizeof(float) * totalVerts * 2;	glBindBuffer(GL_ARRAY_BUFFER, vbo_buffers[0]);	glBufferData(GL_ARRAY_BUFFER, vboObjectSizeArrayVertices + vboObjectSizeArrayNormals + vboObjectSizeArrayTextCoords,								  NULL, GL_STATIC_DRAW);	glBufferSubData(GL_ARRAY_BUFFER, 0, vboObjectSizeArrayVertices, Objects[0].Vertexes);    glBufferSubData(GL_ARRAY_BUFFER, vboObjectSizeArrayVertices, vboObjectSizeArrayNormals, Objects[0].Normals);	glBufferSubData(GL_ARRAY_BUFFER, vboObjectSizeArrayVertices + vboObjectSizeArrayNormals, vboObjectSizeArrayTextCoords, Objects[0].TexCoords);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_buffers[1]);	for(int z = 0; z < numObjects; z++)	{		for(int x = 0; x < Objects[z].numMatFaces; x++)		{			vboObjectSizeElement += Objects[z].MatFaces[x].numSubFaces;		}	}	vboObjectSizeElement *= sizeof(unsigned int);	glBufferData(GL_ELEMENT_ARRAY_BUFFER, vboObjectSizeElement, Objects[0].MatFaces[0].subFaces, GL_STATIC_DRAW);}


this is what I have now... I can't remember the math to figure out how many indices I need for GL_TRIANGLES and what value I should be using from the .3ds models to determine the index count... Any help would be greatly appreciated.
Quote:Original post by deavik
Quote:Original post by MARS_999
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_buffers[1]);
vboObjectSizeElement = sizeof(unsigned int) * 3;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vboObjectSizeElement, Objects[0].MatFaces[0].subFaces, GL_STATIC_DRAW);

I think you forgot to multiply by the number of triangles [grin].


Yeah I seen that after I posted, but I think the issue is where do I get that info from the .3ds format? Faces, subfaces ect... I am lost on that and what value I should end up with... :(
YES I got it working! :) Thanks all for the help and suggestions! :)

This topic is closed to new replies.

Advertisement