deepstone

diff src/mingl.c @ 28:11d14f688485

added clipping
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 22 Sep 2013 06:38:08 +0300
parents 00d84ab1ef26
children 17a5107b6fa4
line diff
     1.1 --- a/src/mingl.c	Sun Sep 22 02:47:46 2013 +0300
     1.2 +++ b/src/mingl.c	Sun Sep 22 06:38:08 2013 +0300
     1.3 @@ -24,7 +24,8 @@
     1.4  
     1.5  static void transform(vec4_t *res, vec4_t *v, float *mat);
     1.6  static void transform3(vec3_t *res, vec3_t *v, float *mat);
     1.7 -static void vertex_proc(struct vertex *vert);
     1.8 +static void vertex_proc_view(struct vertex *vert);
     1.9 +static int vertex_proc_proj(struct vertex *vert);
    1.10  static int calc_shiftmask(int val, int *shiftp, unsigned int *maskp);
    1.11  
    1.12  static struct state st;
    1.13 @@ -75,6 +76,9 @@
    1.14  		st.lint[i] = 0.0f;
    1.15  	}
    1.16  
    1.17 +	st.ambient = 0.1;
    1.18 +
    1.19 +	mgl_clip_init(&st);
    1.20  	return 0;
    1.21  }
    1.22  
    1.23 @@ -133,19 +137,19 @@
    1.24  	}
    1.25  }
    1.26  
    1.27 -void mgl_enable(unsigned int bit)
    1.28 +void mgl_enable(unsigned int what)
    1.29  {
    1.30 -	st.flags |= bit;
    1.31 +	st.flags |= (1 << what);
    1.32  }
    1.33  
    1.34 -void mgl_disable(unsigned int bit)
    1.35 +void mgl_disable(unsigned int what)
    1.36  {
    1.37 -	st.flags &= ~bit;
    1.38 +	st.flags &= ~(1 << what);
    1.39  }
    1.40  
    1.41 -int mgl_isenabled(unsigned int bit)
    1.42 +int mgl_isenabled(unsigned int what)
    1.43  {
    1.44 -	return (st.flags & bit) != 0;
    1.45 +	return IS_ENABLED(st.flags, what);
    1.46  }
    1.47  
    1.48  void mgl_front_face(int ff)
    1.49 @@ -158,6 +162,16 @@
    1.50  	st.cullface = cf;
    1.51  }
    1.52  
    1.53 +void mgl_set_ambient(float amb)
    1.54 +{
    1.55 +	st.ambient = amb;
    1.56 +}
    1.57 +
    1.58 +float mgl_get_ambient(void)
    1.59 +{
    1.60 +	return st.ambient;
    1.61 +}
    1.62 +
    1.63  void mgl_color_range(int rng)
    1.64  {
    1.65  	st.col_range = rng;
    1.66 @@ -228,25 +242,43 @@
    1.67  	st.v[st.vidx].norm = st.curv.norm;
    1.68  	st.v[st.vidx].tc = st.curv.tc;
    1.69  
    1.70 -	vertex_proc(st.v + st.vidx);
    1.71 +	/* T&L up to view space, to perform user-clipping */
    1.72 +	vertex_proc_view(st.v + st.vidx);
    1.73  
    1.74  	if(++st.vidx >= st.prim) {
    1.75 +		st.vidx = 0;
    1.76 +
    1.77  		switch(st.prim) {
    1.78  		case MGL_POINTS:
    1.79 +			vertex_proc_proj(st.v);
    1.80  			mgl_draw_point(st.v);
    1.81  			break;
    1.82  		case MGL_LINES:
    1.83 +			vertex_proc_proj(st.v);
    1.84 +			vertex_proc_proj(st.v + 1);
    1.85  			mgl_draw_line(st.v, st.v + 1);
    1.86  			break;
    1.87  		case MGL_TRIANGLES:
    1.88  		case MGL_QUADS:
    1.89 -			mgl_draw_poly(st.v, st.prim);
    1.90 +			{
    1.91 +				int nverts = mgl_clip_poly(st.v, st.prim);
    1.92 +				if(nverts > 0) {
    1.93 +					int i;
    1.94 +					/* passed clipping, perform projection for all verts and draw */
    1.95 +					for(i=0; i<nverts; i++) {
    1.96 +						if(vertex_proc_proj(st.v + i) == -1) {
    1.97 +							printf("this shouldn't happen!\n");
    1.98 +							return;
    1.99 +						}
   1.100 +					}
   1.101 +					mgl_draw_poly(st.v, nverts);
   1.102 +				}
   1.103 +			}
   1.104  			break;
   1.105  		default:
   1.106  			fprintf(stderr, "invalid primitive: %d\n", st.prim);
   1.107  			abort();
   1.108  		}
   1.109 -		st.vidx = 0;
   1.110  	}
   1.111  }
   1.112  
   1.113 @@ -289,21 +321,20 @@
   1.114  	res->z = mat[2] * v->x + mat[6] * v->y + mat[10] * v->z;
   1.115  }
   1.116  
   1.117 -static void vertex_proc(struct vertex *vert)
   1.118 +static void vertex_proc_view(struct vertex *vert)
   1.119  {
   1.120 -	vec4_t pview, pclip;
   1.121 +	vec4_t pview;
   1.122  
   1.123  	float *mvmat = st.matrix[MGL_MODELVIEW][st.mtop[MGL_MODELVIEW]];
   1.124 -	float *pmat = st.matrix[MGL_PROJECTION][st.mtop[MGL_PROJECTION]];
   1.125  
   1.126  	/* modelview transformation */
   1.127  	transform(&pview, &vert->pos, mvmat);
   1.128  
   1.129 -	if(st.flags & MGL_LIGHTING) {
   1.130 -		if((st.flags & MGL_SMOOTH) || st.vidx == 0) {
   1.131 +	if(mgl_isenabled(MGL_LIGHTING)) {
   1.132 +		if(mgl_isenabled(MGL_SMOOTH) || st.vidx == 0) {
   1.133  			int i;
   1.134  			vec3_t norm;
   1.135 -			float irrad = 0.0f;
   1.136 +			float irrad = st.ambient;
   1.137  
   1.138  			transform3(&norm, &vert->norm, mvmat);
   1.139  
   1.140 @@ -331,18 +362,27 @@
   1.141  					irrad += ndotl * st.lint[i];
   1.142  				}
   1.143  			}
   1.144 -			vert->energy = irrad;
   1.145 +			vert->energy = irrad > 1.0 ? 1.0 : irrad;
   1.146  		} else {
   1.147  			vert->energy = st.v[0].energy;
   1.148  		}
   1.149  	}
   1.150  
   1.151 -	transform(&pclip, &pview, pmat);
   1.152 +	vert->pos = pview;
   1.153 +}
   1.154 +
   1.155 +static int vertex_proc_proj(struct vertex *vert)
   1.156 +{
   1.157 +	vec4_t pclip;
   1.158 +
   1.159 +	float *pmat = st.matrix[MGL_PROJECTION][st.mtop[MGL_PROJECTION]];
   1.160 +
   1.161 +	transform(&pclip, &vert->pos, pmat);
   1.162  	/* TODO clipping in homogenous clip space */
   1.163  
   1.164 -	if(pclip.w < 1e-6 && pclip.w > -1e-6) {
   1.165 +	if(pclip.w < 1e-6) {
   1.166  		vert->pos.x = vert->pos.y = vert->pos.z = vert->pos.w = 0.0f;
   1.167 -		return;
   1.168 +		return -1;
   1.169  	}
   1.170  
   1.171  	/* perspective division */
   1.172 @@ -354,6 +394,8 @@
   1.173  	/* viewport transformation */
   1.174  	vert->pos.x = st.vp[0] + st.vp[2] * (vert->pos.x * 0.5 + 0.5);
   1.175  	vert->pos.y = st.vp[1] + st.vp[3] * (-vert->pos.y * 0.5 + 0.5);
   1.176 +
   1.177 +	return 0;
   1.178  }
   1.179  
   1.180  void mgl_viewport(int x, int y, int width, int height)
   1.181 @@ -534,6 +576,29 @@
   1.182  	}
   1.183  }
   1.184  
   1.185 +void mgl_clip_plane(int id, float nx, float ny, float nz, float dist)
   1.186 +{
   1.187 +	id -= MGL_CLIP_PLANE0;
   1.188 +
   1.189 +	if(id < 0 || id > MAX_CLIP_PLANES) {
   1.190 +		return;
   1.191 +	}
   1.192 +
   1.193 +	st.clip_planes[id].normal.x = nx;
   1.194 +	st.clip_planes[id].normal.y = ny;
   1.195 +	st.clip_planes[id].normal.z = nz;
   1.196 +	NORMALIZE(st.clip_planes[id].normal);
   1.197 +
   1.198 +	st.clip_planes[id].pt.x = st.clip_planes[id].normal.x * dist;
   1.199 +	st.clip_planes[id].pt.y = st.clip_planes[id].normal.y * dist;
   1.200 +	st.clip_planes[id].pt.z = st.clip_planes[id].normal.z * dist;
   1.201 +
   1.202 +	printf("set clip plane %d -> n[%f %f %f]  p[%f %f %f]\n", id,
   1.203 +			st.clip_planes[id].normal.x, st.clip_planes[id].normal.y, st.clip_planes[id].normal.z,
   1.204 +			st.clip_planes[id].pt.x, st.clip_planes[id].pt.y, st.clip_planes[id].pt.z);
   1.205 +
   1.206 +}
   1.207 +
   1.208  #define MAX_SHIFT	12
   1.209  static int calc_shiftmask(int val, int *shiftp, unsigned int *maskp)
   1.210  {