tools/img2bin/img2bin
tools/ropesim/ropesim
tools/gltest/test
+RUN
+*.dae
+*.mtl
+*.glb
+*.blend*
+*.ppm
+*.png
#include "demo.h"
#include "util.h"
+#define ENABLE_ZBUFFER
+
#define STACK_SIZE 8
typedef float g3d_matrix[16];
int g3d_init(void)
{
- if(!(st = malloc(sizeof *st))) {
+ if(!(st = calloc(1, sizeof *st))) {
fprintf(stderr, "failed to allocate G3D context\n");
return -1;
}
void g3d_destroy(void)
{
+#ifdef ENABLE_ZBUFFER
+ free(pfill_zbuf);
+#endif
free(st);
}
{
int i;
+#ifdef ENABLE_ZBUFFER
+ free(pfill_zbuf);
+#endif
memset(st, 0, sizeof *st);
st->opt = G3D_CLIP_FRUSTUM;
void g3d_framebuffer(int width, int height, void *pixels)
{
- static int prev_height;
+ static int max_height;
+
+#ifdef ENABLE_ZBUFFER
+ static int max_npixels;
+ int npixels = width * height;
+
+ if(npixels > max_npixels) {
+ free(pfill_zbuf);
+ pfill_zbuf = malloc(npixels * sizeof *pfill_zbuf);
+ max_npixels = npixels;
+ }
+#endif
- if(height > prev_height) {
+ if(height > max_height) {
polyfill_fbheight(height);
+ max_height = height;
}
st->width = width;
/* g3d_enable/g3d_disable bits */
enum {
G3D_CULL_FACE = 0x000001,
- G3D_DEPTH_TEST = 0x000002, /* XXX not implemented */
+ G3D_DEPTH_TEST = 0x000002,
G3D_LIGHTING = 0x000004,
G3D_LIGHT0 = 0x000008,
G3D_LIGHT1 = 0x000010,
/* mode bits: 00-wire 01-flat 10-gouraud 11-reserved
* bit 2: texture
* bit 3-4: blend mode: 00-none 01-alpha 10-additive 11-reserved
+ * bit 5: zbuffering
*/
void (*fillfunc[])(struct pvertex*, int) = {
polyfill_wire,
polyfill_add_tex_wire,
polyfill_add_tex_flat,
polyfill_add_tex_gouraud,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ polyfill_wire,
+ polyfill_flat_zbuf,
+ polyfill_gouraud_zbuf,
+ 0,
+ polyfill_tex_wire,
+ polyfill_tex_flat_zbuf,
+ polyfill_tex_gouraud_zbuf,
+ 0,
+ polyfill_alpha_wire,
+ polyfill_alpha_flat_zbuf,
+ polyfill_alpha_gouraud_zbuf,
+ 0,
+ polyfill_alpha_tex_wire,
+ polyfill_alpha_tex_flat_zbuf,
+ polyfill_alpha_tex_gouraud_zbuf,
+ 0,
+ polyfill_add_wire,
+ polyfill_add_flat_zbuf,
+ polyfill_add_gouraud_zbuf,
+ 0,
+ polyfill_add_tex_wire,
+ polyfill_add_tex_flat_zbuf,
+ polyfill_add_tex_gouraud_zbuf,
0, 0, 0, 0, 0, 0, 0, 0, 0
};
struct pimage pfill_fb, pfill_tex;
+uint16_t *pfill_zbuf;
#define EDGEPAD 8
static struct pvertex *edgebuf, *left, *right;
#undef TEXMAP
#undef BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#undef TEXMAP
#undef BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define TEXMAP
#undef BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define TEXMAP
#undef BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#undef TEXMAP
#define BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#undef TEXMAP
#define BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define TEXMAP
#define BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define TEXMAP
#define BLEND_ALPHA
#undef BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#undef TEXMAP
#undef BLEND_ALPHA
#define BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#undef TEXMAP
#undef BLEND_ALPHA
#define BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define TEXMAP
#undef BLEND_ALPHA
#define BLEND_ADD
+#undef ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define TEXMAP
#undef BLEND_ALPHA
#define BLEND_ADD
+#undef ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+/* ---- zbuffer variants ----- */
+
+#define POLYFILL polyfill_flat_zbuf
+#define SCANEDGE scanedge_flat_zbuf
+#undef GOURAUD
+#undef TEXMAP
+#undef BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_gouraud_zbuf
+#define SCANEDGE scanedge_gouraud_zbuf
+#define GOURAUD
+#undef TEXMAP
+#undef BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_tex_flat_zbuf
+#define SCANEDGE scanedge_tex_flat_zbuf
+#undef GOURAUD
+#define TEXMAP
+#undef BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_tex_gouraud_zbuf
+#define SCANEDGE scanedge_tex_gouraud_zbuf
+#define GOURAUD
+#define TEXMAP
+#undef BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_alpha_flat_zbuf
+#define SCANEDGE scanedge_alpha_flat_zbuf
+#undef GOURAUD
+#undef TEXMAP
+#define BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_alpha_gouraud_zbuf
+#define SCANEDGE scanedge_alpha_gouraud_zbuf
+#define GOURAUD
+#undef TEXMAP
+#define BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_alpha_tex_flat_zbuf
+#define SCANEDGE scanedge_alpha_tex_flat_zbuf
+#undef GOURAUD
+#define TEXMAP
+#define BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_alpha_tex_gouraud_zbuf
+#define SCANEDGE scanedge_alpha_tex_gouraud_zbuf
+#define GOURAUD
+#define TEXMAP
+#define BLEND_ALPHA
+#undef BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_add_flat_zbuf
+#define SCANEDGE scanedge_add_flat_zbuf
+#undef GOURAUD
+#undef TEXMAP
+#undef BLEND_ALPHA
+#define BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_add_gouraud_zbuf
+#define SCANEDGE scanedge_add_gouraud_zbuf
+#define GOURAUD
+#undef TEXMAP
+#undef BLEND_ALPHA
+#define BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_add_tex_flat_zbuf
+#define SCANEDGE scanedge_add_tex_flat_zbuf
+#undef GOURAUD
+#define TEXMAP
+#undef BLEND_ALPHA
+#define BLEND_ADD
+#define ZBUF
+#include "polytmpl.h"
+#undef POLYFILL
+#undef SCANEDGE
+
+#define POLYFILL polyfill_add_tex_gouraud_zbuf
+#define SCANEDGE scanedge_add_tex_gouraud_zbuf
+#define GOURAUD
+#define TEXMAP
+#undef BLEND_ALPHA
+#define BLEND_ADD
+#define ZBUF
#include "polytmpl.h"
#undef POLYFILL
#undef SCANEDGE
#define POLYFILL_TEX_BIT 0x04
#define POLYFILL_ALPHA_BIT 0x08
#define POLYFILL_ADD_BIT 0x10
+#define POLYFILL_ZBUF_BIT 0x20
enum {
POLYFILL_WIRE = 0,
POLYFILL_ADD_TEX_WIRE = 20,
POLYFILL_ADD_TEX_FLAT,
- POLYFILL_ADD_TEX_GOURAUD
+ POLYFILL_ADD_TEX_GOURAUD,
+
+
+ POLYFILL_WIRE_ZBUF = 32,
+ POLYFILL_FLAT_ZBUF,
+ POLYFILL_GOURAUD_ZBUF,
+
+ POLYFILL_TEX_WIRE_ZBUF = 36,
+ POLYFILL_TEX_FLAT_ZBUF,
+ POLYFILL_TEX_GOURAUD_ZBUF,
+
+ POLYFILL_ALPHA_WIRE_ZBUF = 40,
+ POLYFILL_ALPHA_FLAT_ZBUF,
+ POLYFILL_ALPHA_GOURAUD_ZBUF,
+
+ POLYFILL_ALPHA_TEX_WIRE_ZBUF = 44,
+ POLYFILL_ALPHA_TEX_FLAT_ZBUF,
+ POLYFILL_ALPHA_TEX_GOURAUD_ZBUF,
+
+ POLYFILL_ADD_WIRE_ZBUF = 48,
+ POLYFILL_ADD_FLAT_ZBUF,
+ POLYFILL_ADD_GOURAUD_ZBUF,
+
+ POLYFILL_ADD_TEX_WIRE_ZBUF = 52,
+ POLYFILL_ADD_TEX_FLAT_ZBUF,
+ POLYFILL_ADD_TEX_GOURAUD_ZBUF
};
/* projected vertices for the rasterizer */
int32_t x, y; /* 24.8 fixed point */
int32_t u, v; /* 16.16 fixed point */
int32_t r, g, b, a; /* int 0-255 */
+ uint16_t z; /* 0-65535 */
};
struct pimage {
extern struct pimage pfill_fb;
extern struct pimage pfill_tex;
+extern uint16_t *pfill_zbuf;
void polyfill_fbheight(int height);
void polyfill_add_tex_wire(struct pvertex *verts, int nverts);
void polyfill_add_tex_flat(struct pvertex *verts, int nverts);
void polyfill_add_tex_gouraud(struct pvertex *verts, int nverts);
+void polyfill_flat_zbuf(struct pvertex *verts, int nverts);
+void polyfill_gouraud_zbuf(struct pvertex *verts, int nverts);
+void polyfill_tex_flat_zbuf(struct pvertex *verts, int nverts);
+void polyfill_tex_gouraud_zbuf(struct pvertex *verts, int nverts);
+void polyfill_alpha_flat_zbuf(struct pvertex *verts, int nverts);
+void polyfill_alpha_gouraud_zbuf(struct pvertex *verts, int nverts);
+void polyfill_alpha_tex_flat_zbuf(struct pvertex *verts, int nverts);
+void polyfill_alpha_tex_gouraud_zbuf(struct pvertex *verts, int nverts);
+void polyfill_add_flat_zbuf(struct pvertex *verts, int nverts);
+void polyfill_add_gouraud_zbuf(struct pvertex *verts, int nverts);
+void polyfill_add_tex_flat_zbuf(struct pvertex *verts, int nverts);
+void polyfill_add_tex_gouraud_zbuf(struct pvertex *verts, int nverts);
#endif /* POLYFILL_H_ */
#ifdef TEXMAP
int32_t u, v, du, dv, uslope, vslope;
#endif
+#ifdef ZBUF
+ int z, dz, zslope;
+#endif
int32_t start_idx, end_idx;
if(v0->y > v1->y) {
uslope = (du << 8) / dy;
vslope = (dv << 8) / dy;
#endif
+#ifdef ZBUF
+ z = v0->z;
+ dz = v1->z - v0->z;
+ zslope = (dz << 8) / dy;
+#endif
start_idx = v0->y >> 8;
end_idx = v1->y >> 8;
x += slope;
#ifdef GOURAUD
/* we'll store the color in the edge tables with COLOR_SHIFT extra bits of precision */
- CHECKEDGE(i);
edge[i].r = r;
edge[i].g = g;
edge[i].b = b;
g += gslope;
b += bslope;
#ifdef BLEND_ALPHA
- CHECKEDGE(i);
edge[i].a = a;
a += aslope;
#endif
#endif /* GOURAUD */
#ifdef TEXMAP
- CHECKEDGE(i);
edge[i].u = u;
edge[i].v = v;
u += uslope;
v += vslope;
#endif
+#ifdef ZBUF
+ edge[i].z = z;
+ z += zslope;
+#endif
}
return (uint32_t)start_idx | ((uint32_t)(end_idx - 1) << 16);
int topidx = 0, botidx = 0, sltop = pfill_fb.height, slbot = 0;
g3d_pixel color;
/* the following variables are used for interpolating horizontally accros scanlines */
-#if defined(GOURAUD) || defined(TEXMAP)
+#if defined(GOURAUD) || defined(TEXMAP) || defined(ZBUF)
int mid;
int32_t dx, tmp;
#else
#ifdef TEXMAP
int32_t u, v, du, dv, uslope, vslope;
#endif
+#ifdef ZBUF
+ int z, dz, zslope;
+#endif
for(i=1; i<nverts; i++) {
if(pv[i].y < pv[topidx].y) topidx = i;
right[idx].u = pv[i1].u;
right[idx].v = pv[i1].v;
#endif
+#ifdef ZBUF
+ left[idx].z = pv[i0].z;
+ right[idx].z = pv[i1].z;
+#endif
CHECKEDGE(idx);
if(idx > slbot) slbot = idx;
if(idx < sltop) sltop = idx;
uslope = (du << 8) / dx;
vslope = (dv << 8) / dx;
#endif
+#ifdef ZBUF
+ dz = right[mid].z - left[mid].z;
+ zslope = (dz << 8) / dx;
+#endif
#endif /* !defined(HIGH_QUALITY) */
/* for each scanline ... */
for(i=sltop; i<=slbot; i++) {
g3d_pixel *pixptr;
int32_t x;
+#ifdef ZBUF
+ uint16_t *zptr;
+#endif
CHECKEDGE(i);
x = left[i].x;
u = left[i].u;
v = left[i].v;
#endif
+#ifdef ZBUF
+ z = left[i].z;
+ zptr = pfill_zbuf + i * pfill_fb.width + (x >> 8);
+#endif
CHECKEDGE(i);
-#if defined(HIGH_QUALITY) && (defined(GOURAUD) || defined(TEXMAP))
+#if defined(HIGH_QUALITY) && (defined(GOURAUD) || defined(TEXMAP) || defined(ZBUF))
if(!(dx = right[i].x - left[i].x)) dx = 256;
CHECKEDGE(i);
uslope = (du << 8) / dx;
vslope = (dv << 8) / dx;
#endif
+#ifdef ZBUF
+ dz = right[i].z - left[i].z;
+ zslope = (dz << 8) / dx;
+#endif
#endif /* HIGH_QUALITY */
CHECKEDGE(i);
#ifdef BLEND_ALPHA
int alpha, inv_alpha;
#endif
+
+#ifdef ZBUF
+ int cz = z;
+ z += zslope;
+
+ if(z <= *zptr) {
+ *zptr = z;
+ } else {
+#ifdef GOURAUD
+ r += rslope;
+ g += gslope;
+ b += bslope;
+#ifdef BLEND_ALPHA
+ a += aslope;
+#endif
+#endif
+#ifdef TEXMAP
+ u += uslope;
+ v += vslope;
+#endif
+ goto skip_pixel;
+ }
+ zptr++;
+#endif
+
#ifdef GOURAUD
/* we upped the color precision to while interpolating the
* edges, now drop the extra bits before packing
color = G3D_PACK_RGB(cr, cg, cb);
#endif
+#ifdef ZBUF
+skip_pixel:
+#endif
#ifdef DEBUG_OVERDRAW
*pixptr++ += DEBUG_OVERDRAW;
#else