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