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