How can I properly render faces from a 3ds file

333 views Asked by At

I have implemented the ability to load 3DS files into an OpenGL program of mine, and run into a slight problem. All of the vertices are placed properly, and the faces are drawn, but the issue is that most(or all) of the vertices seem to retain a connection to one or two vertices, creating a large number of extra edges. Anyone run into this issue before or have a suggestion on how I can fix it?

The following block of code is the loop I use to draw the faces. It loops through one vertex at a time, skipping every fourth value (in theory) as they are unused face modifiers.

glBegin(GL_TRIANGLES);
for(int x = 1; x < 4*numberOfTriangles+1; x++)
{
    //Face bit modifiers not needed, skip em.
    if(tLoop == 4)
    {
        tLoop = 0;
        continue;
    }
    else
    {
        glVertex3f(Vertices[Triangles[x]*3],Vertices[(Triangles[x]*3)+1],Vertices[(Triangles[x]*3)+2]);
        tLoop++;
    }
}
glEnd();

This next is an image representing the problem I am having. http://img.photobucket.com/albums/v298/Reaperc89/Pistol.jpg

2

There are 2 answers

1
Christian Rau On BEST ANSWER

The fact that glBegin and glEnd are outside the loop is absolutely no problem. Drawing triangles using every vertex one after the other is just the correct way. It will build a triangle form every 3 consecutive vertices, which is what you want.

Your problem was, that you increased tLoop inside the else block, and therefore actually skipped every fifth index, instead of every fourth. So unrolling prevented it, but it has nothing to do with glBegin/glEnd not working outside of the loop. But like said in the comment, you don't need the tLoop anyway, as you can just use x instead:

glBegin(GL_TRIANGLES);
for(int x = 1; x < 4*numberOfTriangles+1; x++)
    if(x % 4)   //works if x starts at 1, though I don't know why x has to start at 1
        glVertex3f(Vertices[Triangles[x]*3],Vertices[(Triangles[x]*3)+1],Vertices[(Triangles[x]*3)+2]);
glEnd();

or even better unroll the loop:

glBegin(GL_TRIANGLES);
for(int x = 1; x < 4*numberOfTriangles+1; x+=4) {
    glVertex3f(Vertices[Triangles[x]*3],Vertices[(Triangles[x]*3)+1],Vertices[(Triangles[x]*3)+2]);
    glVertex3f(Vertices[Triangles[x+1]*3],Vertices[(Triangles[x+1]*3)+1],Vertices[(Triangles[x+1]*3)+2]);
    glVertex3f(Vertices[Triangles[x+2]*3],Vertices[(Triangles[x+2]*3)+1],Vertices[(Triangles[x+2]*3)+2]);
}
glEnd();

But placing the glBegin/glEnd inside the loop is the silliest thing you can do. In fact if you already use a vertex/index array based representation, it should be quite easy to port your rendering code to vertex arrays, which are much faster than immediate mode, more so when powered by VBOs.

3
Evan On

Figured out my own problem. Notice how the begin and end blocks appear outside of the loop. The program was trying to draw triangles using every vertex in the mesh, one after another. Thus it kinda created one giant mess. I changed to placing three vertices at a time(one face), and I placed the begin/end blocks inside the loop, and changed the loop to increment by 4 each time, allowing me to skip the face data.

Just in case anyone was curious.