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 {