# HG changeset patch # User John Tsiombikas # Date 1403704968 -10800 # Node ID b755fb002f17c248343797672b6e4303eb3f31c6 # Parent c398d834d64a898508b0274d5485f30bdd0e63fa foo diff -r c398d834d64a -r b755fb002f17 Makefile --- a/Makefile Mon Jun 23 10:33:24 2014 +0300 +++ b/Makefile Wed Jun 25 17:02:48 2014 +0300 @@ -15,8 +15,8 @@ OBJCOPY = $(ARCH)-objcopy EMU = vbam -#opt = -O3 -fomit-frame-pointer -mcpu=arm7tdmi -mtune=arm7tdmi -dbg = -g +opt = -O3 -fomit-frame-pointer -mcpu=arm7tdmi -mtune=arm7tdmi +#dbg = -g CFLAGS = $(opt) $(dbg) -pedantic -Wall -I../gbasys/src LDFLAGS = ../gbasys/libgbasys.a -lm diff -r c398d834d64a -r b755fb002f17 src/ggen.c --- a/src/ggen.c Mon Jun 23 10:33:24 2014 +0300 +++ b/src/ggen.c Wed Jun 25 17:02:48 2014 +0300 @@ -17,19 +17,25 @@ *cptr++ = b; \ } while(0) +#define TEXCOORD(u, v) \ + do { \ + *tptr++ = u; \ + *tptr++ = v; \ + } while(0) + int gen_box(struct mesh *m) { int i; - int num_faces = 12; - int num_verts = num_faces * 3; + int num_faces = 6; + int num_verts = num_faces * 4; int32_t v[8][3] = { {-X1, -X1, -X1}, {X1, -X1, -X1}, {X1, -X1, X1}, {-X1, -X1, X1}, {-X1, X1, -X1}, {X1, X1, -X1}, {X1, X1, X1}, {-X1, X1, X1} }; - int32_t *vptr, *cptr; + int32_t *vptr, *cptr, *tptr; - m->prim = X3D_TRIANGLES; + m->prim = X3D_QUADS; m->nverts = num_verts; if(!(m->verts = malloc(num_verts * 3 * sizeof *m->verts))) { return -1; @@ -41,71 +47,76 @@ } cptr = m->colors; + if(!(m->texcoords = malloc(num_verts * 2 * sizeof *m->texcoords))) { + return -1; + } + tptr = m->texcoords; + /* -Y */ VERTEX(v[0][0], v[0][1], v[0][2]); VERTEX(v[1][0], v[1][1], v[1][2]); VERTEX(v[2][0], v[2][1], v[2][2]); - for(i=0; i<3; i++) COLOR(32768, 0, 32768); - - VERTEX(v[0][0], v[0][1], v[0][2]); - VERTEX(v[2][0], v[2][1], v[2][2]); VERTEX(v[3][0], v[3][1], v[3][2]); - for(i=0; i<3; i++) COLOR(65536, 0, 65536); + TEXCOORD(65536, 0); + TEXCOORD(0, 0); + TEXCOORD(0, 65536); + TEXCOORD(65536, 65536); + for(i=0; i<4; i++) COLOR(65536, 0, 65536); /* +Y */ + VERTEX(v[4][0], v[4][1], v[4][2]); VERTEX(v[7][0], v[7][1], v[7][2]); VERTEX(v[6][0], v[6][1], v[6][2]); VERTEX(v[5][0], v[5][1], v[5][2]); - for(i=0; i<3; i++) COLOR(0, 32768, 0); - - VERTEX(v[7][0], v[7][1], v[7][2]); - VERTEX(v[5][0], v[5][1], v[5][2]); - VERTEX(v[4][0], v[4][1], v[4][2]); - for(i=0; i<3; i++) COLOR(0, 65536, 0); + TEXCOORD(0, 0); + TEXCOORD(0, 65536); + TEXCOORD(65536, 65536); + TEXCOORD(65536, 0); + for(i=0; i<4; i++) COLOR(0, 65536, 0); /* -Z */ VERTEX(v[0][0], v[0][1], v[0][2]); VERTEX(v[4][0], v[4][1], v[4][2]); VERTEX(v[5][0], v[5][1], v[5][2]); - for(i=0; i<3; i++) COLOR(32768, 32768, 0); - - VERTEX(v[0][0], v[0][1], v[0][2]); - VERTEX(v[5][0], v[5][1], v[5][2]); VERTEX(v[1][0], v[1][1], v[1][2]); - for(i=0; i<3; i++) COLOR(65536, 65536, 0); + TEXCOORD(0, 0); + TEXCOORD(0, 65536); + TEXCOORD(65536, 65536); + TEXCOORD(65536, 0); + for(i=0; i<4; i++) COLOR(65536, 65536, 0); /* +Z */ VERTEX(v[2][0], v[2][1], v[2][2]); VERTEX(v[6][0], v[6][1], v[6][2]); VERTEX(v[7][0], v[7][1], v[7][2]); - for(i=0; i<3; i++) COLOR(0, 0, 32768); - - VERTEX(v[2][0], v[2][1], v[2][2]); - VERTEX(v[7][0], v[7][1], v[7][2]); VERTEX(v[3][0], v[3][1], v[3][2]); - for(i=0; i<3; i++) COLOR(0, 0, 65536); + TEXCOORD(0, 0); + TEXCOORD(0, 65536); + TEXCOORD(65536, 65536); + TEXCOORD(65536, 0); + for(i=0; i<4; i++) COLOR(0, 0, 65536); /* +X */ VERTEX(v[1][0], v[1][1], v[1][2]); VERTEX(v[5][0], v[5][1], v[5][2]); VERTEX(v[6][0], v[6][1], v[6][2]); - for(i=0; i<3; i++) COLOR(32768, 0, 0); - - VERTEX(v[1][0], v[1][1], v[1][2]); - VERTEX(v[6][0], v[6][1], v[6][2]); VERTEX(v[2][0], v[2][1], v[2][2]); - for(i=0; i<3; i++) COLOR(65536, 0, 0); + TEXCOORD(0, 0); + TEXCOORD(0, 65536); + TEXCOORD(65536, 65536); + TEXCOORD(65536, 0); + for(i=0; i<4; i++) COLOR(65536, 0, 0); /* -X */ VERTEX(v[3][0], v[3][1], v[3][2]); VERTEX(v[7][0], v[7][1], v[7][2]); VERTEX(v[4][0], v[4][1], v[4][2]); - for(i=0; i<3; i++) COLOR(0, 32768, 32768); - - VERTEX(v[3][0], v[3][1], v[3][2]); - VERTEX(v[4][0], v[4][1], v[4][2]); VERTEX(v[0][0], v[0][1], v[0][2]); - for(i=0; i<3; i++) COLOR(0, 65536, 65536); + TEXCOORD(0, 0); + TEXCOORD(0, 65536); + TEXCOORD(65536, 65536); + TEXCOORD(65536, 0); + for(i=0; i<4; i++) COLOR(0, 65536, 65536); return 0; } diff -r c398d834d64a -r b755fb002f17 src/mesh.c --- a/src/mesh.c Mon Jun 23 10:33:24 2014 +0300 +++ b/src/mesh.c Wed Jun 25 17:02:48 2014 +0300 @@ -7,6 +7,7 @@ m->prim = X3D_TRIANGLES; m->verts = 0; m->colors = 0; + m->texcoords = 0; m->nverts = 0; } @@ -14,6 +15,7 @@ { free(m->verts); free(m->colors); + free(m->texcoords); } void draw_mesh(struct mesh *m) @@ -22,9 +24,13 @@ if(m->colors) { x3d_color_array(m->nverts, m->colors); } + if(m->texcoords) { + x3d_texcoord_array(m->nverts, m->texcoords); + } x3d_draw(m->prim, m->nverts); x3d_vertex_array(0, 0); x3d_color_array(0, 0); + x3d_texcoord_array(0, 0); } diff -r c398d834d64a -r b755fb002f17 src/mesh.h --- a/src/mesh.h Mon Jun 23 10:33:24 2014 +0300 +++ b/src/mesh.h Wed Jun 25 17:02:48 2014 +0300 @@ -9,6 +9,7 @@ int32_t *verts; int32_t *colors; + int32_t *texcoords; int nverts; }; diff -r c398d834d64a -r b755fb002f17 src/polyfill.c --- a/src/polyfill.c Mon Jun 23 10:33:24 2014 +0300 +++ b/src/polyfill.c Wed Jun 25 17:02:48 2014 +0300 @@ -5,14 +5,18 @@ #include "fixed.h" #include "gbasys.h" +/* TODO: constant interpolant optimization */ + #define VNEXT(x, n) (((x) + 1) % (n)) #define VPREV(x, n) ((x) > 0 ? (x) - 1 : (n) - 1) -static void fill_scanline_pal(int y, int x0, int x1, uint8_t color); -static void fill_scanline_rgb(int y, int x0, int x1, uint16_t color); +static void fill_scanline_pal(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1, + int32_t v0, int32_t v1, uint8_t color); +static void fill_scanline_rgb(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1, + int32_t v0, int32_t v1, uint16_t color); static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1); -void draw_poly(int num, const pvec3 *verts, uint16_t color) +void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color) { int i, topidx = 0, botidx = 0; int lidx[2] = {-1, -1}, ridx[2] = {-1, -1}; @@ -22,6 +26,8 @@ int start, end; pvec3 v0, v1; + int32_t lu, lv, ru, rv, ldudy, ldvdy, rdudy, rdvdy; /* texture interpolants */ + v0.x = verts[1].x - verts[0].x; v0.y = verts[1].y - verts[0].y; @@ -63,6 +69,10 @@ } lx = verts[lidx[0]].x; ldxdy = x16div(verts[lidx[1]].x - lx, ldy); + lu = tex[lidx[0]].x; + ldudy = x16div(tex[lidx[1]].x - lu, ldy); + lv = tex[lidx[0]].y; + ldvdy = x16div(tex[lidx[1]].y - lv, ldy); /* find starting right edge */ ridx[1] = VNEXT(ridx[0], num); @@ -80,6 +90,10 @@ } rx = verts[ridx[0]].x; rdxdy = x16div(verts[ridx[1]].x - rx, rdy); + ru = tex[ridx[0]].x; + rdudy = x16div(tex[ridx[1]].x - ru, rdy); + rv = tex[ridx[0]].y; + rdvdy = x16div(tex[ridx[1]].y - rv, rdy); start = topy >> 16; end = boty >> 16; @@ -88,7 +102,6 @@ y = topy; for(i=start; i<=end; i++) { - short x0, x1; if(y >= verts[lidx[1]].y) { lx = verts[lidx[1]].x; @@ -98,10 +111,18 @@ if(ldy < 0) { break; } + + lu = tex[lidx[0]].x; + lv = tex[lidx[0]].y; + if(ldy) { ldxdy = x16div(verts[lidx[1]].x - lx, ldy); + ldudy = x16div(tex[lidx[1]].x - lu, ldy); + ldvdy = x16div(tex[lidx[1]].y - lv, ldy); } else { ldxdy = verts[lidx[1]].x - lx; + ldudy = tex[lidx[1]].x - lu; + ldvdy = tex[lidx[1]].y - lv; } } if(y >= verts[ridx[1]].y) { @@ -112,81 +133,145 @@ if(rdy < 0) { break; } + + ru = tex[ridx[0]].x; + rv = tex[ridx[0]].y; + if(rdy) { rdxdy = x16div(verts[ridx[1]].x - rx, rdy); + rdudy = x16div(tex[ridx[1]].x - ru, rdy); + rdvdy = x16div(tex[ridx[1]].y - rv, rdy); } else { rdxdy = verts[ridx[1]].x - rx; + rdudy = tex[ridx[1]].x - ru; + rdvdy = tex[ridx[1]].y - rv; } } - x0 = lx >> 16; - x1 = rx >> 16; - - if(i >= 0) {// && x0 < x1) { + if(i >= 0) { #ifdef PALMODE - fill_scanline_pal(i, x0, x1, (uint8_t)color); + fill_scanline_pal(i, lx, rx, lu, ru, lv, rv, (uint8_t)color); #else - fill_scanline_rgb(i, x0, x1, color); + fill_scanline_rgb(i, lx, rx, lu, ru, lv, rv, color); #endif } lx += ldxdy; rx += rdxdy; y += 65536; + + lu += ldudy; + lv += ldvdy; + ru += rdudy; + rv += rdvdy; } } -static void fill_scanline_pal(int y, int x0, int x1, uint8_t color) +static void fill_scanline_pal(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1, + int32_t v0, int32_t v1, uint8_t color) { -#if 1 - int i, num_pairs, num_pix = x1 - x0; - uint16_t *pixels = (uint16_t*)back_buffer->pixels + (y * WIDTH + x0) / 2; + int ix0, ix1; + int32_t dx; + int32_t u, v, dudx, dvdx; + + int i, num_pairs, num_pix; + uint16_t *pixels; uint16_t colpair = (uint16_t)color | ((uint16_t)color << 8); - if(x0 & 1) { + if(x0 > x1) { + int32_t tmp = x0; + x0 = x1; + x1 = tmp; + } + + dx = x1 - x0; + + u = u0; + v = v0; + if(dx) { + dudx = x16div(u1 - u0, dx); + dvdx = x16div(v1 - v0, dx); + } else { + dudx = u1 - u0; + dvdx = v1 - v0; + } + + ix0 = (x0 + 32768) >> 16; + ix1 = (x1 + 32768) >> 16; + + if(ix0 < 0) ix0 = 0; + if(ix1 >= WIDTH - 1) ix1 = WIDTH - 1; + + num_pix = ix1 - ix0; + pixels = (uint16_t*)back_buffer->pixels + (y * WIDTH + ix0) / 2; + + if(ix0 & 1) { uint16_t pix = *pixels & 0xff; *pixels++ = pix | ((uint16_t)color << 8); --num_pix; + u += dudx; + v += dvdx; } num_pairs = (num_pix & 0xfffe) / 2; for(i=0; ipixels + y * WIDTH + x0; - - for(i=x0; i x1) { - i = x0; + int32_t tmp = x0; x0 = x1; - x1 = i; + x1 = tmp; } - if(x0 < 0) x0 = 0; - if(x1 >= WIDTH - 1) x1 = WIDTH - 1; + dx = x1 - x0; - pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + x0; - for(i=x0; i> 16; + ix1 = (x1 + 32768) >> 16; + + if(ix0 < 0) ix0 = 0; + if(ix1 >= WIDTH - 1) ix1 = WIDTH - 1; + + pixels = (uint16_t*)back_buffer->pixels + y * WIDTH + ix0; + for(i=ix0; i> 8; + int cg = v >> 8; + if(cr > 255) cr = 255; + if(cg > 255) cg = 255; + + *pixels++ = RGB(cr, cg, 0); + + u += dudx; + v += dvdx; } } diff -r c398d834d64a -r b755fb002f17 src/polyfill.h --- a/src/polyfill.h Mon Jun 23 10:33:24 2014 +0300 +++ b/src/polyfill.h Wed Jun 25 17:02:48 2014 +0300 @@ -7,7 +7,11 @@ int32_t x, y, z; } pvec3; -void draw_poly(int num, const pvec3 *verts, uint16_t color); +typedef struct pvec2 { + int32_t x, y; +} pvec2; + +void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color); void draw_point(const pvec3 *v, uint16_t color); diff -r c398d834d64a -r b755fb002f17 src/x3d.c --- a/src/x3d.c Mon Jun 23 10:33:24 2014 +0300 +++ b/src/x3d.c Wed Jun 25 17:02:48 2014 +0300 @@ -17,7 +17,8 @@ int32_t m[12]; }; -static void proc_vertex(const int32_t *vin, const int32_t *cin, pvec3 *vout, pvec3 *cout); +static void proc_vertex(const int32_t *vin, const int32_t *cin, const int32_t *tin, + pvec3 *vout, pvec3 *cout, pvec2 *tout); static int dump_frame(struct pixel_buffer *frame); @@ -39,8 +40,11 @@ static unsigned short vertex_count; static const int32_t *color_array; static unsigned short color_count; +static const int32_t *texcoord_array; +static unsigned short texcoord_count; static int32_t im_color[3]; +static int32_t im_texcoord[2]; static uint8_t im_color_index; void x3d_projection(int fov, int32_t aspect, int32_t nearz, int32_t farz) @@ -163,11 +167,18 @@ color_count = count; } +void x3d_texcoord_array(int count, const int32_t *ptr) +{ + texcoord_array = ptr; + texcoord_count = count; +} + int x3d_draw(int prim, int vnum) { int i, j, pverts = prim; const int32_t *vptr = vertex_array; const int32_t *cptr = color_array; + const int32_t *tptr = texcoord_array; #ifndef PALMODE short cr, cg, cb; #endif @@ -185,14 +196,20 @@ __FUNCTION__, vnum, color_count); vnum = color_count; } + if(texcoord_array && vnum > texcoord_count) { + logmsg(LOG_DBG, "%s called with vnum=%d, but current texcoord array has %d elements\n", + __FUNCTION__, vnum, texcoord_count); + vnum = texcoord_count; + } for(i=0; iy = im_color[1]; cout->z = im_color[2]; } + + if(texcoord_array) { + tout->x = tin[0]; + tout->y = tin[1]; + } else { + tout->x = im_texcoord[0]; + tout->y = im_texcoord[1]; + } } void x3d_color_index(int cidx) diff -r c398d834d64a -r b755fb002f17 src/x3d.h --- a/src/x3d.h Mon Jun 23 10:33:24 2014 +0300 +++ b/src/x3d.h Wed Jun 25 17:02:48 2014 +0300 @@ -23,6 +23,7 @@ void x3d_vertex_array(int count, const int32_t *ptr); void x3d_color_array(int count, const int32_t *ptr); +void x3d_texcoord_array(int count, const int32_t *ptr); int x3d_draw(int prim, int vnum); int x3d_draw_indexed(int prim, int count, uint16_t *ptr);