Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

cousteau

By: a guest on Jan 10th, 2010  |  syntax: C  |  size: 4.26 KB  |  views: 140  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <stdio.h>  /* fopen() */
  2. #include <string.h>  /* strtok() */
  3. #include <stdlib.h>  /* malloc(), free() */
  4. #include <GL/glut.h>
  5.  
  6. struct vector { float x; float y; float z; } *v, *vn;
  7. struct vlist { struct vector v; struct vlist *n; } *v_l, *vn_l;
  8. struct flist { int v; int vn; struct flist *n; } *f_l;
  9. int v_n, vn_n, f_n;
  10.  
  11. float diffuse[] = {1., 1., 1., 1.};
  12. float reflect[] = {.3, .3, .3, 1.};
  13.  
  14.  
  15. void error(char *err, int status)
  16. {
  17.         fprintf(stderr, "%s\n", err);
  18.         exit(status);
  19. }
  20.  
  21.  
  22. /** Functions to parse the .obj file **/
  23.  
  24. struct vlist **appendv(struct vlist **l, struct vector v)
  25. {
  26.         *l = malloc(sizeof(struct vlist));
  27.         (*l)->v = v;
  28.         (*l)->n = NULL;
  29.         return &((*l)->n);
  30. }
  31. struct flist **appendf(struct flist **l, int v, int vn)
  32. {
  33.         *l = malloc(sizeof(struct flist));
  34.         (*l)->v  = v;
  35.         (*l)->vn = vn;
  36.         (*l)->n  = NULL;
  37.         return &((*l)->n);
  38. }
  39.  
  40.  
  41. void get2ints(char *s, int *a, int *b)
  42. {
  43.         sscanf(s, "%d", a);
  44.         while(*s != '/') s++;  /*  first '/' */
  45.         s++;
  46.         while(*s != '/') s++;  /* second '/' */
  47.         s++;
  48.        
  49.         sscanf(s, "%d", b);
  50. }
  51.  
  52.  
  53. void readobj(FILE *obj)
  54. {
  55.         char buffer[256], *tok;
  56.         int v_, vn_, i;
  57.         struct vector vec;
  58.         struct vlist **lv = &v_l, **lvn = &vn_l;
  59.         struct flist **lf = &f_l;
  60.        
  61.         v_n = 0; vn_n = 0; f_n = 0;
  62.        
  63.         while (fgets(buffer, 255, obj))
  64.         {
  65.                 tok = strtok(buffer, " \t");
  66.                 if(!strcmp(tok, "v"))
  67.                 {
  68.                         tok = strtok(NULL, " \t");
  69.                         sscanf(tok, "%f", &(vec.x));
  70.                         tok = strtok(NULL, " \t");
  71.                         sscanf(tok, "%f", &(vec.y));
  72.                         tok = strtok(NULL, " \t");
  73.                         sscanf(tok, "%f", &(vec.z));
  74.                         lv = appendv(lv, vec);
  75.                         v_n++;
  76.                 }
  77.                 else if(!strcmp(tok, "vn"))
  78.                 {
  79.                         tok = strtok(NULL, " \t");
  80.                         sscanf(tok, "%f", &(vec.x));
  81.                         tok = strtok(NULL, " \t");
  82.                         sscanf(tok, "%f", &(vec.y));
  83.                         tok = strtok(NULL, " \t");
  84.                         sscanf(tok, "%f", &(vec.z));
  85.                         lvn = appendv(lvn, vec);
  86.                         vn_n++;
  87.                 }
  88.                 else if(!strcmp(tok, "f"))
  89.                 {
  90.                         for(i=0; i<4; i++)
  91.                         {
  92.                                 tok = strtok(NULL, " \t");
  93.                                 if(tok) get2ints(tok, &v_, &vn_);  /* else: use previous */
  94.                                 lf = appendf(lf, v_ - 1, vn_ - 1);
  95.                         }
  96.                         f_n += 4;
  97.                 }
  98.         }
  99. }
  100.  
  101.  
  102. struct vector *listtoarray(struct vlist *l, int n)
  103. {
  104.         struct vlist *ll;
  105.         int i;
  106.         struct vector *vec = malloc(n * sizeof(struct vector));
  107.        
  108.        
  109.         for(i=0; i<n; i++)
  110.         {
  111.                 ll = l;
  112.                 vec[i] = l->v;
  113.                 l = l->n;
  114.                 free(ll);
  115.         }
  116.         return vec;
  117. }
  118.  
  119.  
  120. /** Functions to render it **/
  121.  
  122. void init_gl(char *name)
  123. {
  124.         int c = 0;
  125.         float sun[] = {-1., -.5, 3., 0.};  /* x,y,z,s */
  126.         float sun_color[] = {1., 1., .9, 1.};  /* R,G,B,a */
  127.         glutInit(&c, NULL);
  128.        
  129.         glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
  130.         glutInitWindowPosition(100,50);
  131.         glutInitWindowSize(800,600);
  132.         glutCreateWindow(name);
  133.        
  134.         gluLookAt( 2., -5.,  3.,  /* camera */
  135.                    0.,  0.,  0.,  /* center */
  136.                    0.,  0.,  1.); /* up dir */
  137.        
  138.         glDepthFunc(GL_LEQUAL);
  139.         glEnable(GL_DEPTH_TEST);  /* Z-Buffer on */
  140.         glClearDepth(1.0);
  141.        
  142.         glEnable(GL_LIGHTING);
  143.         glLightfv(GL_LIGHT0, GL_POSITION, sun);
  144.         glLightfv(GL_LIGHT0, GL_DIFFUSE,  sun_color);
  145.         glEnable(GL_LIGHT0);
  146. }
  147.  
  148.  
  149. void redraw(void)
  150. {
  151.         struct flist *lf = f_l;
  152.         struct vector vec_v, vec_vn;
  153.        
  154.         glClearColor(0., 0., 0., 0.);
  155.         glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  156.        
  157.         glMatrixMode(GL_PROJECTION);
  158.         glLoadIdentity();
  159.         gluPerspective(40.0, 1.333, 1.0, 100.0);
  160.        
  161.         glMatrixMode(GL_MODELVIEW);
  162.        
  163.         glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, diffuse);
  164.         glMaterialfv(GL_FRONT, GL_SPECULAR,            reflect);
  165.        
  166.         glBegin(GL_QUADS);
  167.         while(lf)
  168.         {
  169.                 vec_v  = v [lf->v ];
  170.                 vec_vn = vn[lf->vn];
  171.                 glNormal3f(vec_vn.x, vec_vn.y, vec_vn.z);
  172.                 glVertex3f(vec_v.x,  vec_v.y,  vec_v.z);
  173.                 lf = lf->n;
  174.         }
  175.         glEnd();
  176.         /**/fprintf(stderr, "List rendered\n");
  177.        
  178.         glutSwapBuffers();
  179.         glFlush();
  180. }
  181.  
  182.  
  183. /** Main function **/
  184.  
  185. int main(int argc, char** argv)
  186. {
  187.         FILE *obj;
  188.        
  189.         if(argc < 2) error("Usage: ./obj2ogl file.obj", 1);
  190.         if(!( obj = fopen(argv[1], "r") )) error("Unable to open file", 1);
  191.         obj = fopen(argv[1], "r");
  192.        
  193.         readobj(obj);
  194.         /**/fprintf(stderr, "Parsed successfully\n");
  195.         v  = listtoarray(v_l,  v_n);
  196.         vn = listtoarray(vn_l, vn_n);
  197.         /**/fprintf(stderr, "Converted successfully\n");
  198.        
  199.         init_gl(argv[1]);
  200.         /**/fprintf(stderr, "OpenGL ready\n");
  201.         glutDisplayFunc(redraw);
  202.         glutMainLoop();
  203.        
  204.         return 0;
  205. }