unlit cube
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 14 Mar 2021 10:58:38 +0000 (12:58 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 14 Mar 2021 10:58:38 +0000 (12:58 +0200)
src/main.c
src/meshdata.h [new file with mode: 0644]
src/polyfill.c
src/xgl.c
src/xgl.h

index 195f4a6..f95428f 100644 (file)
@@ -25,6 +25,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #include "xgl.h"
 #include "polyfill.h"
 #include "debug.h"
+#include "meshdata.h"
 
 #define MENU_HEIGHT            17
 #define TRACK_HEIGHT   18
@@ -35,25 +36,15 @@ static void handle_keys(void);
 extern struct { unsigned char r, g, b; } bgimg_cmap[];
 extern unsigned char bgimg_pixels[];
 
-struct xvertex varr[] = {
-       {0, -0xd000},
-       {-0x8000, 0x7000},
-       {0x8000, 0x7000}
-};
+static int32_t cam_theta, cam_phi;
 
 int main(void)
 {
        int i;
        unsigned int nframes = 0, backbuf;
-       unsigned long tm0, tm;
        uint16_t *cptr;
        unsigned char r, g, b;
        unsigned char *fbptr[2], *fb;
-       struct pvertex benchv[3] = {
-               {120 << 8, 8 << 8},
-               {75 << 8, 110 << 8},
-               {164 << 8, 80 << 8}
-       };
 
        intr_init();
        reset_msec_timer();
@@ -86,18 +77,11 @@ int main(void)
        xgl_init();
        xgl_viewport(0, MENU_HEIGHT, 240, VP_HEIGHT);
 
-       /* benchmark */
-       polyfill_framebuffer(fbptr[0] + 240 * MENU_HEIGHT, 240, VP_HEIGHT);
-       tm0 = timer_msec;
-       for(i=0; i<2048; i++) {
-               polyfill_flat(benchv, 3, 128 + (i & 0x7f));
-       }
-       tm = timer_msec - tm0;
-       emuprint("benchmark: %lu ms\n", tm);
-
-       /*key_repeat(500, 75, KEY_LEFT | KEY_RIGHT | KEY_DOWN | KEY_UP);*/
+       key_repeat(75, 75, KEY_LEFT | KEY_RIGHT | KEY_DOWN | KEY_UP);
 
        for(;;) {
+               handle_keys();
+
                backbuf = ++nframes & 1;
 
                fb = fbptr[backbuf] + 240 * MENU_HEIGHT;
@@ -105,8 +89,10 @@ int main(void)
                memset(fb, 14, 240 * VP_HEIGHT);
 
                xgl_load_identity();
-               xgl_rotate_z(nframes << 8);
-               xgl_draw(XGL_TRIANGLES, varr, 3);
+               xgl_translate(0, 0, 5 << 16);
+               xgl_rotate_x(cam_phi);
+               xgl_rotate_y(cam_theta);
+               xgl_draw(XGL_QUADS, cube, sizeof cube / sizeof *cube);
 
                wait_vblank();
                present(backbuf);
@@ -120,11 +106,17 @@ static void handle_keys(void)
        update_keyb();
 
        if(KEYPRESS(KEY_UP)) {
+               cam_phi += 0x2000;
+               if(cam_phi > X_HPI) cam_phi = X_HPI;
        }
        if(KEYPRESS(KEY_DOWN)) {
+               cam_phi -= 0x2000;
+               if(cam_phi < -X_HPI) cam_phi = -X_HPI;
        }
        if(KEYPRESS(KEY_LEFT)) {
+               cam_theta += 0x2000;
        }
        if(KEYPRESS(KEY_RIGHT)) {
+               cam_theta -= 0x2000;
        }
 }
diff --git a/src/meshdata.h b/src/meshdata.h
new file mode 100644 (file)
index 0000000..72a3042
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef MESHDATA_H_
+#define MESHDATA_H_
+
+#include "xgl.h"
+
+static struct xvertex cube[] = {
+       /* front */
+       {-0x10000, -0x10000, -0x10000,  0, 0, -0x10000, 128},
+       {0x10000, -0x10000, -0x10000,   0, 0, -0x10000, 128},
+       {0x10000, 0x10000, -0x10000,    0, 0, -0x10000, 128},
+       {-0x10000, 0x10000, -0x10000,   0, 0, -0x10000, 128},
+       /* right */
+       {0x10000, -0x10000, -0x10000,   0x10000, 0, 0,  129},
+       {0x10000, -0x10000, 0x10000,    0x10000, 0, 0,  129},
+       {0x10000, 0x10000, 0x10000,             0x10000, 0, 0,  129},
+       {0x10000, 0x10000, -0x10000,    0x10000, 0, 0,  129},
+       /* back */
+       {0x10000, -0x10000, 0x10000,    0, 0, 0x10000,  130},
+       {-0x10000, -0x10000, 0x10000,   0, 0, 0x10000,  130},
+       {-0x10000, 0x10000, 0x10000,    0, 0, 0x10000,  130},
+       {0x10000, 0x10000, 0x10000,             0, 0, 0x10000,  130},
+       /* left */
+       {-0x10000, -0x10000, 0x10000,   -0x10000, 0, 0, 131},
+       {-0x10000, -0x10000, -0x10000,  -0x10000, 0, 0, 131},
+       {-0x10000, 0x10000, -0x10000,   -0x10000, 0, 0, 131},
+       {-0x10000, 0x10000, 0x10000,    -0x10000, 0, 0, 131},
+       /* top */
+       {-0x10000, 0x10000, -0x10000,   0, 0x10000, 0,  132},
+       {0x10000, 0x10000, -0x10000,    0, 0x10000, 0,  132},
+       {0x10000, 0x10000, 0x10000,             0, 0x10000, 0,  132},
+       {-0x10000, 0x10000, 0x10000,    0, 0x10000, 0,  132},
+       /* bottom */
+       {0x10000, -0x10000, -0x10000,   0, -0x10000, 0, 133},
+       {-0x10000, -0x10000, -0x10000,  0, -0x10000, 0, 133},
+       {-0x10000, -0x10000, 0x10000,   0, -0x10000, 0, 133},
+       {0x10000, -0x10000, 0x10000,    0, -0x10000, 0, 133}
+};
+
+
+#endif /* MESHDATA_H_ */
index 2595429..f2bb599 100644 (file)
@@ -41,6 +41,7 @@ void polyfill_flat(struct pvertex *varr, int vnum, unsigned char col)
        int32_t x, y0, y1, dx, dy, slope, fx, fy;
        short *tab, start, len;
        unsigned char *fbptr;
+       static int dbg;
 
        vlast = varr + vnum - 1;
        top = fbheight;
@@ -76,7 +77,7 @@ void polyfill_flat(struct pvertex *varr, int vnum, unsigned char col)
 
                if(line > 0) tab += line;
 
-               while(line < (y1 >> 8) && line < fbheight) {
+               while(line <= (y1 >> 8) && line < fbheight) {
                        if(line >= 0) {
                                int val = x < 0 ? 0 : x >> 8;
                                *tab++ = val < fbwidth ? val : fbwidth - 1;
@@ -87,7 +88,7 @@ void polyfill_flat(struct pvertex *varr, int vnum, unsigned char col)
        }
 
        fbptr = fb + top * fbwidth;
-       for(i=top; i<bot; i++) {
+       for(i=top; i<=bot; i++) {
                start = scantab[0][i];
                len = scantab[1][i] - start;
 
@@ -96,4 +97,6 @@ void polyfill_flat(struct pvertex *varr, int vnum, unsigned char col)
                }
                fbptr += fbwidth;
        }
+
+       dbg++;
 }
index 376d792..515919e 100644 (file)
--- a/src/xgl.c
+++ b/src/xgl.c
@@ -157,23 +157,31 @@ static void xform(struct xvertex *out, const struct xvertex *in, const int32_t *
        out->z = XMUL(m[2], in->x) + XMUL(m[6], in->y) + XMUL(m[10], in->z) + m[14];
 }
 
+/* d = 1.0 / tan(fov/2) */
+#define PROJ_D 2.0f
+
 void xgl_draw(int prim, const struct xvertex *varr, int vcount)
 {
-       int i;
+       int i, cidx;
        struct xvertex xv[4];
        struct pvertex pv[4];
 
        while(vcount >= prim) {
+               cidx = varr->cidx;
                for(i=0; i<prim; i++) {
                        xform(xv + i, varr, mat[mtop]);
                        varr++;
 
+                       xv[i].x = xv[i].x / (xv[i].z >> 8);     /* assume aspect: ~2 */
+                       xv[i].y = (xv[i].y << 1) / (xv[i].z >> 8);
+                       /* projection result is 24.8 */
+
                        /* viewport */
-                       pv[i].x = ((((xv[i].x + 0x10000) >> 1) * vp[2]) >> 8) + (vp[0] << 8);
-                       pv[i].y = ((((xv[i].y + 0x10000) >> 1) * vp[3]) >> 8) + (vp[1] << 8);
+                       pv[i].x = (((xv[i].x + 0x100) >> 1) * vp[2]) + (vp[0] << 8);
+                       pv[i].y = (((0x100 - xv[i].y) >> 1) * vp[3]) + (vp[1] << 8);
                }
                vcount -= prim;
 
-               polyfill_flat(pv, prim, 0xff);
+               polyfill_flat(pv, prim, cidx);
        }
 }
index 1e531bb..125af16 100644 (file)
--- a/src/xgl.h
+++ b/src/xgl.h
@@ -18,6 +18,11 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.
 #ifndef XGL_H_
 #define XGL_H_
 
+#define X_PI   0x3243f
+#define X_2PI  0x6487f
+#define X_HPI  0x19220
+#define X_QPI  0xc910
+
 enum {
        XGL_LINES               = 2,
        XGL_TRIANGLES   = 3,
@@ -26,6 +31,7 @@ enum {
 
 struct xvertex {
        int32_t x, y, z;
+       int32_t nx, ny, nz;
        unsigned char cidx;
 };