deepstone

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_ */