X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Flevel.c;fp=src%2Flevel.c;h=0016a702f2d427c0d6c0c2c146e5f055954efa3f;hb=822cd054970ea5bc971c04eb2726333cccc5fb1a;hp=21a82f99690ec71b54d165c57ea583ed5c98ab45;hpb=68f8983b5a92709e92355c2d6e756890b4348319;p=cyberay diff --git a/src/level.c b/src/level.c index 21a82f9..0016a70 100644 --- a/src/level.c +++ b/src/level.c @@ -5,8 +5,7 @@ #include "treestore.h" #include "mesh.h" -static struct material *add_material(struct level *lvl, struct material *mtl); -static int append_polygons(struct bvhnode *bnode, struct triangle *faces, int num_faces, struct material *mtl); +static int add_mesh_faces(struct bvhnode *bnode, struct mesh *mesh); int load_level(struct level *lvl, const char *fname) { @@ -14,8 +13,7 @@ int load_level(struct level *lvl, const char *fname) char path[256]; struct ts_node *root, *node; struct scenefile scn; - struct mesh *mesh; - struct material *mtl; + struct mesh *mesh, *tail; memset(lvl, 0, sizeof *lvl); if(!(lvl->st_root = calloc(1, sizeof *lvl->st_root)) || @@ -60,13 +58,18 @@ int load_level(struct level *lvl, const char *fname) if(load_scenefile(&scn, path) == -1) { goto cont; } - mesh = scn.meshlist; + mesh = tail = scn.meshlist; while(mesh) { - mtl = add_material(lvl, &mesh->mtl); - append_polygons(lvl->st_root, mesh->faces, mesh->num_faces, mtl); + add_mesh_faces(lvl->st_root, mesh); + tail = mesh; mesh = mesh->next; } + if(tail) { + tail->next = lvl->meshlist; + lvl->meshlist = scn.meshlist; + scn.meshlist = 0; + } destroy_scenefile(&scn); } cont: node = node->next; @@ -78,9 +81,16 @@ cont: node = node->next; void destroy_level(struct level *lvl) { + struct mesh *mesh; + free_bvh_tree(lvl->st_root); free_bvh_tree(lvl->dyn_root); - free(lvl->mtls); + + while(lvl->meshlist) { + mesh = lvl->meshlist; + lvl->meshlist = lvl->meshlist->next; + destroy_mesh(mesh); + } } @@ -122,11 +132,11 @@ static void draw_level_rec(struct bvhnode *bn) if(!bn) return; if(bn->faces) { - tri = bn->faces; - curmtl = tri->mtl; + curmtl = bn->faces[0]->mtl; glBegin(GL_TRIANGLES); for(i=0; inum_faces; i++) { + tri = bn->faces[i]; if(tri->mtl != curmtl) { glEnd(); color[0] = tri->mtl->color.x; @@ -142,7 +152,6 @@ static void draw_level_rec(struct bvhnode *bn) glTexCoord2fv(&tri->v[j].tex.x); glVertex3fv(&tri->v[j].pos.x); } - tri++; } glEnd(); } @@ -157,49 +166,24 @@ void draw_level(struct level *lvl) draw_level_rec(lvl->dyn_root); } -static struct material *add_material(struct level *lvl, struct material *mtl) -{ - int i, newsz; - struct material *tmp; - - for(i=0; inum_mtls; i++) { - if(memcmp(lvl->mtls + i, mtl, sizeof *mtl) == 0) { - return lvl->mtls + i; - } - } - - if(lvl->num_mtls >= lvl->max_mtls) { - newsz = lvl->max_mtls ? lvl->max_mtls * 2 : 16; - if(!(tmp = realloc(lvl->mtls, newsz * sizeof *lvl->mtls))) { - fprintf(stderr, "add_material: failed to resize materials array to %d\n", newsz); - return 0; - } - lvl->mtls = tmp; - lvl->max_mtls = newsz; - } - lvl->mtls[lvl->num_mtls] = *mtl; - - return lvl->mtls + lvl->num_mtls++; -} - -static int append_polygons(struct bvhnode *bnode, struct triangle *faces, int num_faces, struct material *mtl) +static int add_mesh_faces(struct bvhnode *bnode, struct mesh *mesh) { int i, j, newsz; - struct triangle *tri; + void *tmp; + struct triangle *tri, **triptr; - newsz = bnode->num_faces + num_faces; - if(!(tri = realloc(bnode->faces, newsz * sizeof *bnode->faces))) { + newsz = bnode->num_faces + mesh->num_faces; + if(!(tmp = realloc(bnode->faces, newsz * sizeof *bnode->faces))) { fprintf(stderr, "append_polygons: failed to resize faces array to %d\n", newsz); return -1; } - bnode->faces = tri; - tri += bnode->num_faces; + bnode->faces = tmp; + triptr = bnode->faces + bnode->num_faces; bnode->num_faces = newsz; - for(i=0; imtl = mtl; - + tri = mesh->faces; + for(i=0; inum_faces; i++) { + *triptr++ = tri; for(j=0; j<3; j++) { cgm_vec3 *p = &tri->v[j].pos; if(p->x < bnode->aabb.vmin.x) bnode->aabb.vmin.x = p->x;