cube

Dependencies:   mbed

Fork of manworm_tv_gpu by Jared DiCarlo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers raster.cpp Source File

raster.cpp

00001 #include "mbed.h"
00002 #include "main.h"
00003 
00004 int8_t zbuf[XL][YL];
00005 
00006 void clear_zbuf() {
00007     for (int i = 0; i < XL; i++) {
00008         for (int j = 0; j < YL; j++) {
00009             zbuf[i][j] = 127;
00010         }
00011     }
00012 }
00013 
00014 void hline(int16_t xmin, int16_t xmax, int16_t y, uint8_t color, int8_t zmin, int8_t zmax) {
00015     if (xmin < 0) xmin = 0;
00016     if (xmin >= XL) xmin = XL - 1;
00017     if (xmax < 0) xmax = 0;
00018     if (xmax >= XL) xmax = XL - 1;
00019     if (y < 0) y = 0;
00020     if (y >= YL) y = YL - 1;
00021 
00022     int tmp;
00023     if (xmax < xmin) {
00024         tmp = xmin;
00025         xmin = xmax;
00026         xmax = tmp;
00027         tmp = zmin;
00028         zmin = zmax;
00029         zmax = tmp;
00030     }
00031 
00032     if (xmin == xmax) { zbuf[xmin][y] = zmin; return; }
00033     int32_t u = ((zmax - zmin) << 16) / (xmax - xmin);
00034     int32_t z = zmin << 16;
00035     
00036     for (int16_t x = xmin; x <= xmax; x++) {
00037         z += u;
00038         int8_t z8 = (int8_t)(z >> 16);
00039         if (z8 < zbuf[x][y]) {
00040             zbuf[x][y] = z8;
00041             set_pixel(x, y, color);
00042         }
00043     }
00044 }
00045 
00046 //y2 == y3
00047 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) {
00048     if (y1 == y2) return;
00049 
00050     int32_t del1 = ((x2 - x1) << 16) / (y2 - y1);
00051     int32_t del2 = ((x3 - x1) << 16) / (y3 - y1);
00052 
00053     int32_t u1 = ((z2 - z1) << 16) / (y2 - y1), u2 = ((z3 - z1) << 16) / (y3 - y1);
00054     int32_t zl = z1 << 16, zr = z1 << 16;
00055 
00056     int32_t c1 = x1 << 16, c2 = x1 << 16;
00057     for (int y = y1; y <= y2; y++) {
00058         hline((int16_t)(c1 >> 16), (int16_t)(c2 >> 16), y, color, (int8_t)(zl >> 16), (int8_t)(zr >> 16));
00059         c1 += del1;
00060         c2 += del2;
00061         zl += u1;
00062         zr += u2;
00063     }
00064 }
00065 
00066 //y1 == y2
00067 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) {
00068     if (y2 == y3) return;
00069 
00070     int32_t del1 = ((x3 - x1) << 16) / (y3 - y1);
00071     int32_t del2 = ((x3 - x2) << 16) / (y3 - y2);
00072 
00073     int32_t u1 = ((z3 - z1) << 16) / (y3 - y1), u2 = ((z3 - z2) << 16) / (y3 - y2);
00074     int32_t zl = z3 << 16, zr = z3 << 16;
00075 
00076     int32_t c1 = x3 << 16, c2 = x3 << 16;
00077     for (int y = y3; y > y1; y--) {
00078         hline((int16_t)(c1 >> 16), (int16_t)(c2 >> 16), y, color, (int8_t)(zl >> 16), (int8_t)(zr >> 16));
00079         c1 -= del1;
00080         c2 -= del2;
00081         zl -= u1;
00082         zr -= u2;
00083     }
00084 }
00085 
00086 //y1 < y2 < y3
00087 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) {
00088     if (y2 == y3) {
00089         bottom_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
00090     }
00091     else if (y1 == y2) {
00092         top_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
00093     }
00094     else {
00095         int16_t x4 = (int16_t)(x1 + ((float)(y2 - y1) / (float)(y3 - y1))*(x3 - x1));
00096         int8_t z4 = (int8_t)(z1 + ((float)(y2 - y1) / (float)(y3 - y1))*(z3 - z1));
00097         bottom_triangle(x1, y1, x2, y2, x4, y2, color, z1, z2, z4);
00098         top_triangle(x2, y2, x4, y2, x3, y3, color, z2, z4, z3);
00099     }
00100 }
00101 
00102 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) {
00103     int16_t tx, ty;
00104     int8_t tz;
00105     if (y1 > y3) {
00106         tx = x1; ty = y1; tz = z1;
00107         x1 = x3; y1 = y3; z1 = z3;
00108         x3 = tx; y3 = ty; z3 = tz;
00109     }
00110     if (y1 > y2) {
00111         tx = x1; ty = y1; tz = z1;
00112         x1 = x2; y1 = y2; z1 = z2;
00113         x2 = tx; y2 = ty; z2 = tz;
00114     }
00115     if (y2 > y3) {
00116         tx = x2; ty = y2; tz = z2;
00117         x2 = x3; y2 = y3; z2 = z3;
00118         x3 = tx; y3 = ty; z3 = tz;
00119     }
00120     sorted_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
00121 }
00122 
00123 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) {
00124     fill_triangle(x1, y1, x2, y2, x3, y3, color, z1, z2, z3);
00125     fill_triangle(x1, y1, x3, y3, x4, y4, color, z1, z3, z4);
00126 }
00127 
00128 float qx[32];
00129 float qy[32];
00130 float qz[32];
00131 int geom_index = 0;
00132 
00133 uint8_t qcolor[32];
00134 int color_index = 0;
00135 
00136 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) {
00137     qx[geom_index] = x1; qy[geom_index] = y1; qz[geom_index] = z1;
00138     geom_index++;
00139     qx[geom_index] = x2; qy[geom_index] = y2; qz[geom_index] = z2;
00140     geom_index++;
00141     qx[geom_index] = x3; qy[geom_index] = y3; qz[geom_index] = z3;
00142     geom_index++;
00143     qx[geom_index] = x4; qy[geom_index] = y4; qz[geom_index] = z4;
00144     geom_index++;
00145     
00146     qcolor[color_index] = color;
00147     color_index++;
00148 }
00149 
00150 float theta, phi, cx, cy, cz;
00151 
00152 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) {
00153     float xo, yo, zo;
00154     xo = x; yo = y;
00155     x = xo * cost - yo * sint;
00156     y = xo * sint + yo * cost;
00157     yo = y; zo = z;
00158     y = yo * cosp - zo * sinp;
00159     z = yo * sinp + zo * cosp;
00160     z = cz - z;
00161 
00162     float scale = fabsf(z) / 256.f + 0.5f;
00163 
00164     *xs = (int16_t)(x / scale) + XL/2;
00165     *ys = (int16_t)(y / scale) + YL/2;
00166     if (z < -120) z = -120;
00167     if (z > 120) z = 120;
00168     *zs = (int8_t)z;
00169 }
00170 
00171 int16_t screen_x[4];
00172 int16_t screen_y[4];
00173 int8_t screen_z[4];
00174 
00175 void render_quads() {
00176     float cost = cosf(theta);
00177     float sint = sinf(theta);
00178     float cosp = cosf(phi);
00179     float sinp = sinf(phi);
00180 
00181     for (int i = 0; i < geom_index / 4; i++) {
00182         for (int j = 0; j < 4; j++) {
00183             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]);
00184         }
00185         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]);
00186     }
00187 }