3dphotoshoot

annotate 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
rev   line source
nuclear@11 1 /*
nuclear@11 2 SaneGL - a small library to bring back sanity to OpenGL ES 2.x
nuclear@11 3 Copyright (C) 2011-2013 John Tsiombikas <nuclear@member.fsf.org>
nuclear@11 4
nuclear@11 5 This program is free software: you can redistribute it and/or modify
nuclear@11 6 it under the terms of the GNU General Public License as published by
nuclear@11 7 the Free Software Foundation, either version 3 of the License, or
nuclear@11 8 (at your option) any later version.
nuclear@11 9
nuclear@11 10 This program is distributed in the hope that it will be useful,
nuclear@11 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@11 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@11 13 GNU General Public License for more details.
nuclear@11 14
nuclear@11 15 You should have received a copy of the GNU General Public License
nuclear@11 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@11 17 */
nuclear@11 18
nuclear@11 19 #include <stdio.h>
nuclear@11 20 #include <stdlib.h>
nuclear@11 21 #include <string.h>
nuclear@11 22 #include <math.h>
nuclear@11 23 #include <assert.h>
nuclear@11 24 #include "sanegl.h"
nuclear@11 25
nuclear@11 26 #define MMODE_IDX(x) ((x) - GL_MODELVIEW)
nuclear@11 27 #define MAT_STACK_SIZE 32
nuclear@11 28 #define MAT_IDENT {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
nuclear@11 29
nuclear@11 30 #define MAX_VERTS 512
nuclear@11 31
nuclear@11 32 static void gl_draw_immediate(void);
nuclear@11 33 static void m4_transpose(double *res, double *m);
nuclear@11 34 static double m4_determinant(double *m);
nuclear@11 35 static void m4_adjoint(double *res, double *m);
nuclear@11 36 static void m4_inverse(double *res, double *m);
nuclear@11 37
nuclear@11 38
nuclear@11 39 typedef struct { float x, y; } vec2_t;
nuclear@11 40 typedef struct { float x, y, z; } vec3_t;
nuclear@11 41 typedef struct { float x, y, z, w; } vec4_t;
nuclear@11 42
nuclear@11 43 static int mm_idx = 0;
nuclear@11 44 static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}};
nuclear@11 45 static int stack_top[3];
nuclear@11 46 static float mat_mvp[16];
nuclear@11 47 static int mvp_valid;
nuclear@11 48 static int prim = -1;
nuclear@11 49
nuclear@11 50 static vec3_t cur_normal;
nuclear@11 51 static vec4_t cur_color, cur_attrib;
nuclear@11 52 static vec2_t cur_texcoord;
nuclear@11 53
nuclear@11 54 static vec4_t *vert_arr, *col_arr, *attr_arr;
nuclear@11 55 static vec3_t *norm_arr;
nuclear@11 56 static vec2_t *texc_arr;
nuclear@11 57 /*static unsigned int vbuf, cbuf, nbuf, tbuf, abuf;*/
nuclear@11 58 static int vloc, nloc, cloc, tloc, aloc = -1;
nuclear@11 59
nuclear@11 60 static int num_verts, vert_calls;
nuclear@11 61 static int cur_prog;
nuclear@11 62
nuclear@11 63 #ifdef GLDEF
nuclear@11 64 #undef glEnable
nuclear@11 65 #undef glDisable
nuclear@11 66 #endif
nuclear@11 67
nuclear@11 68 void gl_enable(int state)
nuclear@11 69 {
nuclear@11 70 switch(state) {
nuclear@11 71 case GL_TEXTURE_2D:
nuclear@11 72 break;
nuclear@11 73
nuclear@11 74 default:
nuclear@11 75 glEnable(state);
nuclear@11 76 }
nuclear@11 77 }
nuclear@11 78
nuclear@11 79 void gl_disable(int state)
nuclear@11 80 {
nuclear@11 81 switch(state) {
nuclear@11 82 case GL_TEXTURE_2D:
nuclear@11 83 glBindTexture(state, 0);
nuclear@11 84 break;
nuclear@11 85
nuclear@11 86 default:
nuclear@11 87 glDisable(state);
nuclear@11 88 }
nuclear@11 89 }
nuclear@11 90
nuclear@11 91 void gl_matrix_mode(int mm)
nuclear@11 92 {
nuclear@11 93 mm_idx = MMODE_IDX(mm);
nuclear@11 94 }
nuclear@11 95
nuclear@11 96 void gl_push_matrix(void)
nuclear@11 97 {
nuclear@11 98 int top = stack_top[mm_idx];
nuclear@11 99
nuclear@11 100 memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float));
nuclear@11 101 stack_top[mm_idx]++;
nuclear@11 102 mvp_valid = 0;
nuclear@11 103 }
nuclear@11 104
nuclear@11 105 void gl_pop_matrix(void)
nuclear@11 106 {
nuclear@11 107 stack_top[mm_idx]--;
nuclear@11 108 mvp_valid = 0;
nuclear@11 109 }
nuclear@11 110
nuclear@11 111 void gl_load_identity(void)
nuclear@11 112 {
nuclear@11 113 static const float idmat[] = MAT_IDENT;
nuclear@11 114 int top = stack_top[mm_idx];
nuclear@11 115 float *mat = mat_stack[mm_idx][top];
nuclear@11 116
nuclear@11 117 memcpy(mat, idmat, sizeof idmat);
nuclear@11 118 mvp_valid = 0;
nuclear@11 119 }
nuclear@11 120
nuclear@11 121 void gl_load_matrixf(const float *m)
nuclear@11 122 {
nuclear@11 123 int top = stack_top[mm_idx];
nuclear@11 124 float *mat = mat_stack[mm_idx][top];
nuclear@11 125
nuclear@11 126 memcpy(mat, m, 16 * sizeof *mat);
nuclear@11 127 mvp_valid = 0;
nuclear@11 128 }
nuclear@11 129
nuclear@11 130 void gl_load_matrixd(const double *m)
nuclear@11 131 {
nuclear@11 132 int i;
nuclear@11 133 float mf[16];
nuclear@11 134
nuclear@11 135 for(i=0; i<16; i++) {
nuclear@11 136 mf[i] = (float)m[i];
nuclear@11 137 }
nuclear@11 138 gl_load_matrixf(mf);
nuclear@11 139 }
nuclear@11 140
nuclear@11 141 #define M(i, j) ((i << 2) + j)
nuclear@11 142
nuclear@11 143 void gl_mult_matrixf(const float *m2)
nuclear@11 144 {
nuclear@11 145 int i, j;
nuclear@11 146 int top = stack_top[mm_idx];
nuclear@11 147 float *m1 = mat_stack[mm_idx][top];
nuclear@11 148 float res[16];
nuclear@11 149
nuclear@11 150 for(i=0; i<4; i++) {
nuclear@11 151 for(j=0; j<4; j++) {
nuclear@11 152 res[M(i,j)] = m2[M(i,0)] * m1[M(0,j)] +
nuclear@11 153 m2[M(i,1)] * m1[M(1,j)] +
nuclear@11 154 m2[M(i,2)] * m1[M(2,j)] +
nuclear@11 155 m2[M(i,3)] * m1[M(3,j)];
nuclear@11 156 }
nuclear@11 157 }
nuclear@11 158
nuclear@11 159 memcpy(m1, res, sizeof res);
nuclear@11 160 mvp_valid = 0;
nuclear@11 161 }
nuclear@11 162
nuclear@11 163 void gl_mult_matrixd(const double *m)
nuclear@11 164 {
nuclear@11 165 int i;
nuclear@11 166 float mf[16];
nuclear@11 167
nuclear@11 168 for(i=0; i<16; i++) {
nuclear@11 169 mf[i] = (float)m[i];
nuclear@11 170 }
nuclear@11 171 gl_mult_matrixf(mf);
nuclear@11 172 }
nuclear@11 173
nuclear@11 174 void gl_translatef(float x, float y, float z)
nuclear@11 175 {
nuclear@11 176 float mat[] = MAT_IDENT;
nuclear@11 177
nuclear@11 178 mat[12] = x;
nuclear@11 179 mat[13] = y;
nuclear@11 180 mat[14] = z;
nuclear@11 181
nuclear@11 182 gl_mult_matrixf(mat);
nuclear@11 183 }
nuclear@11 184
nuclear@11 185 void gl_rotatef(float angle, float x, float y, float z)
nuclear@11 186 {
nuclear@11 187 float mat[] = MAT_IDENT;
nuclear@11 188
nuclear@11 189 float angle_rad = M_PI * angle / 180.0;
nuclear@11 190 float sina = sin(angle_rad);
nuclear@11 191 float cosa = cos(angle_rad);
nuclear@11 192 float one_minus_cosa = 1.0 - cosa;
nuclear@11 193 float nxsq = x * x;
nuclear@11 194 float nysq = y * y;
nuclear@11 195 float nzsq = z * z;
nuclear@11 196
nuclear@11 197 mat[0] = nxsq + (1.0 - nxsq) * cosa;
nuclear@11 198 mat[4] = x * y * one_minus_cosa - z * sina;
nuclear@11 199 mat[8] = x * z * one_minus_cosa + y * sina;
nuclear@11 200 mat[1] = x * y * one_minus_cosa + z * sina;
nuclear@11 201 mat[5] = nysq + (1.0 - nysq) * cosa;
nuclear@11 202 mat[9] = y * z * one_minus_cosa - x * sina;
nuclear@11 203 mat[2] = x * z * one_minus_cosa - y * sina;
nuclear@11 204 mat[6] = y * z * one_minus_cosa + x * sina;
nuclear@11 205 mat[10] = nzsq + (1.0 - nzsq) * cosa;
nuclear@11 206
nuclear@11 207 gl_mult_matrixf(mat);
nuclear@11 208 }
nuclear@11 209
nuclear@11 210 void gl_scalef(float x, float y, float z)
nuclear@11 211 {
nuclear@11 212 float mat[] = MAT_IDENT;
nuclear@11 213
nuclear@11 214 mat[0] = x;
nuclear@11 215 mat[5] = y;
nuclear@11 216 mat[10] = z;
nuclear@11 217
nuclear@11 218 gl_mult_matrixf(mat);
nuclear@11 219 }
nuclear@11 220
nuclear@11 221 void gl_ortho(float left, float right, float bottom, float top, float near, float far)
nuclear@11 222 {
nuclear@11 223 float mat[] = MAT_IDENT;
nuclear@11 224
nuclear@11 225 float dx = right - left;
nuclear@11 226 float dy = top - bottom;
nuclear@11 227 float dz = far - near;
nuclear@11 228
nuclear@11 229 float tx = -(right + left) / dx;
nuclear@11 230 float ty = -(top + bottom) / dy;
nuclear@11 231 float tz = -(far + near) / dz;
nuclear@11 232
nuclear@11 233 float sx = 2.0 / dx;
nuclear@11 234 float sy = 2.0 / dy;
nuclear@11 235 float sz = -2.0 / dz;
nuclear@11 236
nuclear@11 237 mat[0] = sx;
nuclear@11 238 mat[5] = sy;
nuclear@11 239 mat[10] = sz;
nuclear@11 240 mat[12] = tx;
nuclear@11 241 mat[13] = ty;
nuclear@11 242 mat[14] = tz;
nuclear@11 243
nuclear@11 244 gl_mult_matrixf(mat);
nuclear@11 245 }
nuclear@11 246
nuclear@11 247 void gl_frustum(float left, float right, float bottom, float top, float near, float far)
nuclear@11 248 {
nuclear@11 249 float mat[] = MAT_IDENT;
nuclear@11 250
nuclear@11 251 float dx = right - left;
nuclear@11 252 float dy = top - bottom;
nuclear@11 253 float dz = far - near;
nuclear@11 254
nuclear@11 255 float a = (right + left) / dx;
nuclear@11 256 float b = (top + bottom) / dy;
nuclear@11 257 float c = -(far + near) / dz;
nuclear@11 258 float d = -2.0 * far * near / dz;
nuclear@11 259
nuclear@11 260 mat[0] = 2.0 * near / dx;
nuclear@11 261 mat[5] = 2.0 * near / dy;
nuclear@11 262 mat[8] = a;
nuclear@11 263 mat[9] = b;
nuclear@11 264 mat[10] = c;
nuclear@11 265 mat[11] = -1.0;
nuclear@11 266 mat[14] = d;
nuclear@11 267 mat[15] = 0.0;
nuclear@11 268
nuclear@11 269 gl_mult_matrixf(mat);
nuclear@11 270 }
nuclear@11 271
nuclear@11 272 void glu_perspective(float vfov, float aspect, float near, float far)
nuclear@11 273 {
nuclear@11 274 float vfov_rad = M_PI * vfov / 180.0;
nuclear@11 275 float x = near * tan(vfov_rad / 2.0);
nuclear@11 276 gl_frustum(-aspect * x, aspect * x, -x, x, near, far);
nuclear@11 277 }
nuclear@11 278
nuclear@11 279 int glu_un_project(double winx, double winy, double winz,
nuclear@11 280 const double *model, const double *proj, const int *viewp,
nuclear@11 281 double *objx, double *objy, double *objz)
nuclear@11 282 {
nuclear@11 283 double mvp[16], inv_mvp[16];
nuclear@11 284
nuclear@11 285 double ndcx = 2.0 * (winx - viewp[0]) / viewp[2] - 1.0;
nuclear@11 286 double ndcy = 2.0 * (winy - viewp[1]) / viewp[3] - 1.0;
nuclear@11 287 double ndcz = 2.0 * winz - 1.0;
nuclear@11 288
nuclear@11 289 // calculate modelviewprojection
nuclear@11 290 gl_matrix_mode(GL_MODELVIEW);
nuclear@11 291 gl_push_matrix();
nuclear@11 292 gl_load_matrixd(proj);
nuclear@11 293 gl_mult_matrixd(model);
nuclear@11 294 gl_get_doublev(GL_MODELVIEW_MATRIX, mvp);
nuclear@11 295 gl_pop_matrix();
nuclear@11 296
nuclear@11 297 // invert modelviewprojection
nuclear@11 298 m4_inverse(inv_mvp, mvp);
nuclear@11 299
nuclear@11 300 // transform ndc by modelview -> obj
nuclear@11 301 /**objx = inv_mvp[0] * ndcx + inv_mvp[4] * ndcy + inv_mvp[8] * ndcz + inv_mvp[12];
nuclear@11 302 *objy = inv_mvp[1] * ndcx + inv_mvp[5] * ndcy + inv_mvp[9] * ndcz + inv_mvp[13];
nuclear@11 303 *objz = inv_mvp[2] * ndcx + inv_mvp[6] * ndcy + inv_mvp[10] * ndcz + inv_mvp[14];*/
nuclear@11 304 *objx = inv_mvp[0] * ndcx + inv_mvp[1] * ndcy + inv_mvp[2] * ndcz + inv_mvp[3];
nuclear@11 305 *objy = inv_mvp[4] * ndcx + inv_mvp[5] * ndcy + inv_mvp[6] * ndcz + inv_mvp[7];
nuclear@11 306 *objz = inv_mvp[8] * ndcx + inv_mvp[9] * ndcy + inv_mvp[10] * ndcz + inv_mvp[11];
nuclear@11 307 return 0;
nuclear@11 308 }
nuclear@11 309
nuclear@11 310 void gl_apply_xform(unsigned int prog)
nuclear@11 311 {
nuclear@11 312 int loc, mvidx, pidx, tidx, mvtop, ptop, ttop;
nuclear@11 313
nuclear@11 314 mvidx = MMODE_IDX(GL_MODELVIEW);
nuclear@11 315 pidx = MMODE_IDX(GL_PROJECTION);
nuclear@11 316 tidx = MMODE_IDX(GL_TEXTURE);
nuclear@11 317
nuclear@11 318 mvtop = stack_top[mvidx];
nuclear@11 319 ptop = stack_top[pidx];
nuclear@11 320 ttop = stack_top[tidx];
nuclear@11 321
nuclear@11 322 assert(prog);
nuclear@11 323
nuclear@11 324 /*printf("APPLY XFORM\n");*/
nuclear@11 325
nuclear@11 326 CHECK_GLERROR;
nuclear@11 327 if((loc = glGetUniformLocation(prog, "matrix_modelview")) != -1) {
nuclear@11 328 CHECK_GLERROR;
nuclear@11 329 /*printf(" MODELVIEW:\n");
nuclear@11 330 for(i=0; i<16; i+=4) {
nuclear@11 331 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]);
nuclear@11 332 }*/
nuclear@11 333 glUniformMatrix4fv(loc, 1, 0, mat_stack[mvidx][mvtop]);
nuclear@11 334 CHECK_GLERROR;
nuclear@11 335 }
nuclear@11 336 CHECK_GLERROR;
nuclear@11 337
nuclear@11 338 if((loc = glGetUniformLocation(prog, "matrix_projection")) != -1) {
nuclear@11 339 CHECK_GLERROR;
nuclear@11 340 /*printf(" PROJECTION:\n");
nuclear@11 341 for(i=0; i<16; i+=4) {
nuclear@11 342 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]);
nuclear@11 343 }*/
nuclear@11 344 glUniformMatrix4fv(loc, 1, 0, mat_stack[pidx][ptop]);
nuclear@11 345 CHECK_GLERROR;
nuclear@11 346 }
nuclear@11 347 CHECK_GLERROR;
nuclear@11 348
nuclear@11 349 if((loc = glGetUniformLocation(prog, "matrix_texture")) != -1) {
nuclear@11 350 CHECK_GLERROR;
nuclear@11 351 glUniformMatrix4fv(loc, 1, 0, mat_stack[tidx][ttop]);
nuclear@11 352 CHECK_GLERROR;
nuclear@11 353 }
nuclear@11 354 CHECK_GLERROR;
nuclear@11 355
nuclear@11 356 if((loc = glGetUniformLocation(prog, "matrix_normal")) != -1) {
nuclear@11 357 float nmat[9];
nuclear@11 358
nuclear@11 359 CHECK_GLERROR;
nuclear@11 360
nuclear@11 361 nmat[0] = mat_stack[mvidx][mvtop][0];
nuclear@11 362 nmat[1] = mat_stack[mvidx][mvtop][1];
nuclear@11 363 nmat[2] = mat_stack[mvidx][mvtop][2];
nuclear@11 364 nmat[3] = mat_stack[mvidx][mvtop][4];
nuclear@11 365 nmat[4] = mat_stack[mvidx][mvtop][5];
nuclear@11 366 nmat[5] = mat_stack[mvidx][mvtop][6];
nuclear@11 367 nmat[6] = mat_stack[mvidx][mvtop][8];
nuclear@11 368 nmat[7] = mat_stack[mvidx][mvtop][9];
nuclear@11 369 nmat[8] = mat_stack[mvidx][mvtop][10];
nuclear@11 370 glUniformMatrix3fv(loc, 1, 0, nmat);
nuclear@11 371 CHECK_GLERROR;
nuclear@11 372 }
nuclear@11 373 CHECK_GLERROR;
nuclear@11 374
nuclear@11 375 if((loc = glGetUniformLocation(prog, "matrix_modelview_projection")) != -1) {
nuclear@11 376 CHECK_GLERROR;
nuclear@11 377 if(!mvp_valid) {
nuclear@11 378 /* TODO calc mvp */
nuclear@11 379 }
nuclear@11 380 glUniformMatrix4fv(loc, 1, 0, mat_mvp);
nuclear@11 381 CHECK_GLERROR;
nuclear@11 382 }
nuclear@11 383 CHECK_GLERROR;
nuclear@11 384 }
nuclear@11 385
nuclear@11 386
nuclear@11 387 /* immediate mode rendering */
nuclear@11 388 void gl_begin(int p)
nuclear@11 389 {
nuclear@11 390 if(!vert_arr) {
nuclear@11 391 vert_arr = malloc(MAX_VERTS * sizeof *vert_arr);
nuclear@11 392 norm_arr = malloc(MAX_VERTS * sizeof *norm_arr);
nuclear@11 393 texc_arr = malloc(MAX_VERTS * sizeof *texc_arr);
nuclear@11 394 col_arr = malloc(MAX_VERTS * sizeof *col_arr);
nuclear@11 395 attr_arr = malloc(MAX_VERTS * sizeof *attr_arr);
nuclear@11 396 assert(vert_arr && norm_arr && texc_arr && col_arr && attr_arr);
nuclear@11 397 }
nuclear@11 398
nuclear@11 399 prim = p;
nuclear@11 400 num_verts = vert_calls = 0;
nuclear@11 401
nuclear@11 402 glGetIntegerv(GL_CURRENT_PROGRAM, &cur_prog);
nuclear@11 403 CHECK_GLERROR;
nuclear@11 404 assert(cur_prog);
nuclear@11 405
nuclear@11 406 gl_apply_xform(cur_prog);
nuclear@11 407 CHECK_GLERROR;
nuclear@11 408
nuclear@11 409 vloc = glGetAttribLocation(cur_prog, "attr_vertex");
nuclear@11 410 CHECK_GLERROR;
nuclear@11 411 nloc = glGetAttribLocation(cur_prog, "attr_normal");
nuclear@11 412 CHECK_GLERROR;
nuclear@11 413 cloc = glGetAttribLocation(cur_prog, "attr_color");
nuclear@11 414 CHECK_GLERROR;
nuclear@11 415 tloc = glGetAttribLocation(cur_prog, "attr_texcoord");
nuclear@11 416 CHECK_GLERROR;
nuclear@11 417 }
nuclear@11 418
nuclear@11 419 void gl_end(void)
nuclear@11 420 {
nuclear@11 421 if(num_verts > 0) {
nuclear@11 422 gl_draw_immediate();
nuclear@11 423 }
nuclear@11 424 aloc = -1;
nuclear@11 425 }
nuclear@11 426
nuclear@11 427 static void gl_draw_immediate(void)
nuclear@11 428 {
nuclear@11 429 int glprim;
nuclear@11 430
nuclear@11 431 if(vloc == -1) {
nuclear@11 432 fprintf(stderr, "gl_draw_immediate call with vloc == -1\n");
nuclear@11 433 return;
nuclear@11 434 }
nuclear@11 435
nuclear@11 436 glprim = prim == GL_QUADS ? GL_TRIANGLES : prim;
nuclear@11 437
nuclear@11 438 CHECK_GLERROR;
nuclear@11 439 glVertexAttribPointer(vloc, 4, GL_FLOAT, 0, 0, vert_arr);
nuclear@11 440 CHECK_GLERROR;
nuclear@11 441 glEnableVertexAttribArray(vloc);
nuclear@11 442 CHECK_GLERROR;
nuclear@11 443
nuclear@11 444 if(nloc != -1) {
nuclear@11 445 glVertexAttribPointer(nloc, 3, GL_FLOAT, 0, 0, norm_arr);
nuclear@11 446 CHECK_GLERROR;
nuclear@11 447 glEnableVertexAttribArray(nloc);
nuclear@11 448 CHECK_GLERROR;
nuclear@11 449 }
nuclear@11 450
nuclear@11 451 if(cloc != -1) {
nuclear@11 452 glVertexAttribPointer(cloc, 4, GL_FLOAT, 1, 0, col_arr);
nuclear@11 453 CHECK_GLERROR;
nuclear@11 454 glEnableVertexAttribArray(cloc);
nuclear@11 455 CHECK_GLERROR;
nuclear@11 456 }
nuclear@11 457
nuclear@11 458 if(tloc != -1) {
nuclear@11 459 glVertexAttribPointer(tloc, 2, GL_FLOAT, 0, 0, texc_arr);
nuclear@11 460 CHECK_GLERROR;
nuclear@11 461 glEnableVertexAttribArray(tloc);
nuclear@11 462 CHECK_GLERROR;
nuclear@11 463 }
nuclear@11 464
nuclear@11 465 if(aloc != -1) {
nuclear@11 466 glVertexAttribPointer(aloc, 4, GL_FLOAT, 0, 0, attr_arr);
nuclear@11 467 CHECK_GLERROR;
nuclear@11 468 glEnableVertexAttribArray(aloc);
nuclear@11 469 CHECK_GLERROR;
nuclear@11 470 }
nuclear@11 471
nuclear@11 472 glDrawArrays(glprim, 0, num_verts);
nuclear@11 473 CHECK_GLERROR;
nuclear@11 474
nuclear@11 475 glDisableVertexAttribArray(vloc);
nuclear@11 476 CHECK_GLERROR;
nuclear@11 477 if(nloc != -1) {
nuclear@11 478 glDisableVertexAttribArray(nloc);
nuclear@11 479 CHECK_GLERROR;
nuclear@11 480 }
nuclear@11 481 if(cloc != -1) {
nuclear@11 482 glDisableVertexAttribArray(cloc);
nuclear@11 483 CHECK_GLERROR;
nuclear@11 484 }
nuclear@11 485 if(tloc != -1) {
nuclear@11 486 glDisableVertexAttribArray(tloc);
nuclear@11 487 CHECK_GLERROR;
nuclear@11 488 }
nuclear@11 489 if(aloc != -1) {
nuclear@11 490 glDisableVertexAttribArray(aloc);
nuclear@11 491 CHECK_GLERROR;
nuclear@11 492 }
nuclear@11 493 }
nuclear@11 494
nuclear@11 495
nuclear@11 496 void gl_vertex2f(float x, float y)
nuclear@11 497 {
nuclear@11 498 gl_vertex4f(x, y, 0.0f, 1.0f);
nuclear@11 499 }
nuclear@11 500
nuclear@11 501 void gl_vertex3f(float x, float y, float z)
nuclear@11 502 {
nuclear@11 503 gl_vertex4f(x, y, z, 1.0f);
nuclear@11 504 }
nuclear@11 505
nuclear@11 506 void gl_vertex4f(float x, float y, float z, float w)
nuclear@11 507 {
nuclear@11 508 int i, buffer_full;
nuclear@11 509
nuclear@11 510 if(prim == GL_QUADS && vert_calls % 4 == 3) {
nuclear@11 511 for(i=0; i<2; i++) {
nuclear@11 512 if(aloc != -1) {
nuclear@11 513 attr_arr[num_verts] = attr_arr[num_verts - 3 + i];
nuclear@11 514 }
nuclear@11 515 if(cloc != -1) {
nuclear@11 516 col_arr[num_verts] = col_arr[num_verts - 3 + i];
nuclear@11 517 }
nuclear@11 518 if(tloc != -1) {
nuclear@11 519 texc_arr[num_verts] = texc_arr[num_verts - 3 + i];
nuclear@11 520 }
nuclear@11 521 if(nloc != -1) {
nuclear@11 522 norm_arr[num_verts] = norm_arr[num_verts - 3 + i];
nuclear@11 523 }
nuclear@11 524 vert_arr[num_verts] = vert_arr[num_verts - 3 + i];
nuclear@11 525 num_verts++;
nuclear@11 526 }
nuclear@11 527 }
nuclear@11 528
nuclear@11 529 vert_arr[num_verts].x = x;
nuclear@11 530 vert_arr[num_verts].y = y;
nuclear@11 531 vert_arr[num_verts].z = z;
nuclear@11 532 vert_arr[num_verts].w = w;
nuclear@11 533
nuclear@11 534 if(cloc != -1) {
nuclear@11 535 col_arr[num_verts] = cur_color;
nuclear@11 536 }
nuclear@11 537 if(nloc != -1) {
nuclear@11 538 norm_arr[num_verts] = cur_normal;
nuclear@11 539 }
nuclear@11 540 if(tloc != -1) {
nuclear@11 541 texc_arr[num_verts] = cur_texcoord;
nuclear@11 542 }
nuclear@11 543 if(aloc != -1) {
nuclear@11 544 attr_arr[num_verts] = cur_attrib;
nuclear@11 545 }
nuclear@11 546
nuclear@11 547 vert_calls++;
nuclear@11 548 num_verts++;
nuclear@11 549
nuclear@11 550 if(prim == GL_QUADS) {
nuclear@11 551 /* leave space for 6 more worst-case and don't allow flushes mid-quad */
nuclear@11 552 buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0;
nuclear@11 553 } else {
nuclear@11 554 buffer_full = num_verts >= MAX_VERTS - prim;
nuclear@11 555 }
nuclear@11 556
nuclear@11 557 if(buffer_full) {
nuclear@11 558 gl_draw_immediate();
nuclear@11 559 gl_begin(prim); /* reset everything */
nuclear@11 560 }
nuclear@11 561 }
nuclear@11 562
nuclear@11 563
nuclear@11 564 void gl_normal3f(float x, float y, float z)
nuclear@11 565 {
nuclear@11 566 cur_normal.x = x;
nuclear@11 567 cur_normal.y = y;
nuclear@11 568 cur_normal.z = z;
nuclear@11 569 }
nuclear@11 570
nuclear@11 571
nuclear@11 572 void gl_color3f(float r, float g, float b)
nuclear@11 573 {
nuclear@11 574 cur_color.x = r;
nuclear@11 575 cur_color.y = g;
nuclear@11 576 cur_color.z = b;
nuclear@11 577 cur_color.w = 1.0f;
nuclear@11 578 }
nuclear@11 579
nuclear@11 580 void gl_color4f(float r, float g, float b, float a)
nuclear@11 581 {
nuclear@11 582 cur_color.x = r;
nuclear@11 583 cur_color.y = g;
nuclear@11 584 cur_color.z = b;
nuclear@11 585 cur_color.w = a;
nuclear@11 586 }
nuclear@11 587
nuclear@11 588
nuclear@11 589 void gl_texcoord1f(float s)
nuclear@11 590 {
nuclear@11 591 cur_texcoord.x = s;
nuclear@11 592 cur_texcoord.y = 0.0f;
nuclear@11 593 }
nuclear@11 594
nuclear@11 595 void gl_texcoord2f(float s, float t)
nuclear@11 596 {
nuclear@11 597 cur_texcoord.x = s;
nuclear@11 598 cur_texcoord.y = t;
nuclear@11 599 }
nuclear@11 600
nuclear@11 601 void gl_vertex_attrib2f(int loc, float x, float y)
nuclear@11 602 {
nuclear@11 603 aloc = loc;
nuclear@11 604 cur_attrib.x = x;
nuclear@11 605 cur_attrib.y = y;
nuclear@11 606 cur_attrib.z = 0.0f;
nuclear@11 607 cur_attrib.w = 1.0f;
nuclear@11 608 }
nuclear@11 609
nuclear@11 610 void gl_vertex_attrib3f(int loc, float x, float y, float z)
nuclear@11 611 {
nuclear@11 612 aloc = loc;
nuclear@11 613 cur_attrib.x = x;
nuclear@11 614 cur_attrib.y = y;
nuclear@11 615 cur_attrib.z = z;
nuclear@11 616 cur_attrib.w = 1.0f;
nuclear@11 617 }
nuclear@11 618
nuclear@11 619 void gl_vertex_attrib4f(int loc, float x, float y, float z, float w)
nuclear@11 620 {
nuclear@11 621 aloc = loc;
nuclear@11 622 cur_attrib.x = x;
nuclear@11 623 cur_attrib.y = y;
nuclear@11 624 cur_attrib.z = z;
nuclear@11 625 cur_attrib.w = w;
nuclear@11 626 }
nuclear@11 627
nuclear@11 628 #ifdef GLDEF
nuclear@11 629 #undef glGetFloatv
nuclear@11 630 #endif
nuclear@11 631
nuclear@11 632 void gl_get_floatv(int what, float *res)
nuclear@11 633 {
nuclear@11 634 int idx;
nuclear@11 635
nuclear@11 636 switch(what) {
nuclear@11 637 case GL_MODELVIEW_MATRIX:
nuclear@11 638 idx = MMODE_IDX(GL_MODELVIEW);
nuclear@11 639 memcpy(res, mat_stack[idx][stack_top[idx]], 16 * sizeof *res);
nuclear@11 640 break;
nuclear@11 641
nuclear@11 642 case GL_PROJECTION_MATRIX:
nuclear@11 643 idx = MMODE_IDX(GL_PROJECTION);
nuclear@11 644 memcpy(res, mat_stack[idx][stack_top[idx]], 16 * sizeof *res);
nuclear@11 645 break;
nuclear@11 646
nuclear@11 647 default:
nuclear@11 648 glGetFloatv(what, res);
nuclear@11 649 }
nuclear@11 650 }
nuclear@11 651
nuclear@11 652 void gl_get_doublev(int what, double *res)
nuclear@11 653 {
nuclear@11 654 int i, idx;
nuclear@11 655 float tmp[16];
nuclear@11 656
nuclear@11 657 switch(what) {
nuclear@11 658 case GL_MODELVIEW_MATRIX:
nuclear@11 659 if(1) {
nuclear@11 660 idx = MMODE_IDX(GL_MODELVIEW);
nuclear@11 661 } else {
nuclear@11 662 case GL_PROJECTION_MATRIX:
nuclear@11 663 idx = MMODE_IDX(GL_PROJECTION);
nuclear@11 664 }
nuclear@11 665 for(i=0; i<16; i++) {
nuclear@11 666 res[i] = mat_stack[idx][stack_top[idx]][i];
nuclear@11 667 }
nuclear@11 668 break;
nuclear@11 669
nuclear@11 670 default:
nuclear@11 671 glGetFloatv(what, tmp);
nuclear@11 672 for(i=0; i<16; i++) {
nuclear@11 673 res[i] = tmp[i];
nuclear@11 674 }
nuclear@11 675 }
nuclear@11 676 }
nuclear@11 677
nuclear@11 678
nuclear@11 679 /* ---- matrix inversion stuff ---- */
nuclear@11 680 static void m4_transpose(double *res, double *m)
nuclear@11 681 {
nuclear@11 682 int i, j;
nuclear@11 683 double tmp[16];
nuclear@11 684
nuclear@11 685 if(res == m) {
nuclear@11 686 memcpy(tmp, m, 16 * sizeof *m);
nuclear@11 687 m = tmp;
nuclear@11 688 }
nuclear@11 689
nuclear@11 690 for(i=0; i<4; i++) {
nuclear@11 691 for(j=0; j<4; j++) {
nuclear@11 692 res[M(i, j)] = m[M(j, i)];
nuclear@11 693 }
nuclear@11 694 }
nuclear@11 695 }
nuclear@11 696
nuclear@11 697 static double m4_determinant(double *m)
nuclear@11 698 {
nuclear@11 699 double det11, det12, det13, det14;
nuclear@11 700
nuclear@11 701 det11 = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
nuclear@11 702 (m[M(1, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) +
nuclear@11 703 (m[M(1, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)]));
nuclear@11 704
nuclear@11 705 det12 = (m[M(1, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
nuclear@11 706 (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
nuclear@11 707 (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)]));
nuclear@11 708
nuclear@11 709 det13 = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) -
nuclear@11 710 (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
nuclear@11 711 (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
nuclear@11 712
nuclear@11 713 det14 = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) -
nuclear@11 714 (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) +
nuclear@11 715 (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
nuclear@11 716
nuclear@11 717 return m[M(0, 0)] * det11 - m[M(0, 1)] * det12 + m[M(0, 2)] * det13 - m[M(0, 3)] * det14;
nuclear@11 718 }
nuclear@11 719
nuclear@11 720 static void m4_adjoint(double *res, double *m)
nuclear@11 721 {
nuclear@11 722 int i, j;
nuclear@11 723 double coef[16];
nuclear@11 724
nuclear@11 725 coef[M(0, 0)] = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
nuclear@11 726 (m[M(1, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) +
nuclear@11 727 (m[M(1, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)]));
nuclear@11 728 coef[M(0, 1)] = (m[M(1, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
nuclear@11 729 (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
nuclear@11 730 (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)]));
nuclear@11 731 coef[M(0, 2)] = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) -
nuclear@11 732 (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
nuclear@11 733 (m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
nuclear@11 734 coef[M(0, 3)] = (m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) -
nuclear@11 735 (m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) +
nuclear@11 736 (m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
nuclear@11 737
nuclear@11 738 coef[M(1, 0)] = (m[M(0, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
nuclear@11 739 (m[M(0, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) +
nuclear@11 740 (m[M(0, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)]));
nuclear@11 741 coef[M(1, 1)] = (m[M(0, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
nuclear@11 742 (m[M(0, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
nuclear@11 743 (m[M(0, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)]));
nuclear@11 744 coef[M(1, 2)] = (m[M(0, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) -
nuclear@11 745 (m[M(0, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
nuclear@11 746 (m[M(0, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
nuclear@11 747 coef[M(1, 3)] = (m[M(0, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) -
nuclear@11 748 (m[M(0, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) +
nuclear@11 749 (m[M(0, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
nuclear@11 750
nuclear@11 751 coef[M(2, 0)] = (m[M(0, 1)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(1, 3)])) -
nuclear@11 752 (m[M(0, 2)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(1, 3)])) +
nuclear@11 753 (m[M(0, 3)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(1, 2)]));
nuclear@11 754 coef[M(2, 1)] = (m[M(0, 0)] * (m[M(1, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(1, 3)])) -
nuclear@11 755 (m[M(0, 2)] * (m[M(1, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(1, 3)])) +
nuclear@11 756 (m[M(0, 3)] * (m[M(1, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(1, 2)]));
nuclear@11 757 coef[M(2, 2)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(1, 3)])) -
nuclear@11 758 (m[M(0, 1)] * (m[M(1, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(1, 3)])) +
nuclear@11 759 (m[M(0, 3)] * (m[M(1, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(1, 1)]));
nuclear@11 760 coef[M(2, 3)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(1, 2)])) -
nuclear@11 761 (m[M(0, 1)] * (m[M(1, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(1, 2)])) +
nuclear@11 762 (m[M(0, 2)] * (m[M(1, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(1, 1)]));
nuclear@11 763
nuclear@11 764 coef[M(3, 0)] = (m[M(0, 1)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(2, 2)] * m[M(1, 3)])) -
nuclear@11 765 (m[M(0, 2)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(2, 1)] * m[M(1, 3)])) +
nuclear@11 766 (m[M(0, 3)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(2, 1)] * m[M(1, 2)]));
nuclear@11 767 coef[M(3, 1)] = (m[M(0, 0)] * (m[M(1, 2)] * m[M(2, 3)] - m[M(2, 2)] * m[M(1, 3)])) -
nuclear@11 768 (m[M(0, 2)] * (m[M(1, 0)] * m[M(2, 3)] - m[M(2, 0)] * m[M(1, 3)])) +
nuclear@11 769 (m[M(0, 3)] * (m[M(1, 0)] * m[M(2, 2)] - m[M(2, 0)] * m[M(1, 2)]));
nuclear@11 770 coef[M(3, 2)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(2, 1)] * m[M(1, 3)])) -
nuclear@11 771 (m[M(0, 1)] * (m[M(1, 0)] * m[M(2, 3)] - m[M(2, 0)] * m[M(1, 3)])) +
nuclear@11 772 (m[M(0, 3)] * (m[M(1, 0)] * m[M(2, 1)] - m[M(2, 0)] * m[M(1, 1)]));
nuclear@11 773 coef[M(3, 3)] = (m[M(0, 0)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(2, 1)] * m[M(1, 2)])) -
nuclear@11 774 (m[M(0, 1)] * (m[M(1, 0)] * m[M(2, 2)] - m[M(2, 0)] * m[M(1, 2)])) +
nuclear@11 775 (m[M(0, 2)] * (m[M(1, 0)] * m[M(2, 1)] - m[M(2, 0)] * m[M(1, 1)]));
nuclear@11 776
nuclear@11 777 m4_transpose(res, coef);
nuclear@11 778
nuclear@11 779 for(i=0; i<4; i++) {
nuclear@11 780 for(j=0; j<4; j++) {
nuclear@11 781 res[M(i, j)] = j % 2 ? -res[M(i, j)] : res[M(i, j)];
nuclear@11 782 if(i % 2) res[M(i, j)] = -res[M(i, j)];
nuclear@11 783 }
nuclear@11 784 }
nuclear@11 785 }
nuclear@11 786
nuclear@11 787 static void m4_inverse(double *res, double *m)
nuclear@11 788 {
nuclear@11 789 int i, j;
nuclear@11 790 double adj[16];
nuclear@11 791 double det;
nuclear@11 792
nuclear@11 793 m4_adjoint(adj, m);
nuclear@11 794 det = m4_determinant(m);
nuclear@11 795
nuclear@11 796 for(i=0; i<4; i++) {
nuclear@11 797 for(j=0; j<4; j++) {
nuclear@11 798 res[M(i, j)] = adj[M(i, j)] / det;
nuclear@11 799 }
nuclear@11 800 }
nuclear@11 801 }
nuclear@11 802