started the level loading routines
[cyberay] / src / mesh.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "mesh.h"
4
5 static char *cleanline(char *s)
6 {
7         char *ptr;
8
9         if((ptr = strchr(s, '#'))) *ptr = 0;
10
11         while(*s && isspace(*s)) s++;
12         ptr = s + strlen(s) - 1;
13         while(ptr >= s && isspace(*s)) *ptr-- = 0;
14
15         return *s ? s : 0;
16 }
17
18 #define APPEND(prefix)  \
19         do { \
20                 if(prefix##count >= prefix##max) { \
21                         int newsz = prefix##max ? prefix##max * 2 : 8; \
22                         void *ptr = realloc(prefix##arr, newsz * sizeof(cgm_vec3)); \
23                         if(!ptr) { \
24                                 fprintf(stderr, "load_mesh: failed to resize array to %d elements\n", newsz); \
25                                 return -1; \
26                         } \
27                         prefix##arr = ptr; \
28                         prefix##max = newsz; \
29                 } \
30         } while(0)
31
32
33 int load_mesh(struct mesh *m, const char *fname)
34 {
35         int num, nline;
36         FILE *fp;
37         cgm_vec3 v;
38         cgm_vec3 *varr, *narr, *tarr;
39         int vcount, ncount, tcount, vmax, nmax, tmax;
40         char linebuf[256], *line;
41
42         varr = narr = tarr = 0;
43         vcount = ncount = tcount = vmax = nmax = tmax = 0;
44
45         if(!(fp = fopen(fname, "rb"))) {
46                 fprintf(stderr, "load_mesh: failed to open: %s\n", fname);
47                 return -1;
48         }
49
50         nline = 0;
51         while(fgets(linebuf, sizeof linebuf, fp)) {
52                 nline++;
53                 if(!(line = cleanline(linebuf))) {
54                         continue;
55                 }
56
57                 switch(line[0]) {
58                 case 'v':
59                         v.y = v.z = 0;
60                         if((num = sscanf(line + 1, "%f %f %f", &v.x, &v.y, &v.z)) < 2) {
61 verr:                   fprintf(stderr, "load_mesh: ignoring malformed attribute at %d: %s\n", nline, line);
62                                 continue;
63                         }
64                         if(isspace(line[1])) {
65                                 APPEND(v);
66                                 varr[vcount++] = v;
67                         } else if(line[1] == 'n') {
68                                 APPEND(n);
69                                 narr[ncount++] = v;
70                         } else if(line[1] == 't') {
71                                 APPEND(t);
72                                 tarr[ncount].x = v.x;
73                                 tarr[ncount++].y = v.y;
74                         } else {
75                                 goto verr;
76                         }
77                         break;
78
79                         /* TODO cont */
80                 }
81
82         }
83
84         fclose(fp);
85         return 0;
86 }
87
88 void draw_mesh(struct mesh *m)
89 {
90         glEnableClientState(GL_VERTEX_ARRAY);
91         glEnableClientState(GL_NORMAL_ARRAY);
92         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
93
94         glVertexPointer(3, GL_FLOAT, sizeof *m->faces, &m->faces->v[0].pos.x);
95         glNormalPointer(GL_FLOAT, sizeof *m->faces, &m->faces->v[0].norm.x);
96         glTexCoordPointer(2, GL_FLOAT, sizeof *m->faces, &m->faces->v[0].tex.x);
97
98         glDrawArrays(GL_TRIANGLES, 0, m->num_faces * 3);
99
100         glDisableClientState(GL_VERTEX_ARRAY);
101         glDisableClientState(GL_NORMAL_ARRAY);
102         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
103 }