- added blur in gfxutil
[dosdemo] / src / 3dgfx.c
index 46cc9ab..c32e6c2 100644 (file)
@@ -4,9 +4,11 @@
 #include <math.h>
 #include <assert.h>
 #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
@@ -42,7 +44,7 @@ struct g3d_state {
        struct material mtl;
 
        int width, height;
-       void *pixels;
+       uint16_t *pixels;
 
        int vport[4];
 };
@@ -98,9 +100,7 @@ void g3d_framebuffer(int width, int height, void *pixels)
        pfill_fb.width = width;
        pfill_fb.height = height;
 
-       st->vport[0] = st->vport[1] = 0;
-       st->vport[2] = width;
-       st->vport[3] = height;
+       g3d_viewport(0, 0, width, height);
 }
 
 void g3d_viewport(int x, int y, int w, int h)
@@ -404,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; j<nfaces; j++) {
+               vnum = prim;    /* reset vnum for each iteration */
 
                for(i=0; i<vnum; i++) {
                        v[i] = iarr ? varr[*iarr++] : *varr++;
@@ -419,15 +420,18 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size,
 
                /* clipping */
                for(i=0; i<6; i++) {
-                       struct g3d_vertex orig[16];
-                       memcpy(orig, v, vnum * sizeof *v);
+                       struct g3d_vertex tmpv[16];
+                       memcpy(tmpv, v, vnum * sizeof *v);
 
-                       if(clip_frustum(v, &vnum, orig, vnum, i) < 0) {
+                       if(clip_frustum(v, &vnum, tmpv, vnum, i) < 0) {
                                /* polygon completely outside of view volume. discard */
-                               return;
+                               vnum = 0;
+                               break;
                        }
                }
 
+               if(!vnum) continue;
+
                for(i=0; i<vnum; i++) {
                        if(v[i].w != 0.0f) {
                                v[i].x /= v[i].w;
@@ -449,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 */
@@ -465,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);
+               }
        }
 }