DDS loading + VBO problems

Started by
26 comments, last by rvangaal 13 years, 8 months ago
DDS questions
I posted this further down, but realized that many might miss it down there, pasted it here instead:

This is an edit of the original post. Instead of creating a totally new thread.

So, I'm "finished" with the VBO problems I had (the code I'm using now is pasted down below).
I'm now looking at loading DDS textures instead of the TGA's I'm using now.
However, I'm stumped at how complicated it looks when I'm checking out sample code and the MSDN guide (which is focused on Direct3D...).
I'm wondering if maybe anyone here could discuss the process with me? I've used Nehe's now deprecated TGA tutorial before and I think I've understood most of that.

I guess I'm asking for a lot, but it would be very helpful if anyone would like to help me out with this.

I never thought there would be so much to learn when I started this project :)





Original post VBO-stuff
Hi,
I'm working on getting my OBJ-loader (and later on COLLADA-loader) working with VBO's.
This is my first turn trying to understand them. I'm reading the specs and trying out stuff.

At the moment I'm allmost getting the results I want. I just can't figure out why my sphere does this:
VBO error 1

The model loads fine with my old "non-VBO" loader and code for displaying the sphere. So something's gone iffy with the VBO's.
If anyone could shed some light on this, I'd be a very happy guy :)

I just can't seem to figure it out on my own.

GLuint VBO_verts = 0;	GLuint VBO_faces = 0;	glGenBuffers(1, &VBO_verts);	glBindBuffer(GL_ARRAY_BUFFER, VBO_verts);	glBufferData(GL_ARRAY_BUFFER, ((int)(model1.vertices.size()) * 4 * sizeof(float)), &(model1.vertices.at(0)), GL_STATIC_DRAW);	glGenBuffers(1, &VBO_faces);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_faces);	glBufferData(GL_ELEMENT_ARRAY_BUFFER, ((int)(model1.faces_v.size()) * 4 * sizeof(float)), &(model1.faces_v.at(0)), GL_STATIC_DRAW);	glBindBuffer(GL_ARRAY_BUFFER, VBO_verts);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VBO_faces);	glEnableClientState(GL_VERTEX_ARRAY);	glVertexPointer(3, GL_FLOAT, 0, 0);	glDrawElements(GL_TRIANGLES, (model1.faces_v.size()), GL_UNSIGNED_INT, 0);	glDisableClientState(GL_VERTEX_ARRAY);


Thanks in advance,
Marcus Axelsson


EDIT
I've also noticed that when I try to load a model with more than 20000 face references my program crashes. Which I really don't want.
And when I load my VBO-indices ("f" from the obj-file) should I load those face values that reference the same vertex?

f 544/544/544 551/551/551 552/552/552f 544/544/544 552/552/552 545/545/545f 545/545/545 552/552/552 553/553/553f 545/545/545 553/553/553 546/546/546f 546/546/546 553/553/553 554/554/554f 546/546/546 554/554/554 547/547/547


That's a few of my f-references. The numbers before the first slash is a vertex reference. Here you wan see that 544 is referenced twice, 552 twice, 553 four times and so on.
But if I don't reference those numbers, how do I build my globe model later? Vertices must be shared between the faces, right? If not I would get gaps?
Normals are shared because of how they are angled and thus handle light, one vertex in the middle of three polygons would give three normals, either pointing in the same direction or not.
The vertex between the polygons, say "V5" is shared between the polygons. However it's not repeated. There's not three vertices at the same spot.

Have I got this wrong?

[Edited by - tre on July 28, 2010 10:06:19 AM]
Advertisement
What about

f 544/544/544 551/551/551 552/552/552

f 544/544/544 552/552/552 545/545/545

f 545/545/545 552/552/552 553/553/553

f 545/545/545 553/553/553 546/546/546

f 546/546/546 553/553/553 554/554/554

f 546/546/546 554/554/554 547/547/547

I will say that sometimes values per triangle parts can be different like this:
f 546/121/322 313/543/513 524/567/514
the technique that you using is:
f vertex-index/normal-index/texcoord-index
Any vertex,normal,texcoord can be mapped for >1 meshes...

What about " load a model with more than 20000 face references my program crashes"...

I'm sure that you are using a pointer that resizes each 'v','n','t' call.
Try to use array block like:
vec3 *vertices = (vec3*)malloc(sizeof(vec3)*10000);//for example
When it's out of range resize it by the step:
current_size += 10000; //for example
Quote:Original post by FXACE
What about " load a model with more than 20000 face references my program crashes"...

I'm sure that you are using a pointer that resizes each 'v','n','t' call.
Try to use array block like:
vec3 *vertices = (vec3*)malloc(sizeof(vec3)*10000);//for example
When it's out of range resize it by the step:
current_size += 10000; //for example


