major bsp bugs fixed
authorJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 19 Feb 2018 08:01:12 +0000 (10:01 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Mon, 19 Feb 2018 08:01:12 +0000 (10:01 +0200)
Makefile
src/3dgfx.c
src/bsptree.c
src/demo.c
src/mesh.c
src/music.c
src/polyclip.c
src/polytest.c
tools/gltest/src/main.c

index 9845ce2..9f9a98e 100644 (file)
--- 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
 
index a4af73a..044ab66 100644 (file)
@@ -3,6 +3,11 @@
 #include <string.h>
 #include <math.h>
 #include <assert.h>
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__)
+#include <malloc.h>
+#else
+#include <alloca.h>
+#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<nfaces; j++) {
                vnum = prim;    /* reset vnum for each iteration */
index 334e530..89f6c75 100644 (file)
@@ -2,6 +2,11 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined(__DJGPP__)
+#include <malloc.h>
+#else
+#include <alloca.h>
+#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);
        }
 }
index b2a03e0..45b889a 100644 (file)
@@ -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; i<nscr; i++) {
-                                       if(strstr(scr_screen(i)->name, 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; i<nscr; i++) {
+                                               if(strstr(scr_screen(i)->name, 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 */
index af5936e..40b1bb1 100644 (file)
@@ -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; i<zsort_cls.prim; i++) {
+               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];
+               ++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; i<zsort_cls.prim; i++) {
+               const struct g3d_vertex *va = zsort_cls.varr + a[i];
+               const struct g3d_vertex *vb = zsort_cls.varr + b[i];
 
+               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];
+       }
        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;
index 8af6154..f4327f5 100644 (file)
@@ -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;
        }
index d02f645..67e1c83 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <math.h>
 #include <assert.h>
 #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; i++) {
-               int res = clip_edge(vout, &out_vnum, vin + i, vin + (i + 1) % vnum, plane);
+               nextidx = i + 1;
+               if(nextidx >= 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; i++) {
-               int res = clip_edge_frustum(vout, &out_vnum, vin + i, vin + (i + 1) % vnum, fplane);
+               nextidx = i + 1;
+               if(nextidx >= 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;
        }
index 937c9c2..2558389 100644 (file)
@@ -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);
index 82042ca..3e1ea8f 100644 (file)
@@ -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; i<n->vcount; 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; i<n->vcount; 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; i<n->vcount; 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;
        }
 }