gba-x3dtest
changeset 17:0a7f402892b3
texture mapping
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 26 Jun 2014 06:57:51 +0300 |
parents | 02cf4011f566 |
children | f907b2c50a8b |
files | Makefile Makefile.sdl src/game.c src/polyfill.c src/polyfill.h src/x3d.c src/x3d.h src/x3d_impl.h test.png |
diffstat | 9 files changed, 133 insertions(+), 31 deletions(-) [+] |
line diff
1.1 --- a/Makefile Wed Jun 25 18:18:05 2014 +0300 1.2 +++ b/Makefile Thu Jun 26 06:57:51 2014 +0300 1.3 @@ -1,5 +1,6 @@ 1.4 src = $(filter-out src/main_sdl.c,$(wildcard src/*.c)) 1.5 -obj = $(src:.c=.o) 1.6 +imgfiles = $(wildcard *.png) 1.7 +obj = $(src:.c=.o) $(imgfiles:.png=.img.o) 1.8 dep = $(obj:.o=.d) 1.9 name = x3dtest 1.10 elf = $(name).elf 1.11 @@ -18,7 +19,7 @@ 1.12 opt = -O3 -fomit-frame-pointer -mcpu=arm7tdmi -mtune=arm7tdmi 1.13 #dbg = -g 1.14 1.15 -CFLAGS = $(opt) $(dbg) -pedantic -Wall -I../gbasys/src 1.16 +CFLAGS = $(opt) $(dbg) -pedantic -Wall -I. -I../gbasys/src 1.17 LDFLAGS = ../gbasys/libgbasys.a -lm 1.18 EMUFLAGS = -T 100 -f 1 1.19 1.20 @@ -45,6 +46,9 @@ 1.21 %.d: %.c 1.22 @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 1.23 1.24 +%.img.c: %.png 1.25 + img2gba $< 1.26 + 1.27 .PHONY: clean 1.28 clean: 1.29 rm -f $(obj) $(dep) $(bin) $(bin_mb) $(elf) $(elf_mb)
2.1 --- a/Makefile.sdl Wed Jun 25 18:18:05 2014 +0300 2.2 +++ b/Makefile.sdl Thu Jun 26 06:57:51 2014 +0300 2.3 @@ -1,12 +1,13 @@ 2.4 # vi:set filetype=make: 2.5 src = $(filter-out src/main.c,$(wildcard src/*.c)) $(wildcard src/sdlsys/*.c) 2.6 -obj = $(src:.c=.x86.o) 2.7 +imgfiles = $(wildcard *.png) 2.8 +obj = $(src:.c=.x86.o) $(imgfiles:.png=.img.x86.o) 2.9 dep = $(obj:.o=.d) 2.10 bin = x3dtest 2.11 2.12 warn = -Wall -Wno-unused-function 2.13 2.14 -CFLAGS = -pedantic $(warn) -g `pkg-config sdl --cflags` -Isrc -Isrc/sdlsys 2.15 +CFLAGS = -pedantic $(warn) -g `pkg-config sdl --cflags` -I. -Isrc -Isrc/sdlsys 2.16 LDFLAGS = `pkg-config sdl --libs` -lm 2.17 2.18 $(bin): $(obj) 2.19 @@ -20,6 +21,9 @@ 2.20 %.x86.d: %.c 2.21 @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ 2.22 2.23 +%.img.c: %.png 2.24 + img2gba $< 2.25 + 2.26 .PHONY: clean 2.27 clean: 2.28 rm -f $(obj) $(bin)
3.1 --- a/src/game.c Wed Jun 25 18:18:05 2014 +0300 3.2 +++ b/src/game.c Thu Jun 26 06:57:51 2014 +0300 3.3 @@ -6,6 +6,7 @@ 3.4 #include "fixed.h" 3.5 #include "palman.h" 3.6 #include "ggen.h" 3.7 +#include "data.h" 3.8 3.9 extern int dbg_fill_dump; 3.10 3.11 @@ -31,6 +32,7 @@ 3.12 static const short vcount = sizeof poly / sizeof *poly / 3; 3.13 3.14 static struct mesh box; 3.15 +static int tex; 3.16 3.17 3.18 int game_init(void) 3.19 @@ -40,6 +42,8 @@ 3.20 palman_init(); 3.21 #endif 3.22 3.23 + tex = x3d_create_texture_rgb(test_width, test_height, test_pixels); 3.24 + 3.25 x3d_projection(45.0, (WIDTH << 16) / HEIGHT, 65536 / 2, 65536 * 500); 3.26 3.27 init_mesh(&box); 3.28 @@ -81,7 +85,9 @@ 3.29 x3d_color(65536, 65536, 65536); 3.30 #endif 3.31 3.32 + x3d_enable_texture(tex); 3.33 draw_mesh(&box); 3.34 + x3d_disable_texture(); 3.35 3.36 /* 3.37 x3d_vertex_array(vcount, poly);
4.1 --- a/src/polyfill.c Wed Jun 25 18:18:05 2014 +0300 4.2 +++ b/src/polyfill.c Thu Jun 26 06:57:51 2014 +0300 4.3 @@ -13,10 +13,11 @@ 4.4 static void fill_scanline_pal(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1, 4.5 int32_t v0, int32_t v1, uint8_t color); 4.6 static void fill_scanline_rgb(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1, 4.7 - int32_t v0, int32_t v1, uint16_t color); 4.8 + int32_t v0, int32_t v1, uint16_t color, struct texture *tex); 4.9 static int winding(int32_t x0, int32_t y0, int32_t x1, int32_t y1); 4.10 4.11 -void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color) 4.12 +void draw_poly(int num, const pvec3 *verts, const pvec2 *texcoords, uint16_t color, 4.13 + struct texture *tex) 4.14 { 4.15 int i, topidx = 0, botidx = 0; 4.16 int lidx[2] = {-1, -1}, ridx[2] = {-1, -1}; 4.17 @@ -69,10 +70,10 @@ 4.18 } 4.19 lx = verts[lidx[0]].x; 4.20 ldxdy = x16div(verts[lidx[1]].x - lx, ldy); 4.21 - lu = tex[lidx[0]].x; 4.22 - ldudy = x16div(tex[lidx[1]].x - lu, ldy); 4.23 - lv = tex[lidx[0]].y; 4.24 - ldvdy = x16div(tex[lidx[1]].y - lv, ldy); 4.25 + lu = texcoords[lidx[0]].x; 4.26 + ldudy = x16div(texcoords[lidx[1]].x - lu, ldy); 4.27 + lv = texcoords[lidx[0]].y; 4.28 + ldvdy = x16div(texcoords[lidx[1]].y - lv, ldy); 4.29 4.30 /* find starting right edge */ 4.31 ridx[1] = VNEXT(ridx[0], num); 4.32 @@ -90,10 +91,10 @@ 4.33 } 4.34 rx = verts[ridx[0]].x; 4.35 rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 4.36 - ru = tex[ridx[0]].x; 4.37 - rdudy = x16div(tex[ridx[1]].x - ru, rdy); 4.38 - rv = tex[ridx[0]].y; 4.39 - rdvdy = x16div(tex[ridx[1]].y - rv, rdy); 4.40 + ru = texcoords[ridx[0]].x; 4.41 + rdudy = x16div(texcoords[ridx[1]].x - ru, rdy); 4.42 + rv = texcoords[ridx[0]].y; 4.43 + rdvdy = x16div(texcoords[ridx[1]].y - rv, rdy); 4.44 4.45 start = topy >> 16; 4.46 end = boty >> 16; 4.47 @@ -112,17 +113,17 @@ 4.48 break; 4.49 } 4.50 4.51 - lu = tex[lidx[0]].x; 4.52 - lv = tex[lidx[0]].y; 4.53 + lu = texcoords[lidx[0]].x; 4.54 + lv = texcoords[lidx[0]].y; 4.55 4.56 if(ldy) { 4.57 ldxdy = x16div(verts[lidx[1]].x - lx, ldy); 4.58 - ldudy = x16div(tex[lidx[1]].x - lu, ldy); 4.59 - ldvdy = x16div(tex[lidx[1]].y - lv, ldy); 4.60 + ldudy = x16div(texcoords[lidx[1]].x - lu, ldy); 4.61 + ldvdy = x16div(texcoords[lidx[1]].y - lv, ldy); 4.62 } else { 4.63 ldxdy = verts[lidx[1]].x - lx; 4.64 - ldudy = tex[lidx[1]].x - lu; 4.65 - ldvdy = tex[lidx[1]].y - lv; 4.66 + ldudy = texcoords[lidx[1]].x - lu; 4.67 + ldvdy = texcoords[lidx[1]].y - lv; 4.68 } 4.69 } 4.70 if(y >= verts[ridx[1]].y) { 4.71 @@ -134,17 +135,17 @@ 4.72 break; 4.73 } 4.74 4.75 - ru = tex[ridx[0]].x; 4.76 - rv = tex[ridx[0]].y; 4.77 + ru = texcoords[ridx[0]].x; 4.78 + rv = texcoords[ridx[0]].y; 4.79 4.80 if(rdy) { 4.81 rdxdy = x16div(verts[ridx[1]].x - rx, rdy); 4.82 - rdudy = x16div(tex[ridx[1]].x - ru, rdy); 4.83 - rdvdy = x16div(tex[ridx[1]].y - rv, rdy); 4.84 + rdudy = x16div(texcoords[ridx[1]].x - ru, rdy); 4.85 + rdvdy = x16div(texcoords[ridx[1]].y - rv, rdy); 4.86 } else { 4.87 rdxdy = verts[ridx[1]].x - rx; 4.88 - rdudy = tex[ridx[1]].x - ru; 4.89 - rdvdy = tex[ridx[1]].y - rv; 4.90 + rdudy = texcoords[ridx[1]].x - ru; 4.91 + rdvdy = texcoords[ridx[1]].y - rv; 4.92 } 4.93 } 4.94 4.95 @@ -152,7 +153,7 @@ 4.96 #ifdef PALMODE 4.97 fill_scanline_pal(i, lx, rx, lu, ru, lv, rv, (uint8_t)color); 4.98 #else 4.99 - fill_scanline_rgb(i, lx, rx, lu, ru, lv, rv, color); 4.100 + fill_scanline_rgb(i, lx, rx, lu, ru, lv, rv, color, tex); 4.101 #endif 4.102 } 4.103 4.104 @@ -229,7 +230,7 @@ 4.105 } 4.106 4.107 static void fill_scanline_rgb(int y, int32_t x0, int32_t x1, int32_t u0, int32_t u1, 4.108 - int32_t v0, int32_t v1, uint16_t color) 4.109 + int32_t v0, int32_t v1, uint16_t color, struct texture *tex) 4.110 { 4.111 int i, ix0, ix1; 4.112 uint16_t *pixels; 4.113 @@ -268,7 +269,14 @@ 4.114 if(cr > 255) cr = 255; 4.115 if(cg > 255) cg = 255; 4.116 4.117 - *pixels++ = RGB(cr, cg, 0); 4.118 + if(tex) { 4.119 + int tx = (u >> (16 - tex->ushift)) & tex->umask; 4.120 + int ty = (v >> (16 - tex->vshift)) & tex->vmask; 4.121 + uint16_t texel = ((uint16_t*)tex->pixels)[ty * tex->xsz + tx]; 4.122 + *pixels++ = texel; 4.123 + } else { 4.124 + *pixels++ = color; 4.125 + } 4.126 4.127 u += dudx; 4.128 v += dvdx;
5.1 --- a/src/polyfill.h Wed Jun 25 18:18:05 2014 +0300 5.2 +++ b/src/polyfill.h Thu Jun 26 06:57:51 2014 +0300 5.3 @@ -2,6 +2,7 @@ 5.4 #define POLYFILL_H_ 5.5 5.6 #include <stdint.h> 5.7 +#include "x3d_impl.h" 5.8 5.9 typedef struct pvec3 { 5.10 int32_t x, y, z; 5.11 @@ -11,7 +12,8 @@ 5.12 int32_t x, y; 5.13 } pvec2; 5.14 5.15 -void draw_poly(int num, const pvec3 *verts, const pvec2 *tex, uint16_t color); 5.16 +void draw_poly(int num, const pvec3 *verts, const pvec2 *texcoords, uint16_t color, 5.17 + struct texture *tex); 5.18 5.19 void draw_point(const pvec3 *v, uint16_t color); 5.20
6.1 --- a/src/x3d.c Wed Jun 25 18:18:05 2014 +0300 6.2 +++ b/src/x3d.c Thu Jun 26 06:57:51 2014 +0300 6.3 @@ -8,6 +8,7 @@ 6.4 #include "logger.h" 6.5 #include "polyfill.h" 6.6 #include "gbasys.h" 6.7 +#include "x3d_impl.h" 6.8 6.9 int dbg_fill_dump; 6.10 6.11 @@ -47,6 +48,11 @@ 6.12 static int32_t im_texcoord[2]; 6.13 static uint8_t im_color_index; 6.14 6.15 +#define MAX_TEXTURES 64 6.16 +static struct texture textures[MAX_TEXTURES]; 6.17 +static short cur_tex = -1; 6.18 + 6.19 + 6.20 void x3d_projection(int fov, int32_t aspect, int32_t nearz, int32_t farz) 6.21 { 6.22 proj_fov = (M_PI_X16 * fov) / 180; 6.23 @@ -257,7 +263,7 @@ 6.24 6.25 case X3D_TRIANGLES: 6.26 case X3D_QUADS: 6.27 - draw_poly(pverts, vpos, tex, color); 6.28 + draw_poly(pverts, vpos, tex, color, cur_tex >= 0 ? textures + cur_tex : 0); 6.29 if(dbg_fill_dump) { 6.30 dump_frame(back_buffer); 6.31 } 6.32 @@ -324,6 +330,63 @@ 6.33 im_color[2] = b; 6.34 } 6.35 6.36 +static int count_bits(int x) 6.37 +{ 6.38 + int i, count = 0; 6.39 + for(i=0; i<32; i++) { 6.40 + if(x & 1) count++; 6.41 + x >>= 1; 6.42 + } 6.43 + return count; 6.44 +} 6.45 + 6.46 +int x3d_create_texture_rgb(int xsz, int ysz, const uint16_t *pixels) 6.47 +{ 6.48 + int i, j; 6.49 + 6.50 + if(xsz == 0 || count_bits(xsz) > 1 || ysz == 0 || count_bits(ysz) > 1) { 6.51 + logmsg(LOG_DBG, "%s: texture size (%dx%d) not power of two!\n", __func__, xsz, ysz); 6.52 + return -1; 6.53 + } 6.54 + 6.55 + for(i=0; i<MAX_TEXTURES; i++) { 6.56 + if(!textures[i].pixels) { 6.57 + textures[i].pixels = pixels; 6.58 + textures[i].xsz = xsz; 6.59 + textures[i].ysz = ysz; 6.60 + textures[i].umask = xsz - 1; 6.61 + textures[i].vmask = ysz - 1; 6.62 + 6.63 + for(j=0; j<32; j++) { 6.64 + if((1 << j) == xsz) { 6.65 + textures[i].ushift = j; 6.66 + } 6.67 + if((1 << j) == ysz) { 6.68 + textures[i].vshift = j; 6.69 + } 6.70 + } 6.71 + 6.72 + return i; 6.73 + } 6.74 + } 6.75 + return -1; 6.76 +} 6.77 + 6.78 +void x3d_enable_texture(int texid) 6.79 +{ 6.80 + cur_tex = texid; 6.81 +} 6.82 + 6.83 +void x3d_disable_texture(void) 6.84 +{ 6.85 + cur_tex = 0; 6.86 +} 6.87 + 6.88 +int x3d_get_active_texture(void) 6.89 +{ 6.90 + return cur_tex; 6.91 +} 6.92 + 6.93 static int dump_frame(struct pixel_buffer *frame) 6.94 { 6.95 static int frameno;
7.1 --- a/src/x3d.h Wed Jun 25 18:18:05 2014 +0300 7.2 +++ b/src/x3d.h Thu Jun 26 06:57:51 2014 +0300 7.3 @@ -31,4 +31,9 @@ 7.4 void x3d_color_index(int cidx); 7.5 void x3d_color(int32_t r, int32_t g, int32_t b); 7.6 7.7 +int x3d_create_texture_rgb(int xsz, int ysz, const uint16_t *pixels); 7.8 +void x3d_enable_texture(int texid); 7.9 +void x3d_disable_texture(void); 7.10 +int x3d_get_active_texture(void); 7.11 + 7.12 #endif /* X3D_H_ */
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/src/x3d_impl.h Thu Jun 26 06:57:51 2014 +0300 8.3 @@ -0,0 +1,10 @@ 8.4 +#ifndef X3D_IMPL_H_ 8.5 +#define X3D_IMPL_H_ 8.6 + 8.7 +struct texture { 8.8 + int xsz, ysz; 8.9 + unsigned int umask, vmask, ushift, vshift; 8.10 + const void *pixels; 8.11 +}; 8.12 + 8.13 +#endif /* X3D_IMPL_H_ */
9.1 Binary file test.png has changed