X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2F3dgfx.c;h=c32e6c2fe4c5436e7275540aa9e4cd9e4129417f;hb=a563d2f0efaa980af0f0b39cdf1c9115fed99d00;hp=47b3830ee38fcc190b04a67fbd6c1481e6123b93;hpb=07ce18b114e1e01b2a85a04079128f3eb754de1d;p=dosdemo diff --git a/src/3dgfx.c b/src/3dgfx.c index 47b3830..c32e6c2 100644 --- a/src/3dgfx.c +++ b/src/3dgfx.c @@ -4,8 +4,11 @@ #include #include #include "3dgfx.h" +#include "gfxutil.h" #include "polyfill.h" +#include "polyclip.h" #include "inttypes.h" +#include "demo.h" #include "util.h" #define STACK_SIZE 8 @@ -41,7 +44,9 @@ struct g3d_state { struct material mtl; int width, height; - void *pixels; + uint16_t *pixels; + + int vport[4]; }; static void xform4_vec3(const float *mat, float *vec); @@ -94,6 +99,16 @@ void g3d_framebuffer(int width, int height, void *pixels) pfill_fb.pixels = pixels; pfill_fb.width = width; pfill_fb.height = height; + + g3d_viewport(0, 0, width, height); +} + +void g3d_viewport(int x, int y, int w, int h) +{ + st->vport[0] = x; + st->vport[1] = y; + st->vport[2] = w; + st->vport[3] = h; } void g3d_enable(unsigned int opt) @@ -376,8 +391,8 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, const int16_t *iarr, int iarr_size) { int i, j, nfaces; - struct pvertex pv[4]; - struct g3d_vertex v[4]; + 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]; @@ -389,6 +404,7 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, nfaces = (iarr ? iarr_size : varr_size) / vnum; for(j=0; jmat[G3D_PROJECTION][ptop], &v[i].x); } - /* TODO clipping */ + /* clipping */ + for(i=0; i<6; i++) { + struct g3d_vertex tmpv[16]; + memcpy(tmpv, v, vnum * sizeof *v); + + if(clip_frustum(v, &vnum, tmpv, vnum, i) < 0) { + /* polygon completely outside of view volume. discard */ + vnum = 0; + break; + } + } + + if(!vnum) continue; for(i=0; iwidth; - v[i].y = (0.5f - v[i].y * 0.5f) * (float)st->height; + v[i].x = (v[i].x * 0.5f + 0.5f) * (float)st->vport[2] + st->vport[0]; + v[i].y = (0.5f - v[i].y * 0.5f) * (float)st->vport[3] + st->vport[1]; /* convert pos to 24.8 fixed point */ pv[i].x = cround64(v[i].x * 256.0f); @@ -425,6 +453,7 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, pv[i].r = v[i].r; pv[i].g = v[i].g; pv[i].b = v[i].b; + pv[i].a = v[i].a; } /* backface culling */ @@ -441,7 +470,29 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, } } - polyfill(st->fill_mode, pv, vnum); + switch(vnum) { + case 1: + if(st->opt & G3D_BLEND) { + int r, g, b; + int inv_alpha = 255 - pv[0].a; + uint16_t *dest = st->pixels + (pv[0].y >> 8) * st->width + (pv[0].x >> 8); + r = ((int)pv[0].r * pv[0].a + UNPACK_R16(*dest) * inv_alpha) >> 8; + g = ((int)pv[0].g * pv[0].a + UNPACK_G16(*dest) * inv_alpha) >> 8; + b = ((int)pv[0].b * pv[0].a + UNPACK_B16(*dest) * inv_alpha) >> 8; + *dest++ = PACK_RGB16(r, g, b); + } else { + uint16_t *dest = st->pixels + (pv[0].y >> 8) * st->width + (pv[0].x >> 8); + *dest = PACK_RGB16(pv[0].r, pv[0].g, pv[0].b); + } + break; + + case 2: + /* TODO: draw line */ + break; + + default: + polyfill(st->fill_mode, pv, vnum); + } } }