From: John Tsiombikas Date: Mon, 19 Feb 2018 08:01:12 +0000 (+0200) Subject: major bsp bugs fixed X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=commitdiff_plain;h=a5c65ceb155188c8acee31a475f8db9f5b58f4b6 major bsp bugs fixed --- diff --git a/Makefile b/Makefile index 9845ce2..9f9a98e 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,10 @@ demoobj = main.obj demo.obj screen.obj cfgopt.obj music.obj gfxutil.obj & -3dgfx.obj polyfill.obj polyclip.obj metasurf.obj dynarr.obj mesh.obj +3dgfx.obj polyfill.obj polyclip.obj metasurf.obj mesh.obj meshload.obj & +bsptree.obj scrobj = tunnel.obj fract.obj grise.obj polytest.obj plasma.obj bump.obj & thunder.obj metaball.obj greets.obj infcubes.obj sysobj = gfx.obj vbe.obj watdpmi.obj timer.obj keyb.obj mouse.obj sball.obj & -logger.obj tinyfps.obj util.obj +logger.obj tinyfps.obj util.obj dynarr.obj rbtree.obj obj = $(baseobj) $(demoobj) $(sysobj) $(scrobj) bin = demo.exe diff --git a/src/3dgfx.c b/src/3dgfx.c index a4af73a..044ab66 100644 --- a/src/3dgfx.c +++ b/src/3dgfx.c @@ -3,6 +3,11 @@ #include #include #include +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__) +#include +#else +#include +#endif #include "3dgfx.h" #include "gfxutil.h" #include "polyfill.h" @@ -398,10 +403,9 @@ void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size) void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, const uint16_t *iarr, int iarr_size) { - int i, j, nfaces; + int i, j, vnum, nfaces; struct pvertex pv[16]; struct g3d_vertex v[16]; - int vnum = prim; /* primitive vertex counts correspond to enum values */ int mvtop = st->mtop[G3D_MODELVIEW]; int ptop = st->mtop[G3D_PROJECTION]; struct g3d_vertex *tmpv; @@ -412,7 +416,7 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, memcpy(st->norm_mat, st->mat[G3D_MODELVIEW][mvtop], 16 * sizeof(float)); st->norm_mat[12] = st->norm_mat[13] = st->norm_mat[14] = 0.0f; - nfaces = (iarr ? iarr_size : varr_size) / vnum; + nfaces = (iarr ? iarr_size : varr_size) / prim; for(j=0; j #include #include +#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__) +#include +#else +#include +#endif #include "bsptree.h" #include "dynarr.h" #include "inttypes.h" @@ -239,7 +244,10 @@ static struct bspnode *add_poly_tree(struct bspnode *n, struct g3d_vertex *v, in return n; } -void debug_draw_poly(struct g3d_vertex *varr, int vcount) +#undef DRAW_NGONS + +#ifndef DRAW_NGONS +static void debug_draw_poly(struct g3d_vertex *varr, int vcount) { int i, nfaces = vcount - 2; int vbuf_size = nfaces * 3; @@ -254,6 +262,7 @@ void debug_draw_poly(struct g3d_vertex *varr, int vcount) g3d_draw_indexed(G3D_TRIANGLES, vbuf, vbuf_size, 0, 0); } +#endif static void draw_bsp_tree(struct bspnode *n, const vec3_t *vdir) { @@ -264,13 +273,19 @@ static void draw_bsp_tree(struct bspnode *n, const vec3_t *vdir) dot = vdir->x * n->plane.nx + vdir->y * n->plane.ny + vdir->z * n->plane.nz; if(dot >= 0.0f) { draw_bsp_tree(n->front, vdir); - //g3d_draw_indexed(n->vcount, n->verts, n->vcount, 0, 0); +#ifdef DRAW_NGONS + g3d_draw_indexed(n->vcount, n->verts, n->vcount, 0, 0); +#else debug_draw_poly(n->verts, n->vcount); +#endif draw_bsp_tree(n->back, vdir); } else { draw_bsp_tree(n->back, vdir); - //g3d_draw_indexed(n->vcount, n->verts, n->vcount, 0, 0); +#ifdef DRAW_NGONS + g3d_draw_indexed(n->vcount, n->verts, n->vcount, 0, 0); +#else debug_draw_poly(n->verts, n->vcount); +#endif draw_bsp_tree(n->front, vdir); } } diff --git a/src/demo.c b/src/demo.c index b2a03e0..45b889a 100644 --- a/src/demo.c +++ b/src/demo.c @@ -24,6 +24,7 @@ unsigned int mouse_bmask; float sball_matrix[] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; static unsigned long nframes; +static int console_active; int demo_init(int argc, char **argv) { @@ -126,23 +127,44 @@ void demo_keyboard(int key, int press) debug_break(); break; + case '`': + console_active = !console_active; + if(console_active) { + printf("> "); + fflush(stdout); + } else { + putchar('\n'); + } + break; + + case '\b': + if(console_active && wr != rd) { + printf("\b \b"); + fflush(stdout); + wr = (wr + CBUF_SIZE - 1) & CBUF_MASK; + } + break; + case '\n': case '\r': - dptr = inp; - while(rd != wr) { - *dptr++ = cbuf[rd]; - rd = (rd + 1) & CBUF_MASK; - } - *dptr = 0; - if(inp[0]) { - printf("trying to match: %s\n", inp); - nscr = scr_num_screens(); - for(i=0; iname, inp)) { - change_screen(i); - break; + if(console_active) { + dptr = inp; + while(rd != wr) { + *dptr++ = cbuf[rd]; + rd = (rd + 1) & CBUF_MASK; + } + *dptr = 0; + if(inp[0]) { + printf("\ntrying to match: %s\n", inp); + nscr = scr_num_screens(); + for(i=0; iname, inp)) { + change_screen(i); + break; + } } } + console_active = 0; } break; @@ -153,7 +175,10 @@ void demo_keyboard(int key, int press) change_screen(9); } - if(key < 256 && isprint(key)) { + if(console_active && key < 256 && isprint(key)) { + putchar(key); + fflush(stdout); + cbuf[wr] = key; wr = (wr + 1) & CBUF_MASK; if(wr == rd) { /* overflow */ diff --git a/src/mesh.c b/src/mesh.c index af5936e..40b1bb1 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -6,48 +6,46 @@ #include "3dgfx.h" static struct { + int prim; struct g3d_vertex *varr; const float *xform; } zsort_cls; static int zsort_cmp(const void *aptr, const void *bptr) { + int i; + float za = 0.0f; + float zb = 0.0f; const float *m = zsort_cls.xform; - const struct g3d_vertex *va = (const struct g3d_vertex*)aptr; const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr; - float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; - float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - - ++va; - ++vb; - - za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; - zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - + for(i=0; ix + m[6] * va->y + m[10] * va->z + m[14]; + zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; + ++va; + ++vb; + } return za - zb; } static int zsort_indexed_cmp(const void *aptr, const void *bptr) { + int i; + float za = 0.0f; + float zb = 0.0f; const uint16_t *a = (const uint16_t*)aptr; const uint16_t *b = (const uint16_t*)bptr; const float *m = zsort_cls.xform; - const struct g3d_vertex *va = zsort_cls.varr + a[0]; - const struct g3d_vertex *vb = zsort_cls.varr + b[0]; - - float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; - float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; - - va = zsort_cls.varr + a[2]; - vb = zsort_cls.varr + b[2]; - - za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; - zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; + for(i=0; ix + m[6] * va->y + m[10] * va->z + m[14]; + zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; + } return za - zb; } @@ -56,6 +54,7 @@ void zsort_mesh(struct g3d_mesh *m) { zsort_cls.varr = m->varr; zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0); + zsort_cls.prim = m->prim; if(m->iarr) { int nfaces = m->icount / m->prim; diff --git a/src/music.c b/src/music.c index 8af6154..f4327f5 100644 --- a/src/music.c +++ b/src/music.c @@ -68,7 +68,7 @@ int music_open(const char *fname) return -1; } #else - if(!(mod = ML_LoadFN((const signed char*)fname))) { + if(!(mod = ML_LoadFN((char*)fname))) { fprintf(stderr, "failed to load music: %s: %s\n", fname, myerr); return -1; } diff --git a/src/polyclip.c b/src/polyclip.c index d02f645..67e1c83 100644 --- a/src/polyclip.c +++ b/src/polyclip.c @@ -1,3 +1,4 @@ +#include #include #include #include "polyclip.h" @@ -20,12 +21,14 @@ static int inside_frustum_plane(const struct g3d_vertex *v, int fplane); int clip_poly(struct g3d_vertex *vout, int *voutnum, const struct g3d_vertex *vin, int vnum, struct cplane *plane) { - int i; + int i, nextidx, res; int edges_clipped = 0; int out_vnum = 0; for(i=0; i= vnum) nextidx = 0; + res = clip_edge(vout, &out_vnum, vin + i, vin + nextidx, plane); if(res == 0) { ++edges_clipped; } @@ -44,7 +47,7 @@ int clip_poly(struct g3d_vertex *vout, int *voutnum, int clip_frustum(struct g3d_vertex *vout, int *voutnum, const struct g3d_vertex *vin, int vnum, int fplane) { - int i; + int i, nextidx, res; int edges_clipped = 0; int out_vnum = 0; @@ -54,7 +57,9 @@ int clip_frustum(struct g3d_vertex *vout, int *voutnum, } for(i=0; i= vnum) nextidx = 0; + res = clip_edge_frustum(vout, &out_vnum, vin + i, vin + nextidx, fplane); if(res == 0) { ++edges_clipped; } @@ -138,9 +143,9 @@ static int clip_edge(struct g3d_vertex *poly, int *vnumptr, intersect(&ray, plane, &t); - vptr->x = ray.origin[0] + ray.dir[0] + t; - vptr->y = ray.origin[1] + ray.dir[1] + t; - vptr->z = ray.origin[2] + ray.dir[2] + t; + vptr->x = ray.origin[0] + ray.dir[0] * t; + vptr->y = ray.origin[1] + ray.dir[1] * t; + vptr->z = ray.origin[2] + ray.dir[2] * t; vptr->w = 1.0f; LERP_VATTR(vptr, v0, v1, t); @@ -172,7 +177,7 @@ static int intersect(const struct ray *ray, const struct cplane *plane, float *t float orig_pt_dir[3]; float ndotdir = plane->nx * ray->dir[0] + plane->ny * ray->dir[1] + plane->nz * ray->dir[2]; - if(fabs(ndotdir) < 1e-4) { + if(fabs(ndotdir) < 1e-6) { *t = 0.0f; return 0; } diff --git a/src/polytest.c b/src/polytest.c index 937c9c2..2558389 100644 --- a/src/polytest.c +++ b/src/polytest.c @@ -33,6 +33,8 @@ static struct bsptree torus_bsp; static struct pimage tex; +static int use_bsp = 1; + #define LOWRES_SCALE 10 static uint16_t *lowres_pixels; static int lowres_width, lowres_height; @@ -91,7 +93,7 @@ static void start(long trans_time) g3d_enable(G3D_LIGHTING); g3d_enable(G3D_LIGHT0); - g3d_polygon_mode(G3D_GOURAUD); + g3d_polygon_mode(G3D_TEX_GOURAUD); } static void update(void) @@ -103,7 +105,7 @@ static void update(void) static void draw(void) { float vdir[3]; - float mat[16]; + const float *mat; update(); @@ -119,23 +121,24 @@ static void draw(void) g3d_rotate(cam_theta, 0, 1, 0); } - /* calc world-space view direction */ - g3d_get_matrix(G3D_MODELVIEW, mat); - /* transform (0, 0, -1) with transpose(mat3x3) */ - vdir[0] = -mat[2]; - vdir[1] = -mat[6]; - vdir[2] = -mat[10]; - - g3d_light_pos(0, -10, 10, 20); - zsort_mesh(&torus); - g3d_mtl_diffuse(0.4, 0.7, 1.0); g3d_set_texture(tex.width, tex.height, tex.pixels); - /*draw_mesh(&torus);*/ - draw_bsp(&torus_bsp, vdir[0], vdir[1], vdir[2]); + if(use_bsp) { + /* calc world-space view direction */ + mat = g3d_get_matrix(G3D_MODELVIEW, 0); + /* transform (0, 0, -1) with transpose(mat3x3) */ + vdir[0] = -mat[2]; + vdir[1] = -mat[6]; + vdir[2] = -mat[10]; + + draw_bsp(&torus_bsp, vdir[0], vdir[1], vdir[2]); + } else { + zsort_mesh(&torus); + draw_mesh(&torus); + } /*draw_mesh(&cube);*/ swap_buffers(fb_pixels); diff --git a/tools/gltest/src/main.c b/tools/gltest/src/main.c index 82042ca..3e1ea8f 100644 --- a/tools/gltest/src/main.c +++ b/tools/gltest/src/main.c @@ -19,6 +19,9 @@ static int bnstate[8]; /* ----------------------------------- */ static struct g3d_mesh torus; static struct bsptree torus_bsp; + +static int rebuild_bsp; +int debug_max_clip_level = 0; /* ----------------------------------- */ int main(int argc, char **argv) @@ -46,7 +49,6 @@ int main(int argc, char **argv) int init(void) { glEnable(GL_DEPTH_TEST); - glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); @@ -68,11 +70,64 @@ void cleanup(void) destroy_bsp(&torus_bsp); } +static void draw_plane(struct bspnode *n) +{ + int i; + float cx = 0, cy = 0, cz = 0; + + for(i=0; ivcount; i++) { + cx += n->verts[i].x; + cy += n->verts[i].y; + cz += n->verts[i].z; + } + cx /= n->vcount; + cy /= n->vcount; + cz /= n->vcount; + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_CULL_FACE); + glDisable(GL_LIGHTING); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glPushMatrix(); + glTranslatef(cx, cy, cz); + glScalef(10, 10, 10); + glTranslatef(-cx, -cy, -cz); + + glBegin(GL_POLYGON); + glColor4f(0.2, 0.3, 1.0, 0.5); + for(i=0; ivcount; i++) { + glVertex3f(n->verts[i].x, n->verts[i].y, n->verts[i].z); + } + glEnd(); + + glBegin(GL_LINE_LOOP); + glColor4f(0.2, 0.3, 1.0, 0.85); + for(i=0; ivcount; i++) { + glVertex3f(n->verts[i].x, n->verts[i].y, n->verts[i].z); + } + glEnd(); + + glPopMatrix(); + glPopAttrib(); +} + void display(void) { float vdir[3]; float mat[16]; + if(rebuild_bsp) { + destroy_bsp(&torus_bsp); + init_bsp(&torus_bsp); + if(bsp_add_mesh(&torus_bsp, &torus) == -1) { + fprintf(stderr, "failed to construct torus BSP tree\n"); + abort(); + } + rebuild_bsp = 0; + } + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); @@ -89,6 +144,8 @@ void display(void) //g3d_draw_indexed(torus.prim, torus.varr, torus.vcount, torus.iarr, torus.icount); draw_bsp(&torus_bsp, vdir[0], vdir[1], vdir[2]); + draw_plane(torus_bsp.root); + glutSwapBuffers(); } @@ -105,6 +162,23 @@ void keydown(unsigned char key, int x, int y) switch(key) { case 27: exit(0); + + case '=': + debug_max_clip_level++; + printf("max_clip_level: %d\n", debug_max_clip_level); + rebuild_bsp = 1; + glutPostRedisplay(); + break; + + case '-': + if(--debug_max_clip_level < 0) { + debug_max_clip_level = 0; + } else { + printf("max_clip_level: %d\n", debug_max_clip_level); + rebuild_bsp = 1; + glutPostRedisplay(); + } + break; } }