Sign in to follow this  

Need help with VBO

This topic is 3484 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am experiencing some weird problems with my VBO generation. Here is what I do:
// Declare usable variables
int num_faces = my_mesh->NumFaces;
int num_verts_per_face = 3;
int num_elements_per_vert = 3;

// Generate buffer
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, num_faces * num_verts_per_face * num_elements_per_vert * sizeof(GLfloat), NULL, GL_STATIC_DRAW);

// Generate sub data for vertices
glBufferSubData(GL_ARRAY_BUFFER, 0, num_faces * num_verts_per_face * sizeof(GLfloat), my_mesh->Vertices);



I am reading the number of faces from my mesh (~2000) and making the buffer large enough to hold all faces x 3 vertices per face x 3 values per vertex (X, Y and Z). Now, here comes my problem. When I try to draw my mesh using the VBO, I get a crash.
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)NULL);
glEnableClientState(GL_VERTEX_ARRAY);

glDrawArrays(GL_TRIANGLES, 0, my_mesh->NumFaces * 3);

glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);



If I draw a smaller number of elements (i.e. decrease the third parameter for glDrawArrays) it works, but the mesh is not complete since I don't draw all elements. I've followed quite a lot of tutorials on this, but none of them work. I also did try to skip the glBufferSubData() part, but that did not yield any usable result either. Hope someone has some better insight into this. Thanks!

Share this post


Link to post
Share on other sites
shouldn't this

glBufferSubData(GL_ARRAY_BUFFER, 0, num_faces * num_verts_per_face * sizeof(GLfloat), my_mesh->Vertices);

be?

glBufferSubData(GL_ARRAY_BUFFER, 0, num_faces * num_verts_per_face * num_elements_per_vert * sizeof(GLfloat), my_mesh->Vertices);

Also, I recommend you use indexed arrays and draw with glDrawElements.

Share this post


Link to post
Share on other sites
Indexed arrays is my next step, but it turns even more complex that way. I load my meshes from the ASE format, so the data is not conformed to what VBO needs. I'll try your suggestion, thank you.

Share this post


Link to post
Share on other sites
Quote:
Original post by bzroom
shouldn't this

glBufferSubData(GL_ARRAY_BUFFER, 0, num_faces * num_verts_per_face * sizeof(GLfloat), my_mesh->Vertices);

be?

glBufferSubData(GL_ARRAY_BUFFER, 0, num_faces * num_verts_per_face * num_elements_per_vert * sizeof(GLfloat), my_mesh->Vertices);

Also, I recommend you use indexed arrays and draw with glDrawElements.


Hrmm, the change you suggested did not work, still crashes (access violation in the second frame of drawing the mesh when calling glDrawArrays()). I feel VBO's are far too complex, I hope they fix this in OpenGL 3.0 (or better yet, have their own mesh format, but that's just a wish) :)

I'll keep at this, it should not be impossible to solve.

Share this post


Link to post
Share on other sites
Quote:
Original post by Eldritch
Quote:
Original post by bzroom
...
glBufferSubData(GL_ARRAY_BUFFER, 0, num_faces * num_verts_per_face * num_elements_per_vert * sizeof(GLfloat), my_mesh->Vertices);



Hrmm, the change you suggested did not work, still crashes (access violation in the second frame of drawing the mesh when calling glDrawArrays()).

Are you sure that you are allocating and initializing enough memory? Having only the vertices for one frame rather than all frames would fit the symptoms (first frame ok, second frame from unallocated memory).
Quote:
I feel VBO's are far too complex, I hope they fix this in OpenGL 3.0 (or better yet, have their own mesh format, but that's just a wish) :)

Not bloody likely. Vertex buffers and vertex programs allow for any conceivable mesh format, there is no reason to add complication in order to reduce flexibility.
If you resent using low-level OpenGL programming interfaces, maybe you don't need them and you should use higher level libraries such as scene graph frameworks and game engines.

Share this post


