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
#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"
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;
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 */
#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"
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;
g3d_draw_indexed(G3D_TRIANGLES, vbuf, vbuf_size, 0, 0);
}
+#endif
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);
}
}
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)
{
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;
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 */
#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;
}
{
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;
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;
}
+#include <stdio.h>
#include <math.h>
#include <assert.h>
#include "polyclip.h"
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;
}
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;
}
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;
}
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);
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;
}
static struct pimage tex;
+static int use_bsp = 1;
+
#define LOWRES_SCALE 10
static uint16_t *lowres_pixels;
static int lowres_width, lowres_height;
g3d_enable(G3D_LIGHTING);
g3d_enable(G3D_LIGHT0);
- g3d_polygon_mode(G3D_GOURAUD);
+ g3d_polygon_mode(G3D_TEX_GOURAUD);
}
static void update(void)
static void draw(void)
{
float vdir[3];
- float mat[16];
+ const float *mat;
update();
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);
/* ----------------------------------- */
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)
int init(void)
{
glEnable(GL_DEPTH_TEST);
- glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
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);
//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();
}
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;
}
}