Bayley Wang
/
manworm_tv_raster
cube
Fork of manworm_tv_gpu by
Diff: raster.cpp
- 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