# HG changeset patch # User John Tsiombikas # Date 1403755071 -10800 # Node ID 0a7f402892b383ff6fdcc3f284d5e7347a3dd8f9 # Parent 02cf4011f5661d65aea0a5fe2312070bf4c1b886 texture mapping diff -r 02cf4011f566 -r 0a7f402892b3 Makefile --- a/Makefile Wed Jun 25 18:18:05 2014 +0300 +++ b/Makefile Thu Jun 26 06:57:51 2014 +0300 @@ -1,5 +1,6 @@ src = $(filter-out src/main_sdl.c,$(wildcard src/*.c)) -obj = $(src:.c=.o) +imgfiles = $(wildcard *.png) +obj = $(src:.c=.o) $(imgfiles:.png=.img.o) dep = $(obj:.o=.d) name = x3dtest elf = $(name).elf @@ -18,7 +19,7 @@ opt = -O3 -fomit-frame-pointer -mcpu=arm7tdmi -mtune=arm7tdmi #dbg = -g -CFLAGS = $(opt) $(dbg) -pedantic -Wall -I../gbasys/src +CFLAGS = $(opt) $(dbg) -pedantic -Wall -I. -I../gbasys/src LDFLAGS = ../gbasys/libgbasys.a -lm EMUFLAGS = -T 100 -f 1 @@ -45,6 +46,9 @@ %.d: %.c @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ +%.img.c: %.png + img2gba $< + .PHONY: clean clean: rm -f $(obj) $(dep) $(bin) $(bin_mb) $(elf) $(elf_mb) diff -r 02cf4011f566 -r 0a7f402892b3 Makefile.sdl --- a/Makefile.sdl Wed Jun 25 18:18:05 2014 +0300 +++ b/Makefile.sdl Thu Jun 26 06:57:51 2014 +0300 @@ -1,12 +1,13 @@ # vi:set filetype=make: src = $(filter-out src/main.c,$(wildcard src/*.c)) $(wildcard src/sdlsys/*.c) -obj = $(src:.c=.x86.o) +imgfiles = $(wildcard *.png) +obj = $(src:.c=.x86.o) $(imgfiles:.png=.img.x86.o) dep = $(obj:.o=.d) bin = x3dtest warn = -Wall -Wno-unused-function -CFLAGS = -pedantic $(warn) -g `pkg-config sdl --cflags` -Isrc -Isrc/sdlsys +CFLAGS = -pedantic $(warn) -g `pkg-config sdl --cflags` -I. -Isrc -Isrc/sdlsys LDFLAGS = `pkg-config sdl --libs` -lm $(bin): $(obj) @@ -20,6 +21,9 @@ %.x86.d: %.c @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ +%.img.c: %.png + img2gba $< + .PHONY: clean clean: rm -f $(obj) $(bin) diff -r 02cf4011f566 -r 0a7f402892b3 src/game.c --- a/src/game.c Wed Jun 25 18:18:05 2014 +0300 +++ b/src/game.c Thu Jun 26 06:57:51 2014 +0300 @@ -6,6 +6,7 @@ #include "fixed.h" #include "palman.h" #include "ggen.h" +#include "data.h" extern int dbg_fill_dump; @@ -31,6 +32,7 @@ static const short vcount = sizeof poly / sizeof *poly / 3; static struct mesh box; +static int tex; int game_init(void) @@ -40,6 +42,8 @@ palman_init(); #endif + tex = x3d_create_texture_rgb(test_width, test_height, test_pixels); + x3d_projection(45.0, (WIDTH << 16) / HEIGHT, 65536 / 2, 65536 * 500); init_mesh(&box); @@ -81,7 +85,9 @@ x3d_color(65536, 65536, 65536); #endif + x3d_enable_texture(tex); draw_mesh(&box); + x3d_disable_texture(); /* x3d_vertex_array(vcount, poly); diff -r 02cf4011f566 -r 0a7f402892b3 src/polyfill.c --- a/src/polyfill.c Wed Jun 25 18:18:05 2014 +0300 +++ b/src/polyfill.c Thu Jun 26 06:57:51 2014 +0300 @@ -13,10 +13,11 @@ 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); + int32_t v0, int32_t v1, uint16_t color, struct texture *tex); static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1); -void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color) +void draw_poly(int num, const pvec3 *verts, const pvec2 *texcoords, uint16_t color, + struct texture *tex) { int i, topidx = 0, botidx = 0; int lidx[2] = {-1, -1}, ridx[2] = {-1, -1}; @@ -69,10 +70,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); + lu = texcoords[lidx[0]].x; + ldudy = x16div(texcoords[lidx[1]].x - lu, ldy); + lv = texcoords[lidx[0]].y; + ldvdy = x16div(texcoords[lidx[1]].y - lv, ldy); /* find starting right edge */ ridx[1] = VNEXT(ridx[0], num); @@ -90,10 +91,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); + ru = texcoords[ridx[0]].x; + rdudy = x16div(texcoords[ridx[1]].x - ru, rdy); + rv = texcoords[ridx[0]].y; + rdvdy = x16div(texcoords[ridx[1]].y - rv, rdy); start = topy >> 16; end = boty >> 16; @@ -112,17 +113,17 @@ break; } - lu = tex[lidx[0]].x; - lv = tex[lidx[0]].y; + lu = texcoords[lidx[0]].x; + lv = texcoords[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); + ldudy = x16div(texcoords[lidx[1]].x - lu, ldy); + ldvdy = x16div(texcoords[lidx[1]].y - lv, ldy); } else { ldxdy = verts[lidx[1]].x - lx; - ldudy = tex[lidx[1]].x - lu; - ldvdy = tex[lidx[1]].y - lv; + ldudy = texcoords[lidx[1]].x - lu; + ldvdy = texcoords[lidx[1]].y - lv; } } if(y >= verts[ridx[1]].y) { @@ -134,17 +135,17 @@ break; } - ru = tex[ridx[0]].x; - rv = tex[ridx[0]].y; + ru = texcoords[ridx[0]].x; + rv = texcoords[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); + rdudy = x16div(texcoords[ridx[1]].x - ru, rdy); + rdvdy = x16div(texcoords[ridx[1]].y - rv, rdy); } else { rdxdy = verts[ridx[1]].x - rx; - rdudy = tex[ridx[1]].x - ru; - rdvdy = tex[ridx[1]].y - rv; + rdudy = texcoords[ridx[1]].x - ru; + rdvdy = texcoords[ridx[1]].y - rv; } } @@ -152,7 +153,7 @@ #ifdef PALMODE fill_scanline_pal(i, lx, rx, lu, ru, lv, rv, (uint8_t)color); #else - fill_scanline_rgb(i, lx, rx, lu, ru, lv, rv, color); + fill_scanline_rgb(i, lx, rx, lu, ru, lv, rv, color, tex); #endif } @@ -229,7 +230,7 @@ } 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) + int32_t v0, int32_t v1, uint16_t color, struct texture *tex) { int i, ix0, ix1; uint16_t *pixels; @@ -268,7 +269,14 @@ if(cr > 255) cr = 255; if(cg > 255) cg = 255; - *pixels++ = RGB(cr, cg, 0); + if(tex) { + int tx = (u >> (16 - tex->ushift)) & tex->umask; + int ty = (v >> (16 - tex->vshift)) & tex->vmask; + uint16_t texel = ((uint16_t*)tex->pixels)[ty * tex->xsz + tx]; + *pixels++ = texel; + } else { + *pixels++ = color; + } u += dudx; v += dvdx; diff -r 02cf4011f566 -r 0a7f402892b3 src/polyfill.h --- a/src/polyfill.h Wed Jun 25 18:18:05 2014 +0300 +++ b/src/polyfill.h Thu Jun 26 06:57:51 2014 +0300 @@ -2,6 +2,7 @@ #define POLYFILL_H_ #include +#include "x3d_impl.h" typedef struct pvec3 { int32_t x, y, z; @@ -11,7 +12,8 @@ int32_t x, y; } pvec2; -void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color); +void draw_poly(int num, const pvec3 *verts, const pvec2 *texcoords, uint16_t color, + struct texture *tex); void draw_point(const pvec3 *v, uint16_t color); diff -r 02cf4011f566 -r 0a7f402892b3 src/x3d.c --- a/src/x3d.c Wed Jun 25 18:18:05 2014 +0300 +++ b/src/x3d.c Thu Jun 26 06:57:51 2014 +0300 @@ -8,6 +8,7 @@ #include "logger.h" #include "polyfill.h" #include "gbasys.h" +#include "x3d_impl.h" int dbg_fill_dump; @@ -47,6 +48,11 @@ static int32_t im_texcoord[2]; static uint8_t im_color_index; +#define MAX_TEXTURES 64 +static struct texture textures[MAX_TEXTURES]; +static short cur_tex = -1; + + void x3d_projection(int fov, int32_t aspect, int32_t nearz, int32_t farz) { proj_fov = (M_PI_X16 * fov) / 180; @@ -257,7 +263,7 @@ case X3D_TRIANGLES: case X3D_QUADS: - draw_poly(pverts, vpos, tex, color); + draw_poly(pverts, vpos, tex, color, cur_tex >= 0 ? textures + cur_tex : 0); if(dbg_fill_dump) { dump_frame(back_buffer); } @@ -324,6 +330,63 @@ im_color[2] = b; } +static int count_bits(int x) +{ + int i, count = 0; + for(i=0; i<32; i++) { + if(x & 1) count++; + x >>= 1; + } + return count; +} + +int x3d_create_texture_rgb(int xsz, int ysz, const uint16_t *pixels) +{ + int i, j; + + if(xsz == 0 || count_bits(xsz) > 1 || ysz == 0 || count_bits(ysz) > 1) { + logmsg(LOG_DBG, "%s: texture size (%dx%d) not power of two!\n", __func__, xsz, ysz); + return -1; + } + + for(i=0; i