gba-x3dtest
diff src/polyfill.c @ 14:c398d834d64a
fixed the rendering bugs
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 23 Jun 2014 10:33:24 +0300 |
parents | b0ed38f13261 |
children | b755fb002f17 |
line diff
1.1 --- a/src/polyfill.c Mon Jun 23 08:28:28 2014 +0300 1.2 +++ b/src/polyfill.c Mon Jun 23 10:33:24 2014 +0300 1.3 @@ -10,6 +10,7 @@ 1.4 1.5 static void fill_scanline_pal(int y, int x0, int x1, uint8_t color); 1.6 static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color); 1.7 +static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1); 1.8 1.9 void draw_poly(int num, const pvec3 *verts, uint16_t color) 1.10 { 1.11 @@ -19,6 +20,17 @@ 1.12 int32_t ldy = 0, rdy = 0, ldxdy, rdxdy; 1.13 int32_t lx, rx; 1.14 int start, end; 1.15 + pvec3 v0, v1; 1.16 + 1.17 + v0.x = verts[1].x - verts[0].x; 1.18 + v0.y = verts[1].y - verts[0].y; 1.19 + 1.20 + v1.x = verts[2].x - verts[0].x; 1.21 + v1.y = verts[2].y - verts[0].y; 1.22 + 1.23 + if(winding(v0.x, v0.y, v1.x, v1.y) < 0) { 1.24 + return; /* backface */ 1.25 + } 1.26 1.27 topy = boty = verts[0].y; 1.28 for(i=1; i<num; i++) { 1.29 @@ -69,18 +81,13 @@ 1.30 rx = verts[ridx[0]].x; 1.31 rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 1.32 1.33 - 1.34 - if(verts[ridx[1]].x < verts[lidx[1]].x) { 1.35 - return; /* backface (CCW) */ 1.36 - } 1.37 - 1.38 start = topy >> 16; 1.39 end = boty >> 16; 1.40 1.41 if(end >= HEIGHT) end = HEIGHT - 1; 1.42 1.43 y = topy; 1.44 - for(i=start; i<end; i++) { 1.45 + for(i=start; i<=end; i++) { 1.46 short x0, x1; 1.47 1.48 if(y >= verts[lidx[1]].y) { 1.49 @@ -91,7 +98,11 @@ 1.50 if(ldy < 0) { 1.51 break; 1.52 } 1.53 - ldxdy = x16div(verts[lidx[1]].x - lx, ldy); 1.54 + if(ldy) { 1.55 + ldxdy = x16div(verts[lidx[1]].x - lx, ldy); 1.56 + } else { 1.57 + ldxdy = verts[lidx[1]].x - lx; 1.58 + } 1.59 } 1.60 if(y >= verts[ridx[1]].y) { 1.61 rx = verts[ridx[1]].x; 1.62 @@ -101,13 +112,17 @@ 1.63 if(rdy < 0) { 1.64 break; 1.65 } 1.66 - rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 1.67 + if(rdy) { 1.68 + rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 1.69 + } else { 1.70 + rdxdy = verts[ridx[1]].x - rx; 1.71 + } 1.72 } 1.73 1.74 - x0 = lx < 0 ? 0 : (lx >> 16); 1.75 - x1 = (rx >> 16) >= WIDTH ? WIDTH - 1 : (rx >> 16); 1.76 + x0 = lx >> 16; 1.77 + x1 = rx >> 16; 1.78 1.79 - if(i >= 0 && x1 > x0) { 1.80 + if(i >= 0) {// && x0 < x1) { 1.81 #ifdef PALMODE 1.82 fill_scanline_pal(i, x0, x1, (uint8_t)color); 1.83 #else 1.84 @@ -158,8 +173,18 @@ 1.85 static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color) 1.86 { 1.87 int i; 1.88 - uint16_t *pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0; 1.89 + uint16_t *pixels; 1.90 1.91 + if(x0 > x1) { 1.92 + i = x0; 1.93 + x0 = x1; 1.94 + x1 = i; 1.95 + } 1.96 + 1.97 + if(x0 < 0) x0 = 0; 1.98 + if(x1 >= WIDTH - 1) x1 = WIDTH - 1; 1.99 + 1.100 + pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0; 1.101 for(i=x0; i<x1; i++) { 1.102 *pixels++ = color; 1.103 } 1.104 @@ -187,3 +212,8 @@ 1.105 pixels[y * WIDTH + x] = color; 1.106 #endif 1.107 } 1.108 + 1.109 +static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1) 1.110 +{ 1.111 + return x16mul(x0, y1) - x16mul(y0, x1); 1.112 +}