PDA

View Full Version : OBJ file loader



08-05-2000, 12:18 PM
I'm would like to load a .obj file into my C++ application and then draw it with openGL. Does anybody have any good source, tutorial, or any other resource for this?
Thanks in advance,
John

Gunfighter
08-05-2000, 01:48 PM
Here are parts of the code from the program I am using to learn OpenGL...

void readmodel(char* filename) {
FILE* modelo;
int i;
char nvface;
modelo=fopen(filename,"r");
fscanf(modelo,"3DG1\n"); //scans the useless 3DG1 on top.
fscanf(modelo,"%d",&nvertices); //scans the number of vertices
for (i=0;i<nvertices;i++) {
fscanf (modelo,"%f %f %f",&vertices[i][0],&vertices[i][1],&vertices[i][2]);
} //scans all vertices
nfaces=0;
fscanf(modelo,"%d",&faces[nfaces][0]);
//As I was having problem with filereading routines, I added a flag 0 at the last line of my obj. Probably you can remove that by using something like fscanf()!=EOF or !feof(modelo)
while (faces[nfaces][0]!=0) {
if (faces[nfaces][0]==3) { //face is triangular
fscanf(modelo,"%d %d %d %x",&faces[nfaces][1],&faces[nfaces][2],&faces[nfaces][3],&faces[nfaces][4]);
} else { //face is quadrilateral
fscanf(modelo,"%d %d %d %d %x",&faces[nfaces][1],&faces[nfaces][2],&faces[nfaces][3],&faces[nfaces][4],&faces[nfaces][5]);
}
nfaces++;
fscanf(modelo,"%d",&faces[nfaces][0]);
}
fclose(modelo);
}

void drawmodel (void)
{
int i,j;
for (i=0;i<nfaces;i++) {
if (faces[i][0]==3) { //triangular
glBegin (GL_TRIANGLES);
for (j=0;j<3;j++) {
aux1[j]=vertices[faces[i][2]][j]-vertices[faces[i][1]][j];
aux2[j]=vertices[faces[i][3]][j]-vertices[faces[i][1]][j];
}

glNormal3f(aux1[1]*aux2[2]-aux1[2]*aux2[1],aux1[2]*aux2[0]-aux1[0]*aux2[2],aux1[0]*aux2[1]-aux1[1]*aux2[0]);
for (j=1;j<4;j++) {
glVertex3fv(vertices[faces[i][j]]);
}
glEnd ();
} else { //quadrilateral
glBegin (GL_QUADS);
for (j=0;j<3;j++) {
aux1[j]=vertices[faces[i][2]][j]-vertices[faces[i][1]][j];
aux2[j]=vertices[faces[i][3]][j]-vertices[faces[i][1]][j];
}

glNormal3f(aux1[1]*aux2[2]-aux1[2]*aux2[1],aux1[2]*aux2[0]-aux1[0]*aux2[2],aux1[0]*aux2[1]-aux1[1]*aux2[0]);
for (j=4;j>0;j--) {
glVertex3fv(vertices[faces[i][j]]);
}
glEnd ();
}
}
}

This is a simple code. The color is defined _before_ the call to drawmodel (you can use the faces color, they are in the faces vector, index 4 for triangle faces, and 5 for quad faces, but it is in integer format, you'll have to translate it to three clamped float.)

Also, lighting will not be smooth on this code, as the normals are defined for each face. If your model is somewhat "spherical" you can use glNormal3fv(vertices[faces[i][j]]); before each glVertex call, instead of that code for calculating face normals.

Open GL should be initialized like this :

float lightpos[]={-3.0,3.0,1.0,0};
glEnable (GL_DEPTH_TEST);
glLightfv(GL_LIGHT0, GL_POSITION,lightpos);
glEnable (GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable (GL_NORMALIZE);
glShadeModel (GL_SMOOTH);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); //this may need to be changed to GL_FRONT if you use face normals, as some lighting might appear swapped

If you want an entire code, just get cube.c, from http://nate.scuzzy.net, as the rest of my code is "stolen" from that tutorial.

Add the readmodel function, change drawCube() to drawmodel(), and put the code above in the glInit() function. Also change the eye[] vector to some distance that makes it beautier in your demo.

I just didn't want to paste the entire code, as I don't feel right to post parts of the cube.c demo as my own...

Any doubt, just post a reply http://www.opengl.org/discussion_boards/ubb/smile.gif

Gunfighter

Rob The Bloke
08-06-2000, 04:58 AM
Mail Me and I'll send you my *.obj loader code.