gba-x3dtest

diff src/x3d.c @ 8:fb0a0d6a8b52

sortof works
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 19 Jun 2014 05:53:46 +0300
parents 158d23956801
children b0ed38f13261
line diff
     1.1 --- a/src/x3d.c	Wed Jun 18 06:20:07 2014 +0300
     1.2 +++ b/src/x3d.c	Thu Jun 19 05:53:46 2014 +0300
     1.3 @@ -2,27 +2,37 @@
     1.4  #include "x3d.h"
     1.5  #include "fixed.h"
     1.6  #include "sincos.h"
     1.7 +#include "logger.h"
     1.8 +#include "polyfill.h"
     1.9 +#include "gbasys.h"
    1.10  
    1.11  #define MAT_STACK_SIZE	4
    1.12  
    1.13  struct matrix {
    1.14 -	int32_t m[3][4];
    1.15 +	int32_t m[12];
    1.16  };
    1.17  
    1.18 +static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout);
    1.19 +
    1.20 +
    1.21  static int32_t proj_fov = M_PI_X16;
    1.22  static int32_t proj_aspect = 65536;
    1.23  static int32_t proj_near = ftox16(0.5);
    1.24  static int32_t proj_far = 500 << 16;
    1.25  
    1.26 -static struct matrix identity = {
    1.27 -	{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}
    1.28 -};
    1.29 +#define ID_INIT {65536, 0, 0, 0, 0, 65536, 0, 0, 0, 0, 65536, 0}
    1.30 +
    1.31 +static struct matrix identity = { ID_INIT };
    1.32  
    1.33  static short mtop;
    1.34 -static struct matrix mstack[MAT_STACK_SIZE] = {
    1.35 -	{{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}},
    1.36 -	{{{65536, 0, 0, 0}, {0, 65536, 0, 0}, {0, 0, 65536, 0}}}
    1.37 -};
    1.38 +static struct matrix mstack[MAT_STACK_SIZE] = { {ID_INIT}, {ID_INIT} };
    1.39 +
    1.40 +static const int32_t *vertex_array;
    1.41 +static unsigned short vertex_count;
    1.42 +static const int32_t *color_array;
    1.43 +static unsigned short color_count;
    1.44 +
    1.45 +static int32_t im_color[3];
    1.46  
    1.47  void x3d_projection(int32_t fov, int32_t aspect, int32_t nearz, int32_t farz)
    1.48  {
    1.49 @@ -54,7 +64,7 @@
    1.50  
    1.51  void x3d_load_matrix(int32_t *m)
    1.52  {
    1.53 -	memcpy(mstack[mtop].m[0], m, sizeof *mstack);
    1.54 +	memcpy(mstack[mtop].m, m, sizeof *mstack);
    1.55  }
    1.56  
    1.57  
    1.58 @@ -64,21 +74,174 @@
    1.59  	int i, j;
    1.60  	struct matrix tmp;
    1.61  
    1.62 -	memcpy(tmp.m[0], mstack[mtop].m[0], sizeof tmp);
    1.63 +	memcpy(tmp.m, mstack[mtop].m, sizeof tmp);
    1.64  
    1.65  	for(i=0; i<3; i++) {
    1.66  		for(j=0; j<4; j++) {
    1.67 -			mstack[mtop].m[i][j] = x16mul(tmp.m[0][j], m[M(i, 0)]) +
    1.68 -				x16mul(tmp.m[1][j], m[M(i, 1)]) +
    1.69 -				x16mul(tmp.m[2][j], m[M(i, 2)]) +
    1.70 -				m[M(i, 3)];
    1.71 +			mstack[mtop].m[M(i, j)] =
    1.72 +				x16mul(tmp.m[M(0, j)], m[M(i, 0)]) +
    1.73 +				x16mul(tmp.m[M(1, j)], m[M(i, 1)]) +
    1.74 +				x16mul(tmp.m[M(2, j)], m[M(i, 2)]);
    1.75  		}
    1.76 +		mstack[mtop].m[M(i, 3)] += m[M(i, 3)];
    1.77  	}
    1.78  }
    1.79  
    1.80  void x3d_load_identity(void)
    1.81  {
    1.82 -	memcpy(mstack[mtop].m[0], identity.m[0], sizeof identity);
    1.83 +	memcpy(mstack[mtop].m, identity.m, sizeof identity);
    1.84  }
    1.85  
    1.86 -/* TODO cont... */
    1.87 +void x3d_translate(int32_t x, int32_t y, int32_t z)
    1.88 +{
    1.89 +	int32_t m[] = ID_INIT;
    1.90 +	m[3] = x;
    1.91 +	m[7] = y;
    1.92 +	m[11] = z;
    1.93 +
    1.94 +	x3d_mult_matrix(m);
    1.95 +}
    1.96 +
    1.97 +void x3d_rotate(int32_t deg, int32_t x, int32_t y, int32_t z)
    1.98 +{
    1.99 +	int32_t xform[] = ID_INIT;
   1.100 +
   1.101 +	int32_t angle = x16mul(M_PI_X16, deg) / 180;
   1.102 +	int32_t sina = sin_x16(angle);
   1.103 +	int32_t cosa = cos_x16(angle);
   1.104 +	int32_t one_minus_cosa = 65536 - cosa;
   1.105 +	int32_t nxsq = x16sq(x);
   1.106 +	int32_t nysq = x16sq(y);
   1.107 +	int32_t nzsq = x16sq(z);
   1.108 +
   1.109 +	xform[0] = nxsq + x16mul(65536 - nxsq, cosa);
   1.110 +	xform[4] = x16mul(x16mul(x, y), one_minus_cosa) - x16mul(z, sina);
   1.111 +	xform[8] = x16mul(x16mul(x, z), one_minus_cosa) + x16mul(y, sina);
   1.112 +	xform[1] = x16mul(x16mul(x, y), one_minus_cosa) + x16mul(z, sina);
   1.113 +	xform[5] = nysq + x16mul(65536 - nysq, cosa);
   1.114 +	xform[9] = x16mul(x16mul(y, z), one_minus_cosa) - x16mul(x, sina);
   1.115 +	xform[2] = x16mul(x16mul(x, z), one_minus_cosa) - x16mul(y, sina);
   1.116 +	xform[6] = x16mul(x16mul(y, z), one_minus_cosa) + x16mul(x, sina);
   1.117 +	xform[10] = nzsq + x16mul(65536 - nzsq, cosa);
   1.118 +
   1.119 +	x3d_mult_matrix(xform);
   1.120 +}
   1.121 +
   1.122 +void x3d_scale(int32_t x, int32_t y, int32_t z)
   1.123 +{
   1.124 +	int32_t m[] = ID_INIT;
   1.125 +
   1.126 +	m[0] = x;
   1.127 +	m[5] = y;
   1.128 +	m[10] = z;
   1.129 +
   1.130 +	x3d_mult_matrix(m);
   1.131 +}
   1.132 +
   1.133 +void x3d_vertex_array(int count, const int32_t *ptr)
   1.134 +{
   1.135 +	vertex_array = ptr;
   1.136 +	vertex_count = count;
   1.137 +}
   1.138 +
   1.139 +void x3d_color_array(int count, const int32_t *ptr)
   1.140 +{
   1.141 +	color_array = ptr;
   1.142 +	color_count = count;
   1.143 +}
   1.144 +
   1.145 +int x3d_draw_arrays(int prim, int vnum)
   1.146 +{
   1.147 +	int i, j, pverts = prim;
   1.148 +	const int32_t *vptr = vertex_array;
   1.149 +	const int32_t *cptr = color_array;
   1.150 +	short cr, cg, cb;
   1.151 +
   1.152 +	if(!vertex_array) return -1;
   1.153 +
   1.154 +	if(vnum > vertex_count) {
   1.155 +		logmsg(LOG_DBG, "%s called with vnum=%d, but current vertex array has %d vertices\n",
   1.156 +				__FUNCTION__, vnum, vertex_count);
   1.157 +		vnum = vertex_count;
   1.158 +	}
   1.159 +	if(color_array && vnum > color_count) {
   1.160 +		logmsg(LOG_DBG, "%s called with vnum=%d, but current color array has %d elements\n",
   1.161 +				__FUNCTION__, vnum, color_count);
   1.162 +		vnum = color_count;
   1.163 +	}
   1.164 +
   1.165 +	for(i=0; i<vnum; i+=pverts) {
   1.166 +		/* process vertices */
   1.167 +		pvec3 vpos[4];
   1.168 +		pvec3 col[4];
   1.169 +
   1.170 +		for(j=0; j<pverts; j++) {
   1.171 +			proc_vertex(vptr, cptr, vpos + j, col + j);
   1.172 +			vptr += 3;
   1.173 +			if(cptr) cptr += 3;
   1.174 +		}
   1.175 +
   1.176 +		cr = col[0].x >> 8;
   1.177 +		cg = col[0].y >> 8;
   1.178 +		cb = col[0].z >> 8;
   1.179 +
   1.180 +		if(cr > 255) cr = 255;
   1.181 +		if(cg > 255) cg = 255;
   1.182 +		if(cb > 255) cb = 255;
   1.183 +
   1.184 +		switch(pverts) {
   1.185 +		case X3D_POINTS:
   1.186 +			draw_point(vpos, RGB(cr, cg, cb));
   1.187 +			break;
   1.188 +
   1.189 +		case X3D_LINES:
   1.190 +			break;
   1.191 +
   1.192 +		case X3D_TRIANGLES:
   1.193 +		case X3D_QUADS:
   1.194 +			draw_poly(pverts, vpos, RGB(cr, cg, cb));
   1.195 +			break;
   1.196 +		}
   1.197 +	}
   1.198 +	return 0;
   1.199 +}
   1.200 +
   1.201 +static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout)
   1.202 +{
   1.203 +	int i;
   1.204 +	int32_t tvert[3];
   1.205 +	int32_t *mvmat = mstack[mtop].m;
   1.206 +
   1.207 +	/* transform vertex with current matrix */
   1.208 +	for(i=0; i<3; i++) {
   1.209 +		tvert[i] = x16mul(mvmat[0], vin[0]) +
   1.210 +			x16mul(mvmat[1], vin[1]) +
   1.211 +			x16mul(mvmat[2], vin[2]) +
   1.212 +			mvmat[3];
   1.213 +		mvmat += 4;
   1.214 +	}
   1.215 +
   1.216 +	vout->x = tvert[0];
   1.217 +	vout->y = tvert[1];
   1.218 +	vout->z = tvert[2];
   1.219 +	/*logmsg(LOG_DBG, "%s: (%g %g %g) -> (%g %g %g)\n", __FUNCTION__,
   1.220 +			x16tof(vin[0]), x16tof(vin[1]), x16tof(vin[2]),
   1.221 +			x16tof(vout->x), x16tof(vout->y), x16tof(vout->z));*/
   1.222 +
   1.223 +	if(color_array) {
   1.224 +		cout->x = cin[0];
   1.225 +		cout->y = cin[1];
   1.226 +		cout->z = cin[2];
   1.227 +	} else {
   1.228 +		cout->x = im_color[0];
   1.229 +		cout->y = im_color[1];
   1.230 +		cout->z = im_color[2];
   1.231 +	}
   1.232 +}
   1.233 +
   1.234 +void x3d_color(int32_t r, int32_t g, int32_t b)
   1.235 +{
   1.236 +	im_color[0] = r;
   1.237 +	im_color[1] = g;
   1.238 +	im_color[2] = b;
   1.239 +}