![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
cube
Fork of manworm_tv_gpu by
raster.cpp
- Committer:
- bwang
- Date:
- 2019-01-15
- Revision:
- 14:cd89c3c9978a
- Parent:
- 13:9cf720873bf6
File content as of revision 14:cd89c3c9978a:
#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]); } }