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