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