Advertisement
Guest User

cousteau

a guest
Jan 10th, 2010
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.26 KB | None | 0 0
  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. }
  206.  
  207.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement