thecplusplusguy

obj loader example

Sep 22nd, 2011
892
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.44 KB | None | 0 0
  1. //http://www.youtube.com/user/thecplusplusguy
  2. #include <stdlib.h>
  3. #include <GL/glut.h>    //I changed to capital GL, you may have to change it back
  4. #include <GL/gl.h>
  5. #include <vector>
  6. #include <string>
  7. #include<algorithm>
  8. #include <fstream>
  9. #include<cstdio>
  10. #include <iostream>
  11.  
  12. //for vertexes and vectors
  13. struct coordinate{
  14.     float x,y,z;
  15.     coordinate(float a,float b,float c) : x(a),y(b),z(c) {};
  16. };
  17.  
  18. //for faces, it can contain triangles and quads as well, the four variable contain which is that
  19. struct face{
  20.     int facenum;
  21.     bool four;
  22.     int faces[4];
  23.     face(int facen,int f1,int f2,int f3) : facenum(facen){  //constructor for triangle
  24.         faces[0]=f1;
  25.         faces[1]=f2;
  26.         faces[2]=f3;
  27.         four=false;
  28.     }
  29.     face(int facen,int f1,int f2,int f3,int f4) : facenum(facen){ //overloaded constructor for quad
  30.         faces[0]=f1;
  31.         faces[1]=f2;
  32.         faces[2]=f3;
  33.         faces[3]=f4;
  34.         four=true;
  35.     }
  36. };
  37.  
  38. float angle=0.0;    //we rotate or object with angle degrees
  39.  
  40. int loadObject(const char* filename)
  41. {
  42.     std::vector<std::string*> coord;    //read every single line of the obj file as a string
  43.     std::vector<coordinate*> vertex;
  44.     std::vector<face*> faces;
  45.     std::vector<coordinate*> normals;   //normal vectors for every face
  46.     std::ifstream in(filename); //open the .obj file
  47.     if(!in.is_open())   //if not opened, exit with -1
  48.     {
  49.         std::cout << "Nor oepened" << std::endl;
  50.         return -1;
  51.     }
  52.     char buf[256];
  53.     //read in every line to coord
  54.     while(!in.eof())
  55.     {
  56.         in.getline(buf,256);
  57.         coord.push_back(new std::string(buf));
  58.     }
  59.     //go through all of the elements of coord, and decide what kind of element is that
  60.     for(int i=0;i<coord.size();i++)
  61.     {
  62.         if((*coord[i])[0]=='#') //if it is a comment (the first character is #)
  63.             continue;   //we don't care about that
  64.         else if((*coord[i])[0]=='v' && (*coord[i])[1]==' ') //if vector
  65.         {
  66.             float tmpx,tmpy,tmpz;
  67.             sscanf(coord[i]->c_str(),"v %f %f %f",&tmpx,&tmpy,&tmpz);   //read in the 3 float coordinate to tmpx,tmpy,tmpz
  68.             vertex.push_back(new coordinate(tmpx,tmpy,tmpz));   //and then add it to the end of our vertex list
  69.         }else if((*coord[i])[0]=='v' && (*coord[i])[1]=='n')    //if normal vector
  70.         {
  71.             float tmpx,tmpy,tmpz;   //do the same thing
  72.             sscanf(coord[i]->c_str(),"vn %f %f %f",&tmpx,&tmpy,&tmpz);
  73.             normals.push_back(new coordinate(tmpx,tmpy,tmpz)); 
  74.         }else if((*coord[i])[0]=='f')   //if face
  75.         {
  76.             int a,b,c,d,e;
  77.             if(count(coord[i]->begin(),coord[i]->end(),' ')==3) //if it is a triangle (it has 3 space in it)
  78.             {
  79.           sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b);
  80.                 faces.push_back(new face(b,a,c,d)); //read in, and add to the end of the face list
  81.             }else{
  82.                 sscanf(coord[i]->c_str(),"f %d//%d %d//%d %d//%d %d//%d",&a,&b,&c,&b,&d,&b,&e,&b);
  83.                 faces.push_back(new face(b,a,c,d,e));   //do the same, except we call another constructor, and we use different pattern
  84.             }
  85.         }
  86.     }
  87.     //draw
  88.     int num;    //the id for the list
  89.     num=glGenLists(1);  //generate a uniqe
  90.     glNewList(num,GL_COMPILE);  //and create it
  91.     for(int i=0;i<faces.size();i++)
  92.     {
  93.         if(faces[i]->four)  //if it's a quad draw a quad
  94.         {
  95.             glBegin(GL_QUADS);
  96.                 //basically all I do here, is use the facenum (so the number of the face) as an index for the normal, so the 1st normal owe to the first face
  97.                 //I subtract 1 because the index start from 0 in C++
  98.                 glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
  99.                 //draw the faces
  100.                 glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
  101.                 glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
  102.                 glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
  103.                 glVertex3f(vertex[faces[i]->faces[3]-1]->x,vertex[faces[i]->faces[3]-1]->y,vertex[faces[i]->faces[3]-1]->z);
  104.             glEnd();
  105.         }else{
  106.             glBegin(GL_TRIANGLES);
  107.                 glNormal3f(normals[faces[i]->facenum-1]->x,normals[faces[i]->facenum-1]->y,normals[faces[i]->facenum-1]->z);
  108.                 glVertex3f(vertex[faces[i]->faces[0]-1]->x,vertex[faces[i]->faces[0]-1]->y,vertex[faces[i]->faces[0]-1]->z);
  109.                 glVertex3f(vertex[faces[i]->faces[1]-1]->x,vertex[faces[i]->faces[1]-1]->y,vertex[faces[i]->faces[1]-1]->z);
  110.                 glVertex3f(vertex[faces[i]->faces[2]-1]->x,vertex[faces[i]->faces[2]-1]->y,vertex[faces[i]->faces[2]-1]->z);
  111.             glEnd();
  112.         }
  113.     }
  114.     glEndList();
  115.     //delete everything to avoid memory leaks
  116.     for(int i=0;i<coord.size();i++)
  117.         delete coord[i];
  118.     for(int i=0;i<faces.size();i++)
  119.         delete faces[i];
  120.     for(int i=0;i<normals.size();i++)
  121.         delete normals[i];
  122.     for(int i=0;i<vertex.size();i++)
  123.         delete vertex[i];
  124.     return num; //return with the id
  125. }
  126.  
  127. int cube;
  128. void init()
  129. {
  130.     glClearColor(0.0,0.0,0.0,1.0);
  131.     glMatrixMode(GL_PROJECTION);
  132.     glLoadIdentity();
  133.     gluPerspective(45,640.0/480.0,1.0,500.0);
  134.     glMatrixMode(GL_MODELVIEW);
  135.     glEnable(GL_DEPTH_TEST);
  136.     cube=loadObject("test.obj");    //load the test.obj file
  137.     glEnable(GL_LIGHTING);  //we enable lighting, to make the 3D object to 3D
  138.     glEnable(GL_LIGHT0);
  139.     float col[]={1.0,1.0,1.0,1.0};  //light color is white
  140.     glLightfv(GL_LIGHT0,GL_DIFFUSE,col);
  141. }
  142.  
  143. void display()
  144. {
  145.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  146.     glLoadIdentity();
  147.     float pos[]={-1.0,1.0,-2.0,1.0};    //set the position
  148.     glLightfv(GL_LIGHT0,GL_POSITION,pos);
  149.     glTranslatef(0.0,0.0,-5.0);
  150.     glRotatef(angle,1.0,1.0,1.0);
  151.     glCallList(cube);   //draw the 3D mesh
  152.     angle+=1;           //i added this 3 line, so the cube is rotating
  153.     if(angle>360)
  154.         angle-=360;
  155. }
  156.  
  157. void update(int value)
  158. {
  159.     glutPostRedisplay();    //display the screen again
  160.     glutTimerFunc(25,update,0); //in every 25 ms
  161.     glutSwapBuffers();  //and swap the buffers (double buffering)
  162. }
  163.  
  164. int main(int argc, char** argv){
  165.  
  166.  
  167.     glutInit(&argc,argv);                                           //these inits should be before init() function, else I get a segmentation fault
  168.     glutInitWindowSize(640,480);
  169.     glutInitWindowPosition(0,0);
  170.     glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);   //you need to use the depth buffer too, and I use double buffer, to avoid flickering
  171.     glutCreateWindow("hello!");
  172.         init();
  173.  
  174.  
  175.     glutDisplayFunc(display);
  176.     glutTimerFunc(25,update,0); //we need to update the screen somehow, so it will be an animation
  177.    //glutReshapeFunc(reshape);
  178.         //glMatrixMode(GL_MODELVIEW);
  179.       //glEnable(GL_DEPTH_TEST);
  180.    // glMatrixMode(GL_PROJECTION);
  181.    // glLoadIdentity();    
  182.     //  display();
  183.     glutMainLoop();
  184.  
  185. }
Advertisement
Add Comment
Please, Sign In to add comment