The way that I'm loading my model is that I'm pushing all the vertices into a vector called "vertices" and all face references (vertex) goes into another vector (faces_v) and the same with the face references to texture coordinates and normals (faces_t, faces_n).
I am not reserving space for any certain amount of vertices or references since I can't know for sure how many references I will need until the model is read. Instead of reading the obj twice I'm using vectors to dynamically store my vertices.

Wrong way?
I got this result before when i was trying to load it. Solution was to decrease triangle index by one during loading:

triangle.index[0] -= 1;triangle.index[1] -= 1;triangle.index[2] -= 1;


And why are you multiplying the faces by 4. You are using triangles, so they should be multiplied by 3.
tre! I'm recommend you this way because I had the same problem. Using that way the problem was solved...
Thank you all for your answers and sorry for not replying to what you've written.

I will take a closer look on my model loader later and keep loading my low poly globe just to get the VBO part working.

I can't seem to wrap my head around it, though.

I want to use a vertex list (array) that's been gathered from a 3D object (COLLADA/OBJ) and then load a reference list (faces).
Now I'm kind of stuck, I can't find any explanation to VBO's that I can understand. Sure, a lot of code, but I can't seem to get a real grip on this concept.
If you guys have any tutorials or plain information, please let me know.

As I've understood it:
1. Create two buffer objects. One for vertices and one for faces.
2. Allocate memory and assign the arrays to them.
3. Draw them with glDrawElements() and use the "faces VBO" for that.

Still can't get it to work correctly.
This is still not working as it should.
I am however starting to get somewhere.

I am using a "custom" obj-file that I wrote up.
v  1.0 1.0 0.0v  -1.0 1.0 0.0v  -1.0 -1.0 0.0v  1.0 -1.0 0.0# 4 verticesf 1 2 3f 3 4 1# 2 faces


So, I'm loading the v (vertices) to myModel.vertices, and the f (faces) to myModel.faces.
Then I do this:
unsigned int vertex_buf = 0;unsigned int index_buf = 0;glGenBuffers(1, &vertex_buf);glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);glBufferData(GL_ARRAY_BUFFER, myModel.vertices.size() * 3 * sizeof(float), &(myModel.vertices.at(0)), GL_STATIC_DRAW);glGenBuffers(1, &index_buf);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buf);glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * sizeof(GLushort), &(myModel.faces_v.at(0)), GL_STATIC_DRAW);glEnableClientState(GL_VERTEX_ARRAY);	glBindBuffer(GL_ARRAY_BUFFER, vertex_buf);	glVertexPointer(3, GL_FLOAT, 0, 0);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buf);	glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);	glBindBuffer(GL_ARRAY_BUFFER, 0);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);glDisableClientState(GL_VERTEX_ARRAY);


I get nothing on screen. If I change the
glDrawElements(GL_TRIANGLES...)
to
GL_POINTS
I get a single point that is rotating the way the square should've.

I'm not understanding what I'm doing wrong here. Anyone care to correct me?
As Kasya already mentioned, you should ensure to decrease the indicies by one when loading. In c++ and opengl the first index is always 0 whereas in .obj files the indicies start with 1. When you don't decrease the index you will most probably render an undefined last triangle and a missing first triangle (as you can see in your circle example).

Quote:
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);

Here's an other bug, you are trying to render 3 triangles, but you load only two.

Quote:
v 1.0 1.0 0.0
v -1.0 1.0 0.0
v -1.0 -1.0 0.0
v 1.0 -1.0 0.0
# 4 vertices
f 1 2 3
f 3 4 1
# 2 faces

Ensure that you have the correct order of indices (clock or counter-clock wise), else the triangles will be culled if you didn't have turned off culling.
the 2nd argument of glDrawElements is number of indices not number of triangles. You should put there:

glDrawElements(GL_TRIANGLES, 6 /* num_of_tris * 3 */, GL_UNSIGNED_INT, 0);
Thank you so much for your answers. Now I'm beginning to understand the calls.
I've had a huge problem understanding what the different parts of the (for example) glDrawElements, do. And I couldn't seem to understand the description of the functions either.
Now I'm beginning to.

Kasya, I owe you an apology. I didn't understand your post at first and instead of asking I somehow managed to forget it.

Quote:Ensure that you have the correct order of indices (clock or counter-clock wise), else the triangles will be culled if you didn't have turned off culling.

Thats one thing I've allready done, at least :)

And I've actually read posts before that explained the 1-0 OBJ index stuff, but I didn't even think that far. Heh.

I'm at work right now but I'll try these suggestions as soon as I get home. Thank you again. I love these boards, I actually get answers here :)

This topic is closed to new replies.

Advertisement