deepstone
changeset 28:11d14f688485
added clipping
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 22 Sep 2013 06:38:08 +0300 |
parents | dcfe615c4c5f |
children | 5fa2983bfe61 |
files | Makefile dosemu/dosemu.c src/main.c src/mglclip.c src/mglimpl.h src/mglrast.c src/mingl.c src/mingl.h src/scantmpl.h src/test.c src/vmath.h |
diffstat | 11 files changed, 403 insertions(+), 90 deletions(-) [+] |
line diff
1.1 --- a/Makefile Sun Sep 22 02:47:46 2013 +0300 1.2 +++ b/Makefile Sun Sep 22 06:38:08 2013 +0300 1.3 @@ -1,5 +1,5 @@ 1.4 obj = src/main.o \ 1.5 - src/mingl.o src/mglrast.o src/mglgen.o \ 1.6 + src/mingl.o src/mglrast.o src/mglclip.o src/mglgen.o \ 1.7 src/texture.o src/palman.o \ 1.8 src/scene.o src/cvec.o src/fixedp.o \ 1.9 dosemu/dosemu.o 1.10 @@ -7,8 +7,7 @@ 1.11 bin = deepstone 1.12 1.13 CC = gcc 1.14 -CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl` -Isrc -Idosemu 1.15 -#-DRAST_FLOAT -DDBG_USE_FLOAT 1.16 +CFLAGS = -pedantic -Wall -g `pkg-config --cflags sdl` -Isrc -Idosemu -DRAST_FLOAT -DDBG_USE_FLOAT 1.17 LDFLAGS = `pkg-config --libs sdl` -lm 1.18 1.19 $(bin): $(obj)
2.1 --- a/dosemu/dosemu.c Sun Sep 22 02:47:46 2013 +0300 2.2 +++ b/dosemu/dosemu.c Sun Sep 22 06:38:08 2013 +0300 2.3 @@ -14,19 +14,27 @@ 2.4 2.5 /* ----- graphics (wvga.c implementation) ----- */ 2.6 static SDL_Surface *fbsurf; 2.7 - 2.8 -#define DOUBLESZ (fbsurf->w != 320) 2.9 +static int scale = 1; 2.10 2.11 int set_video_mode(int mode) 2.12 { 2.13 int resx = 320, resy = 200; 2.14 unsigned int sdl_flags = SDL_HWPALETTE; 2.15 + char *env; 2.16 2.17 if(getenv("DOSEMU_DOUBLESIZE")) { 2.18 - resx *= 2; 2.19 - resy *= 2; 2.20 + scale = 2; 2.21 } 2.22 2.23 + if((env = getenv("DOSEMU_SCALE"))) { 2.24 + int n = atoi(env); 2.25 + if(n > 0) { 2.26 + scale = n; 2.27 + } 2.28 + } 2.29 + resx *= scale; 2.30 + resy *= scale; 2.31 + 2.32 if(getenv("DOSEMU_FULLSCREEN")) { 2.33 sdl_flags |= SDL_FULLSCREEN; 2.34 } 2.35 @@ -39,7 +47,7 @@ 2.36 abort(); 2.37 } 2.38 SDL_WM_SetCaption("Deepstone", 0); 2.39 - SDL_ShowCursor(0); 2.40 + /*SDL_ShowCursor(0);*/ 2.41 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); 2.42 break; 2.43 2.44 @@ -86,17 +94,17 @@ 2.45 SDL_LockSurface(fbsurf); 2.46 } 2.47 2.48 - if(DOUBLESZ) { 2.49 - int i, j; 2.50 - Uint16 *dest = fbsurf->pixels; 2.51 + if(scale > 1) { 2.52 + int i, j, xsz, ysz; 2.53 + unsigned char *dest = fbsurf->pixels; 2.54 2.55 - for(i=0; i<200; i++) { 2.56 - for(j=0; j<320; j++) { 2.57 - Uint16 twopix = ((Uint16)*frame << 8) | (Uint16)*frame; 2.58 - dest[j] = dest[j + 320] = twopix; 2.59 - frame++; 2.60 + xsz = 320 * scale; 2.61 + ysz = 200 * scale; 2.62 + 2.63 + for(i=0; i<ysz; i++) { 2.64 + for(j=0; j<xsz; j++) { 2.65 + *dest++ = frame[(i / scale) * 320 + (j / scale)]; 2.66 } 2.67 - dest += fbsurf->pitch; 2.68 } 2.69 } else { 2.70 memcpy(fbsurf->pixels, frame, 64000); 2.71 @@ -163,13 +171,8 @@ 2.72 return; 2.73 2.74 case SDL_MOUSEMOTION: 2.75 - mousex = ev.motion.x; 2.76 - mousey = ev.motion.y; 2.77 - 2.78 - if(DOUBLESZ) { 2.79 - mousex /= 2; 2.80 - mousey /= 2; 2.81 - } 2.82 + mousex = ev.motion.x / scale; 2.83 + mousey = ev.motion.y / scale; 2.84 break; 2.85 2.86 case SDL_MOUSEBUTTONDOWN:
3.1 --- a/src/main.c Sun Sep 22 02:47:46 2013 +0300 3.2 +++ b/src/main.c Sun Sep 22 06:38:08 2013 +0300 3.3 @@ -51,6 +51,12 @@ 3.4 3.5 static int init(void) 3.6 { 3.7 + float vfov, hfov, aspect; 3.8 + 3.9 + aspect = 320.0 / 200.0; 3.10 + vfov = 60.0; 3.11 + hfov = vfov * aspect; 3.12 + 3.13 init_timer(100); 3.14 3.15 set_video_mode(0x13); 3.16 @@ -74,7 +80,18 @@ 3.17 3.18 mgl_matrix_mode(MGL_PROJECTION); 3.19 mgl_load_identity(); 3.20 - mgl_perspective(45.0, 320.0 / 200.0, 0.5, 200.0); 3.21 + mgl_perspective(vfov, aspect, 0.5, 200.0); 3.22 + 3.23 +#if 0 3.24 + mgl_enable(MGL_CLIP_PLANE0); 3.25 + mgl_enable(MGL_CLIP_PLANE1); 3.26 + mgl_enable(MGL_CLIP_PLANE2); 3.27 + mgl_enable(MGL_CLIP_PLANE3); 3.28 + mgl_clip_plane(MGL_CLIP_PLANE0, -1, 0, -1, 0); /* positive X */ 3.29 + mgl_clip_plane(MGL_CLIP_PLANE1, 1, 0, -1, 0); /* negative X */ 3.30 + mgl_clip_plane(MGL_CLIP_PLANE2, 0, -1, -0.5, 0); /* positive Y */ 3.31 + mgl_clip_plane(MGL_CLIP_PLANE3, 0, 1, -0.5, 0); /* negative Y */ 3.32 +#endif 3.33 3.34 /* setup palette */ 3.35 palm_add_color(255, 255, 255);
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/mglclip.c Sun Sep 22 06:38:08 2013 +0300 4.3 @@ -0,0 +1,189 @@ 4.4 +#include <stdio.h> 4.5 +#include <string.h> 4.6 +#include <assert.h> 4.7 +#include "mingl.h" 4.8 +#include "mglimpl.h" 4.9 + 4.10 +static struct state *st; 4.11 + 4.12 +static float distance_signed(vec3_t p, const struct plane *plane); 4.13 +static int intersect(const ray3_t *ray, const struct plane *plane, float *t); 4.14 +static int clip_polygon(struct vertex *vout, int *voutnum, const struct vertex *vin, int vnum, 4.15 + const struct plane *plane); 4.16 + 4.17 +#define ZNEAR MAX_CLIP_PLANES 4.18 + 4.19 +int mgl_clip_init(struct state *state) 4.20 +{ 4.21 + st = state; 4.22 + 4.23 + memset(st->clip_planes, 0, sizeof st->clip_planes); 4.24 + 4.25 + /* always setup a near clipping plane */ 4.26 + st->clip_planes[ZNEAR].normal.x = st->clip_planes[ZNEAR].normal.y = 0; 4.27 + st->clip_planes[ZNEAR].normal.z = -1; 4.28 + st->clip_planes[ZNEAR].pt.x = st->clip_planes[ZNEAR].pt.y = 0; 4.29 + st->clip_planes[ZNEAR].pt.z = -0.5; 4.30 + 4.31 + return 0; 4.32 +} 4.33 + 4.34 +int mgl_clip_poly(struct vertex *v, int vnum) 4.35 +{ 4.36 + int i, res, clipped_vnum; 4.37 + struct vertex tmp[6]; 4.38 + 4.39 + for(i=0; i<MAX_CLIP_PLANES + 1; i++) { 4.40 + if(i < ZNEAR && !mgl_isenabled(MGL_CLIP_PLANE0 + i)) { 4.41 + continue; 4.42 + } 4.43 + 4.44 + res = clip_polygon(tmp, &clipped_vnum, v, vnum, st->clip_planes + i); 4.45 + if(res == -1) { 4.46 + /* the polygon was completely outside */ 4.47 + return 0; 4.48 + } 4.49 + if(res == 0) { 4.50 + /* the polygon was clipped, update v and vnum */ 4.51 + vnum = clipped_vnum; 4.52 + memcpy(v, tmp, clipped_vnum * sizeof *v); 4.53 + } 4.54 + /* otherwise the polygon was completely inside, nothing to do... */ 4.55 + } 4.56 + 4.57 + return vnum; 4.58 +} 4.59 + 4.60 +static float distance_signed(vec3_t p, const struct plane *plane) 4.61 +{ 4.62 + vec3_t ptdir; 4.63 + ptdir.x = p.x - plane->pt.x; 4.64 + ptdir.y = p.y - plane->pt.y; 4.65 + ptdir.z = p.z - plane->pt.z; 4.66 + 4.67 + return vec3_dot(ptdir, plane->normal); 4.68 +} 4.69 + 4.70 +static int intersect(const ray3_t *ray, const struct plane *plane, float *t) 4.71 +{ 4.72 + vec3_t orig_pt_dir; 4.73 + 4.74 + float ndotdir = vec3_dot(plane->normal, ray->dir); 4.75 + if(fabs(ndotdir) < 1e-4) { 4.76 + *t = 0.0f; 4.77 + return 0; 4.78 + } 4.79 + 4.80 + orig_pt_dir.x = plane->pt.x - ray->origin.x; 4.81 + orig_pt_dir.y = plane->pt.y - ray->origin.y; 4.82 + orig_pt_dir.z = plane->pt.z - ray->origin.z; 4.83 + 4.84 + *t = vec3_dot(plane->normal, orig_pt_dir) / ndotdir; 4.85 + return 1; 4.86 +} 4.87 + 4.88 +static int clip_edge(struct vertex *poly, int *vnum, const struct vertex *v0, 4.89 + const struct vertex *v1, const struct plane *plane); 4.90 + 4.91 +/* returns: 4.92 + * 1 -> both inside 4.93 + * 0 -> straddling and clipped 4.94 + * -1 -> both outside 4.95 + * 4.96 + * the size of the vout polygon is returned throug voutnum 4.97 + */ 4.98 +static int clip_polygon(struct vertex *vout, int *voutnum, const struct vertex *vin, int vnum, 4.99 + const struct plane *plane) 4.100 +{ 4.101 + int i; 4.102 + int edges_clipped = 0; 4.103 + int out_vnum = 0; 4.104 + 4.105 + for(i=0; i<vnum; i++) { 4.106 + int res = clip_edge(vout, &out_vnum, vin + i, vin + (i + 1) % vnum, plane); 4.107 + if(res == 0) { 4.108 + edges_clipped++; 4.109 + } 4.110 + } 4.111 + 4.112 + if(out_vnum <= 0) { 4.113 + assert(edges_clipped == 0); 4.114 + return -1; 4.115 + } 4.116 + 4.117 + *voutnum = out_vnum; 4.118 + return edges_clipped > 0 ? 0 : 1; 4.119 +} 4.120 + 4.121 +/* returns: 4.122 + * 1 -> both inside 4.123 + * 0 -> straddling and clipped 4.124 + * -1 -> both outside 4.125 + * 4.126 + * also returns the size of the polygon through vnumptr 4.127 + */ 4.128 +static int clip_edge(struct vertex *poly, int *vnumptr, const struct vertex *v0, 4.129 + const struct vertex *v1, const struct plane *plane) 4.130 +{ 4.131 + vec3_t pos0, pos1; 4.132 + float d0, d1, t; 4.133 + ray3_t ray; 4.134 + int vnum = *vnumptr; 4.135 + 4.136 + pos0.x = v0->pos.x; pos0.y = v0->pos.y; pos0.z = v0->pos.z; 4.137 + pos1.x = v1->pos.x; pos1.y = v1->pos.y; pos1.z = v1->pos.z; 4.138 + 4.139 + d0 = distance_signed(pos0, plane); 4.140 + d1 = distance_signed(pos1, plane); 4.141 + 4.142 + ray.origin = pos0; 4.143 + ray.dir.x = pos1.x - pos0.x; 4.144 + ray.dir.y = pos1.y - pos0.y; 4.145 + ray.dir.z = pos1.z - pos0.z; 4.146 + 4.147 + if(d0 >= 0.0) { 4.148 + /* start inside */ 4.149 + if(d1 >= 0.0) { 4.150 + /* all inside */ 4.151 + poly[vnum++] = *v1; /* append v1 */ 4.152 + *vnumptr = vnum; 4.153 + return 1; 4.154 + } else { 4.155 + /* going out */ 4.156 + intersect(&ray, plane, &t); 4.157 + 4.158 + ray3_point(poly[vnum].pos, ray, t); 4.159 + poly[vnum].pos.w = 1.0; 4.160 + 4.161 + vec3_lerp(poly[vnum].norm, v0->norm, v1->norm, t); 4.162 + vec2_lerp(poly[vnum].tc, v0->tc, v1->tc, t); 4.163 + poly[vnum].energy = v0->energy + (v1->energy - v0->energy) * t; 4.164 + poly[vnum].cidx = v0->cidx; 4.165 + vnum++; /* append new vertex on the intersection point */ 4.166 + } 4.167 + } else { 4.168 + /* start outside */ 4.169 + if(d1 >= 0) { 4.170 + /* going in */ 4.171 + intersect(&ray, plane, &t); 4.172 + 4.173 + ray3_point(poly[vnum].pos, ray, t); 4.174 + poly[vnum].pos.w = 1.0; 4.175 + 4.176 + vec3_lerp(poly[vnum].norm, v0->norm, v1->norm, t); 4.177 + vec2_lerp(poly[vnum].tc, v0->tc, v1->tc, t); 4.178 + poly[vnum].energy = v0->energy + (v1->energy - v0->energy) * t; 4.179 + poly[vnum].cidx = v0->cidx; 4.180 + vnum++; /* append new vertex on the intersection point */ 4.181 + 4.182 + /* then append v1 ... */ 4.183 + poly[vnum++] = *v1; 4.184 + } else { 4.185 + /* all outside */ 4.186 + return -1; 4.187 + } 4.188 + } 4.189 + 4.190 + *vnumptr = vnum; 4.191 + return 0; 4.192 +}
5.1 --- a/src/mglimpl.h Sun Sep 22 02:47:46 2013 +0300 5.2 +++ b/src/mglimpl.h Sun Sep 22 06:38:08 2013 +0300 5.3 @@ -5,6 +5,7 @@ 5.4 5.5 #define MATRIX_STACK_SIZE 8 5.6 #define MAX_LIGHTS 4 5.7 +#define MAX_CLIP_PLANES 6 5.8 5.9 #define ZTILE_SIZE 16384 5.10 #define ZTILE_SHIFT 14 5.11 @@ -34,6 +35,11 @@ 5.12 int cidx; 5.13 }; 5.14 5.15 +struct plane { 5.16 + vec3_t pt; 5.17 + vec3_t normal; 5.18 +}; 5.19 + 5.20 struct texture { 5.21 int width, height; 5.22 int xshift, yshift; 5.23 @@ -47,12 +53,15 @@ 5.24 int mmode, mtop[2]; 5.25 mat4_t matrix[2][MATRIX_STACK_SIZE]; 5.26 int prim; 5.27 - struct vertex curv, v[4]; 5.28 + struct vertex curv, v[6]; 5.29 int vidx; 5.30 int vp[4]; /* viewport */ 5.31 int col_range; /* color interpolation range */ 5.32 vec4_t lpos[MAX_LIGHTS]; 5.33 float lint[MAX_LIGHTS]; 5.34 + float ambient; 5.35 + 5.36 + struct plane clip_planes[MAX_CLIP_PLANES + 1]; 5.37 5.38 struct texture tex; 5.39 }; 5.40 @@ -64,6 +73,7 @@ 5.41 int num_ztiles; 5.42 }; 5.43 5.44 +#define IS_ENABLED(f, x) ((f) & (1 << (x))) 5.45 5.46 #define vertex_to_fixedvertex(v, vx) \ 5.47 do { \ 5.48 @@ -91,4 +101,7 @@ 5.49 void mgl_draw_line(struct vertex *v0, struct vertex *v1); 5.50 void mgl_draw_poly(struct vertex *v, int numv); 5.51 5.52 +int mgl_clip_init(struct state *state); 5.53 +int mgl_clip_poly(struct vertex *v, int vnum); 5.54 + 5.55 #endif /* MGL_IMPL_H_ */
6.1 --- a/src/mglrast.c Sun Sep 22 02:47:46 2013 +0300 6.2 +++ b/src/mglrast.c Sun Sep 22 06:38:08 2013 +0300 6.3 @@ -146,13 +146,13 @@ 6.4 }; 6.5 int bits = 0; 6.6 6.7 - if((st->flags & MGL_TEXTURE_2D) && st->tex.pixels) { 6.8 + if(IS_ENABLED(st->flags, MGL_TEXTURE_2D) && st->tex.pixels) { 6.9 bits |= 4; 6.10 } 6.11 - if(st->flags & MGL_SMOOTH) { 6.12 + if(IS_ENABLED(st->flags, MGL_SMOOTH)) { 6.13 bits |= 2; 6.14 } 6.15 - if((st->flags & MGL_DEPTH_TEST) && fb->zbuf) { 6.16 + if(IS_ENABLED(st->flags, MGL_DEPTH_TEST) && fb->zbuf) { 6.17 bits |= 1; 6.18 } 6.19
7.1 --- a/src/mingl.c Sun Sep 22 02:47:46 2013 +0300 7.2 +++ b/src/mingl.c Sun Sep 22 06:38:08 2013 +0300 7.3 @@ -24,7 +24,8 @@ 7.4 7.5 static void transform(vec4_t *res, vec4_t *v, float *mat); 7.6 static void transform3(vec3_t *res, vec3_t *v, float *mat); 7.7 -static void vertex_proc(struct vertex *vert); 7.8 +static void vertex_proc_view(struct vertex *vert); 7.9 +static int vertex_proc_proj(struct vertex *vert); 7.10 static int calc_shiftmask(int val, int *shiftp, unsigned int *maskp); 7.11 7.12 static struct state st; 7.13 @@ -75,6 +76,9 @@ 7.14 st.lint[i] = 0.0f; 7.15 } 7.16 7.17 + st.ambient = 0.1; 7.18 + 7.19 + mgl_clip_init(&st); 7.20 return 0; 7.21 } 7.22 7.23 @@ -133,19 +137,19 @@ 7.24 } 7.25 } 7.26 7.27 -void mgl_enable(unsigned int bit) 7.28 +void mgl_enable(unsigned int what) 7.29 { 7.30 - st.flags |= bit; 7.31 + st.flags |= (1 << what); 7.32 } 7.33 7.34 -void mgl_disable(unsigned int bit) 7.35 +void mgl_disable(unsigned int what) 7.36 { 7.37 - st.flags &= ~bit; 7.38 + st.flags &= ~(1 << what); 7.39 } 7.40 7.41 -int mgl_isenabled(unsigned int bit) 7.42 +int mgl_isenabled(unsigned int what) 7.43 { 7.44 - return (st.flags & bit) != 0; 7.45 + return IS_ENABLED(st.flags, what); 7.46 } 7.47 7.48 void mgl_front_face(int ff) 7.49 @@ -158,6 +162,16 @@ 7.50 st.cullface = cf; 7.51 } 7.52 7.53 +void mgl_set_ambient(float amb) 7.54 +{ 7.55 + st.ambient = amb; 7.56 +} 7.57 + 7.58 +float mgl_get_ambient(void) 7.59 +{ 7.60 + return st.ambient; 7.61 +} 7.62 + 7.63 void mgl_color_range(int rng) 7.64 { 7.65 st.col_range = rng; 7.66 @@ -228,25 +242,43 @@ 7.67 st.v[st.vidx].norm = st.curv.norm; 7.68 st.v[st.vidx].tc = st.curv.tc; 7.69 7.70 - vertex_proc(st.v + st.vidx); 7.71 + /* T&L up to view space, to perform user-clipping */ 7.72 + vertex_proc_view(st.v + st.vidx); 7.73 7.74 if(++st.vidx >= st.prim) { 7.75 + st.vidx = 0; 7.76 + 7.77 switch(st.prim) { 7.78 case MGL_POINTS: 7.79 + vertex_proc_proj(st.v); 7.80 mgl_draw_point(st.v); 7.81 break; 7.82 case MGL_LINES: 7.83 + vertex_proc_proj(st.v); 7.84 + vertex_proc_proj(st.v + 1); 7.85 mgl_draw_line(st.v, st.v + 1); 7.86 break; 7.87 case MGL_TRIANGLES: 7.88 case MGL_QUADS: 7.89 - mgl_draw_poly(st.v, st.prim); 7.90 + { 7.91 + int nverts = mgl_clip_poly(st.v, st.prim); 7.92 + if(nverts > 0) { 7.93 + int i; 7.94 + /* passed clipping, perform projection for all verts and draw */ 7.95 + for(i=0; i<nverts; i++) { 7.96 + if(vertex_proc_proj(st.v + i) == -1) { 7.97 + printf("this shouldn't happen!\n"); 7.98 + return; 7.99 + } 7.100 + } 7.101 + mgl_draw_poly(st.v, nverts); 7.102 + } 7.103 + } 7.104 break; 7.105 default: 7.106 fprintf(stderr, "invalid primitive: %d\n", st.prim); 7.107 abort(); 7.108 } 7.109 - st.vidx = 0; 7.110 } 7.111 } 7.112 7.113 @@ -289,21 +321,20 @@ 7.114 res->z = mat[2] * v->x + mat[6] * v->y + mat[10] * v->z; 7.115 } 7.116 7.117 -static void vertex_proc(struct vertex *vert) 7.118 +static void vertex_proc_view(struct vertex *vert) 7.119 { 7.120 - vec4_t pview, pclip; 7.121 + vec4_t pview; 7.122 7.123 float *mvmat = st.matrix[MGL_MODELVIEW][st.mtop[MGL_MODELVIEW]]; 7.124 - float *pmat = st.matrix[MGL_PROJECTION][st.mtop[MGL_PROJECTION]]; 7.125 7.126 /* modelview transformation */ 7.127 transform(&pview, &vert->pos, mvmat); 7.128 7.129 - if(st.flags & MGL_LIGHTING) { 7.130 - if((st.flags & MGL_SMOOTH) || st.vidx == 0) { 7.131 + if(mgl_isenabled(MGL_LIGHTING)) { 7.132 + if(mgl_isenabled(MGL_SMOOTH) || st.vidx == 0) { 7.133 int i; 7.134 vec3_t norm; 7.135 - float irrad = 0.0f; 7.136 + float irrad = st.ambient; 7.137 7.138 transform3(&norm, &vert->norm, mvmat); 7.139 7.140 @@ -331,18 +362,27 @@ 7.141 irrad += ndotl * st.lint[i]; 7.142 } 7.143 } 7.144 - vert->energy = irrad; 7.145 + vert->energy = irrad > 1.0 ? 1.0 : irrad; 7.146 } else { 7.147 vert->energy = st.v[0].energy; 7.148 } 7.149 } 7.150 7.151 - transform(&pclip, &pview, pmat); 7.152 + vert->pos = pview; 7.153 +} 7.154 + 7.155 +static int vertex_proc_proj(struct vertex *vert) 7.156 +{ 7.157 + vec4_t pclip; 7.158 + 7.159 + float *pmat = st.matrix[MGL_PROJECTION][st.mtop[MGL_PROJECTION]]; 7.160 + 7.161 + transform(&pclip, &vert->pos, pmat); 7.162 /* TODO clipping in homogenous clip space */ 7.163 7.164 - if(pclip.w < 1e-6 && pclip.w > -1e-6) { 7.165 + if(pclip.w < 1e-6) { 7.166 vert->pos.x = vert->pos.y = vert->pos.z = vert->pos.w = 0.0f; 7.167 - return; 7.168 + return -1; 7.169 } 7.170 7.171 /* perspective division */ 7.172 @@ -354,6 +394,8 @@ 7.173 /* viewport transformation */ 7.174 vert->pos.x = st.vp[0] + st.vp[2] * (vert->pos.x * 0.5 + 0.5); 7.175 vert->pos.y = st.vp[1] + st.vp[3] * (-vert->pos.y * 0.5 + 0.5); 7.176 + 7.177 + return 0; 7.178 } 7.179 7.180 void mgl_viewport(int x, int y, int width, int height) 7.181 @@ -534,6 +576,29 @@ 7.182 } 7.183 } 7.184 7.185 +void mgl_clip_plane(int id, float nx, float ny, float nz, float dist) 7.186 +{ 7.187 + id -= MGL_CLIP_PLANE0; 7.188 + 7.189 + if(id < 0 || id > MAX_CLIP_PLANES) { 7.190 + return; 7.191 + } 7.192 + 7.193 + st.clip_planes[id].normal.x = nx; 7.194 + st.clip_planes[id].normal.y = ny; 7.195 + st.clip_planes[id].normal.z = nz; 7.196 + NORMALIZE(st.clip_planes[id].normal); 7.197 + 7.198 + st.clip_planes[id].pt.x = st.clip_planes[id].normal.x * dist; 7.199 + st.clip_planes[id].pt.y = st.clip_planes[id].normal.y * dist; 7.200 + st.clip_planes[id].pt.z = st.clip_planes[id].normal.z * dist; 7.201 + 7.202 + printf("set clip plane %d -> n[%f %f %f] p[%f %f %f]\n", id, 7.203 + st.clip_planes[id].normal.x, st.clip_planes[id].normal.y, st.clip_planes[id].normal.z, 7.204 + st.clip_planes[id].pt.x, st.clip_planes[id].pt.y, st.clip_planes[id].pt.z); 7.205 + 7.206 +} 7.207 + 7.208 #define MAX_SHIFT 12 7.209 static int calc_shiftmask(int val, int *shiftp, unsigned int *maskp) 7.210 {
8.1 --- a/src/mingl.h Sun Sep 22 02:47:46 2013 +0300 8.2 +++ b/src/mingl.h Sun Sep 22 06:38:08 2013 +0300 8.3 @@ -1,29 +1,18 @@ 8.4 -/* 8.5 -256-color 3D graphics hack for real-mode DOS. 8.6 -Copyright (C) 2011 John Tsiombikas <nuclear@member.fsf.org> 8.7 - 8.8 -This program is free software: you can redistribute it and/or modify 8.9 -it under the terms of the GNU General Public License as published by 8.10 -the Free Software Foundation, either version 3 of the License, or 8.11 -(at your option) any later version. 8.12 - 8.13 -This program is distributed in the hope that it will be useful, 8.14 -but WITHOUT ANY WARRANTY; without even the implied warranty of 8.15 -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 8.16 -GNU General Public License for more details. 8.17 - 8.18 -You should have received a copy of the GNU General Public License 8.19 -along with this program. If not, see <http://www.gnu.org/licenses/>. 8.20 -*/ 8.21 #ifndef MINGL_H_ 8.22 #define MINGL_H_ 8.23 8.24 /* enable bitflags */ 8.25 -#define MGL_CULL_FACE 1 8.26 -#define MGL_DEPTH_TEST 2 8.27 -#define MGL_SMOOTH 4 8.28 -#define MGL_LIGHTING 8 8.29 -#define MGL_TEXTURE_2D 16 8.30 +#define MGL_CULL_FACE 0 8.31 +#define MGL_DEPTH_TEST 1 8.32 +#define MGL_SMOOTH 2 8.33 +#define MGL_LIGHTING 3 8.34 +#define MGL_TEXTURE_2D 4 8.35 +#define MGL_CLIP_PLANE0 5 8.36 +#define MGL_CLIP_PLANE1 6 8.37 +#define MGL_CLIP_PLANE2 7 8.38 +#define MGL_CLIP_PLANE3 8 8.39 +#define MGL_CLIP_PLANE4 9 8.40 +#define MGL_CLIP_PLANE5 10 8.41 8.42 /* primitives */ 8.43 #define MGL_POINTS 1 8.44 @@ -57,6 +46,9 @@ 8.45 void mgl_front_face(int ff); 8.46 void mgl_cull_face(int cf); 8.47 8.48 +void mgl_set_ambient(float amb); 8.49 +float mgl_get_ambient(void); 8.50 + 8.51 void mgl_color_range(int rng); 8.52 void mgl_light_intensity(int ltidx, float intens); 8.53 void mgl_light_position(int ltidx, float x, float y, float z, float w); 8.54 @@ -91,6 +83,8 @@ 8.55 8.56 void mgl_teximage(int width, int height, unsigned char *pixels); 8.57 8.58 +void mgl_clip_plane(int id, float nx, float ny, float nz, float dist); 8.59 + 8.60 void mgl_cube(float sz); 8.61 void mgl_sphere(float rad, int usub, int vsub); 8.62 void mgl_sphere_part(float rad, int usub, int vsub, float umax, float vmax);
9.1 --- a/src/scantmpl.h Sun Sep 22 02:47:46 2013 +0300 9.2 +++ b/src/scantmpl.h Sun Sep 22 06:38:08 2013 +0300 9.3 @@ -133,7 +133,7 @@ 9.4 x1 = (int)fixed_round(vright[y].pos.x); 9.5 9.6 if(x1 < x0) { 9.7 - if(st->flags & MGL_CULL_FACE) { 9.8 + if(IS_ENABLED(st->flags, MGL_CULL_FACE)) { 9.9 return; 9.10 } 9.11 tmp = x0;
10.1 --- a/src/test.c Sun Sep 22 02:47:46 2013 +0300 10.2 +++ b/src/test.c Sun Sep 22 06:38:08 2013 +0300 10.3 @@ -286,6 +286,14 @@ 10.4 prim = (prim + 1) % NUM_PRIMS; 10.5 break; 10.6 10.7 + case 'c': 10.8 + if(mgl_isenabled(MGL_CULL_FACE)) { 10.9 + mgl_disable(MGL_CULL_FACE); 10.10 + } else { 10.11 + mgl_enable(MGL_CULL_FACE); 10.12 + } 10.13 + break; 10.14 + 10.15 default: 10.16 break; 10.17 }
11.1 --- a/src/vmath.h Sun Sep 22 02:47:46 2013 +0300 11.2 +++ b/src/vmath.h Sun Sep 22 06:38:08 2013 +0300 11.3 @@ -32,48 +32,73 @@ 11.4 fixed x, y; 11.5 } vec2x_t; 11.6 11.7 +typedef struct { 11.8 + vec3_t origin, dir; 11.9 +} ray3_t; 11.10 + 11.11 +#define vec3_dot(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z) 11.12 + 11.13 +#define vec2_lerp(res, a, b, t) \ 11.14 + do { \ 11.15 + (res).x = (a).x + ((b).x - (a).x) * (t); \ 11.16 + (res).y = (a).y + ((b).y - (a).y) * (t); \ 11.17 + } while(0) 11.18 + 11.19 +#define vec3_lerp(res, a, b, t) \ 11.20 + do { \ 11.21 + (res).x = (a).x + ((b).x - (a).x) * (t); \ 11.22 + (res).y = (a).y + ((b).y - (a).y) * (t); \ 11.23 + (res).z = (a).z + ((b).z - (a).z) * (t); \ 11.24 + } while(0) 11.25 + 11.26 +#define ray3_point(res, ray, t) \ 11.27 + do { \ 11.28 + (res).x = (ray).origin.x + (ray).dir.x * (t); \ 11.29 + (res).y = (ray).origin.y + (ray).dir.y * (t); \ 11.30 + (res).z = (ray).origin.z + (ray).dir.z * (t); \ 11.31 + } while(0) 11.32 11.33 #define vec2_to_fixed2(v, f) \ 11.34 do { \ 11.35 - f.x = fixedf(v.x); \ 11.36 - f.y = fixedf(v.y); \ 11.37 + (f).x = fixedf((v).x); \ 11.38 + (f).y = fixedf((v).y); \ 11.39 } while(0) 11.40 11.41 #define vec3_to_fixed3(v, f) \ 11.42 do { \ 11.43 - f.x = fixedf(v.x); \ 11.44 - f.y = fixedf(v.y); \ 11.45 - f.z = fixedf(v.z); \ 11.46 + (f).x = fixedf((v).x); \ 11.47 + (f).y = fixedf((v).y); \ 11.48 + (f).z = fixedf((v).z); \ 11.49 } while(0) 11.50 11.51 #define vec4_to_fixed4(v, f) \ 11.52 do { \ 11.53 - f.x = fixedf(v.x); \ 11.54 - f.y = fixedf(v.y); \ 11.55 - f.z = fixedf(v.z); \ 11.56 - f.w = fixedf(v.w); \ 11.57 + (f).x = fixedf((v).x); \ 11.58 + (f).y = fixedf((v).y); \ 11.59 + (f).z = fixedf((v).z); \ 11.60 + (f).w = fixedf((v).w); \ 11.61 } while(0) 11.62 11.63 11.64 #define fixed2_to_vec2(f, v) \ 11.65 do { \ 11.66 - v.x = fixed_float(f.x); \ 11.67 - v.y = fixed_float(f.y); \ 11.68 + (v).x = fixed_float((f).x); \ 11.69 + (v).y = fixed_float((f).y); \ 11.70 } while(0) 11.71 11.72 #define fixed3_to_vec3(f, v) \ 11.73 do { \ 11.74 - v.x = fixed_float(f.x); \ 11.75 - v.y = fixed_float(f.y); \ 11.76 - v.z = fixed_float(f.z); \ 11.77 + (v).x = fixed_float((f).x); \ 11.78 + (v).y = fixed_float((f).y); \ 11.79 + (v).z = fixed_float((f).z); \ 11.80 } while(0) 11.81 11.82 #define fixed4_to_vec4(f, v) \ 11.83 do { \ 11.84 - v.x = fixed_float(f.x); \ 11.85 - v.y = fixed_float(f.y); \ 11.86 - v.z = fixed_float(f.z); \ 11.87 - v.w = fixed_float(f.w); \ 11.88 + (v).x = fixed_float((f).x); \ 11.89 + (v).y = fixed_float((f).y); \ 11.90 + (v).z = fixed_float((f).z); \ 11.91 + (v).w = fixed_float((f).w); \ 11.92 } while(0) 11.93 11.94