3dphotoshoot
diff src/sanegl.c @ 11:ad49e1f9b627
foo
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 31 May 2015 06:02:08 +0300 |
parents | |
children | a460b1e5af4a |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sanegl.c Sun May 31 06:02:08 2015 +0300 1.3 @@ -0,0 +1,802 @@ 1.4 +/* 1.5 +SaneGL - a small library to bring back sanity to OpenGL ES 2.x 1.6 +Copyright (C) 2011-2013 John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 + 1.22 +#include <stdio.h> 1.23 +#include <stdlib.h> 1.24 +#include <string.h> 1.25 +#include <math.h> 1.26 +#include <assert.h> 1.27 +#include "sanegl.h" 1.28 + 1.29 +#define MMODE_IDX(x) ((x) - GL_MODELVIEW) 1.30 +#define MAT_STACK_SIZE 32 1.31 +#define MAT_IDENT {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1} 1.32 + 1.33 +#define MAX_VERTS 512 1.34 + 1.35 +static void gl_draw_immediate(void); 1.36 +static void m4_transpose(double *res, double *m); 1.37 +static double m4_determinant(double *m); 1.38 +static void m4_adjoint(double *res, double *m); 1.39 +static void m4_inverse(double *res, double *m); 1.40 + 1.41 + 1.42 +typedef struct { float x, y; } vec2_t; 1.43 +typedef struct { float x, y, z; } vec3_t; 1.44 +typedef struct { float x, y, z, w; } vec4_t; 1.45 + 1.46 +static int mm_idx = 0; 1.47 +static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}}; 1.48 +static int stack_top[3]; 1.49 +static float mat_mvp[16]; 1.50 +static int mvp_valid; 1.51 +static int prim = -1; 1.52 + 1.53 +static vec3_t cur_normal; 1.54 +static vec4_t cur_color, cur_attrib; 1.55 +static vec2_t cur_texcoord; 1.56 + 1.57 +static vec4_t *vert_arr, *col_arr, *attr_arr; 1.58 +static vec3_t *norm_arr; 1.59 +static vec2_t *texc_arr; 1.60 +/*static unsigned int vbuf, cbuf, nbuf, tbuf, abuf;*/ 1.61 +static int vloc, nloc, cloc, tloc, aloc = -1; 1.62 + 1.63 +static int num_verts, vert_calls; 1.64 +static int cur_prog; 1.65 + 1.66 +#ifdef GLDEF 1.67 +#undef glEnable 1.68 +#undef glDisable 1.69 +#endif 1.70 + 1.71 +void gl_enable(int state) 1.72 +{ 1.73 + switch(state) { 1.74 + case GL_TEXTURE_2D: 1.75 + break; 1.76 + 1.77 + default: 1.78 + glEnable(state); 1.79 + } 1.80 +} 1.81 + 1.82 +void gl_disable(int state) 1.83 +{ 1.84 + switch(state) { 1.85 + case GL_TEXTURE_2D: 1.86 + glBindTexture(state, 0); 1.87 + break; 1.88 + 1.89 + default: 1.90 + glDisable(state); 1.91 + } 1.92 +} 1.93 + 1.94 +void gl_matrix_mode(int mm) 1.95 +{ 1.96 + mm_idx = MMODE_IDX(mm); 1.97 +} 1.98 + 1.99 +void gl_push_matrix(void) 1.100 +{ 1.101 + int top = stack_top[mm_idx]; 1.102 + 1.103 + memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float)); 1.104 + stack_top[mm_idx]++; 1.105 + mvp_valid = 0; 1.106 +} 1.107 + 1.108 +void gl_pop_matrix(void) 1.109 +{ 1.110 + stack_top[mm_idx]--; 1.111 + mvp_valid = 0; 1.112 +} 1.113 + 1.114 +void gl_load_identity(void) 1.115 +{ 1.116 + static const float idmat[] = MAT_IDENT; 1.117 + int top = stack_top[mm_idx]; 1.118 + float *mat = mat_stack[mm_idx][top]; 1.119 + 1.120 + memcpy(mat, idmat, sizeof idmat); 1.121 + mvp_valid = 0; 1.122 +} 1.123 + 1.124 +void gl_load_matrixf(const float *m) 1.125 +{ 1.126 + int top = stack_top[mm_idx]; 1.127 + float *mat = mat_stack[mm_idx][top]; 1.128 + 1.129 + memcpy(mat, m, 16 * sizeof *mat); 1.130 + mvp_valid = 0; 1.131 +} 1.132 + 1.133 +void gl_load_matrixd(const double *m) 1.134 +{ 1.135 + int i; 1.136 + float mf[16]; 1.137 + 1.138 + for(i=0; i<16; i++) { 1.139 + mf[i] = (float)m[i]; 1.140 + } 1.141 + gl_load_matrixf(mf); 1.142 +} 1.143 + 1.144 +#define M(i, j) ((i << 2) + j) 1.145 + 1.146 +void gl_mult_matrixf(const float *m2) 1.147 +{ 1.148 + int i, j; 1.149 + int top = stack_top[mm_idx]; 1.150 + float *m1 = mat_stack[mm_idx][top]; 1.151 + float res[16]; 1.152 + 1.153 + for(i=0; i<4; i++) { 1.154 + for(j=0; j<4; j++) { 1.155 + res[M(i,j)] = m2[M(i,0)] * m1[M(0,j)] + 1.156 + m2[M(i,1)] * m1[M(1,j)] + 1.157 + m2[M(i,2)] * m1[M(2,j)] + 1.158 + m2[M(i,3)] * m1[M(3,j)]; 1.159 + } 1.160 + } 1.161 + 1.162 + memcpy(m1, res, sizeof res); 1.163 + mvp_valid = 0; 1.164 +} 1.165 + 1.166 +void gl_mult_matrixd(const double *m) 1.167 +{ 1.168 + int i; 1.169 + float mf[16]; 1.170 + 1.171 + for(i=0; i<16; i++) { 1.172 + mf[i] = (float)m[i]; 1.173 + } 1.174 + gl_mult_matrixf(mf); 1.175 +} 1.176 + 1.177 +void gl_translatef(float x, float y, float z) 1.178 +{ 1.179 + float mat[] = MAT_IDENT; 1.180 + 1.181 + mat[12] = x; 1.182 + mat[13] = y; 1.183 + mat[14] = z; 1.184 + 1.185 + gl_mult_matrixf(mat); 1.186 +} 1.187 + 1.188 +void gl_rotatef(float angle, float x, float y, float z) 1.189 +{ 1.190 + float mat[] = MAT_IDENT; 1.191 + 1.192 + float angle_rad = M_PI * angle / 180.0; 1.193 + float sina = sin(angle_rad); 1.194 + float cosa = cos(angle_rad); 1.195 + float one_minus_cosa = 1.0 - cosa; 1.196 + float nxsq = x * x; 1.197 + float nysq = y * y; 1.198 + float nzsq = z * z; 1.199 + 1.200 + mat[0] = nxsq + (1.0 - nxsq) * cosa; 1.201 + mat[4] = x * y * one_minus_cosa - z * sina; 1.202 + mat[8] = x * z * one_minus_cosa + y * sina; 1.203 + mat[1] = x * y * one_minus_cosa + z * sina; 1.204 + mat[5] = nysq + (1.0 - nysq) * cosa; 1.205 + mat[9] = y * z * one_minus_cosa - x * sina; 1.206 + mat[2] = x * z * one_minus_cosa - y * sina; 1.207 + mat[6] = y * z * one_minus_cosa + x * sina; 1.208 + mat[10] = nzsq + (1.0 - nzsq) * cosa; 1.209 + 1.210 + gl_mult_matrixf(mat); 1.211 +} 1.212 + 1.213 +void gl_scalef(float x, float y, float z) 1.214 +{ 1.215 + float mat[] = MAT_IDENT; 1.216 + 1.217 + mat[0] = x; 1.218 + mat[5] = y; 1.219 + mat[10] = z; 1.220 + 1.221 + gl_mult_matrixf(mat); 1.222 +} 1.223 + 1.224 +void gl_ortho(float left, float right, float bottom, float top, float near, float far) 1.225 +{ 1.226 + float mat[] = MAT_IDENT; 1.227 + 1.228 + float dx = right - left; 1.229 + float dy = top - bottom; 1.230 + float dz = far - near; 1.231 + 1.232 + float tx = -(right + left) / dx; 1.233 + float ty = -(top + bottom) / dy; 1.234 + float tz = -(far + near) / dz; 1.235 + 1.236 + float sx = 2.0 / dx; 1.237 + float sy = 2.0 / dy; 1.238 + float sz = -2.0 / dz; 1.239 + 1.240 + mat[0] = sx; 1.241 + mat[5] = sy; 1.242 + mat[10] = sz; 1.243 + mat[12] = tx; 1.244 + mat[13] = ty; 1.245 + mat[14] = tz; 1.246 + 1.247 + gl_mult_matrixf(mat); 1.248 +} 1.249 + 1.250 +void gl_frustum(float left, float right, float bottom, float top, float near, float far) 1.251 +{ 1.252 + float mat[] = MAT_IDENT; 1.253 + 1.254 + float dx = right - left; 1.255 + float dy = top - bottom; 1.256 + float dz = far - near; 1.257 + 1.258 + float a = (right + left) / dx; 1.259 + float b = (top + bottom) / dy; 1.260 + float c = -(far + near) / dz; 1.261 + float d = -2.0 * far * near / dz; 1.262 + 1.263 + mat[0] = 2.0 * near / dx; 1.264 + mat[5] = 2.0 * near / dy; 1.265 + mat[8] = a; 1.266 + mat[9] = b; 1.267 + mat[10] = c; 1.268 + mat[11] = -1.0; 1.269 + mat[14] = d; 1.270 + mat[15] = 0.0; 1.271 + 1.272 + gl_mult_matrixf(mat); 1.273 +} 1.274 + 1.275 +void glu_perspective(float vfov, float aspect, float near, float far) 1.276 +{ 1.277 + float vfov_rad = M_PI * vfov / 180.0; 1.278 + float x = near * tan(vfov_rad / 2.0); 1.279 + gl_frustum(-aspect * x, aspect * x, -x, x, near, far); 1.280 +} 1.281 + 1.282 +int glu_un_project(double winx, double winy, double winz, 1.283 + const double *model, const double *proj, const int *viewp, 1.284 + double *objx, double *objy, double *objz) 1.285 +{ 1.286 + double mvp[16], inv_mvp[16]; 1.287 + 1.288 + double ndcx = 2.0 * (winx - viewp[0]) / viewp[2] - 1.0; 1.289 + double ndcy = 2.0 * (winy - viewp[1]) / viewp[3] - 1.0; 1.290 + double ndcz = 2.0 * winz - 1.0; 1.291 + 1.292 + // calculate modelviewprojection 1.293 + gl_matrix_mode(GL_MODELVIEW); 1.294 + gl_push_matrix(); 1.295 + gl_load_matrixd(proj); 1.296 + gl_mult_matrixd(model); 1.297 + gl_get_doublev(GL_MODELVIEW_MATRIX, mvp); 1.298 + gl_pop_matrix(); 1.299 + 1.300 + // invert modelviewprojection 1.301 + m4_inverse(inv_mvp, mvp); 1.302 + 1.303 + // transform ndc by modelview -> obj 1.304 + /**objx = inv_mvp[0] * ndcx + inv_mvp[4] * ndcy + inv_mvp[8] * ndcz + inv_mvp[12]; 1.305 + *objy = inv_mvp[1] * ndcx + inv_mvp[5] * ndcy + inv_mvp[9] * ndcz + inv_mvp[13]; 1.306 + *objz = inv_mvp[2] * ndcx + inv_mvp[6] * ndcy + inv_mvp[10] * ndcz + inv_mvp[14];*/ 1.307 + *objx = inv_mvp[0] * ndcx + inv_mvp[1] * ndcy + inv_mvp[2] * ndcz + inv_mvp[3]; 1.308 + *objy = inv_mvp[4] * ndcx + inv_mvp[5] * ndcy + inv_mvp[6] * ndcz + inv_mvp[7]; 1.309 + *objz = inv_mvp[8] * ndcx + inv_mvp[9] * ndcy + inv_mvp[10] * ndcz + inv_mvp[11]; 1.310 + return 0; 1.311 +} 1.312 + 1.313 +void gl_apply_xform(unsigned int prog) 1.314 +{ 1.315 + int loc, mvidx, pidx, tidx, mvtop, ptop, ttop; 1.316 + 1.317 + mvidx = MMODE_IDX(GL_MODELVIEW); 1.318 + pidx = MMODE_IDX(GL_PROJECTION); 1.319 + tidx = MMODE_IDX(GL_TEXTURE); 1.320 + 1.321 + mvtop = stack_top[mvidx]; 1.322 + ptop = stack_top[pidx]; 1.323 + ttop = stack_top[tidx]; 1.324 + 1.325 + assert(prog); 1.326 + 1.327 + /*printf("APPLY XFORM\n");*/ 1.328 + 1.329 + CHECK_GLERROR; 1.330 + if((loc = glGetUniformLocation(prog, "matrix_modelview")) != -1) { 1.331 + CHECK_GLERROR; 1.332 + /*printf(" MODELVIEW:\n"); 1.333 + for(i=0; i<16; i+=4) { 1.334 + printf("%.2f %.2f %.2f %.2f\n", mat_stack[mvidx][mvtop][i], mat_stack[mvidx][mvtop][i + 1], mat_stack[mvidx][mvtop][i + 2], mat_stack[mvidx][mvtop][i + 3]); 1.335 + }*/ 1.336 + glUniformMatrix4fv(loc, 1, 0, mat_stack[mvidx][mvtop]); 1.337 + CHECK_GLERROR; 1.338 + } 1.339 + CHECK_GLERROR; 1.340 + 1.341 + if((loc = glGetUniformLocation(prog, "matrix_projection")) != -1) { 1.342 + CHECK_GLERROR; 1.343 + /*printf(" PROJECTION:\n"); 1.344 + for(i=0; i<16; i+=4) { 1.345 + printf("%.2f %.2f %.2f %.2f\n", mat_stack[pidx][ptop][i], mat_stack[pidx][ptop][i + 1], mat_stack[pidx][ptop][i + 2], mat_stack[pidx][ptop][i + 3]); 1.346 + }*/ 1.347 + glUniformMatrix4fv(loc, 1, 0, mat_stack[pidx][ptop]); 1.348 + CHECK_GLERROR; 1.349 + } 1.350 + CHECK_GLERROR; 1.351 + 1.352 + if((loc = glGetUniformLocation(prog, "matrix_texture")) != -1) { 1.353 + CHECK_GLERROR; 1.354 + glUniformMatrix4fv(loc, 1, 0, mat_stack[tidx][ttop]); 1.355 + CHECK_GLERROR; 1.356 + } 1.357 + CHECK_GLERROR; 1.358 + 1.359 + if((loc = glGetUniformLocation(prog, "matrix_normal")) != -1) { 1.360 + float nmat[9]; 1.361 + 1.362 + CHECK_GLERROR; 1.363 + 1.364 + nmat[0] = mat_stack[mvidx][mvtop][0]; 1.365 + nmat[1] = mat_stack[mvidx][mvtop][1]; 1.366 + nmat[2] = mat_stack[mvidx][mvtop][2]; 1.367 + nmat[3] = mat_stack[mvidx][mvtop][4]; 1.368 + nmat[4] = mat_stack[mvidx][mvtop][5]; 1.369 + nmat[5] = mat_stack[mvidx][mvtop][6]; 1.370 + nmat[6] = mat_stack[mvidx][mvtop][8]; 1.371 + nmat[7] = mat_stack[mvidx][mvtop][9]; 1.372 + nmat[8] = mat_stack[mvidx][mvtop][10]; 1.373 + glUniformMatrix3fv(loc, 1, 0, nmat); 1.374 + CHECK_GLERROR; 1.375 + } 1.376 + CHECK_GLERROR; 1.377 + 1.378 + if((loc = glGetUniformLocation(prog, "matrix_modelview_projection")) != -1) { 1.379 + CHECK_GLERROR; 1.380 + if(!mvp_valid) { 1.381 + /* TODO calc mvp */ 1.382 + } 1.383 + glUniformMatrix4fv(loc, 1, 0, mat_mvp); 1.384 + CHECK_GLERROR; 1.385 + } 1.386 + CHECK_GLERROR; 1.387 +} 1.388 + 1.389 + 1.390 +/* immediate mode rendering */ 1.391 +void gl_begin(int p) 1.392 +{ 1.393 + if(!vert_arr) { 1.394 + vert_arr = malloc(MAX_VERTS * sizeof *vert_arr); 1.395 + norm_arr = malloc(MAX_VERTS * sizeof *norm_arr); 1.396 + texc_arr = malloc(MAX_VERTS * sizeof *texc_arr); 1.397 + col_arr = malloc(MAX_VERTS * sizeof *col_arr); 1.398 + attr_arr = malloc(MAX_VERTS * sizeof *attr_arr); 1.399 + assert(vert_arr && norm_arr && texc_arr && col_arr && attr_arr); 1.400 + } 1.401 + 1.402 + prim = p; 1.403 + num_verts = vert_calls = 0; 1.404 + 1.405 + glGetIntegerv(GL_CURRENT_PROGRAM, &cur_prog); 1.406 + CHECK_GLERROR; 1.407 + assert(cur_prog); 1.408 + 1.409 + gl_apply_xform(cur_prog); 1.410 + CHECK_GLERROR; 1.411 + 1.412 + vloc = glGetAttribLocation(cur_prog, "attr_vertex"); 1.413 + CHECK_GLERROR; 1.414 + nloc = glGetAttribLocation(cur_prog, "attr_normal"); 1.415 + CHECK_GLERROR; 1.416 + cloc = glGetAttribLocation(cur_prog, "attr_color"); 1.417 + CHECK_GLERROR; 1.418 + tloc = glGetAttribLocation(cur_prog, "attr_texcoord"); 1.419 + CHECK_GLERROR; 1.420 +} 1.421 + 1.422 +void gl_end(void) 1.423 +{ 1.424 + if(num_verts > 0) { 1.425 + gl_draw_immediate(); 1.426 + } 1.427 + aloc = -1; 1.428 +} 1.429 + 1.430 +static void gl_draw_immediate(void) 1.431 +{ 1.432 + int glprim; 1.433 + 1.434 + if(vloc == -1) { 1.435 + fprintf(stderr, "gl_draw_immediate call with vloc == -1\n"); 1.436 + return; 1.437 + } 1.438 + 1.439 + glprim = prim == GL_QUADS ? GL_TRIANGLES : prim; 1.440 + 1.441 + CHECK_GLERROR; 1.442 + glVertexAttribPointer(vloc, 4, GL_FLOAT, 0, 0, vert_arr); 1.443 + CHECK_GLERROR; 1.444 + glEnableVertexAttribArray(vloc); 1.445 + CHECK_GLERROR; 1.446 + 1.447 + if(nloc != -1) { 1.448 + glVertexAttribPointer(nloc, 3, GL_FLOAT, 0, 0, norm_arr); 1.449 + CHECK_GLERROR; 1.450 + glEnableVertexAttribArray(nloc); 1.451 + CHECK_GLERROR; 1.452 + } 1.453 + 1.454 + if(cloc != -1) { 1.455 + glVertexAttribPointer(cloc, 4, GL_FLOAT, 1, 0, col_arr); 1.456 + CHECK_GLERROR; 1.457 + glEnableVertexAttribArray(cloc); 1.458 + CHECK_GLERROR; 1.459 + } 1.460 + 1.461 + if(tloc != -1) { 1.462 + glVertexAttribPointer(tloc, 2, GL_FLOAT, 0, 0, texc_arr); 1.463 + CHECK_GLERROR; 1.464 + glEnableVertexAttribArray(tloc); 1.465 + CHECK_GLERROR; 1.466 + } 1.467 + 1.468 + if(aloc != -1) { 1.469 + glVertexAttribPointer(aloc, 4, GL_FLOAT, 0, 0, attr_arr); 1.470 + CHECK_GLERROR; 1.471 + glEnableVertexAttribArray(aloc); 1.472 + CHECK_GLERROR; 1.473 + } 1.474 + 1.475 + glDrawArrays(glprim, 0, num_verts); 1.476 + CHECK_GLERROR; 1.477 + 1.478 + glDisableVertexAttribArray(vloc); 1.479 + CHECK_GLERROR; 1.480 + if(nloc != -1) { 1.481 + glDisableVertexAttribArray(nloc); 1.482 + CHECK_GLERROR; 1.483 + } 1.484 + if(cloc != -1) { 1.485 + glDisableVertexAttribArray(cloc); 1.486 + CHECK_GLERROR; 1.487 + } 1.488 + if(tloc != -1) { 1.489 + glDisableVertexAttribArray(tloc); 1.490 + CHECK_GLERROR; 1.491 + } 1.492 + if(aloc != -1) { 1.493 + glDisableVertexAttribArray(aloc); 1.494 + CHECK_GLERROR; 1.495 + } 1.496 +} 1.497 + 1.498 + 1.499 +void gl_vertex2f(float x, float y) 1.500 +{ 1.501 + gl_vertex4f(x, y, 0.0f, 1.0f); 1.502 +} 1.503 + 1.504 +void gl_vertex3f(float x, float y, float z) 1.505 +{ 1.506 + gl_vertex4f(x, y, z, 1.0f); 1.507 +} 1.508 + 1.509 +void gl_vertex4f(float x, float y, float z, float w) 1.510 +{ 1.511 + int i, buffer_full; 1.512 + 1.513 + if(prim == GL_QUADS && vert_calls % 4 == 3) { 1.514 + for(i=0; i<2; i++) { 1.515 + if(aloc != -1) { 1.516 + attr_arr[num_verts] = attr_arr[num_verts - 3 + i]; 1.517 + } 1.518 + if(cloc != -1) { 1.519 + col_arr[num_verts] = col_arr[num_verts - 3 + i]; 1.520 + } 1.521 + if(tloc != -1) { 1.522 + texc_arr[num_verts] = texc_arr[num_verts - 3 + i]; 1.523 + } 1.524 + if(nloc != -1) { 1.525 + norm_arr[num_verts] = norm_arr[num_verts - 3 + i]; 1.526 + } 1.527 + vert_arr[num_verts] = vert_arr[num_verts - 3 + i]; 1.528 + num_verts++; 1.529 + } 1.530 + } 1.531 + 1.532 + vert_arr[num_verts].x = x; 1.533 + vert_arr[num_verts].y = y; 1.534 + vert_arr[num_verts].z = z; 1.535 + vert_arr[num_verts].w = w; 1.536 + 1.537 + if(cloc != -1) { 1.538 + col_arr[num_verts] = cur_color; 1.539 + } 1.540 + if(nloc != -1) { 1.541 + norm_arr[num_verts] = cur_normal; 1.542 + } 1.543 + if(tloc != -1) { 1.544 + texc_arr[num_verts] = cur_texcoord; 1.545 + } 1.546 + if(aloc != -1) { 1.547 + attr_arr[num_verts] = cur_attrib; 1.548 + } 1.549 + 1.550 + vert_calls++; 1.551 + num_verts++; 1.552 + 1.553 + if(prim == GL_QUADS) { 1.554 + /* leave space for 6 more worst-case and don't allow flushes mid-quad */ 1.555 + buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0; 1.556 + } else { 1.557 + buffer_full = num_verts >= MAX_VERTS - prim; 1.558 + } 1.559 + 1.560 + if(buffer_full) { 1.561 + gl_draw_immediate(); 1.562 + gl_begin(prim); /* reset everything */ 1.563 + } 1.564 +} 1.565 + 1.566 + 1.567 +void gl_normal3f(float x, float y, float z) 1.568 +{ 1.569 + cur_normal.x = x; 1.570 + cur_normal.y = y; 1.571 + cur_normal.z = z; 1.572 +} 1.573 + 1.574 + 1.575 +void gl_color3f(float r, float g, float b) 1.576 +{ 1.577 + cur_color.x = r; 1.578 + cur_color.y = g; 1.579 + cur_color.z = b; 1.580 + cur_color.w = 1.0f; 1.581 +} 1.582 + 1.583 +void gl_color4f(float r, float g, float b, float a) 1.584 +{ 1.585 + cur_color.x = r; 1.586 + cur_color.y = g; 1.587 + cur_color.z = b; 1.588 + cur_color.w = a; 1.589 +} 1.590 + 1.591 + 1.592 +void gl_texcoord1f(float s) 1.593 +{ 1.594 + cur_texcoord.x = s; 1.595 + cur_texcoord.y = 0.0f; 1.596 +} 1.597 + 1.598 +void gl_texcoord2f(float s, float t) 1.599 +{ 1.600 + cur_texcoord.x = s; 1.601 + cur_texcoord.y = t; 1.602 +} 1.603 + 1.604 +void gl_vertex_attrib2f(int loc, float x, float y) 1.605 +{ 1.606 + aloc = loc; 1.607 + cur_attrib.x = x; 1.608 + cur_attrib.y = y; 1.609 + cur_attrib.z = 0.0f; 1.610 + cur_attrib.w = 1.0f; 1.611 +} 1.612 + 1.613 +void gl_vertex_attrib3f(int loc, float x, float y, float z) 1.614 +{ 1.615 + aloc = loc; 1.616 + cur_attrib.x = x; 1.617 + cur_attrib.y = y; 1.618 + cur_attrib.z = z; 1.619 + cur_attrib.w = 1.0f; 1.620 +} 1.621 + 1.622 +void gl_vertex_attrib4f(int loc, float x, float y, float z, float w) 1.623 +{ 1.624 + aloc = loc; 1.625 + cur_attrib.x = x; 1.626 + cur_attrib.y = y; 1.627 + cur_attrib.z = z; 1.628 + cur_attrib.w = w; 1.629 +} 1.630 + 1.631 +#ifdef GLDEF 1.632 +#undef glGetFloatv 1.633 +#endif 1.634 + 1.635 +void gl_get_floatv(int what, float *res) 1.636 +{ 1.637 + int idx; 1.638 + 1.639 + switch(what) { 1.640 + case GL_MODELVIEW_MATRIX: 1.641 + idx = MMODE_IDX(GL_MODELVIEW); 1.642 + memcpy(res, mat_stack[idx][stack_top[idx]], 16 * sizeof *res); 1.643 + break; 1.644 + 1.645 + case GL_PROJECTION_MATRIX: 1.646 + idx = MMODE_IDX(GL_PROJECTION); 1.647 + memcpy(res, mat_stack[idx][stack_top[idx]], 16 * sizeof *res); 1.648 + break; 1.649 + 1.650 + default: 1.651 + glGetFloatv(what, res); 1.652 + } 1.653 +} 1.654 + 1.655 +void gl_get_doublev(int what, double *res) 1.656 +{ 1.657 + int i, idx; 1.658 + float tmp[16]; 1.659 + 1.660 + switch(what) { 1.661 + case GL_MODELVIEW_MATRIX: 1.662 + if(1) { 1.663 + idx = MMODE_IDX(GL_MODELVIEW); 1.664 + } else { 1.665 + case GL_PROJECTION_MATRIX: 1.666 + idx = MMODE_IDX(GL_PROJECTION); 1.667 + } 1.668 + for(i=0; i<16; i++) { 1.669 + res[i] = mat_stack[idx][stack_top[idx]][i]; 1.670 + } 1.671 + break; 1.672 + 1.673 + default: 1.674 + glGetFloatv(what, tmp); 1.675 + for(i=0; i<16; i++) { 1.676 + res[i] = tmp[i]; 1.677 + } 1.678 + } 1.679 +} 1.680 + 1.681 + 1.682 +/* ---- matrix inversion stuff ---- */ 1.683 +static void m4_transpose(double *res, double *m) 1.684 +{ 1.685 + int i, j; 1.686 + double tmp[16]; 1.687 + 1.688 + if(res == m) { 1.689 + memcpy(tmp, m, 16 * sizeof *m); 1.690 + m = tmp; 1.691 + } 1.692 + 1.693 + for(i=0; i<4; i++) { 1.694 + for(j=0; j<4; j++) { 1.695 + res[M(i, j)] = m[M(j, i)]; 1.696 + } 1.697 + } 1.698 +} 1.699 + 1.700 +static double m4_determinant(double *m) 1.701 +{ 1.702 + double det11, det12, det13, det14; 1.703 + 1.704 + det11 = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) - 1.705 + (m[M(1, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) + 1.706 + (m[M(1, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])); 1.707 + 1.708 + det12 = (m[M(1, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) - 1.709 + (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) + 1.710 + (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])); 1.711 + 1.712 + det13 = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) - 1.713 + (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) + 1.714 + (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)])); 1.715 + 1.716 + det14 = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) - 1.717 + (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) + 1.718 + (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)])); 1.719 + 1.720 + return m[M(0, 0)] * det11 - m[M(0, 1)] * det12 + m[M(0, 2)] * det13 - m[M(0, 3)] * det14; 1.721 +} 1.722 + 1.723 +static void m4_adjoint(double *res, double *m) 1.724 +{ 1.725 + int i, j; 1.726 + double coef[16]; 1.727 + 1.728 + coef[M(0, 0)] = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) - 1.729 + (m[M(1, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) + 1.730 + (m[M(1, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])); 1.731 + coef[M(0, 1)] = (m[M(1, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) - 1.732 + (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) + 1.733 + (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])); 1.734 + coef[M(0, 2)] = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) - 1.735 + (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) + 1.736 + (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)])); 1.737 + coef[M(0, 3)] = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) - 1.738 + (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) + 1.739 + (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)])); 1.740 + 1.741 + coef[M(1, 0)] = (m[M(0, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) - 1.742 + (m[M(0, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) + 1.743 + (m[M(0, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])); 1.744 + coef[M(1, 1)] = (m[M(0, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) - 1.745 + (m[M(0, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) + 1.746 + (m[M(0, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])); 1.747 + coef[M(1, 2)] = (m[M(0, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) - 1.748 + (m[M(0, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) + 1.749 + (m[M(0, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)])); 1.750 + coef[M(1, 3)] = (m[M(0, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) - 1.751 + (m[M(0, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) + 1.752 + (m[M(0, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)])); 1.753 + 1.754 + coef[M(2, 0)] = (m[M(0, 1)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(1, 3)])) - 1.755 + (m[M(0, 2)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(1, 3)])) + 1.756 + (m[M(0, 3)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(1, 2)])); 1.757 + coef[M(2, 1)] = (m[M(0, 0)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(1, 3)])) - 1.758 + (m[M(0, 2)] * (m[M(1, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(1, 3)])) + 1.759 + (m[M(0, 3)] * (m[M(1, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(1, 2)])); 1.760 + coef[M(2, 2)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(1, 3)])) - 1.761 + (m[M(0, 1)] * (m[M(1, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(1, 3)])) + 1.762 + (m[M(0, 3)] * (m[M(1, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(1, 1)])); 1.763 + coef[M(2, 3)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(1, 2)])) - 1.764 + (m[M(0, 1)] * (m[M(1, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(1, 2)])) + 1.765 + (m[M(0, 2)] * (m[M(1, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(1, 1)])); 1.766 + 1.767 + coef[M(3, 0)] = (m[M(0, 1)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(2, 2)] * m[M(1, 3)])) - 1.768 + (m[M(0, 2)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(2, 1)] * m[M(1, 3)])) + 1.769 + (m[M(0, 3)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(2, 1)] * m[M(1, 2)])); 1.770 + coef[M(3, 1)] = (m[M(0, 0)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(2, 2)] * m[M(1, 3)])) - 1.771 + (m[M(0, 2)] * (m[M(1, 0)] * m[M(2, 3)] - m[M(2, 0)] * m[M(1, 3)])) + 1.772 + (m[M(0, 3)] * (m[M(1, 0)] * m[M(2, 2)] - m[M(2, 0)] * m[M(1, 2)])); 1.773 + coef[M(3, 2)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(2, 1)] * m[M(1, 3)])) - 1.774 + (m[M(0, 1)] * (m[M(1, 0)] * m[M(2, 3)] - m[M(2, 0)] * m[M(1, 3)])) + 1.775 + (m[M(0, 3)] * (m[M(1, 0)] * m[M(2, 1)] - m[M(2, 0)] * m[M(1, 1)])); 1.776 + coef[M(3, 3)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(2, 1)] * m[M(1, 2)])) - 1.777 + (m[M(0, 1)] * (m[M(1, 0)] * m[M(2, 2)] - m[M(2, 0)] * m[M(1, 2)])) + 1.778 + (m[M(0, 2)] * (m[M(1, 0)] * m[M(2, 1)] - m[M(2, 0)] * m[M(1, 1)])); 1.779 + 1.780 + m4_transpose(res, coef); 1.781 + 1.782 + for(i=0; i<4; i++) { 1.783 + for(j=0; j<4; j++) { 1.784 + res[M(i, j)] = j % 2 ? -res[M(i, j)] : res[M(i, j)]; 1.785 + if(i % 2) res[M(i, j)] = -res[M(i, j)]; 1.786 + } 1.787 + } 1.788 +} 1.789 + 1.790 +static void m4_inverse(double *res, double *m) 1.791 +{ 1.792 + int i, j; 1.793 + double adj[16]; 1.794 + double det; 1.795 + 1.796 + m4_adjoint(adj, m); 1.797 + det = m4_determinant(m); 1.798 + 1.799 + for(i=0; i<4; i++) { 1.800 + for(j=0; j<4; j++) { 1.801 + res[M(i, j)] = adj[M(i, j)] / det; 1.802 + } 1.803 + } 1.804 +} 1.805 +