cube

Dependencies:   mbed

Fork of manworm_tv_gpu by Jared DiCarlo

Revision:
13:9cf720873bf6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/raster.cpp	Fri May 04 19:18:18 2018 +0000
@@ -0,0 +1,187 @@
+#include "mbed.h"
+#include "main.h"
+
+int8_t zbuf[XL][YL];
+
+void clear_zbuf() {
+    for (int i = 0; i < XL; i++) {
+        for (int j = 0; j < YL; j++) {
+            zbuf[i][j] = 127;
+        }
+    }
+}
+
+void hline(int16_t xmin, int16_t xmax, int16_t y, uint8_t color, int8_t zmin, int8_t zmax) {
+    if (xmin < 0) xmin = 0;
+    if (xmin >= XL) xmin = XL - 1;
+    if (xmax < 0) xmax = 0;
+    if (xmax >= XL) xmax = XL - 1;
+    if (y < 0) y = 0;
+    if (y >= YL) y = YL - 1;
+
+    int tmp;
+    if (xmax < xmin) {
+        tmp = xmin;
+        xmin = xmax;
+        xmax = tmp;
+        tmp = zmin;
+        zmin = zmax;
+        zmax = tmp;
+    }
+
+    if (xmin == xmax) { zbuf[xmin][y] = zmin; return; }
+    int32_t u = ((zmax - zmin) << 16) / (xmax - xmin);
+    int32_t z = zmin << 16;
+    
+    for (int16_t x = xmin; x <= xmax; x++) {
+        z += u;
+        int8_t z8 = (int8_t)(z >> 16);
+        if (z8 < zbuf[x][y]) {
+            zbuf[x][y] = z8;
+            set_pixel(x, y, color);
+        }
+    }
+}
+
+//y2 == y3
+void bottom_triangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, uint8_t color, int8_t z1, int8_t z2, int8_t z3) {
+    if (y1 == y2) return;
+
+    int32_t del1 = ((x2 - x1) << 16) / (y2 - y1);
+    int32_t del2 = ((x3 - x1) << 16) / (y3 - y1);
+
+    int32_t u1 = ((z2 - z1) << 16) / (y2 - y1), u2 = ((z3 - z1) << 16) / (y3 - y1);
+    int32_t zl = z1 << 16, zr = z1 << 16;
+
+    int32_t c1 = x1 << 16, c2 = x1 << 16;
+    for (int y = y1; y <= y2; y++) {
+        hline((int16_t)(c1 >> 16), (int16_t)(c2 >> 16), y, color, (int8_t)(zl >> 16), (int8_t)(zr >> 16));
+        c1 += del1;
+        c2 += del2;
+        zl += u1;
+        zr += u2;
+    }
+}
+
+//y1 == y2
+void top_triangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, uint8_t color, int8_t z1, int8_t z2, int8_t z3) {
+    if (y2 == y3) return;
+
+    int32_t del1 = ((x3 - x1) << 16) / (y3 - y1);
+    int32_t del2 = ((x3 - x2) << 16) / (y3 - y2);
+
+    int32_t u1 = ((z3 - z1) << 16) / (y3 - y1), u2 = ((z3 - z2) << 16) / (y3 - y2);
+    int32_t zl = z3 << 16, zr = z3 << 16;
+
+    int32_t c1 = x3 << 16, c2 = x3 << 16;
+    for (int y = y3; y > y1; y--) {
+        hline((int16_t)(c1 >> 16), (int16_t)(c2 >> 16), y, color, (int8_t)(zl >> 16), (int8_t)(zr >> 16));
+        c1 -= del1;
+        c2 -= del2;
+        zl -= u1;
+        zr -= u2;
+    }
+}
+
+//y1 < y2 < y3
+void sorted_triangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, uint8_t color, int8_t z1, int8_t z2, int8_t z3) {
+    if (y2 == y3) {
+        bottom_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
+    }
+    else if (y1 == y2) {
+        top_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
+    }
+    else {
+        int16_t x4 = (int16_t)(x1 + ((float)(y2 - y1) / (float)(y3 - y1))*(x3 - x1));
+        int8_t z4 = (int8_t)(z1 + ((float)(y2 - y1) / (float)(y3 - y1))*(z3 - z1));
+        bottom_triangle(x1, y1, x2, y2, x4, y2, color, z1, z2, z4);
+        top_triangle(x2, y2, x4, y2, x3, y3, color, z2, z4, z3);
+    }
+}
+
+void fill_triangle(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, uint8_t color, int8_t z1, int8_t z2, int8_t z3) {
+    int16_t tx, ty;
+    int8_t tz;
+    if (y1 > y3) {
+        tx = x1; ty = y1; tz = z1;
+        x1 = x3; y1 = y3; z1 = z3;
+        x3 = tx; y3 = ty; z3 = tz;
+    }
+    if (y1 > y2) {
+        tx = x1; ty = y1; tz = z1;
+        x1 = x2; y1 = y2; z1 = z2;
+        x2 = tx; y2 = ty; z2 = tz;
+    }
+    if (y2 > y3) {
+        tx = x2; ty = y2; tz = z2;
+        x2 = x3; y2 = y3; z2 = z3;
+        x3 = tx; y3 = ty; z3 = tz;
+    }
+    sorted_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
+}
+
+void fill_quad(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t x3, int16_t y3, int16_t x4, int16_t y4, uint8_t color, int8_t z1, int8_t z2, int8_t z3, int8_t z4) {
+    fill_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
+    fill_triangle(x1, y1, x3, y3, x4, y4, color, z1, z3, z4);
+}
+
+float qx[32];
+float qy[32];
+float qz[32];
+int geom_index = 0;
+
+uint8_t qcolor[32];
+int color_index = 0;
+
+void add_quad(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4, uint8_t color) {
+    qx[geom_index] = x1; qy[geom_index] = y1; qz[geom_index] = z1;
+    geom_index++;
+    qx[geom_index] = x2; qy[geom_index] = y2; qz[geom_index] = z2;
+    geom_index++;
+    qx[geom_index] = x3; qy[geom_index] = y3; qz[geom_index] = z3;
+    geom_index++;
+    qx[geom_index] = x4; qy[geom_index] = y4; qz[geom_index] = z4;
+    geom_index++;
+    
+    qcolor[color_index] = color;
+    color_index++;
+}
+
+float theta, phi, cx, cy, cz;
+
+void project(float x, float y, float z, float cost, float sint, float cosp, float sinp, int16_t *xs, int16_t *ys, int8_t *zs) {
+    float xo, yo, zo;
+    xo = x; yo = y;
+    x = xo * cost - yo * sint;
+    y = xo * sint + yo * cost;
+    yo = y; zo = z;
+    y = yo * cosp - zo * sinp;
+    z = yo * sinp + zo * cosp;
+    z = cz - z;
+
+    float scale = fabsf(z) / 256.f + 0.5f;
+
+    *xs = (int16_t)(x / scale) + XL/2;
+    *ys = (int16_t)(y / scale) + YL/2;
+    if (z < -120) z = -120;
+    if (z > 120) z = 120;
+    *zs = (int8_t)z;
+}
+
+int16_t screen_x[4];
+int16_t screen_y[4];
+int8_t screen_z[4];
+
+void render_quads() {
+    float cost = cosf(theta);
+    float sint = sinf(theta);
+    float cosp = cosf(phi);
+    float sinp = sinf(phi);
+
+    for (int i = 0; i < geom_index / 4; i++) {
+        for (int j = 0; j < 4; j++) {
+            project(qx[4 * i + j], qy[4 * i + j], qz[4 * i + j], cost, sint, cosp, sinp, &screen_x[j], &screen_y[j], &screen_z[j]);
+        }
+        fill_quad(screen_x[0], screen_y[0], screen_x[1], screen_y[1], screen_x[2], screen_y[2], screen_x[3], screen_y[3], qcolor[i], screen_z[0], screen_z[1], screen_z[2], screen_z[3]);
+    }
+}
\ No newline at end of file