gba-x3dtest
diff src/polyfill.c @ 5:850be43b3135
sdl version
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 16 Jun 2014 22:01:45 +0300 |
parents | |
children | 73b5f2e5d18a |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/polyfill.c Mon Jun 16 22:01:45 2014 +0300 1.3 @@ -0,0 +1,91 @@ 1.4 +#include "config.h" 1.5 +#include <string.h> 1.6 +#include "polyfill.h" 1.7 +#include "fixed.h" 1.8 +#include "gbasys.h" 1.9 + 1.10 +static void fill_scanline(int y, int x0, int x1, uint16_t color); 1.11 + 1.12 +void draw_poly(int num, const pvec3 *verts, uint16_t color) 1.13 +{ 1.14 + int i, topidx = 0, botidx = 0; 1.15 + int lidx[2], ridx[2]; 1.16 + int32_t y, topy, boty; 1.17 + int32_t ldy, rdy, ldxdy, rdxdy; 1.18 + int32_t lx, rx; 1.19 + int start, end; 1.20 + 1.21 + topy = boty = verts[0].y; 1.22 + for(i=1; i<num; i++) { 1.23 + int32_t y = verts[i].y; 1.24 + if(y < topy) { 1.25 + topy = y; 1.26 + topidx = i; 1.27 + } 1.28 + if(y > boty) { 1.29 + boty = y; 1.30 + botidx = i; 1.31 + } 1.32 + } 1.33 + 1.34 + lidx[0] = ridx[0] = topidx; 1.35 + lidx[1] = topidx ? topidx - 1 : num - 1; 1.36 + ridx[1] = (topidx + 1) % num; 1.37 + 1.38 + if(ridx[1] < lidx[1]) { 1.39 + return; /* backface (CCW) */ 1.40 + } 1.41 + 1.42 + lx = rx = verts[lidx[0]].x; 1.43 + 1.44 + ldy = verts[lidx[1]].y - verts[lidx[0]].y; 1.45 + ldxdy = x16div(verts[lidx[1]].x - lx, ldy); 1.46 + 1.47 + rdy = verts[ridx[1]].y - verts[ridx[1]].y; 1.48 + rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 1.49 + 1.50 + start = topy >> 16; 1.51 + end = boty >> 16; 1.52 + 1.53 + y = topy; 1.54 + for(i=start; i<end; i++) { 1.55 + unsigned short x0, x1; 1.56 + 1.57 + x0 = lx < 0 ? 0 : (lx >> 16); 1.58 + x1 = rx >= WIDTH ? WIDTH - 1 : (rx >> 16); 1.59 + 1.60 + fill_scanline(i, x0, x1, color); 1.61 + 1.62 + if(y >= verts[lidx[1]].y) { 1.63 + lidx[0] = lidx[1]; 1.64 + lidx[1] = lidx[1] ? lidx[1] - 1 : num - 1; 1.65 + ldy = verts[lidx[1]].y - verts[lidx[0]].y; 1.66 + if(ldy < 0) { 1.67 + break; 1.68 + } 1.69 + ldxdy = x16div(verts[lidx[1]].x - lx, ldy); 1.70 + } 1.71 + if(y >= verts[ridx[1]].y) { 1.72 + ridx[0] = ridx[1]; 1.73 + ridx[1] = (ridx[1] + 1) % num; 1.74 + rdy = verts[ridx[1]].y - verts[ridx[0]].y; 1.75 + if(rdy < 0) { 1.76 + break; 1.77 + } 1.78 + rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 1.79 + } 1.80 + 1.81 + lx += ldxdy; 1.82 + rx += rdxdy; 1.83 + } 1.84 +} 1.85 + 1.86 +static void fill_scanline(int y, int x0, int x1, uint16_t color) 1.87 +{ 1.88 + int i; 1.89 + uint16_t *pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0; 1.90 + 1.91 + for(i=x0; i<x1; i++) { 1.92 + *pixels++ = color; 1.93 + } 1.94 +}