From: John Tsiombikas Date: Wed, 15 Sep 2021 09:18:47 +0000 (+0300) Subject: started on the level geometry X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=vrlugburz;a=commitdiff_plain;h=0a754b5aac897ffde09e93027aed78c95b81b99b started on the level geometry --- diff --git a/src/game.c b/src/game.c index 42a95f9..8ee1989 100644 --- a/src/game.c +++ b/src/game.c @@ -6,8 +6,9 @@ #include "scenefile.h" #include "sdr.h" +static void draw_level(void); + struct level lvl; -struct scenefile scn; int win_width, win_height; float win_aspect; @@ -41,11 +42,6 @@ int game_init(void) return -1; } - /* DBG */ - if(load_scenefile(&scn, "data/dwall1.obj") == -1) { - return -1; - } - return 0; } @@ -57,8 +53,6 @@ void game_shutdown(void) void game_display(void) { - struct mesh *mesh; - glClearColor(0.1, 0.1, 0.1, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -68,24 +62,36 @@ void game_display(void) glLoadMatrixf(proj_matrix); cgm_midentity(view_matrix); - cgm_mpretranslate(view_matrix, 0, 1.5, -cam_dist); + cgm_mpretranslate(view_matrix, 0, -1.7, -cam_dist); cgm_mprerotate(view_matrix, cam_phi, 1, 0, 0); cgm_mprerotate(view_matrix, cam_theta, 0, 1, 0); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(view_matrix); + draw_level(); + + game_swap_buffers(); + assert(glGetError() == GL_NO_ERROR); +} + +static void draw_level(void) +{ + int i, j, k; + struct cell *cell; + glUseProgram(sdr_foo); - mesh = scn.meshlist; - while(mesh) { - draw_mesh(mesh); - mesh = mesh->next; + cell = lvl.cells; + for(i=0; inum_mgrp; k++) { + draw_meshgroup(cell->mgrp + k); + } + cell++; + } } glUseProgram(0); - - game_swap_buffers(); - assert(glGetError() == GL_NO_ERROR); } void game_reshape(int x, int y) diff --git a/src/level.c b/src/level.c index 9e5fe44..70af648 100644 --- a/src/level.c +++ b/src/level.c @@ -30,7 +30,7 @@ void destroy_level(struct level *lvl) int load_level(struct level *lvl, const char *fname) { struct ts_node *ts, *node, *iter; - int sz, cx, cy; + int i, j, sz, cx, cy; struct cell *cell; lvl->fname = strdup(fname); @@ -75,7 +75,40 @@ int load_level(struct level *lvl, const char *fname) } cell = lvl->cells + cy * sz + cx; cell->type = ts_get_attr_int(node, "blocked", 0) ? CELL_BLOCKED : CELL_WALK; - /* TODO wall tiles and detail objects */ + + /* abuse the next pointer to hang the treestore node temporarilly */ + cell->next = (struct cell*)node; + } + } + + /* assign wall types to all occupied cells */ + cell = lvl->cells; + for(i=0; iheight; i++) { + for(j=0; jwidth; j++) { + if(cell->type == CELL_SOLID) { + cell++; + continue; + } + + /* TODO take wall choice from the level file into account */ + /* TODO detect corners */ + node = (struct ts_node*)cell->next; + cell->next = 0; + + if(j <= 0 || cell[-1].type == CELL_SOLID) { + cell->wall[0] = TILE_STRAIGHT; + } + if(i <= 0 || cell[-lvl->width].type == CELL_SOLID) { + cell->wall[1] = TILE_STRAIGHT; + } + if(j >= lvl->width - 1 || cell[1].type == CELL_SOLID) { + cell->wall[2] = TILE_STRAIGHT; + } + if(i >= lvl->height - 1 || cell[lvl->width].type == CELL_SOLID) { + cell->wall[3] = TILE_STRAIGHT; + } + + cell++; } } @@ -203,3 +236,92 @@ static int load_tileset(struct level *lvl, struct ts_node *tsn) return 0; } + +struct tile *find_level_tile(struct level *lvl, const char *tname) +{ + struct tile *tile = lvl->tiles; + while(tile) { + if(strcmp(tile->name, tname) == 0) { + return tile; + } + tile = tile->next; + } + return 0; +} + +int gen_cell_geom(struct level *lvl, struct cell *cell) +{ + int i; + struct meshgroup *wallgeom; + struct tile *tstr; + struct mesh *mesh, *tmesh; + float xform[16]; + + printf("foo!\n"); + + if(!(tstr = find_level_tile(lvl, "straight"))) { + return -1; + } + + if(!(wallgeom = malloc(sizeof *wallgeom))) { + return -1; + } + init_meshgroup(wallgeom); + + for(i=0; i<4; i++) { + if(cell->wall[i] == TILE_STRAIGHT) { /* TODO: support other wall types */ + cgm_mrotation_y(xform, i * M_PI / 2.0f); + + tmesh = tstr->scn.meshlist; + while(tmesh) { + if(!(mesh = malloc(sizeof *mesh))) { + return -1; + } + + /* create a copy of the tile mesh */ + if(copy_mesh(mesh, tmesh) == -1) { + free(mesh); + return -1; + } + if(i) xform_mesh(mesh, xform); /* rotate it to match the wall angle */ + + /* add it to the level meshlist */ + mesh->next = lvl->meshlist; + lvl->meshlist = mesh; + + /* add it to the meshgroup */ + if(add_meshgroup_mesh(wallgeom, mesh) == -1) { + destroy_mesh(mesh); + free(mesh); + return -1; + } + + tmesh = tmesh->next; + } + } + } + + /* TODO: append to other existing meshgroups for detail objects */ + cell->mgrp = wallgeom; + cell->num_mgrp = 1; + + return 0; +} + +int gen_level_geom(struct level *lvl) +{ + int i, j; + struct cell *cell; + + for(i=0; iheight; i++) { + for(j=0; jwidth; j++) { + cell = lvl->cells + i * lvl->width + j; + if(cell->type != CELL_SOLID) { + if(gen_cell_geom(lvl, cell) == -1) { + return -1; + } + } + } + } + return 0; +} diff --git a/src/level.h b/src/level.h index 6a57dc2..53eb9c1 100644 --- a/src/level.h +++ b/src/level.h @@ -4,6 +4,7 @@ #include "scenefile.h" enum { + TILE_EMPTY, TILE_STRAIGHT, TILE_CORNER, TILE_DOOR @@ -27,7 +28,10 @@ struct cell { int wall[4]; int floor, ceil; - struct meshgroup mgrp; + struct meshgroup *mgrp; + int num_mgrp; + + struct cell *next; }; struct level { @@ -37,6 +41,11 @@ struct level { struct cell *cells; struct tile *tiles; + + /* meshes owned by the level, constructed during geometry generation or + * loaded, excluding meshes in tiles scenefiles + */ + struct mesh *meshlist; }; @@ -46,6 +55,9 @@ void destroy_level(struct level *lvl); int load_level(struct level *lvl, const char *fname); int save_level(struct level *lvl, const char *fname); +struct tile *find_level_tile(struct level *lvl, const char *tname); + +int gen_cell_geom(struct level *lvl, struct cell *cell); int gen_level_geom(struct level *lvl); #endif /* LEVEL_H_ */ diff --git a/src/mesh.c b/src/mesh.c index 538f7c9..dbafcbd 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -39,6 +39,34 @@ void clear_mesh(struct mesh *m) m->bbvalid = m->vbovalid = 0; } +int copy_mesh(struct mesh *dest, struct mesh *src) +{ + init_mesh(dest); + + if(src->max_verts && !(dest->varr = malloc(src->max_verts * sizeof *dest->varr))) { + return -1; + } + if(src->max_idx && !(dest->iarr = malloc(src->max_idx * sizeof *dest->iarr))) { + free(dest->varr); + dest->varr = 0; + return -1; + } + + dest->num_verts = src->num_verts; + dest->max_verts = src->max_verts; + if(dest->varr) { + memcpy(dest->varr, src->varr, src->num_verts * sizeof *dest->varr); + } + + dest->num_idx = src->num_idx; + dest->max_idx = src->max_idx; + if(dest->iarr) { + memcpy(dest->iarr, src->iarr, src->num_idx * sizeof *dest->iarr); + } + + return 0; +} + void init_meshgroup(struct meshgroup *mg) { memset(mg, 0, sizeof *mg); @@ -333,3 +361,17 @@ static int update_meshgroup_vbo(struct meshgroup *mg) free(iarr); return 0; } + +void xform_mesh(struct mesh *mesh, float *mat) +{ + int i; + + mesh->vbovalid = 0; + mesh->bbvalid = 0; + + for(i=0; inum_verts; i++) { + cgm_vmul_v3m4(&mesh->varr[i].pos, mat); + cgm_vmul_v3m3(&mesh->varr[i].norm, mat); + cgm_vmul_v3m3(&mesh->varr[i].tang, mat); + } +} diff --git a/src/mesh.h b/src/mesh.h index b0a0a4b..1f94a8e 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -56,6 +56,7 @@ struct mesh { }; struct meshgroup { + /* doesn't own the meshes */ struct mesh **meshes; int num_meshes, max_meshes; @@ -70,6 +71,7 @@ struct meshgroup { void init_mesh(struct mesh *m); void destroy_mesh(struct mesh *m); void clear_mesh(struct mesh *m); +int copy_mesh(struct mesh *dest, struct mesh *src); void init_meshgroup(struct meshgroup *mg); void destroy_meshgroup(struct meshgroup *mg); @@ -86,4 +88,6 @@ int add_meshgroup_mesh(struct meshgroup *mg, struct mesh *m); void draw_mesh(struct mesh *m); void draw_meshgroup(struct meshgroup *mg); +void xform_mesh(struct mesh *mesh, float *mat); + #endif /* MESH_H_ */