istereo2
diff src/sanegl.c @ 2:81d35769f546
added the tunnel effect source
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 19 Sep 2015 05:51:51 +0300 |
parents | |
children | 3bccfc7d10fe |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/sanegl.c Sat Sep 19 05:51:51 2015 +0300 1.3 @@ -0,0 +1,490 @@ 1.4 +/* 1.5 +SaneGL - a small library to bring back sanity to OpenGL ES 2.x 1.6 +Copyright (C) 2011 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 + 1.37 +typedef struct { float x, y; } vec2_t; 1.38 +typedef struct { float x, y, z; } vec3_t; 1.39 +typedef struct { float x, y, z, w; } vec4_t; 1.40 + 1.41 +static int mm_idx = 0; 1.42 +static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}}; 1.43 +static int stack_top[3]; 1.44 +static float mat_mvp[16]; 1.45 +static int mvp_valid; 1.46 +static int prim = -1; 1.47 + 1.48 +static vec3_t cur_normal; 1.49 +static vec4_t cur_color, cur_attrib; 1.50 +static vec2_t cur_texcoord; 1.51 + 1.52 +static vec4_t *vert_arr, *col_arr, *attr_arr; 1.53 +static vec3_t *norm_arr; 1.54 +static vec2_t *texc_arr; 1.55 +/*static unsigned int vbuf, cbuf, nbuf, tbuf, abuf;*/ 1.56 +static int vloc, nloc, cloc, tloc, aloc = -1; 1.57 + 1.58 +static int num_verts, vert_calls; 1.59 +static int cur_prog; 1.60 + 1.61 + 1.62 +void gl_matrix_mode(int mm) 1.63 +{ 1.64 + mm_idx = MMODE_IDX(mm); 1.65 +} 1.66 + 1.67 +void gl_push_matrix(void) 1.68 +{ 1.69 + int top = stack_top[mm_idx]; 1.70 + 1.71 + memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float)); 1.72 + stack_top[mm_idx]++; 1.73 + mvp_valid = 0; 1.74 +} 1.75 + 1.76 +void gl_pop_matrix(void) 1.77 +{ 1.78 + stack_top[mm_idx]--; 1.79 + mvp_valid = 0; 1.80 +} 1.81 + 1.82 +void gl_load_identity(void) 1.83 +{ 1.84 + static const float idmat[] = MAT_IDENT; 1.85 + int top = stack_top[mm_idx]; 1.86 + float *mat = mat_stack[mm_idx][top]; 1.87 + 1.88 + memcpy(mat, idmat, sizeof idmat); 1.89 + mvp_valid = 0; 1.90 +} 1.91 + 1.92 +void gl_load_matrixf(const float *m) 1.93 +{ 1.94 + int top = stack_top[mm_idx]; 1.95 + float *mat = mat_stack[mm_idx][top]; 1.96 + 1.97 + memcpy(mat, m, 16 * sizeof *mat); 1.98 + mvp_valid = 0; 1.99 +} 1.100 + 1.101 +#define M(i, j) ((i << 2) + j) 1.102 + 1.103 +void gl_mult_matrixf(const float *m2) 1.104 +{ 1.105 + int i, j; 1.106 + int top = stack_top[mm_idx]; 1.107 + float *m1 = mat_stack[mm_idx][top]; 1.108 + float res[16]; 1.109 + 1.110 + for(i=0; i<4; i++) { 1.111 + for(j=0; j<4; j++) { 1.112 + res[M(i,j)] = m1[M(i,0)] * m2[M(0,j)] + 1.113 + m1[M(i,1)] * m2[M(1,j)] + 1.114 + m1[M(i,2)] * m2[M(2,j)] + 1.115 + m1[M(i,3)] * m2[M(3,j)]; 1.116 + } 1.117 + } 1.118 + 1.119 + memcpy(m1, res, sizeof res); 1.120 + mvp_valid = 0; 1.121 +} 1.122 + 1.123 +void gl_translatef(float x, float y, float z) 1.124 +{ 1.125 + float mat[] = MAT_IDENT; 1.126 + 1.127 + mat[12] = x; 1.128 + mat[13] = y; 1.129 + mat[14] = z; 1.130 + 1.131 + gl_mult_matrixf(mat); 1.132 +} 1.133 + 1.134 +void gl_rotatef(float angle, float x, float y, float z) 1.135 +{ 1.136 + float mat[] = MAT_IDENT; 1.137 + 1.138 + float angle_rad = M_PI * angle / 180.0; 1.139 + float sina = sin(angle_rad); 1.140 + float cosa = cos(angle_rad); 1.141 + float one_minus_cosa = 1.0 - cosa; 1.142 + float nxsq = x * x; 1.143 + float nysq = y * y; 1.144 + float nzsq = z * z; 1.145 + 1.146 + mat[0] = nxsq + (1.0 - nxsq) * cosa; 1.147 + mat[4] = x * y * one_minus_cosa - z * sina; 1.148 + mat[8] = x * z * one_minus_cosa + y * sina; 1.149 + mat[1] = x * y * one_minus_cosa + z * sina; 1.150 + mat[5] = nysq + (1.0 - nysq) * cosa; 1.151 + mat[9] = y * z * one_minus_cosa - x * sina; 1.152 + mat[2] = x * z * one_minus_cosa - y * sina; 1.153 + mat[6] = y * z * one_minus_cosa + x * sina; 1.154 + mat[10] = nzsq + (1.0 - nzsq) * cosa; 1.155 + 1.156 + gl_mult_matrixf(mat); 1.157 +} 1.158 + 1.159 +void gl_scalef(float x, float y, float z) 1.160 +{ 1.161 + float mat[] = MAT_IDENT; 1.162 + 1.163 + mat[0] = x; 1.164 + mat[5] = y; 1.165 + mat[10] = z; 1.166 + 1.167 + gl_mult_matrixf(mat); 1.168 +} 1.169 + 1.170 +void gl_ortho(float left, float right, float bottom, float top, float near, float far) 1.171 +{ 1.172 + float mat[] = MAT_IDENT; 1.173 + 1.174 + float dx = right - left; 1.175 + float dy = top - bottom; 1.176 + float dz = far - near; 1.177 + 1.178 + float tx = -(right + left) / dx; 1.179 + float ty = -(top + bottom) / dy; 1.180 + float tz = -(far + near) / dz; 1.181 + 1.182 + float sx = 2.0 / dx; 1.183 + float sy = 2.0 / dy; 1.184 + float sz = -2.0 / dz; 1.185 + 1.186 + mat[0] = sx; 1.187 + mat[5] = sy; 1.188 + mat[10] = sz; 1.189 + mat[12] = tx; 1.190 + mat[13] = ty; 1.191 + mat[14] = tz; 1.192 + 1.193 + gl_mult_matrixf(mat); 1.194 +} 1.195 + 1.196 +void gl_frustum(float left, float right, float bottom, float top, float near, float far) 1.197 +{ 1.198 + float mat[] = MAT_IDENT; 1.199 + 1.200 + float dx = right - left; 1.201 + float dy = top - bottom; 1.202 + float dz = far - near; 1.203 + 1.204 + float a = (right + left) / dx; 1.205 + float b = (top + bottom) / dy; 1.206 + float c = -(far + near) / dz; 1.207 + float d = -2.0 * far * near / dz; 1.208 + 1.209 + mat[0] = 2.0 * near / dx; 1.210 + mat[5] = 2.0 * near / dy; 1.211 + mat[8] = a; 1.212 + mat[9] = b; 1.213 + mat[10] = c; 1.214 + mat[11] = -1.0; 1.215 + mat[14] = d; 1.216 + 1.217 + gl_mult_matrixf(mat); 1.218 +} 1.219 + 1.220 +void glu_perspective(float vfov, float aspect, float near, float far) 1.221 +{ 1.222 + float vfov_rad = M_PI * vfov / 180.0; 1.223 + float x = near * tan(vfov_rad / 2.0); 1.224 + gl_frustum(-aspect * x, aspect * x, -x, x, near, far); 1.225 +} 1.226 + 1.227 +void gl_apply_xform(unsigned int prog) 1.228 +{ 1.229 + int loc, mvidx, pidx, tidx, mvtop, ptop, ttop; 1.230 + 1.231 + mvidx = MMODE_IDX(GL_MODELVIEW); 1.232 + pidx = MMODE_IDX(GL_PROJECTION); 1.233 + tidx = MMODE_IDX(GL_TEXTURE); 1.234 + 1.235 + mvtop = stack_top[mvidx]; 1.236 + ptop = stack_top[pidx]; 1.237 + ttop = stack_top[tidx]; 1.238 + 1.239 + assert(prog); 1.240 + 1.241 + if((loc = glGetUniformLocation(prog, "matrix_modelview")) != -1) { 1.242 + glUniformMatrix4fv(loc, 1, 0, mat_stack[mvidx][mvtop]); 1.243 + } 1.244 + 1.245 + if((loc = glGetUniformLocation(prog, "matrix_projection")) != -1) { 1.246 + glUniformMatrix4fv(loc, 1, 0, mat_stack[pidx][ptop]); 1.247 + } 1.248 + 1.249 + if((loc = glGetUniformLocation(prog, "matrix_texture")) != -1) { 1.250 + glUniformMatrix4fv(loc, 1, 0, mat_stack[tidx][ttop]); 1.251 + } 1.252 + 1.253 + if((loc = glGetUniformLocation(prog, "matrix_normal")) != -1) { 1.254 + float nmat[9]; 1.255 + 1.256 + nmat[0] = mat_stack[mvidx][mvtop][0]; 1.257 + nmat[1] = mat_stack[mvidx][mvtop][1]; 1.258 + nmat[2] = mat_stack[mvidx][mvtop][2]; 1.259 + nmat[3] = mat_stack[mvidx][mvtop][4]; 1.260 + nmat[4] = mat_stack[mvidx][mvtop][5]; 1.261 + nmat[5] = mat_stack[mvidx][mvtop][6]; 1.262 + nmat[6] = mat_stack[mvidx][mvtop][8]; 1.263 + nmat[7] = mat_stack[mvidx][mvtop][9]; 1.264 + nmat[8] = mat_stack[mvidx][mvtop][10]; 1.265 + glUniformMatrix3fv(loc, 1, 0, nmat); 1.266 + } 1.267 + 1.268 + if((loc = glGetUniformLocation(prog, "matrix_modelview_projection")) != -1) { 1.269 + if(!mvp_valid) { 1.270 + /* TODO calc mvp */ 1.271 + } 1.272 + glUniformMatrix4fv(loc, 1, 0, mat_mvp); 1.273 + } 1.274 +} 1.275 + 1.276 + 1.277 +/* immediate mode rendering */ 1.278 +void gl_begin(int p) 1.279 +{ 1.280 + if(!vert_arr) { 1.281 + vert_arr = malloc(MAX_VERTS * sizeof *vert_arr); 1.282 + norm_arr = malloc(MAX_VERTS * sizeof *norm_arr); 1.283 + texc_arr = malloc(MAX_VERTS * sizeof *texc_arr); 1.284 + col_arr = malloc(MAX_VERTS * sizeof *col_arr); 1.285 + attr_arr = malloc(MAX_VERTS * sizeof *attr_arr); 1.286 + assert(vert_arr && norm_arr && texc_arr && col_arr && attr_arr); 1.287 + } 1.288 + 1.289 + prim = p; 1.290 + num_verts = vert_calls = 0; 1.291 + 1.292 + glGetIntegerv(GL_CURRENT_PROGRAM, &cur_prog); 1.293 + assert(cur_prog); 1.294 + 1.295 + gl_apply_xform(cur_prog); 1.296 + 1.297 + vloc = glGetAttribLocation(cur_prog, "attr_vertex"); 1.298 + nloc = glGetAttribLocation(cur_prog, "attr_normal"); 1.299 + cloc = glGetAttribLocation(cur_prog, "attr_color"); 1.300 + tloc = glGetAttribLocation(cur_prog, "attr_texcoord"); 1.301 +} 1.302 + 1.303 +void gl_end(void) 1.304 +{ 1.305 + if(num_verts > 0) { 1.306 + gl_draw_immediate(); 1.307 + } 1.308 + aloc = -1; 1.309 +} 1.310 + 1.311 +static void gl_draw_immediate(void) 1.312 +{ 1.313 + int glprim; 1.314 + 1.315 + if(vloc == -1) { 1.316 + fprintf(stderr, "gl_draw_immediate call with vloc == -1\n"); 1.317 + return; 1.318 + } 1.319 + 1.320 + glprim = prim == GL_QUADS ? GL_TRIANGLES : prim; 1.321 + 1.322 + glVertexAttribPointer(vloc, 4, GL_FLOAT, 0, 0, vert_arr); 1.323 + glEnableVertexAttribArray(vloc); 1.324 + 1.325 + if(nloc != -1) { 1.326 + glVertexAttribPointer(nloc, 3, GL_FLOAT, 0, 0, norm_arr); 1.327 + glEnableVertexAttribArray(nloc); 1.328 + } 1.329 + 1.330 + if(cloc != -1) { 1.331 + glVertexAttribPointer(cloc, 4, GL_FLOAT, 1, 0, col_arr); 1.332 + glEnableVertexAttribArray(cloc); 1.333 + } 1.334 + 1.335 + if(tloc != -1) { 1.336 + glVertexAttribPointer(tloc, 2, GL_FLOAT, 0, 0, texc_arr); 1.337 + glEnableVertexAttribArray(tloc); 1.338 + } 1.339 + 1.340 + if(aloc != -1) { 1.341 + glVertexAttribPointer(aloc, 4, GL_FLOAT, 0, 0, attr_arr); 1.342 + glEnableVertexAttribArray(aloc); 1.343 + } 1.344 + 1.345 + glDrawArrays(glprim, 0, num_verts); 1.346 + 1.347 + glDisableVertexAttribArray(vloc); 1.348 + if(nloc != -1) { 1.349 + glDisableVertexAttribArray(nloc); 1.350 + } 1.351 + if(cloc != -1) { 1.352 + glDisableVertexAttribArray(cloc); 1.353 + } 1.354 + if(tloc != -1) { 1.355 + glDisableVertexAttribArray(tloc); 1.356 + } 1.357 + if(aloc != -1) { 1.358 + glDisableVertexAttribArray(aloc); 1.359 + } 1.360 +} 1.361 + 1.362 + 1.363 +void gl_vertex2f(float x, float y) 1.364 +{ 1.365 + gl_vertex4f(x, y, 0.0f, 1.0f); 1.366 +} 1.367 + 1.368 +void gl_vertex3f(float x, float y, float z) 1.369 +{ 1.370 + gl_vertex4f(x, y, z, 1.0f); 1.371 +} 1.372 + 1.373 +void gl_vertex4f(float x, float y, float z, float w) 1.374 +{ 1.375 + int i, buffer_full; 1.376 + 1.377 + if(prim == GL_QUADS && vert_calls % 4 == 3) { 1.378 + for(i=0; i<2; i++) { 1.379 + if(aloc != -1) { 1.380 + attr_arr[num_verts] = attr_arr[num_verts - 3 + i]; 1.381 + } 1.382 + if(cloc != -1) { 1.383 + col_arr[num_verts] = col_arr[num_verts - 3 + i]; 1.384 + } 1.385 + if(tloc != -1) { 1.386 + texc_arr[num_verts] = texc_arr[num_verts - 3 + i]; 1.387 + } 1.388 + if(nloc != -1) { 1.389 + norm_arr[num_verts] = norm_arr[num_verts - 3 + i]; 1.390 + } 1.391 + vert_arr[num_verts] = vert_arr[num_verts - 3 + i]; 1.392 + num_verts++; 1.393 + } 1.394 + } 1.395 + 1.396 + vert_arr[num_verts].x = x; 1.397 + vert_arr[num_verts].y = y; 1.398 + vert_arr[num_verts].z = z; 1.399 + vert_arr[num_verts].w = w; 1.400 + 1.401 + if(cloc != -1) { 1.402 + col_arr[num_verts] = cur_color; 1.403 + } 1.404 + if(nloc != -1) { 1.405 + norm_arr[num_verts] = cur_normal; 1.406 + } 1.407 + if(tloc != -1) { 1.408 + texc_arr[num_verts] = cur_texcoord; 1.409 + } 1.410 + if(aloc != -1) { 1.411 + attr_arr[num_verts] = cur_attrib; 1.412 + } 1.413 + 1.414 + vert_calls++; 1.415 + num_verts++; 1.416 + 1.417 + if(prim == GL_QUADS) { 1.418 + /* leave space for 6 more worst-case and don't allow flushes mid-quad */ 1.419 + buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0; 1.420 + } else { 1.421 + buffer_full = num_verts >= MAX_VERTS - prim; 1.422 + } 1.423 + 1.424 + if(buffer_full) { 1.425 + gl_draw_immediate(); 1.426 + gl_begin(prim); /* reset everything */ 1.427 + } 1.428 +} 1.429 + 1.430 + 1.431 +void gl_normal3f(float x, float y, float z) 1.432 +{ 1.433 + cur_normal.x = x; 1.434 + cur_normal.y = y; 1.435 + cur_normal.z = z; 1.436 +} 1.437 + 1.438 + 1.439 +void gl_color3f(float r, float g, float b) 1.440 +{ 1.441 + cur_color.x = r; 1.442 + cur_color.y = g; 1.443 + cur_color.z = b; 1.444 + cur_color.w = 1.0f; 1.445 +} 1.446 + 1.447 +void gl_color4f(float r, float g, float b, float a) 1.448 +{ 1.449 + cur_color.x = r; 1.450 + cur_color.y = g; 1.451 + cur_color.z = b; 1.452 + cur_color.w = a; 1.453 +} 1.454 + 1.455 + 1.456 +void gl_texcoord1f(float s) 1.457 +{ 1.458 + cur_texcoord.x = s; 1.459 + cur_texcoord.y = 0.0f; 1.460 +} 1.461 + 1.462 +void gl_texcoord2f(float s, float t) 1.463 +{ 1.464 + cur_texcoord.x = s; 1.465 + cur_texcoord.y = t; 1.466 +} 1.467 + 1.468 +void gl_vertex_attrib2f(int loc, float x, float y) 1.469 +{ 1.470 + aloc = loc; 1.471 + cur_attrib.x = x; 1.472 + cur_attrib.y = y; 1.473 + cur_attrib.z = 0.0f; 1.474 + cur_attrib.w = 1.0f; 1.475 +} 1.476 + 1.477 +void gl_vertex_attrib3f(int loc, float x, float y, float z) 1.478 +{ 1.479 + aloc = loc; 1.480 + cur_attrib.x = x; 1.481 + cur_attrib.y = y; 1.482 + cur_attrib.z = z; 1.483 + cur_attrib.w = 1.0f; 1.484 +} 1.485 + 1.486 +void gl_vertex_attrib4f(int loc, float x, float y, float z, float w) 1.487 +{ 1.488 + aloc = loc; 1.489 + cur_attrib.x = x; 1.490 + cur_attrib.y = y; 1.491 + cur_attrib.z = z; 1.492 + cur_attrib.w = w; 1.493 +}