X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2F3dgfx.c;h=a90da7adfe042af9d3251c1604b4722bc4a4579c;hb=0165ec15f868a16a70b56ada2d42db0cb69ea193;hp=30721c8701c1f11bc7001d5855e8a7d9a74db49b;hpb=25669bf7362645d1c0fee9d7cb07f4a6b0b34903;p=dosdemo diff --git a/src/3dgfx.c b/src/3dgfx.c index 30721c8..a90da7a 100644 --- a/src/3dgfx.c +++ b/src/3dgfx.c @@ -5,7 +5,9 @@ #include #include "3dgfx.h" #include "polyfill.h" +#include "polyclip.h" #include "inttypes.h" +#include "util.h" #define STACK_SIZE 8 typedef float g3d_matrix[16]; @@ -41,6 +43,8 @@ struct g3d_state { int width, height; void *pixels; + + int vport[4]; }; static void xform4_vec3(const float *mat, float *vec); @@ -90,9 +94,19 @@ void g3d_framebuffer(int width, int height, void *pixels) st->height = height; st->pixels = pixels; - pimg_fb.pixels = pixels; - pimg_fb.width = width; - pimg_fb.height = height; + 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) @@ -339,6 +353,33 @@ void g3d_mtl_shininess(float shin) st->mtl.shin = shin; } +static INLINE int calc_shift(unsigned int x) +{ + int res = -1; + while(x) { + x >>= 1; + ++res; + } + return res; +} + +static INLINE int calc_mask(unsigned int x) +{ + return x - 1; +} + +void g3d_set_texture(int xsz, int ysz, void *pixels) +{ + pfill_tex.pixels = pixels; + pfill_tex.width = xsz; + pfill_tex.height = ysz; + + pfill_tex.xshift = calc_shift(xsz); + pfill_tex.yshift = calc_shift(ysz); + pfill_tex.xmask = calc_mask(xsz); + pfill_tex.ymask = calc_mask(ysz); +} + void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size) { g3d_draw_indexed(prim, varr, varr_size, 0, 0); @@ -348,8 +389,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]; @@ -361,6 +402,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 = (int32_t)(v[i].x * 256.0f); - pv[i].y = (int32_t)(v[i].y * 256.0f); + pv[i].x = cround64(v[i].x * 256.0f); + pv[i].y = cround64(v[i].y * 256.0f); /* convert tex coords to 16.16 fixed point */ - pv[i].u = (int32_t)(v[i].u * 65536.0f); - pv[i].v = (int32_t)(v[i].v * 65536.0f); + pv[i].u = cround64(v[i].u * 65536.0f); + pv[i].v = cround64(v[i].v * 65536.0f); /* pass the color through as is */ pv[i].r = v[i].r; pv[i].g = v[i].g; @@ -483,9 +537,9 @@ static void shade(struct g3d_vertex *v) color[2] += st->mtl.kd[2] * st->lt[i].b * ndotl; } - r = color[0] * 255.0; - g = color[1] * 255.0; - b = color[2] * 255.0; + r = cround64(color[0] * 255.0); + g = cround64(color[1] * 255.0); + b = cround64(color[2] * 255.0); v->r = r > 255 ? 255 : r; v->g = g > 255 ? 255 : g;