Link to post
Share on other sites
VBO's are like 10 lines of code to work with. Not that complex. There are no problems to fix. What reference are you using for your code?

The only things I can thing of:
both bufferdata calls should be:
num_faces * num_verts_per_face * num_elements_per_vert * sizeof(GLfloat)

It's crashing because of a pointer obviously. You either don't have the correct data in saying how many faces you have. Assuming all data is a triangle. Are you loading your own mesh in or using a library?

My suggestion would be to start with a smaller model, like 1 triangle. Get that to work, then maybe a cube. In your verison ur saying that one way it doesnt draw all the faces. So my suggestion is to do that with a smaller model that you yourself can debug visually.

Share this post


Link to post
Share on other sites
Quote:
Original post by dpadam450
another note. Your not providing normals, so maybe they arent all drawing due to back facing.

glDisable(GL_CULLFACE);



That wouldn't cause a crash though.

What exactly is my_mesh->Vertices? does it point to the right thing?

Share this post


Link to post
Share on other sites
Quote:
Are you sure that you are allocating and initializing enough memory? Having only the vertices for one frame rather than all frames would fit the symptoms (first frame ok, second frame from unallocated memory).


What exactly do you mean by having the vertices for only one frame? I am sure I am allocating enough memory according to all the tutorials and the book I have read, though all of them have a hardcoded array of vertex positions, normals and tex coords instead of a mesh, but that should not be any different.

Quote:
That wouldn't cause a crash though.

What exactly is my_mesh->Vertices? does it point to the right thing?


It points to the vertices of the mesh, which are stored as (GLfloat*). As soon as I have transferred them to the vertex buffer, I free that memory (in accordance to how most of the tutorials and the article in my book does it).

Quote:
It's crashing because of a pointer obviously. You either don't have the correct data in saying how many faces you have. Assuming all data is a triangle. Are you loading your own mesh in or using a library?


I am using my own code for loading ASE models. All faces are triangles.

In glDrawArrays(), is it really correct to pass my_mesh->NumFaces * 3 as the third param? Just want to make sure that is correct, since we're speaking about pointers and stuff. If I reduce that param to my_mesh->NumFaces, it works, but it does not draw the whole mesh.

Drawing one single triangle was successful using this code. I simply passed 1 face and 3 vertices for it...

Share this post


Link to post
Share on other sites
I've always had problems with glDrawArrays() when using an array of just straight up floats. Try making a structure that holds the 3 floats needed for each vertex and make an array of those structures and fill in the corresponding values from your raw float array.

When you get to allocating the size of the buffer just use the total number of vertices x sizeof(myVertexStructurethingy).

Now when you call glDrawArrays(), the third parameter should correspond to the number of elements in that array of vertex structures.

Share this post


Link to post
Share on other sites
I'm pretty sure I had this problem before, but like I said, if you use a smaller object (like a square grid), it will be easier to debug. You can increase the one paramter by 1 each time and see where it crashes.

It still could very well be that:

Your vertex data isn't all there.
Your data is saying there are more vertices than there are.

Share this post


Link to post
Share on other sites
I highly suggest you switch to glDrawElements because it allows you to specify your stride width. Then I could answer your question about whether ->myverts is sufficient for the pointer.

If you want, take a look at this renderer example here: http://www.gamedev.net/community/forums/topic.asp?topic_id=495126

In the function PushChunk (Renderer.cpp) I use draw elements. You'll need it in the future, might as well upgrade now. You'll likely fix your problem as you go back through everything.

This is how you'd set up the pointers for using a VBO.

char vertexOffset = (0 + offsetof(Vertex, xyz));
char TUVOffset = (0 + offsetof(Vertex, tuv));
char normslOffset = (0 + offsetof(Vertex, normal));
char colorOffset = (0 + offsetof(Vertex, color));


glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (char*)vertexOffset);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (char*)TUVOffset);
glNormalPointer(GL_FLOAT, sizeof(Vertex), (char*)normslOffset);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), (char*)colorOffset);

Share this post


Link to post
Share on other sites

This topic is 3484 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this