Bayley Wang
/
manworm_tv_raster
cube
Fork of manworm_tv_gpu by
raster.cpp@14:cd89c3c9978a, 2019-01-15 (annotated)
- Committer:
- bwang
- Date:
- Tue Jan 15 23:24:16 2019 +0000
- Revision:
- 14:cd89c3c9978a
- Parent:
- 13:9cf720873bf6
raster
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bwang | 13:9cf720873bf6 | 1 | #include "mbed.h" |
bwang | 13:9cf720873bf6 | 2 | #include "main.h" |
bwang | 13:9cf720873bf6 | 3 | |
bwang | 13:9cf720873bf6 | 4 | int8_t zbuf[XL][YL]; |
bwang | 13:9cf720873bf6 | 5 | |
bwang | 13:9cf720873bf6 | 6 | void clear_zbuf() { |
bwang | 13:9cf720873bf6 | 7 | for (int i = 0; i < XL; i++) { |
bwang | 13:9cf720873bf6 | 8 | for (int j = 0; j < YL; j++) { |
bwang | 13:9cf720873bf6 | 9 | zbuf[i][j] = 127; |
bwang | 13:9cf720873bf6 | 10 | } |
bwang | 13:9cf720873bf6 | 11 | } |
bwang | 13:9cf720873bf6 | 12 | } |
bwang | 13:9cf720873bf6 | 13 | |
bwang | 13:9cf720873bf6 | 14 | void hline(int16_t xmin, int16_t xmax, int16_t y, uint8_t color, int8_t zmin, int8_t zmax) { |
bwang | 13:9cf720873bf6 | 15 | if (xmin < 0) xmin = 0; |
bwang | 13:9cf720873bf6 | 16 | if (xmin >= XL) xmin = XL - 1; |
bwang | 13:9cf720873bf6 | 17 | if (xmax < 0) xmax = 0; |
bwang | 13:9cf720873bf6 | 18 | if (xmax >= XL) xmax = XL - 1; |
bwang | 13:9cf720873bf6 | 19 | if (y < 0) y = 0; |
bwang | 13:9cf720873bf6 | 20 | if (y >= YL) y = YL - 1; |
bwang | 13:9cf720873bf6 | 21 | |
bwang | 13:9cf720873bf6 | 22 | int tmp; |
bwang | 13:9cf720873bf6 | 23 | if (xmax < xmin) { |
bwang | 13:9cf720873bf6 | 24 | tmp = xmin; |
bwang | 13:9cf720873bf6 | 25 | xmin = xmax; |
bwang | 13:9cf720873bf6 | 26 | xmax = tmp; |
bwang | 13:9cf720873bf6 | 27 | tmp = zmin; |
bwang | 13:9cf720873bf6 | 28 | zmin = zmax; |
bwang | 13:9cf720873bf6 | 29 | zmax = tmp; |
bwang | 13:9cf720873bf6 | 30 | } |
bwang | 13:9cf720873bf6 | 31 | |
bwang | 13:9cf720873bf6 | 32 | if (xmin == xmax) { zbuf[xmin][y] = zmin; return; } |
bwang | 13:9cf720873bf6 | 33 | int32_t u = ((zmax - zmin) << 16) / (xmax - xmin); |
bwang | 13:9cf720873bf6 | 34 | int32_t z = zmin << 16; |
bwang | 13:9cf720873bf6 | 35 | |
bwang | 13:9cf720873bf6 | 36 | for (int16_t x = xmin; x <= xmax; x++) { |
bwang | 13:9cf720873bf6 | 37 | z += u; |
bwang | 13:9cf720873bf6 | 38 | int8_t z8 = (int8_t)(z >> 16); |
bwang | 13:9cf720873bf6 | 39 | if (z8 < zbuf[x][y]) { |
bwang | 13:9cf720873bf6 | 40 | zbuf[x][y] = z8; |
bwang | 13:9cf720873bf6 | 41 | set_pixel(x, y, color); |
bwang | 13:9cf720873bf6 | 42 | } |
bwang | 13:9cf720873bf6 | 43 | } |
bwang | 13:9cf720873bf6 | 44 | } |
bwang | 13:9cf720873bf6 | 45 | |
bwang | 13:9cf720873bf6 | 46 | //y2 == y3 |
bwang | 13:9cf720873bf6 | 47 | 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) { |
bwang | 13:9cf720873bf6 | 48 | if (y1 == y2) return; |
bwang | 13:9cf720873bf6 | 49 | |
bwang | 13:9cf720873bf6 | 50 | int32_t del1 = ((x2 - x1) << 16) / (y2 - y1); |
bwang | 13:9cf720873bf6 | 51 | int32_t del2 = ((x3 - x1) << 16) / (y3 - y1); |
bwang | 13:9cf720873bf6 | 52 | |
bwang | 13:9cf720873bf6 | 53 | int32_t u1 = ((z2 - z1) << 16) / (y2 - y1), u2 = ((z3 - z1) << 16) / (y3 - y1); |
bwang | 13:9cf720873bf6 | 54 | int32_t zl = z1 << 16, zr = z1 << 16; |
bwang | 13:9cf720873bf6 | 55 | |
bwang | 13:9cf720873bf6 | 56 | int32_t c1 = x1 << 16, c2 = x1 << 16; |
bwang | 13:9cf720873bf6 | 57 | for (int y = y1; y <= y2; y++) { |
bwang | 13:9cf720873bf6 | 58 | hline((int16_t)(c1 >> 16), (int16_t)(c2 >> 16), y, color, (int8_t)(zl >> 16), (int8_t)(zr >> 16)); |
bwang | 13:9cf720873bf6 | 59 | c1 += del1; |
bwang | 13:9cf720873bf6 | 60 | c2 += del2; |
bwang | 13:9cf720873bf6 | 61 | zl += u1; |
bwang | 13:9cf720873bf6 | 62 | zr += u2; |
bwang | 13:9cf720873bf6 | 63 | } |
bwang | 13:9cf720873bf6 | 64 | } |
bwang | 13:9cf720873bf6 | 65 | |
bwang | 13:9cf720873bf6 | 66 | //y1 == y2 |
bwang | 13:9cf720873bf6 | 67 | 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) { |
bwang | 13:9cf720873bf6 | 68 | if (y2 == y3) return; |
bwang | 13:9cf720873bf6 | 69 | |
bwang | 13:9cf720873bf6 | 70 | int32_t del1 = ((x3 - x1) << 16) / (y3 - y1); |
bwang | 13:9cf720873bf6 | 71 | int32_t del2 = ((x3 - x2) << 16) / (y3 - y2); |
bwang | 13:9cf720873bf6 | 72 | |
bwang | 13:9cf720873bf6 | 73 | int32_t u1 = ((z3 - z1) << 16) / (y3 - y1), u2 = ((z3 - z2) << 16) / (y3 - y2); |
bwang | 13:9cf720873bf6 | 74 | int32_t zl = z3 << 16, zr = z3 << 16; |
bwang | 13:9cf720873bf6 | 75 | |
bwang | 13:9cf720873bf6 | 76 | int32_t c1 = x3 << 16, c2 = x3 << 16; |
bwang | 13:9cf720873bf6 | 77 | for (int y = y3; y > y1; y--) { |
bwang | 13:9cf720873bf6 | 78 | hline((int16_t)(c1 >> 16), (int16_t)(c2 >> 16), y, color, (int8_t)(zl >> 16), (int8_t)(zr >> 16)); |
bwang | 13:9cf720873bf6 | 79 | c1 -= del1; |
bwang | 13:9cf720873bf6 | 80 | c2 -= del2; |
bwang | 13:9cf720873bf6 | 81 | zl -= u1; |
bwang | 13:9cf720873bf6 | 82 | zr -= u2; |
bwang | 13:9cf720873bf6 | 83 | } |
bwang | 13:9cf720873bf6 | 84 | } |
bwang | 13:9cf720873bf6 | 85 | |
bwang | 13:9cf720873bf6 | 86 | //y1 < y2 < y3 |
bwang | 13:9cf720873bf6 | 87 | 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) { |
bwang | 13:9cf720873bf6 | 88 | if (y2 == y3) { |
bwang | 13:9cf720873bf6 | 89 | bottom_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3); |
bwang | 13:9cf720873bf6 | 90 | } |
bwang | 13:9cf720873bf6 | 91 | else if (y1 == y2) { |
bwang | 13:9cf720873bf6 | 92 | top_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3); |
bwang | 13:9cf720873bf6 | 93 | } |
bwang | 13:9cf720873bf6 | 94 | else { |
bwang | 13:9cf720873bf6 | 95 | int16_t x4 = (int16_t)(x1 + ((float)(y2 - y1) / (float)(y3 - y1))*(x3 - x1)); |
bwang | 13:9cf720873bf6 | 96 | int8_t z4 = (int8_t)(z1 + ((float)(y2 - y1) / (float)(y3 - y1))*(z3 - z1)); |
bwang | 13:9cf720873bf6 | 97 | bottom_triangle(x1, y1, x2, y2, x4, y2, color, z1, z2, z4); |
bwang | 13:9cf720873bf6 | 98 | top_triangle(x2, y2, x4, y2, x3, y3, color, z2, z4, z3); |
bwang | 13:9cf720873bf6 | 99 | } |
bwang | 13:9cf720873bf6 | 100 | } |
bwang | 13:9cf720873bf6 | 101 | |
bwang | 13:9cf720873bf6 | 102 | 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) { |
bwang | 13:9cf720873bf6 | 103 | int16_t tx, ty; |
bwang | 13:9cf720873bf6 | 104 | int8_t tz; |
bwang | 13:9cf720873bf6 | 105 | if (y1 > y3) { |
bwang | 13:9cf720873bf6 | 106 | tx = x1; ty = y1; tz = z1; |
bwang | 13:9cf720873bf6 | 107 | x1 = x3; y1 = y3; z1 = z3; |
bwang | 13:9cf720873bf6 | 108 | x3 = tx; y3 = ty; z3 = tz; |
bwang | 13:9cf720873bf6 | 109 | } |
bwang | 13:9cf720873bf6 | 110 | if (y1 > y2) { |
bwang | 13:9cf720873bf6 | 111 | tx = x1; ty = y1; tz = z1; |
bwang | 13:9cf720873bf6 | 112 | x1 = x2; y1 = y2; z1 = z2; |
bwang | 13:9cf720873bf6 | 113 | x2 = tx; y2 = ty; z2 = tz; |
bwang | 13:9cf720873bf6 | 114 | } |
bwang | 13:9cf720873bf6 | 115 | if (y2 > y3) { |
bwang | 13:9cf720873bf6 | 116 | tx = x2; ty = y2; tz = z2; |
bwang | 13:9cf720873bf6 | 117 | x2 = x3; y2 = y3; z2 = z3; |
bwang | 13:9cf720873bf6 | 118 | x3 = tx; y3 = ty; z3 = tz; |
bwang | 13:9cf720873bf6 | 119 | } |
bwang | 13:9cf720873bf6 | 120 | sorted_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3); |
bwang | 13:9cf720873bf6 | 121 | } |
bwang | 13:9cf720873bf6 | 122 | |
bwang | 13:9cf720873bf6 | 123 | 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) { |
bwang | 13:9cf720873bf6 | 124 | fill_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3); |
bwang | 13:9cf720873bf6 | 125 | fill_triangle(x1, y1, x3, y3, x4, y4, color, z1, z3, z4); |
bwang | 13:9cf720873bf6 | 126 | } |
bwang | 13:9cf720873bf6 | 127 | |
bwang | 13:9cf720873bf6 | 128 | float qx[32]; |
bwang | 13:9cf720873bf6 | 129 | float qy[32]; |
bwang | 13:9cf720873bf6 | 130 | float qz[32]; |
bwang | 13:9cf720873bf6 | 131 | int geom_index = 0; |
bwang | 13:9cf720873bf6 | 132 | |
bwang | 13:9cf720873bf6 | 133 | uint8_t qcolor[32]; |
bwang | 13:9cf720873bf6 | 134 | int color_index = 0; |
bwang | 13:9cf720873bf6 | 135 | |
bwang | 13:9cf720873bf6 | 136 | 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) { |
bwang | 13:9cf720873bf6 | 137 | qx[geom_index] = x1; qy[geom_index] = y1; qz[geom_index] = z1; |
bwang | 13:9cf720873bf6 | 138 | geom_index++; |
bwang | 13:9cf720873bf6 | 139 | qx[geom_index] = x2; qy[geom_index] = y2; qz[geom_index] = z2; |
bwang | 13:9cf720873bf6 | 140 | geom_index++; |
bwang | 13:9cf720873bf6 | 141 | qx[geom_index] = x3; qy[geom_index] = y3; qz[geom_index] = z3; |
bwang | 13:9cf720873bf6 | 142 | geom_index++; |
bwang | 13:9cf720873bf6 | 143 | qx[geom_index] = x4; qy[geom_index] = y4; qz[geom_index] = z4; |
bwang | 13:9cf720873bf6 | 144 | geom_index++; |
bwang | 13:9cf720873bf6 | 145 | |
bwang | 13:9cf720873bf6 | 146 | qcolor[color_index] = color; |
bwang | 13:9cf720873bf6 | 147 | color_index++; |
bwang | 13:9cf720873bf6 | 148 | } |
bwang | 13:9cf720873bf6 | 149 | |
bwang | 13:9cf720873bf6 | 150 | float theta, phi, cx, cy, cz; |
bwang | 13:9cf720873bf6 | 151 | |
bwang | 13:9cf720873bf6 | 152 | 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) { |
bwang | 13:9cf720873bf6 | 153 | float xo, yo, zo; |
bwang | 13:9cf720873bf6 | 154 | xo = x; yo = y; |
bwang | 13:9cf720873bf6 | 155 | x = xo * cost - yo * sint; |
bwang | 13:9cf720873bf6 | 156 | y = xo * sint + yo * cost; |
bwang | 13:9cf720873bf6 | 157 | yo = y; zo = z; |
bwang | 13:9cf720873bf6 | 158 | y = yo * cosp - zo * sinp; |
bwang | 13:9cf720873bf6 | 159 | z = yo * sinp + zo * cosp; |
bwang | 13:9cf720873bf6 | 160 | z = cz - z; |
bwang | 13:9cf720873bf6 | 161 | |
bwang | 13:9cf720873bf6 | 162 | float scale = fabsf(z) / 256.f + 0.5f; |
bwang | 13:9cf720873bf6 | 163 | |
bwang | 13:9cf720873bf6 | 164 | *xs = (int16_t)(x / scale) + XL/2; |
bwang | 13:9cf720873bf6 | 165 | *ys = (int16_t)(y / scale) + YL/2; |
bwang | 13:9cf720873bf6 | 166 | if (z < -120) z = -120; |
bwang | 13:9cf720873bf6 | 167 | if (z > 120) z = 120; |
bwang | 13:9cf720873bf6 | 168 | *zs = (int8_t)z; |
bwang | 13:9cf720873bf6 | 169 | } |
bwang | 13:9cf720873bf6 | 170 | |
bwang | 13:9cf720873bf6 | 171 | int16_t screen_x[4]; |
bwang | 13:9cf720873bf6 | 172 | int16_t screen_y[4]; |
bwang | 13:9cf720873bf6 | 173 | int8_t screen_z[4]; |
bwang | 13:9cf720873bf6 | 174 | |
bwang | 13:9cf720873bf6 | 175 | void render_quads() { |
bwang | 13:9cf720873bf6 | 176 | float cost = cosf(theta); |
bwang | 13:9cf720873bf6 | 177 | float sint = sinf(theta); |
bwang | 13:9cf720873bf6 | 178 | float cosp = cosf(phi); |
bwang | 13:9cf720873bf6 | 179 | float sinp = sinf(phi); |
bwang | 13:9cf720873bf6 | 180 | |
bwang | 13:9cf720873bf6 | 181 | for (int i = 0; i < geom_index / 4; i++) { |
bwang | 13:9cf720873bf6 | 182 | for (int j = 0; j < 4; j++) { |
bwang | 13:9cf720873bf6 | 183 | 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]); |
bwang | 13:9cf720873bf6 | 184 | } |
bwang | 13:9cf720873bf6 | 185 | 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]); |
bwang | 13:9cf720873bf6 | 186 | } |
bwang | 13:9cf720873bf6 | 187 | } |