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 +}