dos3d
changeset 16:cb676ff89e69
added missing cvec and scene files
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 29 Nov 2011 07:23:57 +0200 |
parents | 4a0e9ab12ad0 |
children | 1e9f0b3616fa |
files | src/cvec.c src/cvec.h src/scene.c src/scene.h |
diffstat | 4 files changed, 536 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cvec.c Tue Nov 29 07:23:57 2011 +0200 1.3 @@ -0,0 +1,68 @@ 1.4 +#include <stdlib.h> 1.5 +#include <string.h> 1.6 +#include <stddef.h> 1.7 +#include "cvec.h" 1.8 + 1.9 +struct vector { 1.10 + int elem_sz; 1.11 + int size, used; 1.12 + char data[1]; 1.13 +}; 1.14 + 1.15 +#define HDRSZ offsetof(struct vector, data) 1.16 +#define VECTOR(p) ((struct vector*)((char*)(p) - HDRSZ)) 1.17 + 1.18 +void *cvec_alloc(int cnt, int esz) 1.19 +{ 1.20 + struct vector *vec; 1.21 + 1.22 + if(!(vec = malloc(HDRSZ + esz * cnt))) { 1.23 + return 0; 1.24 + } 1.25 + vec->elem_sz = esz; 1.26 + vec->size = cnt; 1.27 + vec->used = cnt; 1.28 + return vec->data; 1.29 +} 1.30 + 1.31 +void cvec_free(void *cvec) 1.32 +{ 1.33 + free(VECTOR(cvec)); 1.34 +} 1.35 + 1.36 +void *cvec_resize(void *cvec, int newsz) 1.37 +{ 1.38 + struct vector *newvec, *vec = VECTOR(cvec); 1.39 + 1.40 + if(!(newvec = realloc(vec, newsz * vec->elem_sz + HDRSZ))) { 1.41 + return 0; 1.42 + } 1.43 + newvec->size = newvec->used = newsz; 1.44 + return newvec->data; 1.45 +} 1.46 + 1.47 +void *cvec_append(void *cvec, void *data) 1.48 +{ 1.49 + struct vector *vec = VECTOR(cvec); 1.50 + 1.51 + if(vec->used >= vec->size) { 1.52 + int used = vec->used; 1.53 + void *tmp; 1.54 + 1.55 + if(!(tmp = cvec_resize(cvec, vec->size ? vec->size * 2 : 1))) { 1.56 + return cvec; 1.57 + } 1.58 + cvec = tmp; 1.59 + vec = VECTOR(tmp); 1.60 + vec->used = used; 1.61 + } 1.62 + 1.63 + memcpy(vec->data + vec->used * vec->elem_sz, data, vec->elem_sz); 1.64 + vec->used++; 1.65 + return cvec; 1.66 +} 1.67 + 1.68 +int cvec_size(void *cvec) 1.69 +{ 1.70 + return VECTOR(cvec)->used; 1.71 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/cvec.h Tue Nov 29 07:23:57 2011 +0200 2.3 @@ -0,0 +1,20 @@ 2.4 +#ifndef CVEC_H_ 2.5 +#define CVEC_H_ 2.6 + 2.7 +#ifdef __cplusplus 2.8 +extern "C" { 2.9 +#endif 2.10 + 2.11 +void *cvec_alloc(int cnt, int esz); 2.12 +void cvec_free(void *cvec); 2.13 + 2.14 +void *cvec_resize(void *cvec, int newsz); 2.15 +void *cvec_append(void *cvec, void *data); 2.16 + 2.17 +int cvec_size(void *cvec); 2.18 + 2.19 +#ifdef __cplusplus 2.20 +} 2.21 +#endif 2.22 + 2.23 +#endif /* CVEC_H_ */
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/scene.c Tue Nov 29 07:23:57 2011 +0200 3.3 @@ -0,0 +1,379 @@ 3.4 +#include <stdio.h> 3.5 +#include <stdlib.h> 3.6 +#include <string.h> 3.7 +#include <ctype.h> 3.8 +#include <errno.h> 3.9 +#include "scene.h" 3.10 +#include "cvec.h" 3.11 +#include "mingl.h" 3.12 + 3.13 + 3.14 +struct face { 3.15 + int v[3], n[3], t[3]; 3.16 +}; 3.17 + 3.18 +static int load_materials(struct scene *scn, const char *fname); 3.19 +static int parse_face(struct face *face, char *buf); 3.20 + 3.21 + 3.22 +/* --- scene --- */ 3.23 +int scn_init(struct scene *scn) 3.24 +{ 3.25 + memset(scn, 0, sizeof *scn); 3.26 + return 0; 3.27 +} 3.28 + 3.29 +void scn_destroy(struct scene *scn) 3.30 +{ 3.31 + while(scn->matlist) { 3.32 + struct material *tmp = scn->matlist; 3.33 + scn->matlist = scn->matlist->next; 3.34 + 3.35 + mtl_destroy(tmp); 3.36 + free(tmp); 3.37 + } 3.38 + while(scn->meshlist) { 3.39 + struct mesh *tmp = scn->meshlist; 3.40 + scn->meshlist = scn->meshlist->next; 3.41 + 3.42 + mesh_destroy(tmp); 3.43 + free(tmp); 3.44 + } 3.45 +} 3.46 + 3.47 + 3.48 +void scn_add_mesh(struct scene *scn, struct mesh *m) 3.49 +{ 3.50 + printf("adding mesh: %d faces\n", m->nface); 3.51 + m->next = scn->meshlist; 3.52 + scn->meshlist = m; 3.53 +} 3.54 + 3.55 +void scn_add_material(struct scene *scn, struct material *m) 3.56 +{ 3.57 + printf("adding material: %s\n", m->name); 3.58 + m->next = scn->matlist; 3.59 + scn->matlist = m; 3.60 +} 3.61 + 3.62 +struct material *scn_find_material(struct scene *scn, const char *name) 3.63 +{ 3.64 + struct material *mtl = scn->matlist; 3.65 + 3.66 + while(mtl) { 3.67 + if(strcmp(mtl->name, name) == 0) { 3.68 + break; 3.69 + } 3.70 + mtl = mtl->next; 3.71 + } 3.72 + return mtl; 3.73 +} 3.74 + 3.75 +#define SEP " \t\n\r" 3.76 +int scn_load(struct scene *scn, const char *fname) 3.77 +{ 3.78 + FILE *fp; 3.79 + char buf[256]; 3.80 + struct mesh *m; 3.81 + vec3_t *varr, *vnarr; 3.82 + vec2_t *vtarr; 3.83 + 3.84 + if(!(fp = fopen(fname, "rb"))) { 3.85 + fprintf(stderr, "failed to open scene file: %s: %s\n", fname, strerror(errno)); 3.86 + return -1; 3.87 + } 3.88 + 3.89 + varr = cvec_alloc(0, sizeof *varr); 3.90 + vnarr = cvec_alloc(0, sizeof *vnarr); 3.91 + vtarr = cvec_alloc(0, sizeof *vtarr); 3.92 + 3.93 + if(!(m = malloc(sizeof *m)) || mesh_init(m) == -1) { 3.94 + fprintf(stderr, "meshed up\n"); 3.95 + fclose(fp); 3.96 + return -1; 3.97 + } 3.98 + 3.99 + while(fgets(buf, sizeof buf, fp)) { 3.100 + char *line = buf; 3.101 + char *tok, *rest, *tmp; 3.102 + 3.103 + while(*line && isspace(*line)) { 3.104 + line++; 3.105 + } 3.106 + if(*line == 0 || *line == '#') { 3.107 + continue; 3.108 + } 3.109 + 3.110 + if(!(tok = strtok(line, SEP))) { 3.111 + continue; 3.112 + } 3.113 + rest = tok + strlen(tok) + 1; 3.114 + 3.115 + if((tmp = strchr(rest, '\r')) || (tmp = strchr(rest, '\n'))) { 3.116 + *tmp = 0; 3.117 + } 3.118 + 3.119 + if(strcmp(tok, "mtllib") == 0) { 3.120 + if(!rest) { 3.121 + fprintf(stderr, "invalid mtllib directive\n"); 3.122 + continue; 3.123 + } 3.124 + load_materials(scn, rest); 3.125 + 3.126 + } else if(strcmp(tok, "usemtl") == 0) { 3.127 + if(rest) { 3.128 + m->mtl = scn_find_material(scn, rest); 3.129 + } 3.130 + 3.131 + } else if(strcmp(tok, "o") == 0 || strcmp(tok, "g") == 0) { 3.132 + if(cvec_size(m->vert) > 0) { 3.133 + scn_add_mesh(scn, m); 3.134 + 3.135 + if(!(m = malloc(sizeof *m)) || mesh_init(m) == -1) { 3.136 + fprintf(stderr, "meshed up\n"); 3.137 + fclose(fp); 3.138 + return -1; 3.139 + } 3.140 + } 3.141 + 3.142 + } else if(strcmp(tok, "v") == 0) { 3.143 + vec3_t v; 3.144 + 3.145 + if(!rest || sscanf(rest, "%f %f %f\n", &v.x, &v.y, &v.z) != 3) { 3.146 + continue; 3.147 + } 3.148 + varr = cvec_append(varr, &v); 3.149 + 3.150 + } else if(strcmp(tok, "vn") == 0) { 3.151 + vec3_t v; 3.152 + 3.153 + if(!rest || sscanf(rest, "%f %f %f\n", &v.x, &v.y, &v.z) != 3) { 3.154 + continue; 3.155 + } 3.156 + vnarr = cvec_append(vnarr, &v); 3.157 + 3.158 + } else if(strcmp(tok, "vt") == 0) { 3.159 + vec3_t v; 3.160 + 3.161 + if(!rest || sscanf(rest, "%f %f %f\n", &v.x, &v.y, &v.z) != 3) { 3.162 + continue; 3.163 + } 3.164 + vtarr = cvec_append(vtarr, &v); 3.165 + 3.166 + } else if(strcmp(tok, "f") == 0) { 3.167 + int i; 3.168 + struct face face; 3.169 + 3.170 + if(!rest || parse_face(&face, rest) == -1) { 3.171 + continue; 3.172 + } 3.173 + 3.174 + for(i=0; i<3; i++) { 3.175 + int vidx = face.v[i]; 3.176 + int nidx = face.n[i]; 3.177 + int tidx = face.t[i]; 3.178 + 3.179 + mesh_add_vertex(m, varr[vidx]); 3.180 + if(nidx >= 0) { 3.181 + mesh_add_normal(m, vnarr[nidx]); 3.182 + } 3.183 + if(tidx >= 0) { 3.184 + mesh_add_texcoord(m, vtarr[tidx]); 3.185 + } 3.186 + m->nface++; 3.187 + } 3.188 + } 3.189 + 3.190 + } 3.191 + fclose(fp); 3.192 + 3.193 + if(cvec_size(m->vert) > 0) { 3.194 + scn_add_mesh(scn, m); 3.195 + } 3.196 + 3.197 + cvec_free(varr); 3.198 + cvec_free(vnarr); 3.199 + cvec_free(vtarr); 3.200 + 3.201 + return 0; 3.202 +} 3.203 + 3.204 +static int load_materials(struct scene *scn, const char *fname) 3.205 +{ 3.206 + FILE *fp; 3.207 + struct material *m = 0; 3.208 + char buf[256]; 3.209 + 3.210 + if(!(fp = fopen(fname, "r"))) { 3.211 + fprintf(stderr, "failed to load material file: %s: %s\n", fname, strerror(errno)); 3.212 + return -1; 3.213 + } 3.214 + 3.215 + while(fgets(buf, sizeof buf, fp)) { 3.216 + char *line = buf; 3.217 + char *tok, *rest, *tmp; 3.218 + 3.219 + while(*line && isspace(*line)) { 3.220 + line++; 3.221 + } 3.222 + if(*line == 0 || *line == '#') { 3.223 + continue; 3.224 + } 3.225 + 3.226 + if(!(tok = strtok(line, SEP))) { 3.227 + continue; 3.228 + } 3.229 + rest = tok + strlen(tok) + 1; 3.230 + 3.231 + if((tmp = strchr(rest, '\r')) || (tmp = strchr(rest, '\n'))) { 3.232 + *tmp = 0; 3.233 + } 3.234 + 3.235 + if(strcmp(tok, "newmtl") == 0) { 3.236 + if(m) { 3.237 + scn_add_material(scn, m); 3.238 + } 3.239 + if(!(m = malloc(sizeof *m)) || mtl_init(m) == -1) { 3.240 + continue; 3.241 + } 3.242 + mtl_set_name(m, rest); 3.243 + 3.244 + } else if(strcmp(tok, "Kd") == 0) { 3.245 + if(sscanf(rest, "%f %f %f", &m->kd.x, &m->kd.y, &m->kd.z) != 3) { 3.246 + continue; 3.247 + } 3.248 + } else if(strcmp(tok, "map_Kd") == 0) { 3.249 + printf("ignoring texture: `%s'\n", rest); 3.250 + } 3.251 + } 3.252 + 3.253 + if(m) { 3.254 + scn_add_material(scn, m); 3.255 + } 3.256 + 3.257 + fclose(fp); 3.258 + return 0; 3.259 +} 3.260 + 3.261 +static int parse_face(struct face *face, char *buf) 3.262 +{ 3.263 + int i, found; 3.264 + char *tok; 3.265 + 3.266 + for(i=0; i<3; i++) { 3.267 + tok = strtok(i > 0 ? 0 : buf, SEP); 3.268 + found = sscanf(tok, "%d/%d/%d", &face->v[i], &face->t[i], &face->n[i]); 3.269 + 3.270 + face->v[i]--; 3.271 + 3.272 + if(found > 1) { 3.273 + face->t[i]--; 3.274 + } else { 3.275 + face->t[i] = -1; 3.276 + } 3.277 + if(found > 2) { 3.278 + face->n[i]--; 3.279 + } else { 3.280 + face->n[i] = -1; 3.281 + } 3.282 + } 3.283 + return 0; 3.284 +} 3.285 + 3.286 +void scn_render(struct scene *scn) 3.287 +{ 3.288 + struct mesh *m = scn->meshlist; 3.289 + 3.290 + while(m) { 3.291 + mesh_draw(m); 3.292 + m = m->next; 3.293 + } 3.294 +} 3.295 + 3.296 +/* --- material --- */ 3.297 +int mtl_init(struct material *mtl) 3.298 +{ 3.299 + memset(mtl, 0, sizeof *mtl); 3.300 + return 0; 3.301 +} 3.302 + 3.303 +void mtl_destroy(struct material *mtl) 3.304 +{ 3.305 + free(mtl->name); 3.306 + 3.307 + if(mtl->tex) { 3.308 + free_texture(mtl->tex); 3.309 + } 3.310 +} 3.311 + 3.312 + 3.313 +int mtl_set_name(struct material *mtl, const char *name) 3.314 +{ 3.315 + char *tmp; 3.316 + int len = strlen(name); 3.317 + 3.318 + if(!(tmp = malloc(len + 1))) { 3.319 + perror("failed to allocate material name"); 3.320 + return -1; 3.321 + } 3.322 + memcpy(tmp, name, len); 3.323 + tmp[len] = 0; 3.324 + 3.325 + free(mtl->name); 3.326 + mtl->name = tmp; 3.327 + return 0; 3.328 +} 3.329 + 3.330 + 3.331 +/* --- mesh --- */ 3.332 +int mesh_init(struct mesh *m) 3.333 +{ 3.334 + memset(m, 0, sizeof *m); 3.335 + 3.336 + m->vert = cvec_alloc(0, sizeof *m->vert); 3.337 + m->norm = cvec_alloc(0, sizeof *m->norm); 3.338 + m->texcoord = cvec_alloc(0, sizeof *m->texcoord); 3.339 + 3.340 + if(!m->vert || !m->norm || !m->texcoord) { 3.341 + return -1; 3.342 + } 3.343 + return 0; 3.344 +} 3.345 + 3.346 +void mesh_destroy(struct mesh *m) 3.347 +{ 3.348 + cvec_free(m->vert); 3.349 + cvec_free(m->norm); 3.350 + cvec_free(m->texcoord); 3.351 +} 3.352 + 3.353 +void mesh_add_vertex(struct mesh *m, vec3_t v) 3.354 +{ 3.355 + m->vert = cvec_append(m->vert, &v); 3.356 +} 3.357 + 3.358 +void mesh_add_normal(struct mesh *m, vec3_t n) 3.359 +{ 3.360 + m->norm = cvec_append(m->norm, &n); 3.361 +} 3.362 + 3.363 +void mesh_add_texcoord(struct mesh *m, vec2_t tc) 3.364 +{ 3.365 + m->texcoord = cvec_append(m->texcoord, &tc); 3.366 +} 3.367 + 3.368 +void mesh_draw(struct mesh *m) 3.369 +{ 3.370 + int i, numv; 3.371 + 3.372 + mgl_begin(MGL_TRIANGLES); 3.373 + 3.374 + numv = cvec_size(m->vert); 3.375 + for(i=0; i<numv; i++) { 3.376 + mgl_normal(m->norm[i].x, m->norm[i].y, m->norm[i].z); 3.377 + mgl_texcoord2f(m->texcoord[i].x, m->texcoord[i].y); 3.378 + mgl_vertex3f(m->vert[i].x, m->vert[i].y, m->vert[i].z); 3.379 + } 3.380 + 3.381 + mgl_end(); 3.382 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/scene.h Tue Nov 29 07:23:57 2011 +0200 4.3 @@ -0,0 +1,69 @@ 4.4 +#ifndef SCENE_H_ 4.5 +#define SCENE_H_ 4.6 + 4.7 +#include "vmath.h" 4.8 +#include "texture.h" 4.9 + 4.10 + 4.11 +struct material { 4.12 + char *name; 4.13 + vec3_t kd; 4.14 + int kd_base; 4.15 + struct texture *tex; 4.16 + 4.17 + struct material *next; 4.18 +}; 4.19 + 4.20 +struct mesh { 4.21 + int nface; 4.22 + vec3_t *vert; 4.23 + vec3_t *norm; 4.24 + vec2_t *texcoord; 4.25 + struct material *mtl; 4.26 + 4.27 + struct mesh *next; 4.28 +}; 4.29 + 4.30 +struct scene { 4.31 + struct material *matlist; 4.32 + struct mesh *meshlist; 4.33 +}; 4.34 + 4.35 +#ifdef __cplusplus 4.36 +extern "C" { 4.37 +#endif 4.38 + 4.39 +/* --- scene --- */ 4.40 +int scn_init(struct scene *scn); 4.41 +void scn_destroy(struct scene *scn); 4.42 + 4.43 +void scn_add_mesh(struct scene *scn, struct mesh *m); 4.44 +void scn_add_material(struct scene *scn, struct material *m); 4.45 + 4.46 +struct material *scn_find_material(struct scene *scn, const char *name); 4.47 + 4.48 +int scn_load(struct scene *scn, const char *fname); 4.49 + 4.50 +void scn_render(struct scene *scn); 4.51 + 4.52 +/* --- material --- */ 4.53 +int mtl_init(struct material *mtl); 4.54 +void mtl_destroy(struct material *mtl); 4.55 + 4.56 +int mtl_set_name(struct material *mtl, const char *name); 4.57 + 4.58 +/* --- mesh --- */ 4.59 +int mesh_init(struct mesh *m); 4.60 +void mesh_destroy(struct mesh *m); 4.61 + 4.62 +void mesh_add_vertex(struct mesh *m, vec3_t v); 4.63 +void mesh_add_normal(struct mesh *m, vec3_t n); 4.64 +void mesh_add_texcoord(struct mesh *m, vec2_t tc); 4.65 + 4.66 +void mesh_draw(struct mesh *m); 4.67 + 4.68 +#ifdef __cplusplus 4.69 +} 4.70 +#endif 4.71 + 4.72 +#endif /* SCENE_H_ */