Basic 3D graphics for the MBED application-shield on-board LCD (initial/incomplete).
g3d_render.cpp@9:db4ec6f7d8b2, 2015-11-29 (annotated)
- Committer:
- co657_frmb
- Date:
- Sun Nov 29 00:03:41 2015 +0000
- Revision:
- 9:db4ec6f7d8b2
- Parent:
- 8:55ee7af49f47
Font updates.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
co657_frmb | 5:2aaaf4e78a53 | 1 | /* |
co657_frmb | 5:2aaaf4e78a53 | 2 | * g3d_render.cpp -- rendering stuff for G3D library |
co657_frmb | 5:2aaaf4e78a53 | 3 | * Copyright (C) 2015 Fred Barnes, University of Kent |
co657_frmb | 5:2aaaf4e78a53 | 4 | * GPL >= 2.0 |
co657_frmb | 5:2aaaf4e78a53 | 5 | */ |
co657_frmb | 5:2aaaf4e78a53 | 6 | |
co657_frmb | 5:2aaaf4e78a53 | 7 | |
co657_frmb | 5:2aaaf4e78a53 | 8 | #include "mbed.h" |
co657_frmb | 5:2aaaf4e78a53 | 9 | #include "C12832.h" |
co657_frmb | 5:2aaaf4e78a53 | 10 | #include "gfx3d.h" |
co657_frmb | 5:2aaaf4e78a53 | 11 | |
co657_frmb | 5:2aaaf4e78a53 | 12 | #define DISPLAY_WIDTH (128) |
co657_frmb | 5:2aaaf4e78a53 | 13 | #define DISPLAY_HEIGHT (32) |
co657_frmb | 5:2aaaf4e78a53 | 14 | |
co657_frmb | 5:2aaaf4e78a53 | 15 | #define ZB_YSHIFT (7) |
co657_frmb | 5:2aaaf4e78a53 | 16 | |
co657_frmb | 5:2aaaf4e78a53 | 17 | /* grotty: single global Z buffer that matches the LCD size */ |
co657_frmb | 5:2aaaf4e78a53 | 18 | static int16_t zbuffer[DISPLAY_HEIGHT * DISPLAY_WIDTH]; |
co657_frmb | 5:2aaaf4e78a53 | 19 | |
co657_frmb | 5:2aaaf4e78a53 | 20 | #define ZBUFFER(X,Y) zbuffer[(Y << ZB_YSHIFT) | X] |
co657_frmb | 5:2aaaf4e78a53 | 21 | |
co657_frmb | 5:2aaaf4e78a53 | 22 | /** |
co657_frmb | 5:2aaaf4e78a53 | 23 | * clears the Z buffer (sets all to maximum) |
co657_frmb | 5:2aaaf4e78a53 | 24 | */ |
co657_frmb | 5:2aaaf4e78a53 | 25 | void gfx3d_clear_zb (void) |
co657_frmb | 5:2aaaf4e78a53 | 26 | { |
co657_frmb | 5:2aaaf4e78a53 | 27 | int i; |
co657_frmb | 5:2aaaf4e78a53 | 28 | int lim = (DISPLAY_HEIGHT * DISPLAY_WIDTH) >> 1; |
co657_frmb | 5:2aaaf4e78a53 | 29 | uint32_t *halfbuf = (uint32_t *)zbuffer; |
co657_frmb | 5:2aaaf4e78a53 | 30 | |
co657_frmb | 5:2aaaf4e78a53 | 31 | for (i=0; i<lim; i++) { |
co657_frmb | 5:2aaaf4e78a53 | 32 | halfbuf[i] = 0x7fff7fff; |
co657_frmb | 5:2aaaf4e78a53 | 33 | } |
co657_frmb | 5:2aaaf4e78a53 | 34 | } |
co657_frmb | 5:2aaaf4e78a53 | 35 | |
co657_frmb | 5:2aaaf4e78a53 | 36 | #if 0 |
co657_frmb | 5:2aaaf4e78a53 | 37 | /** |
co657_frmb | 5:2aaaf4e78a53 | 38 | * fixes scan-line starts/ends in a g3d_polyscan_t structure based on edge |
co657_frmb | 5:2aaaf4e78a53 | 39 | */ |
co657_frmb | 5:2aaaf4e78a53 | 40 | static void gfx3d_polyfix (g3d_polyscan_t *dst, int16_t x1, int16_t y1, int32_t z1, int16_t x2, int16_t y2, int32_t z2, const float co_a, const float co_b, const float co_c, const float co_d) |
co657_frmb | 5:2aaaf4e78a53 | 41 | { |
co657_frmb | 5:2aaaf4e78a53 | 42 | if (y2 < y1) { |
co657_frmb | 5:2aaaf4e78a53 | 43 | /* swap around: make sure we go in the same direction (down) */ |
co657_frmb | 5:2aaaf4e78a53 | 44 | int16_t t16; |
co657_frmb | 5:2aaaf4e78a53 | 45 | int32_t t32; |
co657_frmb | 5:2aaaf4e78a53 | 46 | |
co657_frmb | 5:2aaaf4e78a53 | 47 | t16 = x1; |
co657_frmb | 5:2aaaf4e78a53 | 48 | x1 = x2; |
co657_frmb | 5:2aaaf4e78a53 | 49 | x2 = t16; |
co657_frmb | 5:2aaaf4e78a53 | 50 | |
co657_frmb | 5:2aaaf4e78a53 | 51 | t16 = y1; |
co657_frmb | 5:2aaaf4e78a53 | 52 | y1 = y2; |
co657_frmb | 5:2aaaf4e78a53 | 53 | y2 = t16; |
co657_frmb | 5:2aaaf4e78a53 | 54 | |
co657_frmb | 5:2aaaf4e78a53 | 55 | t32 = z1; |
co657_frmb | 5:2aaaf4e78a53 | 56 | z1 = z2; |
co657_frmb | 5:2aaaf4e78a53 | 57 | z2 = t32; |
co657_frmb | 5:2aaaf4e78a53 | 58 | } |
co657_frmb | 5:2aaaf4e78a53 | 59 | |
co657_frmb | 5:2aaaf4e78a53 | 60 | /* scan limit */ |
co657_frmb | 5:2aaaf4e78a53 | 61 | if (y1 < dst->scan_s) { |
co657_frmb | 5:2aaaf4e78a53 | 62 | dst->scan_s = y1; |
co657_frmb | 5:2aaaf4e78a53 | 63 | } |
co657_frmb | 5:2aaaf4e78a53 | 64 | if (y2 > dst->scan_e) { |
co657_frmb | 5:2aaaf4e78a53 | 65 | dst->scan_e = y2; |
co657_frmb | 5:2aaaf4e78a53 | 66 | } |
co657_frmb | 5:2aaaf4e78a53 | 67 | if (y1 == y2) { |
co657_frmb | 5:2aaaf4e78a53 | 68 | /* flat polygon */ |
co657_frmb | 5:2aaaf4e78a53 | 69 | dst->scans[y1][0] = x1; |
co657_frmb | 5:2aaaf4e78a53 | 70 | dst->scans[y1][1] = x2; |
co657_frmb | 5:2aaaf4e78a53 | 71 | dst->zscan[y1][0] = z1; |
co657_frmb | 5:2aaaf4e78a53 | 72 | dst->zscan[y1][1] = z2; |
co657_frmb | 5:2aaaf4e78a53 | 73 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 74 | /* vaguely complex polygon */ |
co657_frmb | 5:2aaaf4e78a53 | 75 | int x, y, z, step, z_step; |
co657_frmb | 5:2aaaf4e78a53 | 76 | |
co657_frmb | 5:2aaaf4e78a53 | 77 | x = (int)x1 << 16; |
co657_frmb | 5:2aaaf4e78a53 | 78 | step = ((int)(x2 - x1) << 16) / (int)(y2 - y1); |
co657_frmb | 5:2aaaf4e78a53 | 79 | x += step; |
co657_frmb | 5:2aaaf4e78a53 | 80 | |
co657_frmb | 5:2aaaf4e78a53 | 81 | z = z1; |
co657_frmb | 5:2aaaf4e78a53 | 82 | z_step = (z2 - z1) / ((y2 - y1) + 1); |
co657_frmb | 5:2aaaf4e78a53 | 83 | y1++; |
co657_frmb | 5:2aaaf4e78a53 | 84 | |
co657_frmb | 5:2aaaf4e78a53 | 85 | for (y=y1; y<=y2; y++) { |
co657_frmb | 5:2aaaf4e78a53 | 86 | if ((y >= 0) && (y < 32)) { |
co657_frmb | 5:2aaaf4e78a53 | 87 | int shx = x >> 16; |
co657_frmb | 5:2aaaf4e78a53 | 88 | |
co657_frmb | 5:2aaaf4e78a53 | 89 | if (x < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 90 | shx = shx - 65536; |
co657_frmb | 5:2aaaf4e78a53 | 91 | } |
co657_frmb | 5:2aaaf4e78a53 | 92 | if (dst->scans[y][0] == 0xff) { |
co657_frmb | 5:2aaaf4e78a53 | 93 | /* start of scan */ |
co657_frmb | 5:2aaaf4e78a53 | 94 | uint8_t x8 = (uint8_t)(shx & 0xff); |
co657_frmb | 5:2aaaf4e78a53 | 95 | |
co657_frmb | 5:2aaaf4e78a53 | 96 | if (x8 == 0xff) { |
co657_frmb | 5:2aaaf4e78a53 | 97 | x8 = 128; |
co657_frmb | 5:2aaaf4e78a53 | 98 | } |
co657_frmb | 5:2aaaf4e78a53 | 99 | dst->scans[y][0] = x8; |
co657_frmb | 5:2aaaf4e78a53 | 100 | if (co_c != 0.0f) { |
co657_frmb | 5:2aaaf4e78a53 | 101 | dst->zscan[y][0] = (int32_t)(((-(co_a * (float)shx) - (co_b * (float)y)) - co_d) / co_c); |
co657_frmb | 5:2aaaf4e78a53 | 102 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 103 | dst->zscan[y][0] = z; |
co657_frmb | 5:2aaaf4e78a53 | 104 | } |
co657_frmb | 5:2aaaf4e78a53 | 105 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 106 | /* end of scan */ |
co657_frmb | 5:2aaaf4e78a53 | 107 | uint8_t x8 = (uint8_t)(shx & 0xff); |
co657_frmb | 5:2aaaf4e78a53 | 108 | |
co657_frmb | 5:2aaaf4e78a53 | 109 | if (x8 == 0xff) { |
co657_frmb | 5:2aaaf4e78a53 | 110 | x8 = 128; |
co657_frmb | 5:2aaaf4e78a53 | 111 | } |
co657_frmb | 5:2aaaf4e78a53 | 112 | dst->scans[y][1] = x8; |
co657_frmb | 5:2aaaf4e78a53 | 113 | if (co_c != 0.0f) { |
co657_frmb | 5:2aaaf4e78a53 | 114 | dst->zscan[y][1] = (int32_t)(((-(co_a * (float)shx) - (co_b * (float)y)) - co_d) / co_c); |
co657_frmb | 5:2aaaf4e78a53 | 115 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 116 | dst->zscan[y][1] = z; |
co657_frmb | 5:2aaaf4e78a53 | 117 | } |
co657_frmb | 5:2aaaf4e78a53 | 118 | } |
co657_frmb | 5:2aaaf4e78a53 | 119 | } |
co657_frmb | 5:2aaaf4e78a53 | 120 | x += step; |
co657_frmb | 5:2aaaf4e78a53 | 121 | z += z_step; |
co657_frmb | 5:2aaaf4e78a53 | 122 | } |
co657_frmb | 5:2aaaf4e78a53 | 123 | } |
co657_frmb | 5:2aaaf4e78a53 | 124 | } |
co657_frmb | 5:2aaaf4e78a53 | 125 | |
co657_frmb | 5:2aaaf4e78a53 | 126 | |
co657_frmb | 5:2aaaf4e78a53 | 127 | /** |
co657_frmb | 5:2aaaf4e78a53 | 128 | * takes a polygon structure and generates a set of scanline data from it |
co657_frmb | 5:2aaaf4e78a53 | 129 | */ |
co657_frmb | 5:2aaaf4e78a53 | 130 | void gfx3d_polyscan (const g3d_poly_t *src, g3d_polyscan_t *dst) |
co657_frmb | 5:2aaaf4e78a53 | 131 | { |
co657_frmb | 5:2aaaf4e78a53 | 132 | int i; |
co657_frmb | 5:2aaaf4e78a53 | 133 | float co_a, co_b, co_c, co_d; |
co657_frmb | 5:2aaaf4e78a53 | 134 | float x1 = (float)src->x[0]; |
co657_frmb | 5:2aaaf4e78a53 | 135 | float y1 = (float)src->y[0]; |
co657_frmb | 5:2aaaf4e78a53 | 136 | float z1 = (float)src->z[0]; |
co657_frmb | 5:2aaaf4e78a53 | 137 | float x2 = (float)src->x[1]; |
co657_frmb | 5:2aaaf4e78a53 | 138 | float y2 = (float)src->y[1]; |
co657_frmb | 5:2aaaf4e78a53 | 139 | float z2 = (float)src->z[1]; |
co657_frmb | 5:2aaaf4e78a53 | 140 | float x3 = (float)src->x[2]; |
co657_frmb | 5:2aaaf4e78a53 | 141 | float y3 = (float)src->y[2]; |
co657_frmb | 5:2aaaf4e78a53 | 142 | float z3 = (float)src->z[2]; |
co657_frmb | 5:2aaaf4e78a53 | 143 | |
co657_frmb | 5:2aaaf4e78a53 | 144 | for (i=0; i<32; i++) { |
co657_frmb | 5:2aaaf4e78a53 | 145 | dst->scans[i][0] = 0xff; |
co657_frmb | 5:2aaaf4e78a53 | 146 | dst->scans[i][1] = 0xff; |
co657_frmb | 5:2aaaf4e78a53 | 147 | dst->zscan[i][0] = 0; |
co657_frmb | 5:2aaaf4e78a53 | 148 | dst->zscan[i][1] = 0; |
co657_frmb | 5:2aaaf4e78a53 | 149 | } |
co657_frmb | 5:2aaaf4e78a53 | 150 | dst->scan_s = 32; |
co657_frmb | 5:2aaaf4e78a53 | 151 | dst->scan_e = 0; |
co657_frmb | 5:2aaaf4e78a53 | 152 | dst->norm = src->norm; |
co657_frmb | 5:2aaaf4e78a53 | 153 | |
co657_frmb | 5:2aaaf4e78a53 | 154 | /* coefficients for plane equations, Herne & Baker p308 */ |
co657_frmb | 5:2aaaf4e78a53 | 155 | co_a = ((y1 * (z2 - z3)) + (y2 * (z3 - z1))) + (y3 * (z1 - z2)); |
co657_frmb | 5:2aaaf4e78a53 | 156 | co_b = ((z1 * (x2 - x3)) + (z2 * (x3 - x1))) + (z3 * (x1 - x2)); |
co657_frmb | 5:2aaaf4e78a53 | 157 | co_c = ((x1 * (y2 - y3)) + (x2 * (y3 - y1))) + (x3 * (y1 - y2)); |
co657_frmb | 5:2aaaf4e78a53 | 158 | co_d = ((-x1 * ((y2 * z3) - (y3 * z2))) - (x2 * ((y3 * z1) - (y1 * z3)))) - (x3 * ((y1 * z2) - (y2 * z1))); |
co657_frmb | 5:2aaaf4e78a53 | 159 | |
co657_frmb | 5:2aaaf4e78a53 | 160 | gfx3d_polyfix (dst, src->x[0], src->y[0], src->z[0], src->x[1], src->y[1], src->z[1], co_a, co_b, co_c, co_d); |
co657_frmb | 5:2aaaf4e78a53 | 161 | gfx3d_polyfix (dst, src->x[1], src->y[1], src->z[1], src->x[2], src->y[2], src->z[2], co_a, co_b, co_c, co_d); |
co657_frmb | 5:2aaaf4e78a53 | 162 | gfx3d_polyfix (dst, src->x[2], src->y[2], src->z[2], src->x[0], src->y[0], src->z[0], co_a, co_b, co_c, co_d); |
co657_frmb | 5:2aaaf4e78a53 | 163 | |
co657_frmb | 5:2aaaf4e78a53 | 164 | if (dst->scan_s < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 165 | dst->scan_s = 0; |
co657_frmb | 5:2aaaf4e78a53 | 166 | } else if (dst->scan_s >= 32) { |
co657_frmb | 5:2aaaf4e78a53 | 167 | dst->scan_s = 31; |
co657_frmb | 5:2aaaf4e78a53 | 168 | } |
co657_frmb | 5:2aaaf4e78a53 | 169 | if (dst->scan_e < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 170 | dst->scan_e = 0; |
co657_frmb | 5:2aaaf4e78a53 | 171 | } else if (dst->scan_e >= 32) { |
co657_frmb | 5:2aaaf4e78a53 | 172 | dst->scan_e = 31; |
co657_frmb | 5:2aaaf4e78a53 | 173 | } |
co657_frmb | 5:2aaaf4e78a53 | 174 | |
co657_frmb | 5:2aaaf4e78a53 | 175 | } |
co657_frmb | 5:2aaaf4e78a53 | 176 | #endif |
co657_frmb | 5:2aaaf4e78a53 | 177 | |
co657_frmb | 5:2aaaf4e78a53 | 178 | static inline void gfx3d_swap_points (g3d_2p3_t *p1, g3d_2p3_t *p2) |
co657_frmb | 5:2aaaf4e78a53 | 179 | { |
co657_frmb | 5:2aaaf4e78a53 | 180 | uint32_t *v1 = (uint32_t *)p1; |
co657_frmb | 5:2aaaf4e78a53 | 181 | uint32_t *v2 = (uint32_t *)p2; |
co657_frmb | 5:2aaaf4e78a53 | 182 | uint32_t tmp; |
co657_frmb | 5:2aaaf4e78a53 | 183 | |
co657_frmb | 5:2aaaf4e78a53 | 184 | tmp = *v1; |
co657_frmb | 5:2aaaf4e78a53 | 185 | *v1 = *v2; |
co657_frmb | 5:2aaaf4e78a53 | 186 | *v2 = tmp; |
co657_frmb | 5:2aaaf4e78a53 | 187 | |
co657_frmb | 5:2aaaf4e78a53 | 188 | v1++, v2++; |
co657_frmb | 5:2aaaf4e78a53 | 189 | tmp = *v1; |
co657_frmb | 5:2aaaf4e78a53 | 190 | *v1 = *v2; |
co657_frmb | 5:2aaaf4e78a53 | 191 | *v2 = tmp; |
co657_frmb | 5:2aaaf4e78a53 | 192 | } |
co657_frmb | 5:2aaaf4e78a53 | 193 | |
co657_frmb | 5:2aaaf4e78a53 | 194 | static inline void gfx3d_swap_txpoints (uint16_t *p1, uint16_t *p2) |
co657_frmb | 5:2aaaf4e78a53 | 195 | { |
co657_frmb | 5:2aaaf4e78a53 | 196 | uint16_t tmp = *p1; |
co657_frmb | 5:2aaaf4e78a53 | 197 | |
co657_frmb | 5:2aaaf4e78a53 | 198 | *p1 = *p2; |
co657_frmb | 5:2aaaf4e78a53 | 199 | *p2 = tmp; |
co657_frmb | 5:2aaaf4e78a53 | 200 | return; |
co657_frmb | 5:2aaaf4e78a53 | 201 | } |
co657_frmb | 5:2aaaf4e78a53 | 202 | |
co657_frmb | 5:2aaaf4e78a53 | 203 | void gfx3d_sort_poly (g3d_poly_t *p) |
co657_frmb | 5:2aaaf4e78a53 | 204 | { |
co657_frmb | 5:2aaaf4e78a53 | 205 | /* arranges points in the polygon into left->right order -- crude */ |
co657_frmb | 5:2aaaf4e78a53 | 206 | if (p->pts[1].x < p->pts[0].x) { |
co657_frmb | 5:2aaaf4e78a53 | 207 | /* point in 1 left of 0, swap */ |
co657_frmb | 5:2aaaf4e78a53 | 208 | gfx3d_swap_points (&(p->pts[0]), &(p->pts[1])); |
co657_frmb | 5:2aaaf4e78a53 | 209 | gfx3d_swap_txpoints (&(p->tx_pts[0]), &(p->tx_pts[1])); |
co657_frmb | 5:2aaaf4e78a53 | 210 | } |
co657_frmb | 5:2aaaf4e78a53 | 211 | if (p->pts[2].x < p->pts[0].x) { |
co657_frmb | 5:2aaaf4e78a53 | 212 | /* point in 2 left of 0, swap */ |
co657_frmb | 5:2aaaf4e78a53 | 213 | gfx3d_swap_points (&(p->pts[0]), &(p->pts[2])); |
co657_frmb | 5:2aaaf4e78a53 | 214 | gfx3d_swap_txpoints (&(p->tx_pts[0]), &(p->tx_pts[2])); |
co657_frmb | 5:2aaaf4e78a53 | 215 | } |
co657_frmb | 5:2aaaf4e78a53 | 216 | if (p->pts[2].x < p->pts[1].x) { |
co657_frmb | 5:2aaaf4e78a53 | 217 | /* point in 2 left of 1, swap */ |
co657_frmb | 5:2aaaf4e78a53 | 218 | gfx3d_swap_points (&(p->pts[1]), &(p->pts[2])); |
co657_frmb | 5:2aaaf4e78a53 | 219 | gfx3d_swap_txpoints (&(p->tx_pts[1]), &(p->tx_pts[2])); |
co657_frmb | 5:2aaaf4e78a53 | 220 | } |
co657_frmb | 5:2aaaf4e78a53 | 221 | } |
co657_frmb | 5:2aaaf4e78a53 | 222 | |
co657_frmb | 5:2aaaf4e78a53 | 223 | |
co657_frmb | 5:2aaaf4e78a53 | 224 | static inline void gfx3d_edgebuf_z_fixin (const g3d_2p3_t *p0, const g3d_2p3_t *p1, uint8_t *yedge, uint16_t *zedge, uint16_t xoff) |
co657_frmb | 5:2aaaf4e78a53 | 225 | { |
co657_frmb | 5:2aaaf4e78a53 | 226 | int32_t y = (p0->y << 16) | 0x8000; /* half-way... */ |
co657_frmb | 5:2aaaf4e78a53 | 227 | int32_t ydelta; |
co657_frmb | 5:2aaaf4e78a53 | 228 | int32_t z = (p0->z << 16) | 0x8000; /* half-way... */ |
co657_frmb | 5:2aaaf4e78a53 | 229 | int32_t zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 230 | int x; |
co657_frmb | 5:2aaaf4e78a53 | 231 | |
co657_frmb | 5:2aaaf4e78a53 | 232 | if (p0->x == p1->x) { |
co657_frmb | 5:2aaaf4e78a53 | 233 | /* same X position -- should have been dealt with */ |
co657_frmb | 5:2aaaf4e78a53 | 234 | return; |
co657_frmb | 5:2aaaf4e78a53 | 235 | } |
co657_frmb | 5:2aaaf4e78a53 | 236 | |
co657_frmb | 5:2aaaf4e78a53 | 237 | ydelta = ((int32_t)(p1->y - p0->y) << 16) / (int32_t)(p1->x - p0->x); |
co657_frmb | 5:2aaaf4e78a53 | 238 | zdelta = ((int32_t)(p1->z - p0->z) << 16) / (int32_t)(p1->x - p0->x); |
co657_frmb | 5:2aaaf4e78a53 | 239 | |
co657_frmb | 5:2aaaf4e78a53 | 240 | for (x = p0->x; x <= p1->x; x++) { |
co657_frmb | 5:2aaaf4e78a53 | 241 | int16_t rc_y; |
co657_frmb | 5:2aaaf4e78a53 | 242 | int16_t rc_z; |
co657_frmb | 5:2aaaf4e78a53 | 243 | |
co657_frmb | 5:2aaaf4e78a53 | 244 | if (x < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 245 | y += ydelta; |
co657_frmb | 5:2aaaf4e78a53 | 246 | z += zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 247 | continue; |
co657_frmb | 5:2aaaf4e78a53 | 248 | } |
co657_frmb | 5:2aaaf4e78a53 | 249 | if (x >= DISPLAY_WIDTH) { |
co657_frmb | 5:2aaaf4e78a53 | 250 | /* can't have any more */ |
co657_frmb | 5:2aaaf4e78a53 | 251 | return; |
co657_frmb | 5:2aaaf4e78a53 | 252 | } |
co657_frmb | 5:2aaaf4e78a53 | 253 | |
co657_frmb | 5:2aaaf4e78a53 | 254 | rc_y = (y >> 16); |
co657_frmb | 5:2aaaf4e78a53 | 255 | if (rc_y < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 256 | y += ydelta; |
co657_frmb | 5:2aaaf4e78a53 | 257 | z += zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 258 | continue; |
co657_frmb | 5:2aaaf4e78a53 | 259 | } |
co657_frmb | 5:2aaaf4e78a53 | 260 | if (rc_y >= DISPLAY_HEIGHT) { |
co657_frmb | 5:2aaaf4e78a53 | 261 | y += ydelta; |
co657_frmb | 5:2aaaf4e78a53 | 262 | z += zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 263 | continue; |
co657_frmb | 5:2aaaf4e78a53 | 264 | } |
co657_frmb | 5:2aaaf4e78a53 | 265 | yedge[x - xoff] = rc_y; |
co657_frmb | 5:2aaaf4e78a53 | 266 | y += ydelta; |
co657_frmb | 5:2aaaf4e78a53 | 267 | |
co657_frmb | 5:2aaaf4e78a53 | 268 | rc_z = (z >> 16); |
co657_frmb | 5:2aaaf4e78a53 | 269 | zedge[x - xoff] = rc_z; |
co657_frmb | 5:2aaaf4e78a53 | 270 | z += zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 271 | } |
co657_frmb | 5:2aaaf4e78a53 | 272 | } |
co657_frmb | 5:2aaaf4e78a53 | 273 | |
co657_frmb | 5:2aaaf4e78a53 | 274 | |
co657_frmb | 5:2aaaf4e78a53 | 275 | /** |
co657_frmb | 5:2aaaf4e78a53 | 276 | * takes a polygon and fills an edge-buffer with it. Assumes triangular and sorted poly. |
co657_frmb | 5:2aaaf4e78a53 | 277 | */ |
co657_frmb | 5:2aaaf4e78a53 | 278 | void gfx3d_edgebuf_z (const g3d_poly_t *src, g3d_edgebuf_t *dst) |
co657_frmb | 5:2aaaf4e78a53 | 279 | { |
co657_frmb | 5:2aaaf4e78a53 | 280 | if (src->pts[0].x < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 281 | /* left-hand point off-screen */ |
co657_frmb | 5:2aaaf4e78a53 | 282 | dst->xoff = 0; |
co657_frmb | 5:2aaaf4e78a53 | 283 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 284 | dst->xoff = src->pts[0].x; |
co657_frmb | 5:2aaaf4e78a53 | 285 | } |
co657_frmb | 5:2aaaf4e78a53 | 286 | dst->s_end = (src->pts[2].x - src->pts[0].x) + 1; |
co657_frmb | 5:2aaaf4e78a53 | 287 | |
co657_frmb | 5:2aaaf4e78a53 | 288 | if (src->pts[0].x == src->pts[2].x) { |
co657_frmb | 5:2aaaf4e78a53 | 289 | /* vertical line only */ |
co657_frmb | 5:2aaaf4e78a53 | 290 | if (src->pts[0].y <= src->pts[1].y) { |
co657_frmb | 5:2aaaf4e78a53 | 291 | /* p0 is above p1 */ |
co657_frmb | 5:2aaaf4e78a53 | 292 | if (src->pts[1].y < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 293 | /* off top */ |
co657_frmb | 5:2aaaf4e78a53 | 294 | dst->s_end = 0; |
co657_frmb | 5:2aaaf4e78a53 | 295 | } else if (src->pts[0].y >= DISPLAY_HEIGHT) { |
co657_frmb | 5:2aaaf4e78a53 | 296 | /* off bottom */ |
co657_frmb | 5:2aaaf4e78a53 | 297 | dst->s_end = 0; |
co657_frmb | 5:2aaaf4e78a53 | 298 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 299 | if (src->pts[0].y < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 300 | dst->start[0] = 0; |
co657_frmb | 5:2aaaf4e78a53 | 301 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 302 | dst->start[0] = src->pts[0].y; |
co657_frmb | 5:2aaaf4e78a53 | 303 | } |
co657_frmb | 5:2aaaf4e78a53 | 304 | if (src->pts[1].y >= DISPLAY_HEIGHT) { |
co657_frmb | 5:2aaaf4e78a53 | 305 | dst->end[0] = DISPLAY_HEIGHT - 1; |
co657_frmb | 5:2aaaf4e78a53 | 306 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 307 | dst->end[0] = src->pts[1].y; |
co657_frmb | 5:2aaaf4e78a53 | 308 | } |
co657_frmb | 5:2aaaf4e78a53 | 309 | /* if we over-shot, this will be wrong */ |
co657_frmb | 5:2aaaf4e78a53 | 310 | dst->zstart[0] = src->pts[0].z; |
co657_frmb | 5:2aaaf4e78a53 | 311 | dst->zend[0] = src->pts[1].z; |
co657_frmb | 5:2aaaf4e78a53 | 312 | } |
co657_frmb | 5:2aaaf4e78a53 | 313 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 314 | if (src->pts[0].y < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 315 | /* off top */ |
co657_frmb | 5:2aaaf4e78a53 | 316 | dst->s_end = 0; |
co657_frmb | 5:2aaaf4e78a53 | 317 | } else if (src->pts[1].y >= DISPLAY_HEIGHT) { |
co657_frmb | 5:2aaaf4e78a53 | 318 | /* off bottom */ |
co657_frmb | 5:2aaaf4e78a53 | 319 | dst->s_end = 0; |
co657_frmb | 5:2aaaf4e78a53 | 320 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 321 | if (src->pts[1].y < 0) { |
co657_frmb | 5:2aaaf4e78a53 | 322 | dst->start[0] = 0; |
co657_frmb | 5:2aaaf4e78a53 | 323 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 324 | dst->start[0] = src->pts[1].y; |
co657_frmb | 5:2aaaf4e78a53 | 325 | } |
co657_frmb | 5:2aaaf4e78a53 | 326 | if (src->pts[0].y >= DISPLAY_HEIGHT) { |
co657_frmb | 5:2aaaf4e78a53 | 327 | dst->end[0] = DISPLAY_HEIGHT - 1; |
co657_frmb | 5:2aaaf4e78a53 | 328 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 329 | dst->end[0] = src->pts[0].y; |
co657_frmb | 5:2aaaf4e78a53 | 330 | } |
co657_frmb | 5:2aaaf4e78a53 | 331 | /* if we over-shot, this will be wrong */ |
co657_frmb | 5:2aaaf4e78a53 | 332 | dst->zstart[0] = src->pts[1].z; |
co657_frmb | 5:2aaaf4e78a53 | 333 | dst->zend[0] = src->pts[0].z; |
co657_frmb | 5:2aaaf4e78a53 | 334 | } |
co657_frmb | 5:2aaaf4e78a53 | 335 | } |
co657_frmb | 5:2aaaf4e78a53 | 336 | return; |
co657_frmb | 5:2aaaf4e78a53 | 337 | } |
co657_frmb | 5:2aaaf4e78a53 | 338 | |
co657_frmb | 5:2aaaf4e78a53 | 339 | /* figure out whether the middle point belongs above or below the longest edge */ |
co657_frmb | 5:2aaaf4e78a53 | 340 | if (((src->pts[2].y - src->pts[0].y) * (src->pts[1].x - src->pts[0].x)) < ((src->pts[1].y - src->pts[0].y) * (src->pts[2].x - src->pts[0].x))) { |
co657_frmb | 5:2aaaf4e78a53 | 341 | /* middle point is on the top-portion */ |
co657_frmb | 5:2aaaf4e78a53 | 342 | gfx3d_edgebuf_z_fixin (&(src->pts[0]), &(src->pts[1]), dst->start, dst->zstart, dst->xoff); |
co657_frmb | 5:2aaaf4e78a53 | 343 | gfx3d_edgebuf_z_fixin (&(src->pts[1]), &(src->pts[2]), dst->start, dst->zstart, dst->xoff); |
co657_frmb | 5:2aaaf4e78a53 | 344 | gfx3d_edgebuf_z_fixin (&(src->pts[0]), &(src->pts[2]), dst->end, dst->zend, dst->xoff); |
co657_frmb | 5:2aaaf4e78a53 | 345 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 346 | /* middle point is on the bottom-portion */ |
co657_frmb | 5:2aaaf4e78a53 | 347 | gfx3d_edgebuf_z_fixin (&(src->pts[0]), &(src->pts[2]), dst->start, dst->zstart, dst->xoff); |
co657_frmb | 5:2aaaf4e78a53 | 348 | gfx3d_edgebuf_z_fixin (&(src->pts[0]), &(src->pts[1]), dst->end, dst->zend, dst->xoff); |
co657_frmb | 5:2aaaf4e78a53 | 349 | gfx3d_edgebuf_z_fixin (&(src->pts[1]), &(src->pts[2]), dst->end, dst->zend, dst->xoff); |
co657_frmb | 5:2aaaf4e78a53 | 350 | } |
co657_frmb | 5:2aaaf4e78a53 | 351 | } |
co657_frmb | 5:2aaaf4e78a53 | 352 | |
co657_frmb | 5:2aaaf4e78a53 | 353 | |
co657_frmb | 5:2aaaf4e78a53 | 354 | /** |
co657_frmb | 8:55ee7af49f47 | 355 | * takes a polygon (containing a texture) and an LCD and draws it. |
co657_frmb | 6:0bd002c936bb | 356 | * |
co657_frmb | 6:0bd002c936bb | 357 | * @param src Source polygon. |
co657_frmb | 6:0bd002c936bb | 358 | * @param lcd Display LCD to use (size fixed in various places..). |
co657_frmb | 5:2aaaf4e78a53 | 359 | */ |
co657_frmb | 8:55ee7af49f47 | 360 | void gfx3d_polytxmap (const g3d_poly_t *src, C12832 &lcd) |
co657_frmb | 5:2aaaf4e78a53 | 361 | { |
co657_frmb | 5:2aaaf4e78a53 | 362 | /* assert: polygon points are in order left-to-right */ |
co657_frmb | 5:2aaaf4e78a53 | 363 | int16_t x, use_z = src->pts[0].z; |
co657_frmb | 5:2aaaf4e78a53 | 364 | int32_t dydx_ab, dydx_ac, dydx_bc; |
co657_frmb | 5:2aaaf4e78a53 | 365 | int32_t dudx_ab, dudx_ac, dudx_bc; |
co657_frmb | 5:2aaaf4e78a53 | 366 | int32_t dvdx_ab, dvdx_ac, dvdx_bc; |
co657_frmb | 5:2aaaf4e78a53 | 367 | |
co657_frmb | 5:2aaaf4e78a53 | 368 | if (src->pts[1].x > src->pts[0].x) { |
co657_frmb | 5:2aaaf4e78a53 | 369 | /* we have a left-hand side */ |
co657_frmb | 5:2aaaf4e78a53 | 370 | dydx_ab = ((src->pts[1].y - src->pts[0].y) << 16) / (src->pts[1].x - src->pts[0].x); |
co657_frmb | 5:2aaaf4e78a53 | 371 | dudx_ab = (((int32_t)(src->tx_pts[1] & 0xff) - (int32_t)(src->tx_pts[0] & 0xff)) << 16) / (int32_t)(src->pts[1].x - src->pts[0].x); |
co657_frmb | 5:2aaaf4e78a53 | 372 | dvdx_ab = (((int32_t)(src->tx_pts[1] >> 8) - (int32_t)(src->tx_pts[0] >> 8)) << 16) / (int32_t)(src->pts[1].x - src->pts[0].x); |
co657_frmb | 5:2aaaf4e78a53 | 373 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 374 | dydx_ab = 0; |
co657_frmb | 5:2aaaf4e78a53 | 375 | dudx_ab = 0; |
co657_frmb | 5:2aaaf4e78a53 | 376 | dvdx_ab = 0; |
co657_frmb | 5:2aaaf4e78a53 | 377 | } |
co657_frmb | 5:2aaaf4e78a53 | 378 | if (src->pts[2].x > src->pts[0].x) { |
co657_frmb | 5:2aaaf4e78a53 | 379 | /* we have the long X edge */ |
co657_frmb | 5:2aaaf4e78a53 | 380 | dydx_ac = ((src->pts[2].y - src->pts[0].y) << 16) / (src->pts[2].x - src->pts[0].x); |
co657_frmb | 5:2aaaf4e78a53 | 381 | dudx_ac = (((int32_t)(src->tx_pts[2] & 0xff) - (int32_t)(src->tx_pts[0] & 0xff)) << 16) / (int32_t)(src->pts[2].x - src->pts[0].x); |
co657_frmb | 5:2aaaf4e78a53 | 382 | dvdx_ac = (((int32_t)(src->tx_pts[2] >> 8) - (int32_t)(src->tx_pts[0] >> 8)) << 16) / (int32_t)(src->pts[2].x - src->pts[0].x); |
co657_frmb | 5:2aaaf4e78a53 | 383 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 384 | dydx_ac = 0; |
co657_frmb | 5:2aaaf4e78a53 | 385 | dudx_ac = 0; |
co657_frmb | 5:2aaaf4e78a53 | 386 | dvdx_ac = 0; |
co657_frmb | 5:2aaaf4e78a53 | 387 | } |
co657_frmb | 5:2aaaf4e78a53 | 388 | if (src->pts[2].x > src->pts[1].x) { |
co657_frmb | 5:2aaaf4e78a53 | 389 | /* we have a right-hand side */ |
co657_frmb | 5:2aaaf4e78a53 | 390 | dydx_bc = ((src->pts[2].y - src->pts[1].y) << 16) / (src->pts[2].x - src->pts[1].x); |
co657_frmb | 5:2aaaf4e78a53 | 391 | dudx_bc = (((int32_t)(src->tx_pts[2] & 0xff) - (int32_t)(src->tx_pts[1] & 0xff)) << 16) / (int32_t)(src->pts[2].x - src->pts[1].x); |
co657_frmb | 5:2aaaf4e78a53 | 392 | dvdx_bc = (((int32_t)(src->tx_pts[2] >> 8) - (int32_t)(src->tx_pts[1] >> 8)) << 16) / (int32_t)(src->pts[2].x - src->pts[1].x); |
co657_frmb | 5:2aaaf4e78a53 | 393 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 394 | dydx_bc = 0; |
co657_frmb | 5:2aaaf4e78a53 | 395 | dudx_bc = 0; |
co657_frmb | 5:2aaaf4e78a53 | 396 | dvdx_bc = 0; |
co657_frmb | 5:2aaaf4e78a53 | 397 | } |
co657_frmb | 6:0bd002c936bb | 398 | |
co657_frmb | 6:0bd002c936bb | 399 | /* Note: |
co657_frmb | 6:0bd002c936bb | 400 | * - mostly 16.16 fixpoint stuff. |
co657_frmb | 6:0bd002c936bb | 401 | * - could optimise more by better pixel plotting (directly into the buffer). |
co657_frmb | 6:0bd002c936bb | 402 | */ |
co657_frmb | 6:0bd002c936bb | 403 | |
co657_frmb | 5:2aaaf4e78a53 | 404 | int32_t y_top = (src->pts[0].y << 16) + 0x8000; |
co657_frmb | 5:2aaaf4e78a53 | 405 | int32_t y_bot = (src->pts[0].y << 16) + 0x8000; |
co657_frmb | 5:2aaaf4e78a53 | 406 | int32_t tx_top_x = (src->tx_pts[0] & 0xff) << 16; |
co657_frmb | 5:2aaaf4e78a53 | 407 | int32_t tx_top_y = (src->tx_pts[0] >> 8) << 16; |
co657_frmb | 5:2aaaf4e78a53 | 408 | int32_t tx_bot_x = (src->tx_pts[0] & 0xff) << 16; |
co657_frmb | 5:2aaaf4e78a53 | 409 | int32_t tx_bot_y = (src->tx_pts[0] >> 8) << 16; |
co657_frmb | 6:0bd002c936bb | 410 | int32_t tx_dudy, tx_dvdy; |
co657_frmb | 6:0bd002c936bb | 411 | int16_t ys; |
co657_frmb | 6:0bd002c936bb | 412 | |
co657_frmb | 6:0bd002c936bb | 413 | /* the texture gradients (tx_dudy, tx_dvdy) are constant for any particular triangle */ |
co657_frmb | 5:2aaaf4e78a53 | 414 | |
co657_frmb | 6:0bd002c936bb | 415 | int32_t tx_ctemp, tx_tall, p_y, tp_x, tp_y; |
co657_frmb | 6:0bd002c936bb | 416 | |
co657_frmb | 6:0bd002c936bb | 417 | if (src->pts[2].x == src->pts[0].x) { |
co657_frmb | 6:0bd002c936bb | 418 | /* skinny */ |
co657_frmb | 6:0bd002c936bb | 419 | tx_ctemp = 0; |
co657_frmb | 6:0bd002c936bb | 420 | } else { |
co657_frmb | 6:0bd002c936bb | 421 | tx_ctemp = ((src->pts[1].x - src->pts[0].x) << 16) / (src->pts[2].x - src->pts[0].x); /* factor of AB to AC, (fixpoint 0->1) */ |
co657_frmb | 6:0bd002c936bb | 422 | } |
co657_frmb | 6:0bd002c936bb | 423 | |
co657_frmb | 6:0bd002c936bb | 424 | p_y = y_top + ((src->pts[2].y - src->pts[0].y) * tx_ctemp); |
co657_frmb | 6:0bd002c936bb | 425 | tp_x = ((int32_t)(src->tx_pts[0] & 0xff) << 16) + ((int32_t)((src->tx_pts[2] & 0xff) - (src->tx_pts[0] & 0xff)) * tx_ctemp); |
co657_frmb | 6:0bd002c936bb | 426 | tp_y = ((int32_t)(src->tx_pts[0] >> 8) << 16) + ((int32_t)((src->tx_pts[2] >> 8) - (src->tx_pts[0] >> 8)) * tx_ctemp); |
co657_frmb | 6:0bd002c936bb | 427 | |
co657_frmb | 6:0bd002c936bb | 428 | tx_tall = abs ((p_y - (src->pts[1].y << 16)) >> 8); /* height of tallest scan -- positive 24.8 fixpoint */ |
co657_frmb | 6:0bd002c936bb | 429 | |
co657_frmb | 6:0bd002c936bb | 430 | if (tx_tall == 0) { |
co657_frmb | 6:0bd002c936bb | 431 | /* flat in effect */ |
co657_frmb | 6:0bd002c936bb | 432 | tx_dudy = 0; |
co657_frmb | 6:0bd002c936bb | 433 | tx_dvdy = 0; |
co657_frmb | 6:0bd002c936bb | 434 | ys = 1; |
co657_frmb | 6:0bd002c936bb | 435 | } else { |
co657_frmb | 6:0bd002c936bb | 436 | tx_dudy = (tp_x - ((int32_t)(src->tx_pts[1] & 0xff) << 16)); |
co657_frmb | 6:0bd002c936bb | 437 | tx_dudy = (tx_dudy / tx_tall) << 8; |
co657_frmb | 6:0bd002c936bb | 438 | tx_dvdy = (tp_y - ((int32_t)(src->tx_pts[1] >> 8) << 16)); |
co657_frmb | 6:0bd002c936bb | 439 | tx_dvdy = (tx_dvdy / tx_tall) << 8; |
co657_frmb | 6:0bd002c936bb | 440 | ys = (p_y > (src->pts[1].y << 16)) ? 1 : -1; |
co657_frmb | 6:0bd002c936bb | 441 | } |
co657_frmb | 6:0bd002c936bb | 442 | |
co657_frmb | 5:2aaaf4e78a53 | 443 | /* left-hand side */ |
co657_frmb | 5:2aaaf4e78a53 | 444 | for (x=src->pts[0].x; x<src->pts[1].x; x++) { |
co657_frmb | 5:2aaaf4e78a53 | 445 | int16_t pix_y = (y_top >> 16); |
co657_frmb | 5:2aaaf4e78a53 | 446 | int16_t bpix_y = (y_bot >> 16) + ys; /* make sure we include the bottom pixel */ |
co657_frmb | 5:2aaaf4e78a53 | 447 | int16_t y; |
co657_frmb | 6:0bd002c936bb | 448 | int16_t tpix_y, tpix_x; |
co657_frmb | 5:2aaaf4e78a53 | 449 | |
co657_frmb | 5:2aaaf4e78a53 | 450 | int32_t stx_y = tx_top_y; |
co657_frmb | 5:2aaaf4e78a53 | 451 | int32_t stx_x = tx_top_x; |
co657_frmb | 5:2aaaf4e78a53 | 452 | |
co657_frmb | 5:2aaaf4e78a53 | 453 | y_top += dydx_ab; y_bot += dydx_ac; |
co657_frmb | 5:2aaaf4e78a53 | 454 | tx_top_x += dudx_ab; tx_top_y += dvdx_ab; |
co657_frmb | 5:2aaaf4e78a53 | 455 | tx_bot_x += dudx_ac; tx_bot_y += dvdx_ac; |
co657_frmb | 5:2aaaf4e78a53 | 456 | |
co657_frmb | 5:2aaaf4e78a53 | 457 | if ((x < 0) || (x >= DISPLAY_WIDTH)) { |
co657_frmb | 5:2aaaf4e78a53 | 458 | continue; |
co657_frmb | 5:2aaaf4e78a53 | 459 | } |
co657_frmb | 5:2aaaf4e78a53 | 460 | |
co657_frmb | 5:2aaaf4e78a53 | 461 | for (y=pix_y; y != bpix_y; y += ys) { |
co657_frmb | 5:2aaaf4e78a53 | 462 | if ((y < 0) || (y >= DISPLAY_HEIGHT)) { |
co657_frmb | 6:0bd002c936bb | 463 | goto yl_loop_advance; |
co657_frmb | 5:2aaaf4e78a53 | 464 | } |
co657_frmb | 5:2aaaf4e78a53 | 465 | if (use_z > ZBUFFER (x, y)) { |
co657_frmb | 6:0bd002c936bb | 466 | goto yl_loop_advance; |
co657_frmb | 5:2aaaf4e78a53 | 467 | } |
co657_frmb | 5:2aaaf4e78a53 | 468 | ZBUFFER (x, y) = use_z; |
co657_frmb | 5:2aaaf4e78a53 | 469 | |
co657_frmb | 6:0bd002c936bb | 470 | tpix_y = (stx_y >> 16) & (DISPLAY_HEIGHT - 1); |
co657_frmb | 6:0bd002c936bb | 471 | tpix_x = (stx_x >> 16) & (DISPLAY_WIDTH - 1); |
co657_frmb | 5:2aaaf4e78a53 | 472 | |
co657_frmb | 8:55ee7af49f47 | 473 | lcd.pixel_nochk_norm (x, y, g3d_texture_bit (src->txptr, tpix_x, tpix_y)); |
co657_frmb | 6:0bd002c936bb | 474 | yl_loop_advance: |
co657_frmb | 5:2aaaf4e78a53 | 475 | stx_x += tx_dudy; |
co657_frmb | 5:2aaaf4e78a53 | 476 | stx_y += tx_dvdy; |
co657_frmb | 5:2aaaf4e78a53 | 477 | } |
co657_frmb | 5:2aaaf4e78a53 | 478 | } |
co657_frmb | 5:2aaaf4e78a53 | 479 | |
co657_frmb | 5:2aaaf4e78a53 | 480 | y_top = (src->pts[1].y << 16) + 0x8000; |
co657_frmb | 5:2aaaf4e78a53 | 481 | tx_top_x = (src->tx_pts[1] & 0xff) << 16; |
co657_frmb | 5:2aaaf4e78a53 | 482 | tx_top_y = (src->tx_pts[1] >> 8) << 16; |
co657_frmb | 5:2aaaf4e78a53 | 483 | |
co657_frmb | 5:2aaaf4e78a53 | 484 | /* right-hand side */ |
co657_frmb | 5:2aaaf4e78a53 | 485 | for (; x<src->pts[2].x; x++) { |
co657_frmb | 5:2aaaf4e78a53 | 486 | int16_t pix_y = (y_top >> 16); |
co657_frmb | 5:2aaaf4e78a53 | 487 | int16_t bpix_y = (y_bot >> 16) + ys; |
co657_frmb | 5:2aaaf4e78a53 | 488 | int16_t y; |
co657_frmb | 6:0bd002c936bb | 489 | int16_t tpix_y, tpix_x; |
co657_frmb | 5:2aaaf4e78a53 | 490 | |
co657_frmb | 5:2aaaf4e78a53 | 491 | int32_t stx_y = tx_top_y; |
co657_frmb | 5:2aaaf4e78a53 | 492 | int32_t stx_x = tx_top_x; |
co657_frmb | 6:0bd002c936bb | 493 | |
co657_frmb | 5:2aaaf4e78a53 | 494 | y_top += dydx_bc; y_bot += dydx_ac; |
co657_frmb | 5:2aaaf4e78a53 | 495 | tx_top_x += dudx_bc; tx_top_y += dvdx_bc; |
co657_frmb | 5:2aaaf4e78a53 | 496 | tx_bot_x += dudx_ac; tx_bot_y += dvdx_ac; |
co657_frmb | 5:2aaaf4e78a53 | 497 | |
co657_frmb | 5:2aaaf4e78a53 | 498 | if ((x < 0) || (x >= DISPLAY_WIDTH)) { |
co657_frmb | 5:2aaaf4e78a53 | 499 | continue; |
co657_frmb | 5:2aaaf4e78a53 | 500 | } |
co657_frmb | 5:2aaaf4e78a53 | 501 | |
co657_frmb | 5:2aaaf4e78a53 | 502 | for (y=pix_y; y != bpix_y; y += ys) { |
co657_frmb | 5:2aaaf4e78a53 | 503 | if ((y < 0) || (y >= DISPLAY_HEIGHT)) { |
co657_frmb | 6:0bd002c936bb | 504 | goto yr_loop_advance; |
co657_frmb | 5:2aaaf4e78a53 | 505 | } |
co657_frmb | 5:2aaaf4e78a53 | 506 | if (use_z > ZBUFFER (x, y)) { |
co657_frmb | 6:0bd002c936bb | 507 | goto yr_loop_advance; |
co657_frmb | 5:2aaaf4e78a53 | 508 | } |
co657_frmb | 5:2aaaf4e78a53 | 509 | ZBUFFER (x, y) = use_z; |
co657_frmb | 5:2aaaf4e78a53 | 510 | |
co657_frmb | 6:0bd002c936bb | 511 | tpix_y = (stx_y >> 16) & (DISPLAY_HEIGHT - 1); |
co657_frmb | 6:0bd002c936bb | 512 | tpix_x = (stx_x >> 16) & (DISPLAY_WIDTH - 1); |
co657_frmb | 5:2aaaf4e78a53 | 513 | |
co657_frmb | 8:55ee7af49f47 | 514 | lcd.pixel_nochk_norm (x, y, g3d_texture_bit (src->txptr, tpix_x, tpix_y)); |
co657_frmb | 5:2aaaf4e78a53 | 515 | |
co657_frmb | 6:0bd002c936bb | 516 | yr_loop_advance: |
co657_frmb | 5:2aaaf4e78a53 | 517 | stx_x += tx_dudy; |
co657_frmb | 5:2aaaf4e78a53 | 518 | stx_y += tx_dvdy; |
co657_frmb | 5:2aaaf4e78a53 | 519 | } |
co657_frmb | 5:2aaaf4e78a53 | 520 | } |
co657_frmb | 5:2aaaf4e78a53 | 521 | } |
co657_frmb | 5:2aaaf4e78a53 | 522 | |
co657_frmb | 5:2aaaf4e78a53 | 523 | |
co657_frmb | 5:2aaaf4e78a53 | 524 | /** |
co657_frmb | 6:0bd002c936bb | 525 | * takes a polygon, drawing it on the given LCD with shading based on normal value. |
co657_frmb | 6:0bd002c936bb | 526 | * |
co657_frmb | 6:0bd002c936bb | 527 | * @param src Source polygon. |
co657_frmb | 6:0bd002c936bb | 528 | * @param lcd Display LCD to use (size fixed in various places..). |
co657_frmb | 6:0bd002c936bb | 529 | */ |
co657_frmb | 6:0bd002c936bb | 530 | void gfx3d_polynormmap (const g3d_poly_t *src, C12832 &lcd) |
co657_frmb | 6:0bd002c936bb | 531 | { |
co657_frmb | 6:0bd002c936bb | 532 | /* assert: polygon points are in order left-to-right */ |
co657_frmb | 6:0bd002c936bb | 533 | int16_t x, use_z = src->pts[0].z; |
co657_frmb | 6:0bd002c936bb | 534 | int32_t dydx_ab, dydx_ac, dydx_bc; |
co657_frmb | 6:0bd002c936bb | 535 | |
co657_frmb | 6:0bd002c936bb | 536 | if (src->pts[1].x > src->pts[0].x) { |
co657_frmb | 6:0bd002c936bb | 537 | /* we have a left-hand side */ |
co657_frmb | 6:0bd002c936bb | 538 | dydx_ab = ((src->pts[1].y - src->pts[0].y) << 16) / (src->pts[1].x - src->pts[0].x); |
co657_frmb | 6:0bd002c936bb | 539 | } else { |
co657_frmb | 6:0bd002c936bb | 540 | dydx_ab = 0; |
co657_frmb | 6:0bd002c936bb | 541 | } |
co657_frmb | 6:0bd002c936bb | 542 | if (src->pts[2].x > src->pts[0].x) { |
co657_frmb | 6:0bd002c936bb | 543 | /* we have the long X edge */ |
co657_frmb | 6:0bd002c936bb | 544 | dydx_ac = ((src->pts[2].y - src->pts[0].y) << 16) / (src->pts[2].x - src->pts[0].x); |
co657_frmb | 6:0bd002c936bb | 545 | } else { |
co657_frmb | 6:0bd002c936bb | 546 | dydx_ac = 0; |
co657_frmb | 6:0bd002c936bb | 547 | } |
co657_frmb | 6:0bd002c936bb | 548 | if (src->pts[2].x > src->pts[1].x) { |
co657_frmb | 6:0bd002c936bb | 549 | /* we have a right-hand side */ |
co657_frmb | 6:0bd002c936bb | 550 | dydx_bc = ((src->pts[2].y - src->pts[1].y) << 16) / (src->pts[2].x - src->pts[1].x); |
co657_frmb | 6:0bd002c936bb | 551 | } else { |
co657_frmb | 6:0bd002c936bb | 552 | dydx_bc = 0; |
co657_frmb | 6:0bd002c936bb | 553 | } |
co657_frmb | 6:0bd002c936bb | 554 | |
co657_frmb | 6:0bd002c936bb | 555 | /* Note: |
co657_frmb | 6:0bd002c936bb | 556 | * - mostly 16.16 fixpoint stuff. |
co657_frmb | 6:0bd002c936bb | 557 | * - could optimise more by better pixel plotting (directly into the buffer). |
co657_frmb | 6:0bd002c936bb | 558 | */ |
co657_frmb | 6:0bd002c936bb | 559 | |
co657_frmb | 6:0bd002c936bb | 560 | int32_t y_top = (src->pts[0].y << 16) + 0x8000; |
co657_frmb | 6:0bd002c936bb | 561 | int32_t y_bot = (src->pts[0].y << 16) + 0x8000; |
co657_frmb | 6:0bd002c936bb | 562 | int16_t ys; |
co657_frmb | 6:0bd002c936bb | 563 | int32_t tx_ctemp, tx_tall, p_y; |
co657_frmb | 6:0bd002c936bb | 564 | int bitstep = (32 - __CLZ (src->norm)) >> 2; |
co657_frmb | 6:0bd002c936bb | 565 | int pcount = 0; |
co657_frmb | 6:0bd002c936bb | 566 | |
co657_frmb | 6:0bd002c936bb | 567 | if (bitstep == 0) { |
co657_frmb | 6:0bd002c936bb | 568 | bitstep = 1; |
co657_frmb | 6:0bd002c936bb | 569 | } |
co657_frmb | 6:0bd002c936bb | 570 | if (src->pts[2].x == src->pts[0].x) { |
co657_frmb | 6:0bd002c936bb | 571 | /* skinny */ |
co657_frmb | 6:0bd002c936bb | 572 | tx_ctemp = 0; |
co657_frmb | 6:0bd002c936bb | 573 | } else { |
co657_frmb | 6:0bd002c936bb | 574 | tx_ctemp = ((src->pts[1].x - src->pts[0].x) << 16) / (src->pts[2].x - src->pts[0].x); /* factor of AB to AC, (fixpoint 0->1) */ |
co657_frmb | 6:0bd002c936bb | 575 | } |
co657_frmb | 6:0bd002c936bb | 576 | |
co657_frmb | 6:0bd002c936bb | 577 | p_y = y_top + ((src->pts[2].y - src->pts[0].y) * tx_ctemp); |
co657_frmb | 6:0bd002c936bb | 578 | tx_tall = abs ((p_y - (src->pts[1].y << 16)) >> 8); /* height of tallest scan -- positive 24.8 fixpoint */ |
co657_frmb | 6:0bd002c936bb | 579 | |
co657_frmb | 6:0bd002c936bb | 580 | if (tx_tall == 0) { |
co657_frmb | 6:0bd002c936bb | 581 | /* flat in effect */ |
co657_frmb | 6:0bd002c936bb | 582 | ys = 1; |
co657_frmb | 6:0bd002c936bb | 583 | } else { |
co657_frmb | 6:0bd002c936bb | 584 | ys = (p_y > (src->pts[1].y << 16)) ? 1 : -1; |
co657_frmb | 6:0bd002c936bb | 585 | } |
co657_frmb | 6:0bd002c936bb | 586 | |
co657_frmb | 6:0bd002c936bb | 587 | /* left-hand side */ |
co657_frmb | 6:0bd002c936bb | 588 | for (x=src->pts[0].x; x<src->pts[1].x; x++) { |
co657_frmb | 6:0bd002c936bb | 589 | int16_t pix_y = (y_top >> 16); |
co657_frmb | 6:0bd002c936bb | 590 | int16_t bpix_y = (y_bot >> 16) + ys; /* make sure we include the bottom pixel */ |
co657_frmb | 6:0bd002c936bb | 591 | int16_t y; |
co657_frmb | 6:0bd002c936bb | 592 | |
co657_frmb | 6:0bd002c936bb | 593 | y_top += dydx_ab; y_bot += dydx_ac; |
co657_frmb | 6:0bd002c936bb | 594 | |
co657_frmb | 6:0bd002c936bb | 595 | if ((x < 0) || (x >= DISPLAY_WIDTH)) { |
co657_frmb | 6:0bd002c936bb | 596 | continue; |
co657_frmb | 6:0bd002c936bb | 597 | } |
co657_frmb | 6:0bd002c936bb | 598 | |
co657_frmb | 6:0bd002c936bb | 599 | pcount = 0; |
co657_frmb | 6:0bd002c936bb | 600 | for (y=pix_y; y != bpix_y; y += ys) { |
co657_frmb | 6:0bd002c936bb | 601 | if ((y < 0) || (y >= DISPLAY_HEIGHT)) { |
co657_frmb | 6:0bd002c936bb | 602 | continue; |
co657_frmb | 6:0bd002c936bb | 603 | } |
co657_frmb | 6:0bd002c936bb | 604 | if (use_z > ZBUFFER (x, y)) { |
co657_frmb | 6:0bd002c936bb | 605 | continue; |
co657_frmb | 6:0bd002c936bb | 606 | } |
co657_frmb | 6:0bd002c936bb | 607 | ZBUFFER (x, y) = use_z; |
co657_frmb | 6:0bd002c936bb | 608 | |
co657_frmb | 7:393b963e7988 | 609 | lcd.pixel_nochk_norm (x, y, (pcount == 0) ? 1 : 0); |
co657_frmb | 6:0bd002c936bb | 610 | if (!pcount) { |
co657_frmb | 6:0bd002c936bb | 611 | pcount = bitstep; |
co657_frmb | 6:0bd002c936bb | 612 | } |
co657_frmb | 6:0bd002c936bb | 613 | pcount--; |
co657_frmb | 6:0bd002c936bb | 614 | } |
co657_frmb | 6:0bd002c936bb | 615 | } |
co657_frmb | 6:0bd002c936bb | 616 | |
co657_frmb | 6:0bd002c936bb | 617 | y_top = (src->pts[1].y << 16) + 0x8000; |
co657_frmb | 6:0bd002c936bb | 618 | |
co657_frmb | 6:0bd002c936bb | 619 | /* right-hand side */ |
co657_frmb | 6:0bd002c936bb | 620 | for (; x<src->pts[2].x; x++) { |
co657_frmb | 6:0bd002c936bb | 621 | int16_t pix_y = (y_top >> 16); |
co657_frmb | 6:0bd002c936bb | 622 | int16_t bpix_y = (y_bot >> 16) + ys; |
co657_frmb | 6:0bd002c936bb | 623 | int16_t y; |
co657_frmb | 6:0bd002c936bb | 624 | |
co657_frmb | 6:0bd002c936bb | 625 | y_top += dydx_bc; y_bot += dydx_ac; |
co657_frmb | 6:0bd002c936bb | 626 | |
co657_frmb | 6:0bd002c936bb | 627 | if ((x < 0) || (x >= DISPLAY_WIDTH)) { |
co657_frmb | 6:0bd002c936bb | 628 | continue; |
co657_frmb | 6:0bd002c936bb | 629 | } |
co657_frmb | 6:0bd002c936bb | 630 | |
co657_frmb | 6:0bd002c936bb | 631 | pcount = 0; |
co657_frmb | 6:0bd002c936bb | 632 | for (y=pix_y; y != bpix_y; y += ys) { |
co657_frmb | 6:0bd002c936bb | 633 | if ((y < 0) || (y >= DISPLAY_HEIGHT)) { |
co657_frmb | 6:0bd002c936bb | 634 | continue; |
co657_frmb | 6:0bd002c936bb | 635 | } |
co657_frmb | 6:0bd002c936bb | 636 | if (use_z > ZBUFFER (x, y)) { |
co657_frmb | 6:0bd002c936bb | 637 | continue; |
co657_frmb | 6:0bd002c936bb | 638 | } |
co657_frmb | 6:0bd002c936bb | 639 | ZBUFFER (x, y) = use_z; |
co657_frmb | 6:0bd002c936bb | 640 | |
co657_frmb | 7:393b963e7988 | 641 | lcd.pixel_nochk_norm (x, y, (pcount == 0) ? 1 : 0); |
co657_frmb | 6:0bd002c936bb | 642 | if (!pcount) { |
co657_frmb | 6:0bd002c936bb | 643 | pcount = bitstep; |
co657_frmb | 6:0bd002c936bb | 644 | } |
co657_frmb | 6:0bd002c936bb | 645 | pcount--; |
co657_frmb | 6:0bd002c936bb | 646 | } |
co657_frmb | 6:0bd002c936bb | 647 | } |
co657_frmb | 6:0bd002c936bb | 648 | } |
co657_frmb | 6:0bd002c936bb | 649 | |
co657_frmb | 6:0bd002c936bb | 650 | |
co657_frmb | 6:0bd002c936bb | 651 | /** |
co657_frmb | 5:2aaaf4e78a53 | 652 | * takes an edge-buffer and draws its wireframe on the given LCD (start and end). |
co657_frmb | 5:2aaaf4e78a53 | 653 | */ |
co657_frmb | 5:2aaaf4e78a53 | 654 | void gfx3d_wireedge (const g3d_edgebuf_t *edge, C12832 &lcd) |
co657_frmb | 5:2aaaf4e78a53 | 655 | { |
co657_frmb | 5:2aaaf4e78a53 | 656 | int x; |
co657_frmb | 5:2aaaf4e78a53 | 657 | |
co657_frmb | 5:2aaaf4e78a53 | 658 | if (edge->s_end == 1) { |
co657_frmb | 5:2aaaf4e78a53 | 659 | /* special case: vertical line */ |
co657_frmb | 5:2aaaf4e78a53 | 660 | int xp = edge->xoff; |
co657_frmb | 5:2aaaf4e78a53 | 661 | int y0 = edge->start[0]; |
co657_frmb | 5:2aaaf4e78a53 | 662 | int y1 = edge->end[0]; |
co657_frmb | 5:2aaaf4e78a53 | 663 | int ys = (y1 >= y0) ? 1 : -1; |
co657_frmb | 5:2aaaf4e78a53 | 664 | int y; |
co657_frmb | 5:2aaaf4e78a53 | 665 | |
co657_frmb | 5:2aaaf4e78a53 | 666 | int16_t z0 = edge->zstart[0]; |
co657_frmb | 5:2aaaf4e78a53 | 667 | int16_t z1 = edge->zend[0]; |
co657_frmb | 5:2aaaf4e78a53 | 668 | int32_t zval = (z0 << 16) | 0x8000; /* half-way.. */ |
co657_frmb | 5:2aaaf4e78a53 | 669 | |
co657_frmb | 9:db4ec6f7d8b2 | 670 | if (xp >= DISPLAY_WIDTH) { |
co657_frmb | 9:db4ec6f7d8b2 | 671 | /* off right-hand edge */ |
co657_frmb | 9:db4ec6f7d8b2 | 672 | return; |
co657_frmb | 9:db4ec6f7d8b2 | 673 | } else if (xp < 0) { |
co657_frmb | 9:db4ec6f7d8b2 | 674 | /* off left-hand edge */ |
co657_frmb | 9:db4ec6f7d8b2 | 675 | return; |
co657_frmb | 9:db4ec6f7d8b2 | 676 | } |
co657_frmb | 9:db4ec6f7d8b2 | 677 | |
co657_frmb | 5:2aaaf4e78a53 | 678 | if ((y0 == y1) || ((y0 + ys) == y1)) { |
co657_frmb | 5:2aaaf4e78a53 | 679 | /* one or two point, since we're narrow, just y0 */ |
co657_frmb | 5:2aaaf4e78a53 | 680 | if (z0 <= ZBUFFER (xp, y0)) { |
co657_frmb | 5:2aaaf4e78a53 | 681 | ZBUFFER (xp, y0) = z0; |
co657_frmb | 7:393b963e7988 | 682 | lcd.pixel_nochk_norm (xp, y0, 1); |
co657_frmb | 5:2aaaf4e78a53 | 683 | } |
co657_frmb | 5:2aaaf4e78a53 | 684 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 685 | /* long vertical poly, set all points except at y1 */ |
co657_frmb | 5:2aaaf4e78a53 | 686 | int32_t zdelta = ((int32_t)(z1 - z0) << 16) / (int32_t)(y1 - y0); |
co657_frmb | 5:2aaaf4e78a53 | 687 | int16_t rc_z = z0; |
co657_frmb | 5:2aaaf4e78a53 | 688 | |
co657_frmb | 5:2aaaf4e78a53 | 689 | for (y = y0; y != y1; y += ys) { |
co657_frmb | 5:2aaaf4e78a53 | 690 | zval += zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 691 | rc_z = (zval >> 16); |
co657_frmb | 5:2aaaf4e78a53 | 692 | if (rc_z <= ZBUFFER (xp, y)) { |
co657_frmb | 5:2aaaf4e78a53 | 693 | ZBUFFER (xp, y) = rc_z; |
co657_frmb | 7:393b963e7988 | 694 | lcd.pixel_nochk_norm (xp, y, 1); |
co657_frmb | 5:2aaaf4e78a53 | 695 | } |
co657_frmb | 5:2aaaf4e78a53 | 696 | } |
co657_frmb | 5:2aaaf4e78a53 | 697 | } |
co657_frmb | 5:2aaaf4e78a53 | 698 | return; |
co657_frmb | 5:2aaaf4e78a53 | 699 | } |
co657_frmb | 5:2aaaf4e78a53 | 700 | |
co657_frmb | 5:2aaaf4e78a53 | 701 | for (x=0; x<edge->s_end; x++) { |
co657_frmb | 5:2aaaf4e78a53 | 702 | int xp = x + edge->xoff; |
co657_frmb | 5:2aaaf4e78a53 | 703 | int y0 = edge->start[x]; |
co657_frmb | 5:2aaaf4e78a53 | 704 | int y1 = edge->end[x]; |
co657_frmb | 5:2aaaf4e78a53 | 705 | int ys = (y1 >= y0) ? 1 : -1; |
co657_frmb | 5:2aaaf4e78a53 | 706 | int y; |
co657_frmb | 5:2aaaf4e78a53 | 707 | |
co657_frmb | 5:2aaaf4e78a53 | 708 | int16_t z0 = edge->zstart[x]; |
co657_frmb | 5:2aaaf4e78a53 | 709 | int16_t z1 = edge->zend[x]; |
co657_frmb | 5:2aaaf4e78a53 | 710 | |
co657_frmb | 5:2aaaf4e78a53 | 711 | int32_t zval = (z0 << 16) | 0x8000; /* half-way.. */ |
co657_frmb | 9:db4ec6f7d8b2 | 712 | |
co657_frmb | 9:db4ec6f7d8b2 | 713 | if ((xp >= DISPLAY_WIDTH) || (xp < 0)) { |
co657_frmb | 9:db4ec6f7d8b2 | 714 | continue; |
co657_frmb | 9:db4ec6f7d8b2 | 715 | } |
co657_frmb | 9:db4ec6f7d8b2 | 716 | |
co657_frmb | 5:2aaaf4e78a53 | 717 | if (y0 == y1) { |
co657_frmb | 5:2aaaf4e78a53 | 718 | /* point, but we don't plot assuming it belongs to the adjoining polygon */ |
co657_frmb | 5:2aaaf4e78a53 | 719 | } else if ((y0 + ys) == y1) { |
co657_frmb | 5:2aaaf4e78a53 | 720 | /* two-point poly, just plot y0 */ |
co657_frmb | 5:2aaaf4e78a53 | 721 | if (z0 <= ZBUFFER (xp, y0)) { |
co657_frmb | 5:2aaaf4e78a53 | 722 | ZBUFFER (xp, y0) = z0; |
co657_frmb | 7:393b963e7988 | 723 | lcd.pixel_nochk_norm (xp, y0, 1); |
co657_frmb | 5:2aaaf4e78a53 | 724 | } |
co657_frmb | 5:2aaaf4e78a53 | 725 | } else { |
co657_frmb | 5:2aaaf4e78a53 | 726 | /* more than two points, shrink y1 to avoid plotting the last one here */ |
co657_frmb | 5:2aaaf4e78a53 | 727 | int32_t zdelta = ((int32_t)(z1 - z0) << 16) / (int32_t)(y1 - y0); |
co657_frmb | 5:2aaaf4e78a53 | 728 | int16_t rc_z = z0; |
co657_frmb | 5:2aaaf4e78a53 | 729 | |
co657_frmb | 5:2aaaf4e78a53 | 730 | y1 -= ys; |
co657_frmb | 5:2aaaf4e78a53 | 731 | |
co657_frmb | 5:2aaaf4e78a53 | 732 | /* start at y0 */ |
co657_frmb | 5:2aaaf4e78a53 | 733 | y = y0; |
co657_frmb | 5:2aaaf4e78a53 | 734 | if (rc_z <= ZBUFFER (xp, y)) { |
co657_frmb | 5:2aaaf4e78a53 | 735 | ZBUFFER (xp, y) = rc_z; |
co657_frmb | 7:393b963e7988 | 736 | lcd.pixel_nochk_norm (xp, y, 1); |
co657_frmb | 5:2aaaf4e78a53 | 737 | } |
co657_frmb | 5:2aaaf4e78a53 | 738 | |
co657_frmb | 5:2aaaf4e78a53 | 739 | for (y += ys; y != y1; y += ys) { |
co657_frmb | 5:2aaaf4e78a53 | 740 | zval += zdelta; |
co657_frmb | 5:2aaaf4e78a53 | 741 | rc_z = (zval >> 16); |
co657_frmb | 5:2aaaf4e78a53 | 742 | if (rc_z <= ZBUFFER (xp, y)) { |
co657_frmb | 5:2aaaf4e78a53 | 743 | ZBUFFER (xp, y) = rc_z; |
co657_frmb | 7:393b963e7988 | 744 | lcd.pixel_nochk_norm (xp, y, 0); |
co657_frmb | 5:2aaaf4e78a53 | 745 | } |
co657_frmb | 5:2aaaf4e78a53 | 746 | } |
co657_frmb | 5:2aaaf4e78a53 | 747 | /* last pixel at y1,z1 */ |
co657_frmb | 5:2aaaf4e78a53 | 748 | rc_z = z1; |
co657_frmb | 5:2aaaf4e78a53 | 749 | if (rc_z <= ZBUFFER (xp, y1)) { |
co657_frmb | 5:2aaaf4e78a53 | 750 | ZBUFFER (xp, y1) = rc_z; |
co657_frmb | 7:393b963e7988 | 751 | lcd.pixel_nochk_norm (xp, y1, 1); |
co657_frmb | 5:2aaaf4e78a53 | 752 | } |
co657_frmb | 5:2aaaf4e78a53 | 753 | } |
co657_frmb | 5:2aaaf4e78a53 | 754 | |
co657_frmb | 5:2aaaf4e78a53 | 755 | /* end of x-loop */ |
co657_frmb | 5:2aaaf4e78a53 | 756 | } |
co657_frmb | 5:2aaaf4e78a53 | 757 | } |
co657_frmb | 5:2aaaf4e78a53 | 758 |