rev |
line source |
nuclear@16
|
1 #include <stdio.h>
|
nuclear@16
|
2 #include <stdlib.h>
|
nuclear@16
|
3 #include <string.h>
|
nuclear@16
|
4 #include <ctype.h>
|
nuclear@16
|
5 #include <errno.h>
|
nuclear@19
|
6 #include <assert.h>
|
nuclear@16
|
7 #include "scene.h"
|
nuclear@16
|
8 #include "cvec.h"
|
nuclear@17
|
9 #include "palman.h"
|
nuclear@17
|
10
|
nuclear@17
|
11 #ifdef USE_GL
|
nuclear@17
|
12 #include <GL/gl.h>
|
nuclear@17
|
13 #else
|
nuclear@16
|
14 #include "mingl.h"
|
nuclear@17
|
15 #endif
|
nuclear@16
|
16
|
nuclear@16
|
17
|
nuclear@16
|
18 struct face {
|
nuclear@16
|
19 int v[3], n[3], t[3];
|
nuclear@16
|
20 };
|
nuclear@16
|
21
|
nuclear@16
|
22 static int load_materials(struct scene *scn, const char *fname);
|
nuclear@16
|
23 static int parse_face(struct face *face, char *buf);
|
nuclear@16
|
24
|
nuclear@16
|
25
|
nuclear@16
|
26 /* --- scene --- */
|
nuclear@16
|
27 int scn_init(struct scene *scn)
|
nuclear@16
|
28 {
|
nuclear@16
|
29 memset(scn, 0, sizeof *scn);
|
nuclear@16
|
30 return 0;
|
nuclear@16
|
31 }
|
nuclear@16
|
32
|
nuclear@16
|
33 void scn_destroy(struct scene *scn)
|
nuclear@16
|
34 {
|
nuclear@16
|
35 while(scn->matlist) {
|
nuclear@16
|
36 struct material *tmp = scn->matlist;
|
nuclear@16
|
37 scn->matlist = scn->matlist->next;
|
nuclear@16
|
38
|
nuclear@16
|
39 mtl_destroy(tmp);
|
nuclear@16
|
40 free(tmp);
|
nuclear@16
|
41 }
|
nuclear@16
|
42 while(scn->meshlist) {
|
nuclear@16
|
43 struct mesh *tmp = scn->meshlist;
|
nuclear@16
|
44 scn->meshlist = scn->meshlist->next;
|
nuclear@16
|
45
|
nuclear@16
|
46 mesh_destroy(tmp);
|
nuclear@16
|
47 free(tmp);
|
nuclear@16
|
48 }
|
nuclear@16
|
49 }
|
nuclear@16
|
50
|
nuclear@16
|
51
|
nuclear@16
|
52 void scn_add_mesh(struct scene *scn, struct mesh *m)
|
nuclear@16
|
53 {
|
nuclear@16
|
54 printf("adding mesh: %d faces\n", m->nface);
|
nuclear@16
|
55 m->next = scn->meshlist;
|
nuclear@16
|
56 scn->meshlist = m;
|
nuclear@16
|
57 }
|
nuclear@16
|
58
|
nuclear@16
|
59 void scn_add_material(struct scene *scn, struct material *m)
|
nuclear@16
|
60 {
|
nuclear@16
|
61 printf("adding material: %s\n", m->name);
|
nuclear@16
|
62 m->next = scn->matlist;
|
nuclear@16
|
63 scn->matlist = m;
|
nuclear@16
|
64 }
|
nuclear@16
|
65
|
nuclear@16
|
66 struct material *scn_find_material(struct scene *scn, const char *name)
|
nuclear@16
|
67 {
|
nuclear@16
|
68 struct material *mtl = scn->matlist;
|
nuclear@16
|
69
|
nuclear@16
|
70 while(mtl) {
|
nuclear@16
|
71 if(strcmp(mtl->name, name) == 0) {
|
nuclear@16
|
72 break;
|
nuclear@16
|
73 }
|
nuclear@16
|
74 mtl = mtl->next;
|
nuclear@16
|
75 }
|
nuclear@16
|
76 return mtl;
|
nuclear@16
|
77 }
|
nuclear@16
|
78
|
nuclear@16
|
79 #define SEP " \t\n\r"
|
nuclear@16
|
80 int scn_load(struct scene *scn, const char *fname)
|
nuclear@16
|
81 {
|
nuclear@16
|
82 FILE *fp;
|
nuclear@16
|
83 char buf[256];
|
nuclear@16
|
84 struct mesh *m;
|
nuclear@16
|
85 vec3_t *varr, *vnarr;
|
nuclear@16
|
86 vec2_t *vtarr;
|
nuclear@16
|
87
|
nuclear@16
|
88 if(!(fp = fopen(fname, "rb"))) {
|
nuclear@16
|
89 fprintf(stderr, "failed to open scene file: %s: %s\n", fname, strerror(errno));
|
nuclear@16
|
90 return -1;
|
nuclear@16
|
91 }
|
nuclear@16
|
92
|
nuclear@16
|
93 varr = cvec_alloc(0, sizeof *varr);
|
nuclear@16
|
94 vnarr = cvec_alloc(0, sizeof *vnarr);
|
nuclear@16
|
95 vtarr = cvec_alloc(0, sizeof *vtarr);
|
nuclear@16
|
96
|
nuclear@16
|
97 if(!(m = malloc(sizeof *m)) || mesh_init(m) == -1) {
|
nuclear@16
|
98 fprintf(stderr, "meshed up\n");
|
nuclear@16
|
99 fclose(fp);
|
nuclear@16
|
100 return -1;
|
nuclear@16
|
101 }
|
nuclear@16
|
102
|
nuclear@16
|
103 while(fgets(buf, sizeof buf, fp)) {
|
nuclear@16
|
104 char *line = buf;
|
nuclear@16
|
105 char *tok, *rest, *tmp;
|
nuclear@16
|
106
|
nuclear@16
|
107 while(*line && isspace(*line)) {
|
nuclear@16
|
108 line++;
|
nuclear@16
|
109 }
|
nuclear@16
|
110 if(*line == 0 || *line == '#') {
|
nuclear@16
|
111 continue;
|
nuclear@16
|
112 }
|
nuclear@16
|
113
|
nuclear@16
|
114 if(!(tok = strtok(line, SEP))) {
|
nuclear@16
|
115 continue;
|
nuclear@16
|
116 }
|
nuclear@16
|
117 rest = tok + strlen(tok) + 1;
|
nuclear@16
|
118
|
nuclear@16
|
119 if((tmp = strchr(rest, '\r')) || (tmp = strchr(rest, '\n'))) {
|
nuclear@16
|
120 *tmp = 0;
|
nuclear@16
|
121 }
|
nuclear@16
|
122
|
nuclear@16
|
123 if(strcmp(tok, "mtllib") == 0) {
|
nuclear@16
|
124 if(!rest) {
|
nuclear@16
|
125 fprintf(stderr, "invalid mtllib directive\n");
|
nuclear@16
|
126 continue;
|
nuclear@16
|
127 }
|
nuclear@16
|
128 load_materials(scn, rest);
|
nuclear@16
|
129
|
nuclear@16
|
130 } else if(strcmp(tok, "usemtl") == 0) {
|
nuclear@16
|
131 if(rest) {
|
nuclear@16
|
132 m->mtl = scn_find_material(scn, rest);
|
nuclear@16
|
133 }
|
nuclear@16
|
134
|
nuclear@16
|
135 } else if(strcmp(tok, "o") == 0 || strcmp(tok, "g") == 0) {
|
nuclear@16
|
136 if(cvec_size(m->vert) > 0) {
|
nuclear@16
|
137 scn_add_mesh(scn, m);
|
nuclear@16
|
138
|
nuclear@16
|
139 if(!(m = malloc(sizeof *m)) || mesh_init(m) == -1) {
|
nuclear@16
|
140 fprintf(stderr, "meshed up\n");
|
nuclear@16
|
141 fclose(fp);
|
nuclear@16
|
142 return -1;
|
nuclear@16
|
143 }
|
nuclear@16
|
144 }
|
nuclear@16
|
145
|
nuclear@16
|
146 } else if(strcmp(tok, "v") == 0) {
|
nuclear@16
|
147 vec3_t v;
|
nuclear@16
|
148
|
nuclear@16
|
149 if(!rest || sscanf(rest, "%f %f %f\n", &v.x, &v.y, &v.z) != 3) {
|
nuclear@16
|
150 continue;
|
nuclear@16
|
151 }
|
nuclear@16
|
152 varr = cvec_append(varr, &v);
|
nuclear@16
|
153
|
nuclear@16
|
154 } else if(strcmp(tok, "vn") == 0) {
|
nuclear@16
|
155 vec3_t v;
|
nuclear@16
|
156
|
nuclear@16
|
157 if(!rest || sscanf(rest, "%f %f %f\n", &v.x, &v.y, &v.z) != 3) {
|
nuclear@16
|
158 continue;
|
nuclear@16
|
159 }
|
nuclear@16
|
160 vnarr = cvec_append(vnarr, &v);
|
nuclear@16
|
161
|
nuclear@16
|
162 } else if(strcmp(tok, "vt") == 0) {
|
nuclear@19
|
163 vec2_t v;
|
nuclear@16
|
164
|
nuclear@19
|
165 if(!rest || sscanf(rest, "%f %f\n", &v.x, &v.y) != 2) {
|
nuclear@16
|
166 continue;
|
nuclear@16
|
167 }
|
nuclear@19
|
168 v.y = 1.0 - v.y;
|
nuclear@16
|
169 vtarr = cvec_append(vtarr, &v);
|
nuclear@16
|
170
|
nuclear@16
|
171 } else if(strcmp(tok, "f") == 0) {
|
nuclear@16
|
172 int i;
|
nuclear@16
|
173 struct face face;
|
nuclear@16
|
174
|
nuclear@16
|
175 if(!rest || parse_face(&face, rest) == -1) {
|
nuclear@16
|
176 continue;
|
nuclear@16
|
177 }
|
nuclear@16
|
178
|
nuclear@16
|
179 for(i=0; i<3; i++) {
|
nuclear@16
|
180 int vidx = face.v[i];
|
nuclear@16
|
181 int nidx = face.n[i];
|
nuclear@16
|
182 int tidx = face.t[i];
|
nuclear@16
|
183
|
nuclear@16
|
184 mesh_add_vertex(m, varr[vidx]);
|
nuclear@16
|
185 if(nidx >= 0) {
|
nuclear@16
|
186 mesh_add_normal(m, vnarr[nidx]);
|
nuclear@16
|
187 }
|
nuclear@16
|
188 if(tidx >= 0) {
|
nuclear@16
|
189 mesh_add_texcoord(m, vtarr[tidx]);
|
nuclear@16
|
190 }
|
nuclear@16
|
191 m->nface++;
|
nuclear@16
|
192 }
|
nuclear@16
|
193 }
|
nuclear@16
|
194
|
nuclear@16
|
195 }
|
nuclear@16
|
196 fclose(fp);
|
nuclear@16
|
197
|
nuclear@16
|
198 if(cvec_size(m->vert) > 0) {
|
nuclear@16
|
199 scn_add_mesh(scn, m);
|
nuclear@16
|
200 }
|
nuclear@16
|
201
|
nuclear@16
|
202 cvec_free(varr);
|
nuclear@16
|
203 cvec_free(vnarr);
|
nuclear@16
|
204 cvec_free(vtarr);
|
nuclear@16
|
205
|
nuclear@16
|
206 return 0;
|
nuclear@16
|
207 }
|
nuclear@16
|
208
|
nuclear@16
|
209 static int load_materials(struct scene *scn, const char *fname)
|
nuclear@16
|
210 {
|
nuclear@16
|
211 FILE *fp;
|
nuclear@16
|
212 struct material *m = 0;
|
nuclear@16
|
213 char buf[256];
|
nuclear@16
|
214
|
nuclear@16
|
215 if(!(fp = fopen(fname, "r"))) {
|
nuclear@16
|
216 fprintf(stderr, "failed to load material file: %s: %s\n", fname, strerror(errno));
|
nuclear@16
|
217 return -1;
|
nuclear@16
|
218 }
|
nuclear@16
|
219
|
nuclear@16
|
220 while(fgets(buf, sizeof buf, fp)) {
|
nuclear@16
|
221 char *line = buf;
|
nuclear@16
|
222 char *tok, *rest, *tmp;
|
nuclear@16
|
223
|
nuclear@16
|
224 while(*line && isspace(*line)) {
|
nuclear@16
|
225 line++;
|
nuclear@16
|
226 }
|
nuclear@16
|
227 if(*line == 0 || *line == '#') {
|
nuclear@16
|
228 continue;
|
nuclear@16
|
229 }
|
nuclear@16
|
230
|
nuclear@16
|
231 if(!(tok = strtok(line, SEP))) {
|
nuclear@16
|
232 continue;
|
nuclear@16
|
233 }
|
nuclear@16
|
234 rest = tok + strlen(tok) + 1;
|
nuclear@16
|
235
|
nuclear@16
|
236 if((tmp = strchr(rest, '\r')) || (tmp = strchr(rest, '\n'))) {
|
nuclear@16
|
237 *tmp = 0;
|
nuclear@16
|
238 }
|
nuclear@16
|
239
|
nuclear@16
|
240 if(strcmp(tok, "newmtl") == 0) {
|
nuclear@16
|
241 if(m) {
|
nuclear@17
|
242 if(!m->tex) {
|
nuclear@17
|
243 palm_add_color(m->kd[0], m->kd[1], m->kd[2]);
|
nuclear@17
|
244 }
|
nuclear@16
|
245 scn_add_material(scn, m);
|
nuclear@16
|
246 }
|
nuclear@16
|
247 if(!(m = malloc(sizeof *m)) || mtl_init(m) == -1) {
|
nuclear@16
|
248 continue;
|
nuclear@16
|
249 }
|
nuclear@16
|
250 mtl_set_name(m, rest);
|
nuclear@16
|
251
|
nuclear@16
|
252 } else if(strcmp(tok, "Kd") == 0) {
|
nuclear@17
|
253 float r, g, b;
|
nuclear@17
|
254 if(sscanf(rest, "%f %f %f", &r, &g, &b) != 3) {
|
nuclear@16
|
255 continue;
|
nuclear@16
|
256 }
|
nuclear@17
|
257 m->kd[0] = (int)(r * 255.0);
|
nuclear@17
|
258 m->kd[1] = (int)(g * 255.0);
|
nuclear@17
|
259 m->kd[2] = (int)(b * 255.0);
|
nuclear@17
|
260
|
nuclear@16
|
261 } else if(strcmp(tok, "map_Kd") == 0) {
|
nuclear@17
|
262 if(!(m->tex = load_texture(rest))) {
|
nuclear@17
|
263 fprintf(stderr, "failed to load texture: `%s'\n", rest);
|
nuclear@17
|
264 }
|
nuclear@16
|
265 }
|
nuclear@16
|
266 }
|
nuclear@16
|
267
|
nuclear@16
|
268 if(m) {
|
nuclear@17
|
269 if(!m->tex) {
|
nuclear@17
|
270 palm_add_color(m->kd[0], m->kd[1], m->kd[2]);
|
nuclear@17
|
271 }
|
nuclear@16
|
272 scn_add_material(scn, m);
|
nuclear@16
|
273 }
|
nuclear@16
|
274
|
nuclear@16
|
275 fclose(fp);
|
nuclear@16
|
276 return 0;
|
nuclear@16
|
277 }
|
nuclear@16
|
278
|
nuclear@16
|
279 static int parse_face(struct face *face, char *buf)
|
nuclear@16
|
280 {
|
nuclear@16
|
281 int i, found;
|
nuclear@16
|
282 char *tok;
|
nuclear@16
|
283
|
nuclear@16
|
284 for(i=0; i<3; i++) {
|
nuclear@16
|
285 tok = strtok(i > 0 ? 0 : buf, SEP);
|
nuclear@16
|
286 found = sscanf(tok, "%d/%d/%d", &face->v[i], &face->t[i], &face->n[i]);
|
nuclear@16
|
287
|
nuclear@16
|
288 face->v[i]--;
|
nuclear@16
|
289
|
nuclear@16
|
290 if(found > 1) {
|
nuclear@16
|
291 face->t[i]--;
|
nuclear@16
|
292 } else {
|
nuclear@16
|
293 face->t[i] = -1;
|
nuclear@16
|
294 }
|
nuclear@16
|
295 if(found > 2) {
|
nuclear@16
|
296 face->n[i]--;
|
nuclear@16
|
297 } else {
|
nuclear@16
|
298 face->n[i] = -1;
|
nuclear@16
|
299 }
|
nuclear@16
|
300 }
|
nuclear@16
|
301 return 0;
|
nuclear@16
|
302 }
|
nuclear@16
|
303
|
nuclear@16
|
304 void scn_render(struct scene *scn)
|
nuclear@16
|
305 {
|
nuclear@17
|
306 struct mesh *m;
|
nuclear@16
|
307
|
nuclear@17
|
308 if(!scn->ready) {
|
nuclear@17
|
309 struct material *mtl = scn->matlist;
|
nuclear@17
|
310 while(mtl) {
|
nuclear@17
|
311 if(mtl->tex) {
|
nuclear@17
|
312 get_texture_pixels(mtl->tex);
|
nuclear@17
|
313 #ifdef USE_GL
|
nuclear@17
|
314 {
|
nuclear@17
|
315 int i, npix = mtl->tex->width * mtl->tex->height;
|
nuclear@17
|
316 int range = palm_color_range();
|
nuclear@17
|
317 unsigned char *rgb = malloc(npix * 3);
|
nuclear@17
|
318 struct palm_color *pal = palm_palette();
|
nuclear@17
|
319
|
nuclear@17
|
320 for(i=0; i<npix; i++) {
|
nuclear@17
|
321 int idx = mtl->tex->pixels[i] + range - 1;
|
nuclear@17
|
322 rgb[i * 3] = pal[idx].r;
|
nuclear@17
|
323 rgb[i * 3 + 1] = pal[idx].g;
|
nuclear@17
|
324 rgb[i * 3 + 2] = pal[idx].b;
|
nuclear@17
|
325 }
|
nuclear@17
|
326 free(mtl->tex->pixels);
|
nuclear@17
|
327 mtl->tex->pixels = rgb;
|
nuclear@17
|
328 }
|
nuclear@17
|
329 #endif /* USE_GL */
|
nuclear@17
|
330 } else {
|
nuclear@17
|
331 mtl->kd_base = palm_color_base(mtl->kd[0], mtl->kd[1], mtl->kd[2]);
|
nuclear@17
|
332 }
|
nuclear@17
|
333 mtl = mtl->next;
|
nuclear@17
|
334 }
|
nuclear@17
|
335 scn->ready = 1;
|
nuclear@17
|
336 }
|
nuclear@17
|
337
|
nuclear@17
|
338 m = scn->meshlist;
|
nuclear@16
|
339 while(m) {
|
nuclear@16
|
340 mesh_draw(m);
|
nuclear@16
|
341 m = m->next;
|
nuclear@16
|
342 }
|
nuclear@19
|
343
|
nuclear@19
|
344 #if 0
|
nuclear@19
|
345 {
|
nuclear@19
|
346 int i;
|
nuclear@19
|
347 struct palm_color *pal = palm_palette();
|
nuclear@19
|
348 float dx = 1.8 / 256;
|
nuclear@19
|
349 struct material *mtl = scn->matlist;
|
nuclear@19
|
350
|
nuclear@19
|
351 glMatrixMode(GL_MODELVIEW);
|
nuclear@19
|
352 glPushMatrix();
|
nuclear@19
|
353 glLoadIdentity();
|
nuclear@19
|
354 glMatrixMode(GL_PROJECTION);
|
nuclear@19
|
355 glPushMatrix();
|
nuclear@19
|
356 glLoadIdentity();
|
nuclear@19
|
357
|
nuclear@19
|
358 glPushAttrib(GL_ENABLE_BIT);
|
nuclear@19
|
359 glDisable(GL_LIGHTING);
|
nuclear@19
|
360 glDisable(GL_DEPTH_TEST);
|
nuclear@19
|
361
|
nuclear@19
|
362 glBegin(GL_QUADS);
|
nuclear@19
|
363 for(i=0; i<255; i++) {
|
nuclear@19
|
364 float x = i * dx - 0.9;
|
nuclear@19
|
365 glColor3ub(pal[i].r, pal[i].g, pal[i].b);
|
nuclear@19
|
366 glVertex2f(x, 0.98);
|
nuclear@19
|
367 glVertex2f(x, 0.9);
|
nuclear@19
|
368 glColor3ub(pal[i + 1].r, pal[i + 1].g, pal[i + 1].b);
|
nuclear@19
|
369 glVertex2f(x + dx, 0.9);
|
nuclear@19
|
370 glVertex2f(x + dx, 0.98);
|
nuclear@19
|
371 }
|
nuclear@19
|
372 glEnd();
|
nuclear@19
|
373
|
nuclear@19
|
374 glPopAttrib();
|
nuclear@19
|
375
|
nuclear@19
|
376 glMatrixMode(GL_PROJECTION);
|
nuclear@19
|
377 glPopMatrix();
|
nuclear@19
|
378 glMatrixMode(GL_MODELVIEW);
|
nuclear@19
|
379 glPopMatrix();
|
nuclear@19
|
380 }
|
nuclear@19
|
381 #endif
|
nuclear@16
|
382 }
|
nuclear@16
|
383
|
nuclear@16
|
384 /* --- material --- */
|
nuclear@16
|
385 int mtl_init(struct material *mtl)
|
nuclear@16
|
386 {
|
nuclear@16
|
387 memset(mtl, 0, sizeof *mtl);
|
nuclear@16
|
388 return 0;
|
nuclear@16
|
389 }
|
nuclear@16
|
390
|
nuclear@16
|
391 void mtl_destroy(struct material *mtl)
|
nuclear@16
|
392 {
|
nuclear@16
|
393 free(mtl->name);
|
nuclear@16
|
394
|
nuclear@16
|
395 if(mtl->tex) {
|
nuclear@16
|
396 free_texture(mtl->tex);
|
nuclear@16
|
397 }
|
nuclear@16
|
398 }
|
nuclear@16
|
399
|
nuclear@16
|
400
|
nuclear@16
|
401 int mtl_set_name(struct material *mtl, const char *name)
|
nuclear@16
|
402 {
|
nuclear@16
|
403 char *tmp;
|
nuclear@16
|
404 int len = strlen(name);
|
nuclear@16
|
405
|
nuclear@16
|
406 if(!(tmp = malloc(len + 1))) {
|
nuclear@16
|
407 perror("failed to allocate material name");
|
nuclear@16
|
408 return -1;
|
nuclear@16
|
409 }
|
nuclear@16
|
410 memcpy(tmp, name, len);
|
nuclear@16
|
411 tmp[len] = 0;
|
nuclear@16
|
412
|
nuclear@16
|
413 free(mtl->name);
|
nuclear@16
|
414 mtl->name = tmp;
|
nuclear@16
|
415 return 0;
|
nuclear@16
|
416 }
|
nuclear@16
|
417
|
nuclear@16
|
418
|
nuclear@16
|
419 /* --- mesh --- */
|
nuclear@16
|
420 int mesh_init(struct mesh *m)
|
nuclear@16
|
421 {
|
nuclear@16
|
422 memset(m, 0, sizeof *m);
|
nuclear@16
|
423
|
nuclear@16
|
424 m->vert = cvec_alloc(0, sizeof *m->vert);
|
nuclear@16
|
425 m->norm = cvec_alloc(0, sizeof *m->norm);
|
nuclear@16
|
426 m->texcoord = cvec_alloc(0, sizeof *m->texcoord);
|
nuclear@16
|
427
|
nuclear@16
|
428 if(!m->vert || !m->norm || !m->texcoord) {
|
nuclear@16
|
429 return -1;
|
nuclear@16
|
430 }
|
nuclear@16
|
431 return 0;
|
nuclear@16
|
432 }
|
nuclear@16
|
433
|
nuclear@16
|
434 void mesh_destroy(struct mesh *m)
|
nuclear@16
|
435 {
|
nuclear@16
|
436 cvec_free(m->vert);
|
nuclear@16
|
437 cvec_free(m->norm);
|
nuclear@16
|
438 cvec_free(m->texcoord);
|
nuclear@16
|
439 }
|
nuclear@16
|
440
|
nuclear@16
|
441 void mesh_add_vertex(struct mesh *m, vec3_t v)
|
nuclear@16
|
442 {
|
nuclear@16
|
443 m->vert = cvec_append(m->vert, &v);
|
nuclear@16
|
444 }
|
nuclear@16
|
445
|
nuclear@16
|
446 void mesh_add_normal(struct mesh *m, vec3_t n)
|
nuclear@16
|
447 {
|
nuclear@16
|
448 m->norm = cvec_append(m->norm, &n);
|
nuclear@16
|
449 }
|
nuclear@16
|
450
|
nuclear@16
|
451 void mesh_add_texcoord(struct mesh *m, vec2_t tc)
|
nuclear@16
|
452 {
|
nuclear@16
|
453 m->texcoord = cvec_append(m->texcoord, &tc);
|
nuclear@16
|
454 }
|
nuclear@16
|
455
|
nuclear@16
|
456 void mesh_draw(struct mesh *m)
|
nuclear@16
|
457 {
|
nuclear@16
|
458 int i, numv;
|
nuclear@17
|
459 struct material *mtl = m->mtl;
|
nuclear@17
|
460
|
nuclear@17
|
461 numv = cvec_size(m->vert);
|
nuclear@17
|
462
|
nuclear@17
|
463 #ifdef USE_GL
|
nuclear@17
|
464 if(mtl->tex) {
|
nuclear@19
|
465 assert(mtl->tex->pixels);
|
nuclear@17
|
466 glEnable(GL_TEXTURE_2D);
|
nuclear@17
|
467 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
nuclear@17
|
468 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
nuclear@17
|
469 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
nuclear@17
|
470 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
nuclear@17
|
471
|
nuclear@17
|
472 glTexImage2D(GL_TEXTURE_2D, 0, 3, mtl->tex->width, mtl->tex->height, 0, GL_RGB, GL_UNSIGNED_BYTE, mtl->tex->pixels);
|
nuclear@17
|
473 }
|
nuclear@17
|
474
|
nuclear@17
|
475 glBegin(GL_TRIANGLES);
|
nuclear@17
|
476 for(i=0; i<numv; i++) {
|
nuclear@17
|
477 glNormal3f(m->norm[i].x, m->norm[i].y, m->norm[i].z);
|
nuclear@17
|
478 glTexCoord2f(m->texcoord[i].x, m->texcoord[i].y);
|
nuclear@17
|
479 glVertex3f(m->vert[i].x, m->vert[i].y, m->vert[i].z);
|
nuclear@17
|
480 }
|
nuclear@17
|
481 glEnd();
|
nuclear@17
|
482
|
nuclear@17
|
483 if(mtl->tex) {
|
nuclear@17
|
484 glDisable(GL_TEXTURE_2D);
|
nuclear@17
|
485 }
|
nuclear@17
|
486 #else
|
nuclear@17
|
487 if(mtl->tex) {
|
nuclear@19
|
488 mgl_enable(MGL_TEXTURE_2D);
|
nuclear@17
|
489 mgl_teximage(mtl->tex->width, mtl->tex->height, mtl->tex->pixels);
|
nuclear@17
|
490 } else {
|
nuclear@17
|
491 mgl_index(mtl->kd_base);
|
nuclear@17
|
492 }
|
nuclear@16
|
493
|
nuclear@16
|
494 mgl_begin(MGL_TRIANGLES);
|
nuclear@16
|
495
|
nuclear@16
|
496 for(i=0; i<numv; i++) {
|
nuclear@16
|
497 mgl_normal(m->norm[i].x, m->norm[i].y, m->norm[i].z);
|
nuclear@16
|
498 mgl_texcoord2f(m->texcoord[i].x, m->texcoord[i].y);
|
nuclear@16
|
499 mgl_vertex3f(m->vert[i].x, m->vert[i].y, m->vert[i].z);
|
nuclear@16
|
500 }
|
nuclear@17
|
501 mgl_end();
|
nuclear@16
|
502
|
nuclear@17
|
503 if(mtl->tex) {
|
nuclear@17
|
504 mgl_disable(MGL_TEXTURE_2D);
|
nuclear@17
|
505 }
|
nuclear@17
|
506 #endif
|
nuclear@16
|
507 }
|