deepstone
changeset 25:5ff8ce78059a
first pass at converting the rasterizer to fixed point
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 22 Sep 2013 02:21:30 +0300 |
parents | ad6b185723cd |
children | 61d97b17cd2b |
files | Makefile dosemu/dosemu.c src/fixed_point.c src/fixed_point.h src/mglimpl.h src/mglrast.c src/scantmpl.h src/test.c src/vmath.h |
diffstat | 9 files changed, 353 insertions(+), 90 deletions(-) [+] |
line diff
1.1 --- a/Makefile Sat Sep 21 20:18:28 2013 +0300 1.2 +++ b/Makefile Sun Sep 22 02:21:30 2013 +0300 1.3 @@ -1,14 +1,15 @@ 1.4 obj = src/test.o \ 1.5 src/mingl.o src/mglrast.o src/mglgen.o \ 1.6 src/texture.o src/palman.o \ 1.7 - src/scene.o src/cvec.o \ 1.8 + src/scene.o src/cvec.o src/fixed_point.o \ 1.9 dosemu/dosemu.o 1.10 dep = $(obj:.o=.d) 1.11 -bin = test 1.12 +bin = deepstone 1.13 1.14 CC = gcc 1.15 CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl` -Isrc -Idosemu 1.16 -LDFLAGS = `pkg-config --libs sdl` 1.17 +#-DRAST_FLOAT -DDBG_USE_FLOAT 1.18 +LDFLAGS = `pkg-config --libs sdl` -lm 1.19 1.20 $(bin): $(obj) 1.21 $(CC) -o $@ $(obj) $(LDFLAGS)
2.1 --- a/dosemu/dosemu.c Sat Sep 21 20:18:28 2013 +0300 2.2 +++ b/dosemu/dosemu.c Sun Sep 22 02:21:30 2013 +0300 2.3 @@ -38,6 +38,7 @@ 2.4 fprintf(stderr, "failed to set video mode\n"); 2.5 abort(); 2.6 } 2.7 + SDL_WM_SetCaption("Deepstone", 0); 2.8 SDL_ShowCursor(0); 2.9 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 2.10 break;
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/src/fixed_point.c Sun Sep 22 02:21:30 2013 +0300 3.3 @@ -0,0 +1,52 @@ 3.4 +#include <math.h> 3.5 +#include "fixed_point.h" 3.6 + 3.7 +const fixed fixed_zero = 0; 3.8 +const fixed fixed_one = fixedi(1); 3.9 +const fixed fixed_half = fixedf(0.5); 3.10 +const fixed fixed_tenth = fixedf(0.1); 3.11 +const fixed fixed_255 = fixedi(255); 3.12 + 3.13 +#ifndef DBG_USE_FLOAT 3.14 + 3.15 +#define PI 3.1415927 3.16 +#define TWO_PI 6.2831853 3.17 + 3.18 +#define LUT_SIZE 256 3.19 + 3.20 +static fixed sin_lut[LUT_SIZE], cos_lut[LUT_SIZE]; 3.21 +static int initialized; 3.22 + 3.23 +static void precalc_lut(void) 3.24 +{ 3.25 + int i; 3.26 + 3.27 + for(i=0; i<LUT_SIZE; i++) { 3.28 + float angle = TWO_PI * (float)i / (float)LUT_SIZE; 3.29 + 3.30 + sin_lut[i] = FLOAT_TO_FIXED(sin(angle)); 3.31 + cos_lut[i] = FLOAT_TO_FIXED(cos(angle)); 3.32 + } 3.33 + 3.34 + initialized = 1; 3.35 +} 3.36 + 3.37 +static const fixed fix_two_pi = FLOAT_TO_FIXED(TWO_PI); 3.38 + 3.39 +fixed fixed_sin(fixed angle) { 3.40 + int a; 3.41 + 3.42 + if(!initialized) precalc_lut(); 3.43 + a = FIXED_INT_PART(fixed_div(angle, fix_two_pi) * 255) % 256; 3.44 + return a >= 0 ? sin_lut[a] : -sin_lut[-a]; 3.45 +} 3.46 + 3.47 +fixed fixed_cos(fixed angle) { 3.48 + int a; 3.49 + 3.50 + if(!initialized) precalc_lut(); 3.51 + a = FIXED_INT_PART(fixed_div(angle, fix_two_pi) * 255) % 256; 3.52 + return a >= 0 ? cos_lut[a] : cos_lut[-a]; 3.53 +} 3.54 + 3.55 +#endif
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/fixed_point.h Sun Sep 22 02:21:30 2013 +0300 4.3 @@ -0,0 +1,106 @@ 4.4 +#ifndef FIXED_POINT_H_ 4.5 +#define FIXED_POINT_H_ 4.6 + 4.7 +#include "inttypes.h" 4.8 + 4.9 +#ifdef DBG_USE_FLOAT 4.10 +typedef float fixed; 4.11 +#else 4.12 +typedef int32_t fixed; 4.13 +#endif 4.14 + 4.15 +/* valid choices for DECIMAL_BITS 4.16 + * 8: for fixed point 24:8 4.17 + * 16: for fixed point 16:16 4.18 + */ 4.19 +#define DECIMAL_BITS 16 4.20 + 4.21 +#if DECIMAL_BITS == 8 4.22 +#define FIXED_SHIFT 8 4.23 +#define FLT_SCALE 256.0f 4.24 +#define FRAC_MASK 0xff 4.25 +#else /* DECIMAL_BITS == 16 */ 4.26 +#define FIXED_SHIFT 16 4.27 +#define FLT_SCALE 65536.0f 4.28 +#define FRAC_MASK 0xffff 4.29 +#endif /* DECIMAL_BITS */ 4.30 + 4.31 +/*extern const fixed fixed_zero; 4.32 +extern const fixed fixed_one; 4.33 +extern const fixed fixed_half; 4.34 +extern const fixed fixed_tenth; 4.35 +extern const fixed fixed_255;*/ 4.36 + 4.37 +#ifdef DBG_USE_FLOAT 4.38 +/* ------- debug mode, use floating point -------- */ 4.39 +#define FIXED_INT_PART(n) ((int)(n)) 4.40 +#define FIXED_FRAC_PART(n) ((n) > 0.0f ? (FIXED_INT_PART(n) - (n)) : (FIXED_INT_PART(n) + (n))) 4.41 +#define FIXED_ROUND(n) FIXED_INT_PART((n) >= 0.0 ? (n) + 0.5f : (n) - 0.5f) 4.42 + 4.43 +#define FIXED_TO_FLOAT(n) (n) 4.44 +#define FLOAT_TO_FIXED(n) (n) 4.45 +#define INT_TO_FIXED(n) ((float)(n)) 4.46 + 4.47 +#define FIXED_EPSILON (1e-6) 4.48 + 4.49 +#else /* ---- really fixed point ---- */ 4.50 + 4.51 +#define FIXED_INT_PART(n) ((n) >> FIXED_SHIFT) 4.52 +#define FIXED_FRAC_PART(n) ((n) & FRAC_MASK) 4.53 +#define FIXED_ROUND(n) FIXED_INT_PART((n) >= 0 ? (n) + fixedf(0.5) : (n) - fixedf(0.5)) 4.54 +/*#define FIXED_ROUND(n) FIXED_INT_PART(n)*/ 4.55 + 4.56 +#define FIXED_TO_FLOAT(n) (float)((n) / FLT_SCALE) 4.57 +#define FLOAT_TO_FIXED(n) (fixed)((n) * FLT_SCALE) 4.58 +#define INT_TO_FIXED(n) (fixed)((n) << FIXED_SHIFT) 4.59 + 4.60 +#define FIXED_EPSILON (1) 4.61 + 4.62 +#endif 4.63 + 4.64 + 4.65 +#define fixed_int(n) FIXED_INT_PART(n) 4.66 +#define fixed_frac(n) FIXED_FRAC_PART(n) 4.67 +#define fixed_float(n) FIXED_TO_FLOAT(n) 4.68 +#define fixed_round(n) FIXED_ROUND(n) 4.69 + 4.70 +#define fixedf(n) FLOAT_TO_FIXED(n) 4.71 +#define fixedi(n) INT_TO_FIXED(n) 4.72 + 4.73 +#define fixed_add(n1, n2) ((n1) + (n2)) 4.74 +#define fixed_sub(n1, n2) ((n1) - (n2)) 4.75 + 4.76 + 4.77 + 4.78 +#ifdef DBG_USE_FLOAT 4.79 + 4.80 +#define fixed_mul(n1, n2) ((n1) * (n2)) 4.81 +#define fixed_div(n1, n2) ((n1) / (n2)) 4.82 + 4.83 +#define fixed_sin(x) (fixed)sin(x) 4.84 +#define fixed_cos(x) (fixed)cos(x) 4.85 + 4.86 +#else 4.87 + 4.88 +#if DECIMAL_BITS == 8 4.89 +#define fixed_mul(n1, n2) (fixed)((n1) * (n2) >> FIXED_SHIFT) 4.90 +#define fixed_div(n1, n2) (((n1) << FIXED_SHIFT) / (n2)) 4.91 +#else 4.92 +#define fixed_div(n1, n2) (((int64_t)(n1) << FIXED_SHIFT) / (int64_t)(n2)) 4.93 +#define fixed_mul(n1, n2) (((n1) >> 8) * ((n2) >> 8)) 4.94 +#endif /* DECIMAL_BITS */ 4.95 + 4.96 +#ifdef __cplusplus 4.97 +extern "C" { 4.98 +#endif 4.99 + 4.100 +fixed fixed_sin(fixed angle); 4.101 +fixed fixed_cos(fixed angle); 4.102 + 4.103 +#ifdef __cplusplus 4.104 +} 4.105 +#endif 4.106 + 4.107 +#endif 4.108 + 4.109 +#endif /* FIXED_POINT_H_ */
5.1 --- a/src/mglimpl.h Sat Sep 21 20:18:28 2013 +0300 5.2 +++ b/src/mglimpl.h Sun Sep 22 02:21:30 2013 +0300 5.3 @@ -26,6 +26,14 @@ 5.4 int cidx; 5.5 }; 5.6 5.7 +struct fixed_vertex { 5.8 + vec4x_t pos; 5.9 + vec4x_t norm; 5.10 + vec2x_t tc; 5.11 + fixed energy; 5.12 + int cidx; 5.13 +}; 5.14 + 5.15 struct texture { 5.16 int width, height; 5.17 int xshift, yshift; 5.18 @@ -57,6 +65,25 @@ 5.19 }; 5.20 5.21 5.22 +#define vertex_to_fixedvertex(v, vx) \ 5.23 + do { \ 5.24 + vec4_to_fixed4((v).pos, (vx).pos); \ 5.25 + vec3_to_fixed3((v).norm, (vx).norm); \ 5.26 + vec2_to_fixed2((v).tc, (vx).tc); \ 5.27 + (vx).energy = fixedf((v).energy); \ 5.28 + (vx).cidx = (v).cidx; \ 5.29 + } while(0) 5.30 + 5.31 +#define fixedvertex_to_vertex(vx, v) \ 5.32 + do { \ 5.33 + fixed4_to_vec4((vx).pos, (v).pos); \ 5.34 + fixed3_to_vec3((vx).norm, (v).norm); \ 5.35 + fixed2_to_vec2((vx).tc, (v).tc); \ 5.36 + (v).energy = fixed_float((vx).energy); \ 5.37 + (v).cidx = (vx).cidx; \ 5.38 + } while(0) 5.39 + 5.40 + 5.41 int mgl_rast_init(struct state *state, struct framebuffer *fbuf); 5.42 void mgl_rast_cleanup(void); 5.43 void mgl_rast_prepare(void);
6.1 --- a/src/mglrast.c Sat Sep 21 20:18:28 2013 +0300 6.2 +++ b/src/mglrast.c Sun Sep 22 02:21:30 2013 +0300 6.3 @@ -1,20 +1,3 @@ 6.4 -/* 6.5 -256-color 3D graphics hack for real-mode DOS. 6.6 -Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 6.7 - 6.8 -This program is free software: you can redistribute it and/or modify 6.9 -it under the terms of the GNU General Public License as published by 6.10 -the Free Software Foundation, either version 3 of the License, or 6.11 -(at your option) any later version. 6.12 - 6.13 -This program is distributed in the hope that it will be useful, 6.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of 6.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 6.16 -GNU General Public License for more details. 6.17 - 6.18 -You should have received a copy of the GNU General Public License 6.19 -along with this program. If not, see <http://www.gnu.org/licenses/>. 6.20 -*/ 6.21 #include <stdio.h> 6.22 #include <stdlib.h> 6.23 #include <string.h> 6.24 @@ -24,7 +7,13 @@ 6.25 #include "mglimpl.h" 6.26 6.27 6.28 -static struct vertex *vleft, *vright; 6.29 +#ifdef RAST_FLOAT 6.30 +typedef struct vertex VERTEX; 6.31 +#else 6.32 +typedef struct fixed_vertex VERTEX; 6.33 +#endif 6.34 + 6.35 +static VERTEX *vleft, *vright; 6.36 static struct framebuffer *fb; 6.37 static struct state *st; 6.38 6.39 @@ -102,9 +91,10 @@ 6.40 #undef SCAN_LINE 6.41 6.42 6.43 -static void (*scan_edge)(struct vertex*, struct vertex*); 6.44 +static void (*scan_edge)(VERTEX*, VERTEX*); 6.45 static void (*scan_line)(int, unsigned char*); 6.46 6.47 + 6.48 int mgl_rast_init(struct state *state, struct framebuffer *fbuf) 6.49 { 6.50 fb = fbuf; 6.51 @@ -132,7 +122,7 @@ 6.52 6.53 void mgl_rast_prepare(void) 6.54 { 6.55 - static void (*sedge[])(struct vertex*, struct vertex*) = { 6.56 + static void (*sedge[])(VERTEX*, VERTEX*) = { 6.57 /* tez */ 6.58 scan_edge_flat, /* 000 */ 6.59 scan_edge_z, /* 001 */ 6.60 @@ -190,6 +180,7 @@ 6.61 6.62 void mgl_draw_poly(struct vertex *v, int numv) 6.63 { 6.64 +#ifdef RAST_FLOAT 6.65 int ybeg, yend, i; 6.66 unsigned char *sline; 6.67 6.68 @@ -215,4 +206,37 @@ 6.69 scan_line(i, sline); 6.70 sline += fb->width; 6.71 } 6.72 +#else 6.73 + int ybeg, yend, i; 6.74 + unsigned char *sline; 6.75 + 6.76 + ybeg = fb->height; 6.77 + yend = 0; 6.78 + 6.79 + for(i=0; i<numv; i++) { 6.80 + int y; 6.81 + struct vertex *v0 = v + i; 6.82 + struct vertex *v1 = v + (i + 1) % numv; 6.83 + struct fixed_vertex vx0, vx1; 6.84 + 6.85 + vertex_to_fixedvertex(*v0, vx0); 6.86 + vertex_to_fixedvertex(*v1, vx1); 6.87 + 6.88 + y = fixed_round(vx0.pos.y); 6.89 + 6.90 + scan_edge(&vx0, &vx1); 6.91 + 6.92 + if(y > yend) yend = y; 6.93 + if(y < ybeg) ybeg = y; 6.94 + } 6.95 + 6.96 + if(ybeg < 0) ybeg = 0; 6.97 + if(yend >= fb->height) yend = fb->height - 1; 6.98 + 6.99 + sline = fb->pixels + ybeg * fb->width; 6.100 + for(i=ybeg; i<yend; i++) { 6.101 + scan_line(i, sline); 6.102 + sline += fb->width; 6.103 + } 6.104 +#endif 6.105 }
7.1 --- a/src/scantmpl.h Sat Sep 21 20:18:28 2013 +0300 7.2 +++ b/src/scantmpl.h Sun Sep 22 02:21:30 2013 +0300 7.3 @@ -1,61 +1,44 @@ 7.4 -/* 7.5 -256-color 3D graphics hack for real-mode DOS. 7.6 -Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 7.7 - 7.8 -This program is free software: you can redistribute it and/or modify 7.9 -it under the terms of the GNU General Public License as published by 7.10 -the Free Software Foundation, either version 3 of the License, or 7.11 -(at your option) any later version. 7.12 - 7.13 -This program is distributed in the hope that it will be useful, 7.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of 7.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 7.16 -GNU General Public License for more details. 7.17 - 7.18 -You should have received a copy of the GNU General Public License 7.19 -along with this program. If not, see <http://www.gnu.org/licenses/>. 7.20 -*/ 7.21 -static void SCAN_EDGE(struct vertex *v0, struct vertex *v1) 7.22 +static void SCAN_EDGE(VERTEX *v0, VERTEX *v1) 7.23 { 7.24 int i, start, end; 7.25 - float dx, dy, dfdx; 7.26 + fixed dx, dy, dfdx; 7.27 #ifdef INTERP_DEPTH 7.28 - float z, dz, dfdz; 7.29 + fixed z, dz, dfdz; 7.30 #endif 7.31 #ifdef INTERP_ENERGY 7.32 - float e, de, dfde; 7.33 + fixed e, de, dfde; 7.34 #endif 7.35 #ifdef INTERP_TEX 7.36 - float u, v, du, dv, dfdu, dfdv; 7.37 + fixed u, v, du, dv, dfdu, dfdv; 7.38 #endif 7.39 - float x; 7.40 - struct vertex *edge; 7.41 + fixed x; 7.42 + VERTEX *edge; 7.43 7.44 dy = v1->pos.y - v0->pos.y; 7.45 - if(dy < 1e-6 && dy > -1e-6) { 7.46 + if(dy < FIXED_EPSILON && dy > -FIXED_EPSILON) { 7.47 return; 7.48 } 7.49 7.50 dx = v1->pos.x - v0->pos.x; 7.51 - dfdx = dx / dy; 7.52 + dfdx = fixed_div(dx, dy); 7.53 7.54 #ifdef INTERP_DEPTH 7.55 dz = v1->pos.z - v0->pos.z; 7.56 - dfdz = dz / dy; 7.57 + dfdz = fixed_div(dz, dy); 7.58 #endif 7.59 #ifdef INTERP_ENERGY 7.60 de = v1->energy - v0->energy; 7.61 - dfde = de / dy; 7.62 + dfde = fixed_div(de, dy); 7.63 #endif 7.64 #ifdef INTERP_TEX 7.65 du = v1->tc.x - v0->tc.x; 7.66 dv = v1->tc.y - v0->tc.y; 7.67 - dfdu = du / dy; 7.68 - dfdv = dv / dy; 7.69 + dfdu = fixed_div(du, dy); 7.70 + dfdv = fixed_div(dv, dy); 7.71 #endif 7.72 7.73 - if(dy < 0.0) { 7.74 - struct vertex *tmp = v0; 7.75 + if(dy < 0) { 7.76 + VERTEX *tmp = v0; 7.77 v0 = v1; 7.78 v1 = tmp; 7.79 edge = (st->ord == MGL_CCW) ? vright : vleft; 7.80 @@ -63,8 +46,8 @@ 7.81 edge = (st->ord == MGL_CCW) ? vleft : vright; 7.82 } 7.83 7.84 - start = (int)ROUND(v0->pos.y); 7.85 - end = (int)ROUND(v1->pos.y); 7.86 + start = (int)fixed_round(v0->pos.y); 7.87 + end = (int)fixed_round(v1->pos.y); 7.88 7.89 if(start >= 0) { 7.90 7.91 @@ -80,18 +63,18 @@ 7.92 v = v0->tc.y; 7.93 #endif 7.94 } else { 7.95 - float lines = -v0->pos.y; 7.96 + fixed lines = -v0->pos.y; 7.97 7.98 - x = v0->pos.x + dfdx * lines; 7.99 + x = v0->pos.x + fixed_mul(dfdx, lines); 7.100 #ifdef INTERP_DEPTH 7.101 - z = v0->pos.z + dfdz * lines; 7.102 + z = v0->pos.z + fixed_mul(dfdz, lines); 7.103 #endif 7.104 #ifdef INTERP_ENERGY 7.105 - e = v0->energy + dfde * lines; 7.106 + e = v0->energy + fixed_mul(dfde, lines); 7.107 #endif 7.108 #ifdef INTERP_TEX 7.109 - u = v0->tc.x + dfdu * lines; 7.110 - v = v0->tc.y + dfdv * lines; 7.111 + u = v0->tc.x + fixed_mul(dfdu, lines); 7.112 + v = v0->tc.y + fixed_mul(dfdv, lines); 7.113 #endif 7.114 start = 0; 7.115 } 7.116 @@ -132,22 +115,22 @@ 7.117 int x0, x1, len, tmp, cidx; 7.118 #if defined(INTERP_DEPTH) || defined(INTERP_ENERGY) || defined(INTERP_TEX) 7.119 int i; 7.120 - float x, dx; 7.121 + fixed x, dx; 7.122 #endif 7.123 #ifdef INTERP_DEPTH 7.124 - float z, dz, dfdz; 7.125 + fixed z, dz, dfdz; 7.126 #endif 7.127 #ifdef INTERP_ENERGY 7.128 - float e, de, dfde; 7.129 + fixed e, de, dfde; 7.130 #endif 7.131 #ifdef INTERP_TEX 7.132 unsigned int tx, ty; 7.133 - float u, v, du, dv, dfdu, dfdv; 7.134 + fixed u, v, du, dv, dfdu, dfdv; 7.135 #endif 7.136 - struct vertex *left, *right; 7.137 + VERTEX *left, *right; 7.138 7.139 - x0 = (int)ROUND(vleft[y].pos.x); 7.140 - x1 = (int)ROUND(vright[y].pos.x); 7.141 + x0 = (int)fixed_round(vleft[y].pos.x); 7.142 + x1 = (int)fixed_round(vright[y].pos.x); 7.143 7.144 if(x1 < x0) { 7.145 if(st->flags & MGL_CULL_FACE) { 7.146 @@ -174,13 +157,13 @@ 7.147 len = x1 - x0; 7.148 assert(len >= 0); 7.149 /* no interpolation at all, just memset the whole scanline */ 7.150 - memset(sline + x0, cidx + left[y].energy * st->col_range, len); 7.151 + memset(sline + x0, cidx + fixed_int(fixed_mul(left[y].energy, fixedi(st->col_range))), len); 7.152 #else 7.153 /* otherwise do a loop and interpolate whatever needs interpolating */ 7.154 x = left[y].pos.x; 7.155 dx = right[y].pos.x - x; 7.156 7.157 - if(dx < 0.5 && dx > -0.5) { 7.158 + if(dx < fixedf(0.5) && dx > -fixedf(0.5)) { 7.159 return; 7.160 } 7.161 7.162 @@ -188,41 +171,41 @@ 7.163 #ifdef INTERP_DEPTH 7.164 z = left[y].pos.z; 7.165 dz = right[y].pos.z - z; 7.166 - dfdz = dz / dx; 7.167 + dfdz = fixed_div(dz, dx); 7.168 #endif 7.169 #ifdef INTERP_ENERGY 7.170 e = left[y].energy; 7.171 de = right[y].energy - e; 7.172 - dfde = de / dx; 7.173 + dfde = fixed_div(de, dx); 7.174 #endif 7.175 #ifdef INTERP_TEX 7.176 u = left[y].tc.x; 7.177 v = left[y].tc.y; 7.178 du = right[y].tc.x - u; 7.179 dv = right[y].tc.y - v; 7.180 - dfdu = du / dx; 7.181 - dfdv = dv / dx; 7.182 + dfdu = fixed_div(du, dx); 7.183 + dfdv = fixed_div(dv, dx); 7.184 #endif 7.185 } else { 7.186 - float dist = -left[y].pos.x; 7.187 + fixed dist = -left[y].pos.x; 7.188 7.189 #ifdef INTERP_DEPTH 7.190 dz = right[y].pos.z - left[y].pos.z; 7.191 - dfdz = dz / dx; 7.192 - z = left[y].pos.z + dfdz * dist; 7.193 + dfdz = fixed_div(dz, dx); 7.194 + z = left[y].pos.z + fixed_mul(dfdz, dist); 7.195 #endif 7.196 #ifdef INTERP_ENERGY 7.197 de = right[y].energy - left[y].energy; 7.198 - dfde = de / dx; 7.199 - e = left[y].energy + dfde * dist; 7.200 + dfde = fixed_div(de, dx); 7.201 + e = left[y].energy + fixed_mul(dfde, dist); 7.202 #endif 7.203 #ifdef INTERP_TEX 7.204 du = right[y].tc.x - left[y].tc.x; 7.205 dv = right[y].tc.y - left[y].tc.y; 7.206 - dfdu = du / dx; 7.207 - dfdv = dv / dx; 7.208 - u = left[y].tc.x + dfdu * dist; 7.209 - v = left[y].tc.y + dfdv * dist; 7.210 + dfdu = fixed_div(du, dx); 7.211 + dfdv = fixed_div(dv, dx); 7.212 + u = left[y].tc.x + fixed_mul(dfdu, dist); 7.213 + v = left[y].tc.y + fixed_mul(dfdv, dist); 7.214 #endif 7.215 x0 = 0; 7.216 } 7.217 @@ -234,10 +217,14 @@ 7.218 7.219 #ifdef INTERP_DEPTH 7.220 long pix = (sline + x0 + i) - fb->pixels; 7.221 +#ifdef RAST_FLOAT 7.222 unsigned short zval = (unsigned short)(z * USHRT_MAX); 7.223 +#else 7.224 + unsigned short zval = (unsigned short)((z >> 1) & 0xffff); 7.225 +#endif 7.226 unsigned short *zptr = fb->zbuf[ZTILE(pix)] + ZTILE_OFFS(pix); 7.227 7.228 - if(z < 0.0 || z >= 1.0 || zval > *zptr) { 7.229 + if(z < 0 || z >= fixedi(1) || zval > *zptr) { 7.230 # ifdef INTERP_TEX 7.231 u += dfdu; 7.232 v += dfdv; 7.233 @@ -253,18 +240,18 @@ 7.234 z += dfdz; 7.235 #endif 7.236 #ifdef INTERP_TEX 7.237 - tx = (unsigned int)(u * st->tex.width) & st->tex.xmask; 7.238 - ty = (unsigned int)(v * st->tex.height) & st->tex.ymask; 7.239 + tx = (unsigned int)fixed_int(fixed_mul(u, fixedi(st->tex.width))) & st->tex.xmask; 7.240 + ty = (unsigned int)fixed_int(fixed_mul(v, fixedi(st->tex.height))) & st->tex.ymask; 7.241 c = st->tex.pixels[(ty << st->tex.xshift) + tx]; 7.242 7.243 u += dfdu; 7.244 v += dfdv; 7.245 #endif 7.246 #ifdef INTERP_ENERGY 7.247 - c += e * st->col_range; 7.248 + c += fixed_int(fixed_mul(e, fixedi(st->col_range))); 7.249 e += dfde; 7.250 #else 7.251 - c += left[y].energy * st->col_range; 7.252 + c += fixed_int(fixed_mul(left[y].energy, fixedi(st->col_range))); 7.253 #endif 7.254 sline[x0 + i] = c; 7.255 }
8.1 --- a/src/test.c Sat Sep 21 20:18:28 2013 +0300 8.2 +++ b/src/test.c Sun Sep 22 02:21:30 2013 +0300 8.3 @@ -270,6 +270,14 @@ 8.4 } 8.5 break; 8.6 8.7 + case 'z': 8.8 + if(mgl_isenabled(MGL_DEPTH_TEST)) { 8.9 + mgl_disable(MGL_DEPTH_TEST); 8.10 + } else { 8.11 + mgl_enable(MGL_DEPTH_TEST); 8.12 + } 8.13 + break; 8.14 + 8.15 case ' ': 8.16 auto_rotate = !auto_rotate; 8.17 break;
9.1 --- a/src/vmath.h Sat Sep 21 20:18:28 2013 +0300 9.2 +++ b/src/vmath.h Sun Sep 22 02:21:30 2013 +0300 9.3 @@ -2,6 +2,7 @@ 9.4 #define VMATH_H_ 9.5 9.6 #include <math.h> 9.7 +#include "fixed_point.h" 9.8 9.9 #ifndef M_PI 9.10 #define M_PI 3.1415926536 9.11 @@ -19,5 +20,61 @@ 9.12 float x, y; 9.13 } vec2_t; 9.14 9.15 +typedef struct { 9.16 + fixed x, y, z, w; 9.17 +} vec4x_t; 9.18 + 9.19 +typedef struct { 9.20 + fixed x, y, z; 9.21 +} vec3x_t; 9.22 + 9.23 +typedef struct { 9.24 + fixed x, y; 9.25 +} vec2x_t; 9.26 + 9.27 + 9.28 +#define vec2_to_fixed2(v, f) \ 9.29 + do { \ 9.30 + f.x = fixedf(v.x); \ 9.31 + f.y = fixedf(v.y); \ 9.32 + } while(0) 9.33 + 9.34 +#define vec3_to_fixed3(v, f) \ 9.35 + do { \ 9.36 + f.x = fixedf(v.x); \ 9.37 + f.y = fixedf(v.y); \ 9.38 + f.z = fixedf(v.z); \ 9.39 + } while(0) 9.40 + 9.41 +#define vec4_to_fixed4(v, f) \ 9.42 + do { \ 9.43 + f.x = fixedf(v.x); \ 9.44 + f.y = fixedf(v.y); \ 9.45 + f.z = fixedf(v.z); \ 9.46 + f.w = fixedf(v.w); \ 9.47 + } while(0) 9.48 + 9.49 + 9.50 +#define fixed2_to_vec2(f, v) \ 9.51 + do { \ 9.52 + v.x = fixed_float(f.x); \ 9.53 + v.y = fixed_float(f.y); \ 9.54 + } while(0) 9.55 + 9.56 +#define fixed3_to_vec3(f, v) \ 9.57 + do { \ 9.58 + v.x = fixed_float(f.x); \ 9.59 + v.y = fixed_float(f.y); \ 9.60 + v.z = fixed_float(f.z); \ 9.61 + } while(0) 9.62 + 9.63 +#define fixed4_to_vec4(f, v) \ 9.64 + do { \ 9.65 + v.x = fixed_float(f.x); \ 9.66 + v.y = fixed_float(f.y); \ 9.67 + v.z = fixed_float(f.z); \ 9.68 + v.w = fixed_float(f.w); \ 9.69 + } while(0) 9.70 + 9.71 9.72 #endif /* VMATH_H_ */