gba-x3dtest

changeset 14:c398d834d64a

fixed the rendering bugs
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 23 Jun 2014 10:33:24 +0300
parents 2070a81127f2
children b755fb002f17
files src/game.c src/ggen.c src/polyfill.c src/x3d.c
diffstat 4 files changed, 141 insertions(+), 32 deletions(-) [+]
line diff
     1.1 --- a/src/game.c	Mon Jun 23 08:28:28 2014 +0300
     1.2 +++ b/src/game.c	Mon Jun 23 10:33:24 2014 +0300
     1.3 @@ -7,6 +7,8 @@
     1.4  #include "palman.h"
     1.5  #include "ggen.h"
     1.6  
     1.7 +extern int dbg_fill_dump;
     1.8 +
     1.9  static void draw_rect(int x, int y, int w, int h, uint16_t color);
    1.10  
    1.11  #define X16INT(x)	((x) << 16)
    1.12 @@ -65,9 +67,13 @@
    1.13  	}
    1.14  	x3d_translate(itox16(WIDTH / 2), itox16(HEIGHT / 2), 0);*/
    1.15  
    1.16 +	x3d_translate(0, 0, X16INT(6));
    1.17  	x3d_rotate(cam_phi, 65536, 0, 0);
    1.18 -	x3d_rotate(keyrot << 16, 0, 65536, 0);
    1.19 -	x3d_translate(0, 0, X16INT(6));
    1.20 +	if(autorot) {
    1.21 +		x3d_rotate((msec / 64) << 16, 0, 65536, 0);
    1.22 +	} else {
    1.23 +		x3d_rotate(cam_theta, 0, 65536, 0);
    1.24 +	}
    1.25  
    1.26  #ifdef PALMODE
    1.27  	x3d_color_index(255);
    1.28 @@ -102,17 +108,29 @@
    1.29  
    1.30  	switch(key) {
    1.31  	case KEY_LEFT:
    1.32 -		keyrot--;
    1.33 +		cam_theta += 65536;
    1.34  		break;
    1.35  
    1.36  	case KEY_RIGHT:
    1.37 -		keyrot++;
    1.38 +		cam_theta -= 65536;
    1.39 +		break;
    1.40 +
    1.41 +	case KEY_UP:
    1.42 +		cam_phi += 65536;
    1.43 +		break;
    1.44 +
    1.45 +	case KEY_DOWN:
    1.46 +		cam_phi -= 65536;
    1.47  		break;
    1.48  
    1.49  	case KEY_A:
    1.50  		autorot = !autorot;
    1.51  		break;
    1.52  
    1.53 +	case KEY_SELECT:
    1.54 +		dbg_fill_dump = 1;
    1.55 +		break;
    1.56 +
    1.57  	default:
    1.58  		break;
    1.59  	}
     2.1 --- a/src/ggen.c	Mon Jun 23 08:28:28 2014 +0300
     2.2 +++ b/src/ggen.c	Mon Jun 23 10:33:24 2014 +0300
     2.3 @@ -20,8 +20,8 @@
     2.4  int gen_box(struct mesh *m)
     2.5  {
     2.6  	int i;
     2.7 -	int num_faces = 8;
     2.8 -	int num_verts = num_faces * 4;
     2.9 +	int num_faces = 12;
    2.10 +	int num_verts = num_faces * 3;
    2.11  	int32_t v[8][3] = {
    2.12  		{-X1, -X1, -X1}, {X1, -X1, -X1}, {X1, -X1, X1}, {-X1, -X1, X1},
    2.13  		{-X1, X1, -X1}, {X1, X1, -X1}, {X1, X1, X1}, {-X1, X1, X1}
    2.14 @@ -29,7 +29,7 @@
    2.15  	int32_t *vptr, *cptr;
    2.16  
    2.17  
    2.18 -	m->prim = X3D_QUADS;
    2.19 +	m->prim = X3D_TRIANGLES;
    2.20  	m->nverts = num_verts;
    2.21  	if(!(m->verts = malloc(num_verts * 3 * sizeof *m->verts))) {
    2.22  		return -1;
    2.23 @@ -45,43 +45,67 @@
    2.24  	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.25  	VERTEX(v[1][0], v[1][1], v[1][2]);
    2.26  	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.27 +	for(i=0; i<3; i++) COLOR(32768, 0, 32768);
    2.28 +
    2.29 +	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.30 +	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.31  	VERTEX(v[3][0], v[3][1], v[3][2]);
    2.32 -	for(i=0; i<4; i++) COLOR(65536, 0, 65536);
    2.33 +	for(i=0; i<3; i++) COLOR(65536, 0, 65536);
    2.34  
    2.35  	/* +Y */
    2.36 +	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.37 +	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.38 +	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.39 +	for(i=0; i<3; i++) COLOR(0, 32768, 0);
    2.40 +
    2.41 +	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.42 +	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.43  	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.44 -	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.45 -	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.46 -	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.47 -	for(i=0; i<4; i++) COLOR(0, 65536, 0);
    2.48 +	for(i=0; i<3; i++) COLOR(0, 65536, 0);
    2.49  
    2.50  	/* -Z */
    2.51  	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.52  	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.53  	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.54 +	for(i=0; i<3; i++) COLOR(32768, 32768, 0);
    2.55 +
    2.56 +	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.57 +	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.58  	VERTEX(v[1][0], v[1][1], v[1][2]);
    2.59 -	for(i=0; i<4; i++) COLOR(65536, 65536, 0);
    2.60 +	for(i=0; i<3; i++) COLOR(65536, 65536, 0);
    2.61  
    2.62  	/* +Z */
    2.63  	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.64  	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.65  	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.66 +	for(i=0; i<3; i++) COLOR(0, 0, 32768);
    2.67 +
    2.68 +	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.69 +	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.70  	VERTEX(v[3][0], v[3][1], v[3][2]);
    2.71 -	for(i=0; i<4; i++) COLOR(0, 0, 65536);
    2.72 +	for(i=0; i<3; i++) COLOR(0, 0, 65536);
    2.73  
    2.74  	/* +X */
    2.75  	VERTEX(v[1][0], v[1][1], v[1][2]);
    2.76  	VERTEX(v[5][0], v[5][1], v[5][2]);
    2.77  	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.78 +	for(i=0; i<3; i++) COLOR(32768, 0, 0);
    2.79 +
    2.80 +	VERTEX(v[1][0], v[1][1], v[1][2]);
    2.81 +	VERTEX(v[6][0], v[6][1], v[6][2]);
    2.82  	VERTEX(v[2][0], v[2][1], v[2][2]);
    2.83 -	for(i=0; i<4; i++) COLOR(65536, 0, 0);
    2.84 +	for(i=0; i<3; i++) COLOR(65536, 0, 0);
    2.85  
    2.86  	/* -X */
    2.87  	VERTEX(v[3][0], v[3][1], v[3][2]);
    2.88  	VERTEX(v[7][0], v[7][1], v[7][2]);
    2.89  	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.90 +	for(i=0; i<3; i++) COLOR(0, 32768, 32768);
    2.91 +
    2.92 +	VERTEX(v[3][0], v[3][1], v[3][2]);
    2.93 +	VERTEX(v[4][0], v[4][1], v[4][2]);
    2.94  	VERTEX(v[0][0], v[0][1], v[0][2]);
    2.95 -	for(i=0; i<4; i++) COLOR(0, 65536, 65536);
    2.96 +	for(i=0; i<3; i++) COLOR(0, 65536, 65536);
    2.97  
    2.98  	return 0;
    2.99  }
     3.1 --- a/src/polyfill.c	Mon Jun 23 08:28:28 2014 +0300
     3.2 +++ b/src/polyfill.c	Mon Jun 23 10:33:24 2014 +0300
     3.3 @@ -10,6 +10,7 @@
     3.4  
     3.5  static void fill_scanline_pal(int y, int x0, int x1, uint8_t color);
     3.6  static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color);
     3.7 +static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1);
     3.8  
     3.9  void draw_poly(int num, const pvec3 *verts, uint16_t color)
    3.10  {
    3.11 @@ -19,6 +20,17 @@
    3.12  	int32_t ldy = 0, rdy = 0, ldxdy, rdxdy;
    3.13  	int32_t lx, rx;
    3.14  	int start, end;
    3.15 +	pvec3 v0, v1;
    3.16 +
    3.17 +	v0.x = verts[1].x - verts[0].x;
    3.18 +	v0.y = verts[1].y - verts[0].y;
    3.19 +
    3.20 +	v1.x = verts[2].x - verts[0].x;
    3.21 +	v1.y = verts[2].y - verts[0].y;
    3.22 +
    3.23 +	if(winding(v0.x, v0.y, v1.x, v1.y) < 0) {
    3.24 +		return;	/* backface */
    3.25 +	}
    3.26  
    3.27  	topy = boty = verts[0].y;
    3.28  	for(i=1; i<num; i++) {
    3.29 @@ -69,18 +81,13 @@
    3.30  	rx = verts[ridx[0]].x;
    3.31  	rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
    3.32  
    3.33 -
    3.34 -	if(verts[ridx[1]].x < verts[lidx[1]].x) {
    3.35 -		return;	/*  backface (CCW) */
    3.36 -	}
    3.37 -
    3.38  	start = topy >> 16;
    3.39  	end = boty >> 16;
    3.40  
    3.41  	if(end >= HEIGHT) end = HEIGHT - 1;
    3.42  
    3.43  	y = topy;
    3.44 -	for(i=start; i<end; i++) {
    3.45 +	for(i=start; i<=end; i++) {
    3.46  		short x0, x1;
    3.47  
    3.48  		if(y >= verts[lidx[1]].y) {
    3.49 @@ -91,7 +98,11 @@
    3.50  			if(ldy < 0) {
    3.51  				break;
    3.52  			}
    3.53 -			ldxdy = x16div(verts[lidx[1]].x - lx, ldy);
    3.54 +			if(ldy) {
    3.55 +				ldxdy = x16div(verts[lidx[1]].x - lx, ldy);
    3.56 +			} else {
    3.57 +				ldxdy = verts[lidx[1]].x - lx;
    3.58 +			}
    3.59  		}
    3.60  		if(y >= verts[ridx[1]].y) {
    3.61  			rx = verts[ridx[1]].x;
    3.62 @@ -101,13 +112,17 @@
    3.63  			if(rdy < 0) {
    3.64  				break;
    3.65  			}
    3.66 -			rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
    3.67 +			if(rdy) {
    3.68 +				rdxdy = x16div(verts[ridx[1]].x - rx, rdy);
    3.69 +			} else {
    3.70 +				rdxdy = verts[ridx[1]].x - rx;
    3.71 +			}
    3.72  		}
    3.73  
    3.74 -		x0 = lx < 0 ? 0 : (lx >> 16);
    3.75 -		x1 = (rx >> 16) >= WIDTH ? WIDTH - 1 : (rx >> 16);
    3.76 +		x0 = lx >> 16;
    3.77 +		x1 = rx >> 16;
    3.78  
    3.79 -		if(i >= 0 && x1 > x0) {
    3.80 +		if(i >= 0) {// && x0 < x1) {
    3.81  #ifdef PALMODE
    3.82  			fill_scanline_pal(i, x0, x1, (uint8_t)color);
    3.83  #else
    3.84 @@ -158,8 +173,18 @@
    3.85  static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color)
    3.86  {
    3.87  	int i;
    3.88 -	uint16_t *pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0;
    3.89 +	uint16_t *pixels;
    3.90  
    3.91 +	if(x0 > x1) {
    3.92 +		i = x0;
    3.93 +		x0 = x1;
    3.94 +		x1 = i;
    3.95 +	}
    3.96 +
    3.97 +	if(x0 < 0) x0 = 0;
    3.98 +	if(x1 >= WIDTH - 1) x1 = WIDTH - 1;
    3.99 +
   3.100 +	pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0;
   3.101  	for(i=x0; i<x1; i++) {
   3.102  		*pixels++ = color;
   3.103  	}
   3.104 @@ -187,3 +212,8 @@
   3.105  	pixels[y * WIDTH + x] = color;
   3.106  #endif
   3.107  }
   3.108 +
   3.109 +static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
   3.110 +{
   3.111 +	return x16mul(x0, y1) - x16mul(y0, x1);
   3.112 +}
     4.1 --- a/src/x3d.c	Mon Jun 23 08:28:28 2014 +0300
     4.2 +++ b/src/x3d.c	Mon Jun 23 10:33:24 2014 +0300
     4.3 @@ -1,4 +1,5 @@
     4.4  #include "config.h"
     4.5 +#include <stdio.h>
     4.6  #include <string.h>
     4.7  #include <math.h>
     4.8  #include "x3d.h"
     4.9 @@ -8,6 +9,8 @@
    4.10  #include "polyfill.h"
    4.11  #include "gbasys.h"
    4.12  
    4.13 +int dbg_fill_dump;
    4.14 +
    4.15  #define MAT_STACK_SIZE	4
    4.16  
    4.17  struct matrix {
    4.18 @@ -15,6 +18,7 @@
    4.19  };
    4.20  
    4.21  static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout);
    4.22 +static int dump_frame(struct pixel_buffer *frame);
    4.23  
    4.24  
    4.25  static int32_t proj_fov = M_PI_X16;
    4.26 @@ -88,11 +92,11 @@
    4.27  	for(i=0; i<3; i++) {
    4.28  		for(j=0; j<4; j++) {
    4.29  			mstack[mtop].m[M(i, j)] =
    4.30 -				x16mul(tmp.m[M(0, j)], m[M(i, 0)]) +
    4.31 -				x16mul(tmp.m[M(1, j)], m[M(i, 1)]) +
    4.32 -				x16mul(tmp.m[M(2, j)], m[M(i, 2)]);
    4.33 +				x16mul(m[M(0, j)], tmp.m[M(i, 0)]) +
    4.34 +				x16mul(m[M(1, j)], tmp.m[M(i, 1)]) +
    4.35 +				x16mul(m[M(2, j)], tmp.m[M(i, 2)]);
    4.36  		}
    4.37 -		mstack[mtop].m[M(i, 3)] += m[M(i, 3)];
    4.38 +		mstack[mtop].m[M(i, 3)] += tmp.m[M(i, 3)];
    4.39  	}
    4.40  }
    4.41  
    4.42 @@ -236,10 +240,15 @@
    4.43  		case X3D_TRIANGLES:
    4.44  		case X3D_QUADS:
    4.45  			draw_poly(pverts, vpos, color);
    4.46 +			if(dbg_fill_dump) {
    4.47 +				dump_frame(back_buffer);
    4.48 +			}
    4.49  			break;
    4.50  		}
    4.51  skip_prim: ;
    4.52  	}
    4.53 +
    4.54 +	dbg_fill_dump = 0;
    4.55  	return 0;
    4.56  }
    4.57  
    4.58 @@ -287,3 +296,31 @@
    4.59  	im_color[1] = g;
    4.60  	im_color[2] = b;
    4.61  }
    4.62 +
    4.63 +static int dump_frame(struct pixel_buffer *frame)
    4.64 +{
    4.65 +	static int frameno;
    4.66 +	char buf[128];
    4.67 +	FILE *fp;
    4.68 +	int i, npix;
    4.69 +	uint16_t *ptr = frame->pixels;
    4.70 +
    4.71 +	sprintf(buf, "dump%03d.ppm", ++frameno);
    4.72 +
    4.73 +	if(!(fp = fopen(buf, "wb"))) {
    4.74 +		fprintf(stderr, "failed to dump file: %s\n", buf);
    4.75 +		return -1;
    4.76 +	}
    4.77 +
    4.78 +	fprintf(fp, "P6\n%d %d\n255\n", frame->x, frame->y);
    4.79 +
    4.80 +	npix = frame->x * frame->y;
    4.81 +	for(i=0; i<npix; i++) {
    4.82 +		uint16_t pixel = *ptr++;
    4.83 +		fputc(GET_R(pixel), fp);
    4.84 +		fputc(GET_G(pixel), fp);
    4.85 +		fputc(GET_B(pixel), fp);
    4.86 +	}
    4.87 +	fclose(fp);
    4.88 +	return 0;
    4.89 +}