Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h> /* fopen() */
- #include <string.h> /* strtok() */
- #include <stdlib.h> /* malloc(), free() */
- #include <GL/glut.h>
- struct vector { float x; float y; float z; } *v, *vn;
- struct vlist { struct vector v; struct vlist *n; } *v_l, *vn_l;
- struct flist { int v; int vn; struct flist *n; } *f_l;
- int v_n, vn_n, f_n;
- float diffuse[] = {1., 1., 1., 1.};
- float reflect[] = {.3, .3, .3, 1.};
- void error(char *err, int status)
- {
- fprintf(stderr, "%s\n", err);
- exit(status);
- }
- /** Functions to parse the .obj file **/
- struct vlist **appendv(struct vlist **l, struct vector v)
- {
- *l = malloc(sizeof(struct vlist));
- (*l)->v = v;
- (*l)->n = NULL;
- return &((*l)->n);
- }
- struct flist **appendf(struct flist **l, int v, int vn)
- {
- *l = malloc(sizeof(struct flist));
- (*l)->v = v;
- (*l)->vn = vn;
- (*l)->n = NULL;
- return &((*l)->n);
- }
- void get2ints(char *s, int *a, int *b)
- {
- sscanf(s, "%d", a);
- while(*s != '/') s++; /* first '/' */
- s++;
- while(*s != '/') s++; /* second '/' */
- s++;
- sscanf(s, "%d", b);
- }
- void readobj(FILE *obj)
- {
- char buffer[256], *tok;
- int v_, vn_, i;
- struct vector vec;
- struct vlist **lv = &v_l, **lvn = &vn_l;
- struct flist **lf = &f_l;
- v_n = 0; vn_n = 0; f_n = 0;
- while (fgets(buffer, 255, obj))
- {
- tok = strtok(buffer, " \t");
- if(!strcmp(tok, "v"))
- {
- tok = strtok(NULL, " \t");
- sscanf(tok, "%f", &(vec.x));
- tok = strtok(NULL, " \t");
- sscanf(tok, "%f", &(vec.y));
- tok = strtok(NULL, " \t");
- sscanf(tok, "%f", &(vec.z));
- lv = appendv(lv, vec);
- v_n++;
- }
- else if(!strcmp(tok, "vn"))
- {
- tok = strtok(NULL, " \t");
- sscanf(tok, "%f", &(vec.x));
- tok = strtok(NULL, " \t");
- sscanf(tok, "%f", &(vec.y));
- tok = strtok(NULL, " \t");
- sscanf(tok, "%f", &(vec.z));
- lvn = appendv(lvn, vec);
- vn_n++;
- }
- else if(!strcmp(tok, "f"))
- {
- for(i=0; i<4; i++)
- {
- tok = strtok(NULL, " \t");
- if(tok) get2ints(tok, &v_, &vn_); /* else: use previous */
- lf = appendf(lf, v_ - 1, vn_ - 1);
- }
- f_n += 4;
- }
- }
- }
- struct vector *listtoarray(struct vlist *l, int n)
- {
- struct vlist *ll;
- int i;
- struct vector *vec = malloc(n * sizeof(struct vector));
- for(i=0; i<n; i++)
- {
- ll = l;
- vec[i] = l->v;
- l = l->n;
- free(ll);
- }
- return vec;
- }
- /** Functions to render it **/
- void init_gl(char *name)
- {
- int c = 0;
- float sun[] = {-1., -.5, 3., 0.}; /* x,y,z,s */
- float sun_color[] = {1., 1., .9, 1.}; /* R,G,B,a */
- glutInit(&c, NULL);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
- glutInitWindowPosition(100,50);
- glutInitWindowSize(800,600);
- glutCreateWindow(name);
- gluLookAt( 2., -5., 3., /* camera */
- 0., 0., 0., /* center */
- 0., 0., 1.); /* up dir */
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST); /* Z-Buffer on */
- glClearDepth(1.0);
- glEnable(GL_LIGHTING);
- glLightfv(GL_LIGHT0, GL_POSITION, sun);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_color);
- glEnable(GL_LIGHT0);
- }
- void redraw(void)
- {
- struct flist *lf = f_l;
- struct vector vec_v, vec_vn;
- glClearColor(0., 0., 0., 0.);
- glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(40.0, 1.333, 1.0, 100.0);
- glMatrixMode(GL_MODELVIEW);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, diffuse);
- glMaterialfv(GL_FRONT, GL_SPECULAR, reflect);
- glBegin(GL_QUADS);
- while(lf)
- {
- vec_v = v [lf->v ];
- vec_vn = vn[lf->vn];
- glNormal3f(vec_vn.x, vec_vn.y, vec_vn.z);
- glVertex3f(vec_v.x, vec_v.y, vec_v.z);
- lf = lf->n;
- }
- glEnd();
- /**/fprintf(stderr, "List rendered\n");
- glutSwapBuffers();
- glFlush();
- }
- /** Main function **/
- int main(int argc, char** argv)
- {
- FILE *obj;
- if(argc < 2) error("Usage: ./obj2ogl file.obj", 1);
- if(!( obj = fopen(argv[1], "r") )) error("Unable to open file", 1);
- obj = fopen(argv[1], "r");
- readobj(obj);
- /**/fprintf(stderr, "Parsed successfully\n");
- v = listtoarray(v_l, v_n);
- vn = listtoarray(vn_l, vn_n);
- /**/fprintf(stderr, "Converted successfully\n");
- init_gl(argv[1]);
- /**/fprintf(stderr, "OpenGL ready\n");
- glutDisplayFunc(redraw);
- glutMainLoop();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement