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 +}