3dphotoshoot

changeset 11:ad49e1f9b627

foo
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 31 May 2015 06:02:08 +0300
parents c71c477521ca
children abe7960e4a77
files src/game.c src/gfxstate.cc src/gfxstate.h src/opengl.c src/opengl.h src/sanegl.c src/sanegl.h
diffstat 7 files changed, 1031 insertions(+), 128 deletions(-) [+]
line diff
     1.1 --- a/src/game.c	Sun May 31 00:40:26 2015 +0300
     1.2 +++ b/src/game.c	Sun May 31 06:02:08 2015 +0300
     1.3 @@ -1,10 +1,12 @@
     1.4  #include <stdio.h>
     1.5  #include <stdlib.h>
     1.6  #include <math.h>
     1.7 +#include <assert.h>
     1.8  #include "opengl.h"
     1.9  #include "game.h"
    1.10  #include "camera.h"
    1.11  #include "sdr.h"
    1.12 +#include "sanegl.h"
    1.13  
    1.14  static void draw_quad(float hsz, float vsz);
    1.15  
    1.16 @@ -13,22 +15,22 @@
    1.17  static int video_width, video_height;
    1.18  static float video_aspect;
    1.19  static unsigned int sdrprog;
    1.20 -static int aloc_vertex, aloc_texcoord, uloc_texmat, uloc_wmat, uloc_vmat, uloc_pmat;
    1.21 +static int aloc_vertex, aloc_texcoord, uloc_tex;
    1.22  
    1.23  static const char *vsdr_source =
    1.24 -	"attribute vec4 attr_pos, attr_tex;\n"
    1.25 -	"uniform mat4 world_matrix, proj_matrix, tex_matrix;\n"
    1.26 +	"attribute vec4 attr_vertex, attr_texcoord;\n"
    1.27 +	"uniform mat4 matrix_modelview, matrix_projection, matrix_texture;\n"
    1.28  	"varying vec4 tex_coords;\n"
    1.29  	"void main()\n"
    1.30  	"{\n"
    1.31 -	"\tmat4 mvp = proj_matrix * world_matrix;\n"
    1.32 -	"\tgl_Position = mvp * attr_pos;\n"
    1.33 -	"\ttex_coords = tex_matrix * attr_tex;\n"
    1.34 +	"\tmat4 mvp = matrix_projection * matrix_modelview;\n"
    1.35 +	"\tgl_Position = mvp * attr_vertex;\n"
    1.36 +	"\ttex_coords = matrix_texture * attr_texcoord;\n"
    1.37  	"}\n";
    1.38  
    1.39  static const char *psdr_source =
    1.40  	"#extension GL_OES_EGL_image_external : require\n"
    1.41 -	"precision lowp float;\n"
    1.42 +	"precision mediump float;\n"
    1.43  	"uniform samplerExternalOES tex;\n"
    1.44  	"varying vec4 tex_coords;\n"
    1.45  	"void main()\n"
    1.46 @@ -49,19 +51,18 @@
    1.47  
    1.48  	if(!(vsdr = create_vertex_shader(vsdr_source)))
    1.49  		return -1;
    1.50 +	assert(glGetError() == GL_NO_ERROR);
    1.51  	if(!(psdr = create_pixel_shader(psdr_source)))
    1.52  		return -1;
    1.53 +	assert(glGetError() == GL_NO_ERROR);
    1.54  	if(!(sdrprog = create_program_link(vsdr, psdr))) {
    1.55  		fprintf(stderr, "failed to create shader program\n");
    1.56  		return -1;
    1.57  	}
    1.58  	glUseProgram(sdrprog);
    1.59 -	aloc_vertex = glGetAttribLocation(sdrprog, "attr_pos");
    1.60 -	aloc_texcoord = glGetAttribLocation(sdrprog, "attr_tex");
    1.61 -	uloc_texmat = glGetUniformLocation(sdrprog, "tex_matrix");
    1.62 -	uloc_wmat = glGetUniformLocation(sdrprog, "world_matrix");
    1.63 -	uloc_vmat = glGetUniformLocation(sdrprog, "view_matrix");
    1.64 -	uloc_pmat = glGetUniformLocation(sdrprog, "proj_matrix");
    1.65 +	aloc_vertex = glGetAttribLocation(sdrprog, "attr_vertex");
    1.66 +	aloc_texcoord = glGetAttribLocation(sdrprog, "attr_texcoord");
    1.67 +	uloc_tex = glGetUniformLocation(sdrprog, "tex");
    1.68  
    1.69  	cam_start_video();
    1.70  	cam_video_size(&video_width, &video_height);
    1.71 @@ -96,9 +97,16 @@
    1.72  	//glClearColor(sin(tsec * 10.0), cos(tsec * 10.0), -sin(tsec * 10.0), 1.0);
    1.73  	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    1.74  
    1.75 +	gl_matrix_mode(GL_MODELVIEW);
    1.76 +	gl_load_identity();
    1.77 +	gl_matrix_mode(GL_TEXTURE);
    1.78 +	gl_load_matrixf(tex_matrix);
    1.79 +
    1.80  	glUseProgram(sdrprog);
    1.81 -	glUniformMatrix4fv(uloc_texmat, 1, 0, tex_matrix);
    1.82  	glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
    1.83 +	if(uloc_tex >= 0) {
    1.84 +		glUniform1i(uloc_tex, 0);
    1.85 +	}
    1.86  
    1.87  	if(video_aspect > win_aspect) {
    1.88  		xscale = 1.0;
    1.89 @@ -114,19 +122,20 @@
    1.90  {
    1.91  	static const float varr[] = {-1, -1, 1, -1, 1, 1, -1, 1};
    1.92  	static const float tcarr[] = {0, 0, 1, 0, 1, 1, 0, 1};
    1.93 -	float xform[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
    1.94  
    1.95  	if(aloc_vertex == -1) {
    1.96  		return;
    1.97  	}
    1.98  
    1.99 -	xform[0] = hsz;
   1.100 -	xform[5] = vsz;
   1.101 -	glUniformMatrix4fv(uloc_wmat, 1, 0, xform);
   1.102 +	gl_matrix_mode(GL_MODELVIEW);
   1.103 +	gl_push_matrix();
   1.104 +	gl_scalef(hsz, vsz, 1);
   1.105 +
   1.106 +	gl_apply_xform(sdrprog);
   1.107  
   1.108  	glEnableVertexAttribArray(aloc_vertex);
   1.109  	glVertexAttribPointer(aloc_vertex, 2, GL_FLOAT, 0, 0, varr);
   1.110 -	if(aloc_texcoord) {
   1.111 +	if(aloc_texcoord != -1) {
   1.112  		glEnableVertexAttribArray(aloc_texcoord);
   1.113  		glVertexAttribPointer(aloc_texcoord, 2, GL_FLOAT, 0, 0, tcarr);
   1.114  	}
   1.115 @@ -134,9 +143,11 @@
   1.116  	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
   1.117  
   1.118  	glDisableVertexAttribArray(aloc_vertex);
   1.119 -	if(aloc_texcoord) {
   1.120 +	if(aloc_texcoord != -1) {
   1.121  		glDisableVertexAttribArray(aloc_texcoord);
   1.122  	}
   1.123 +
   1.124 +	gl_pop_matrix();
   1.125  }
   1.126  
   1.127  void game_reshape(int x, int y)
   1.128 @@ -146,9 +157,9 @@
   1.129  	win_aspect = y ? (float)x / (float)y : 1.0;
   1.130  	glViewport(0, 0, x, y);
   1.131  
   1.132 -	/*glMatrixMode(GL_PROJECTION);
   1.133 -	glLoadIdentity();
   1.134 -	glScalef((float)win_height / (float)win_width, 1.0, 1.0);*/
   1.135 +	gl_matrix_mode(GL_PROJECTION);
   1.136 +	gl_load_identity();
   1.137 +	gl_scalef((float)win_height / (float)win_width, 1, 1);
   1.138  }
   1.139  
   1.140  void game_keyboard(int key, int pressed)
     2.1 --- a/src/gfxstate.cc	Sun May 31 00:40:26 2015 +0300
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,68 +0,0 @@
     2.4 -#include <stack>
     2.5 -#include "vmath/vmath.h"
     2.6 -#include "gfxstate.h"
     2.7 -
     2.8 -static std::stack<Matrix4x4> mstack[NUM_MATRICES];
     2.9 -
    2.10 -static bool init_stack(int midx)
    2.11 -{
    2.12 -	if(mstack[midx].empty()) {
    2.13 -		mstack[midx].push(Matrix4x4::identity);
    2.14 -		return true;
    2.15 -	}
    2.16 -	return false;
    2.17 -}
    2.18 -
    2.19 -void push_matrix(int midx)
    2.20 -{
    2.21 -	init_stack(midx);
    2.22 -	mstack[midx].push(mstack[midx].top());
    2.23 -}
    2.24 -
    2.25 -void pop_matrix(int midx)
    2.26 -{
    2.27 -	if(!mstack[midx].empty()) {
    2.28 -		mstack[midx].pop();
    2.29 -	}
    2.30 -}
    2.31 -
    2.32 -void set_identity_matrix(int midx)
    2.33 -{
    2.34 -	set_matrix4x4(midx, Matrix4x4::identity);
    2.35 -}
    2.36 -
    2.37 -void set_matrix(int midx, const float *m)
    2.38 -{
    2.39 -	Matrix4x4 tmp;
    2.40 -	memcpy(tmp[0], m, 16 * sizeof *m);
    2.41 -	set_matrix4x4(midx, tmp.transposed());
    2.42 -}
    2.43 -
    2.44 -void mult_matrix(int midx, const float *m)
    2.45 -{
    2.46 -	Matrix4x4 tmp;
    2.47 -	memcpy(tmp[0], m, 16 * sizeof *m);
    2.48 -	mult_matrix4x4(midx, tmp.transposed());
    2.49 -}
    2.50 -
    2.51 -void get_matrix(int midx, float *m)
    2.52 -{
    2.53 -	Matrix4x4 tmp = get_matrix4x4(midx);
    2.54 -	tmp.transpose();
    2.55 -	memcpy(m, tmp[0], 16 * sizeof *m);
    2.56 -}
    2.57 -
    2.58 -void set_matrix4x4(int midx, const Matrix4x4 &m)
    2.59 -{
    2.60 -	mstack[midx].top() = m;
    2.61 -}
    2.62 -
    2.63 -void mult_matrix4x4(int midx, const Matrix4x4 &m)
    2.64 -{
    2.65 -	mstack[midx].top() *= m;
    2.66 -}
    2.67 -
    2.68 -Matrix4x4 &get_matrix4x4(int midx)
    2.69 -{
    2.70 -	return mstack[midx].top();
    2.71 -}
     3.1 --- a/src/gfxstate.h	Sun May 31 00:40:26 2015 +0300
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,37 +0,0 @@
     3.4 -#ifndef GFXSTATE_H_
     3.5 -#define GFXSTATE_H_
     3.6 -
     3.7 -enum {
     3.8 -	WORLD_MATRIX,
     3.9 -	VIEW_MATRIX,
    3.10 -	PROJECTION_MATRIX,
    3.11 -	TEXTURE_MATRIX,
    3.12 -
    3.13 -	NUM_MATRICES
    3.14 -};
    3.15 -
    3.16 -#ifdef __cplusplus
    3.17 -extern "C" {
    3.18 -#endif
    3.19 -
    3.20 -void push_matrix(int midx);
    3.21 -void pop_matrix(int midx);
    3.22 -
    3.23 -void set_identity_matrix(int midx);
    3.24 -void set_matrix(int midx, const float *m);
    3.25 -void mult_matrix(int midx, const float *m);
    3.26 -void get_matrix(int midx, float *m);
    3.27 -float *get_matrix_ptr(int midx);
    3.28 -
    3.29 -#ifdef __cplusplus
    3.30 -}
    3.31 -
    3.32 -#ifdef VMATH_MATRIX_H_
    3.33 -void set_matrix4x4(int midx, const Matrix4x4 &m);
    3.34 -void mult_matrix4x4(int midx, const Matrix4x4 &m);
    3.35 -Matrix4x4 &get_matrix4x4(int midx);
    3.36 -#endif	/* VMATH_MATRIX_H_ */
    3.37 -
    3.38 -#endif	/* __cplusplus */
    3.39 -
    3.40 -#endif	/* GFXSTATE_H_ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/opengl.c	Sun May 31 06:02:08 2015 +0300
     4.3 @@ -0,0 +1,21 @@
     4.4 +#include "opengl.h"
     4.5 +
     4.6 +static const char *errstr[] = {
     4.7 +	"GL_INVALID_ENUM",
     4.8 +	"GL_INVALID_VALUE",
     4.9 +	"GL_INVALID_OPERATION",
    4.10 +	"GL_STACK_OVERFLOW",
    4.11 +	"GL_STACK_UNDERFLOW",
    4.12 +	"GL_OUT_OF_MEMORY"
    4.13 +};
    4.14 +
    4.15 +const char *glerrstr(int err)
    4.16 +{
    4.17 +	if(!err) {
    4.18 +		return "no error";
    4.19 +	}
    4.20 +	if(err < GL_INVALID_ENUM || err > GL_OUT_OF_MEMORY) {
    4.21 +		return "unknown error";
    4.22 +	}
    4.23 +	return errstr[err - GL_INVALID_ENUM];
    4.24 +}
     5.1 --- a/src/opengl.h	Sun May 31 00:40:26 2015 +0300
     5.2 +++ b/src/opengl.h	Sun May 31 06:02:08 2015 +0300
     5.3 @@ -9,4 +9,24 @@
     5.4  #include <GL/glew.h>
     5.5  #endif
     5.6  
     5.7 +#define CHECK_GLERROR \
     5.8 +	do { \
     5.9 +		int err = glGetError(); \
    5.10 +		if(err) { \
    5.11 +			fprintf(stderr, "%s:%d: OpenGL error %d: %s\n", __FILE__, __LINE__, err, glerrstr(err)); \
    5.12 +			abort(); \
    5.13 +		} \
    5.14 +	} while(0)
    5.15 +
    5.16 +#ifdef __cplusplus
    5.17 +extern "C" {
    5.18 +#endif
    5.19 +
    5.20 +const char *glerrstr(int err);
    5.21 +
    5.22 +#ifdef __cplusplus
    5.23 +}
    5.24 +#endif
    5.25 +
    5.26 +
    5.27  #endif	/* OPENGL_H_ */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/sanegl.c	Sun May 31 06:02:08 2015 +0300
     6.3 @@ -0,0 +1,802 @@
     6.4 +/*
     6.5 +SaneGL - a small library to bring back sanity to OpenGL ES 2.x
     6.6 +Copyright (C) 2011-2013  John Tsiombikas <nuclear@member.fsf.org>
     6.7 +
     6.8 +This program is free software: you can redistribute it and/or modify
     6.9 +it under the terms of the GNU General Public License as published by
    6.10 +the Free Software Foundation, either version 3 of the License, or
    6.11 +(at your option) any later version.
    6.12 +
    6.13 +This program is distributed in the hope that it will be useful,
    6.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 +GNU General Public License for more details.
    6.17 +
    6.18 +You should have received a copy of the GNU General Public License
    6.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
    6.20 +*/
    6.21 +
    6.22 +#include <stdio.h>
    6.23 +#include <stdlib.h>
    6.24 +#include <string.h>
    6.25 +#include <math.h>
    6.26 +#include <assert.h>
    6.27 +#include "sanegl.h"
    6.28 +
    6.29 +#define MMODE_IDX(x)	((x) - GL_MODELVIEW)
    6.30 +#define MAT_STACK_SIZE	32
    6.31 +#define MAT_IDENT	{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}
    6.32 +
    6.33 +#define MAX_VERTS	512
    6.34 +
    6.35 +static void gl_draw_immediate(void);
    6.36 +static void m4_transpose(double *res, double *m);
    6.37 +static double m4_determinant(double *m);
    6.38 +static void m4_adjoint(double *res, double *m);
    6.39 +static void m4_inverse(double *res, double *m);
    6.40 +
    6.41 +
    6.42 +typedef struct { float x, y; } vec2_t;
    6.43 +typedef struct { float x, y, z; } vec3_t;
    6.44 +typedef struct { float x, y, z, w; } vec4_t;
    6.45 +
    6.46 +static int mm_idx = 0;
    6.47 +static float mat_stack[3][MAT_STACK_SIZE][16] = {{MAT_IDENT}, {MAT_IDENT}, {MAT_IDENT}};
    6.48 +static int stack_top[3];
    6.49 +static float mat_mvp[16];
    6.50 +static int mvp_valid;
    6.51 +static int prim = -1;
    6.52 +
    6.53 +static vec3_t cur_normal;
    6.54 +static vec4_t cur_color, cur_attrib;
    6.55 +static vec2_t cur_texcoord;
    6.56 +
    6.57 +static vec4_t *vert_arr, *col_arr, *attr_arr;
    6.58 +static vec3_t *norm_arr;
    6.59 +static vec2_t *texc_arr;
    6.60 +/*static unsigned int vbuf, cbuf, nbuf, tbuf, abuf;*/
    6.61 +static int vloc, nloc, cloc, tloc, aloc = -1;
    6.62 +
    6.63 +static int num_verts, vert_calls;
    6.64 +static int cur_prog;
    6.65 +
    6.66 +#ifdef GLDEF
    6.67 +#undef glEnable
    6.68 +#undef glDisable
    6.69 +#endif
    6.70 +
    6.71 +void gl_enable(int state)
    6.72 +{
    6.73 +	switch(state) {
    6.74 +	case GL_TEXTURE_2D:
    6.75 +		break;
    6.76 +
    6.77 +	default:
    6.78 +		glEnable(state);
    6.79 +	}
    6.80 +}
    6.81 +
    6.82 +void gl_disable(int state)
    6.83 +{
    6.84 +	switch(state) {
    6.85 +	case GL_TEXTURE_2D:
    6.86 +		glBindTexture(state, 0);
    6.87 +		break;
    6.88 +
    6.89 +	default:
    6.90 +		glDisable(state);
    6.91 +	}
    6.92 +}
    6.93 +
    6.94 +void gl_matrix_mode(int mm)
    6.95 +{
    6.96 +	mm_idx = MMODE_IDX(mm);
    6.97 +}
    6.98 +
    6.99 +void gl_push_matrix(void)
   6.100 +{
   6.101 +	int top = stack_top[mm_idx];
   6.102 +
   6.103 +	memcpy(mat_stack[mm_idx][top + 1], mat_stack[mm_idx][top], 16 * sizeof(float));
   6.104 +	stack_top[mm_idx]++;
   6.105 +	mvp_valid = 0;
   6.106 +}
   6.107 +
   6.108 +void gl_pop_matrix(void)
   6.109 +{
   6.110 +	stack_top[mm_idx]--;
   6.111 +	mvp_valid = 0;
   6.112 +}
   6.113 +
   6.114 +void gl_load_identity(void)
   6.115 +{
   6.116 +	static const float idmat[] = MAT_IDENT;
   6.117 +	int top = stack_top[mm_idx];
   6.118 +	float *mat = mat_stack[mm_idx][top];
   6.119 +
   6.120 +	memcpy(mat, idmat, sizeof idmat);
   6.121 +	mvp_valid = 0;
   6.122 +}
   6.123 +
   6.124 +void gl_load_matrixf(const float *m)
   6.125 +{
   6.126 +	int top = stack_top[mm_idx];
   6.127 +	float *mat = mat_stack[mm_idx][top];
   6.128 +
   6.129 +	memcpy(mat, m, 16 * sizeof *mat);
   6.130 +	mvp_valid = 0;
   6.131 +}
   6.132 +
   6.133 +void gl_load_matrixd(const double *m)
   6.134 +{
   6.135 +	int i;
   6.136 +	float mf[16];
   6.137 +
   6.138 +	for(i=0; i<16; i++) {
   6.139 +		mf[i] = (float)m[i];
   6.140 +	}
   6.141 +	gl_load_matrixf(mf);
   6.142 +}
   6.143 +
   6.144 +#define M(i, j)	((i << 2) + j)
   6.145 +
   6.146 +void gl_mult_matrixf(const float *m2)
   6.147 +{
   6.148 +	int i, j;
   6.149 +	int top = stack_top[mm_idx];
   6.150 +	float *m1 = mat_stack[mm_idx][top];
   6.151 +	float res[16];
   6.152 +
   6.153 +	for(i=0; i<4; i++) {
   6.154 +		for(j=0; j<4; j++) {
   6.155 +			res[M(i,j)] = m2[M(i,0)] * m1[M(0,j)] +
   6.156 +						m2[M(i,1)] * m1[M(1,j)] +
   6.157 +						m2[M(i,2)] * m1[M(2,j)] +
   6.158 +						m2[M(i,3)] * m1[M(3,j)];
   6.159 +		}
   6.160 +	}
   6.161 +
   6.162 +	memcpy(m1, res, sizeof res);
   6.163 +	mvp_valid = 0;
   6.164 +}
   6.165 +
   6.166 +void gl_mult_matrixd(const double *m)
   6.167 +{
   6.168 +	int i;
   6.169 +	float mf[16];
   6.170 +
   6.171 +	for(i=0; i<16; i++) {
   6.172 +		mf[i] = (float)m[i];
   6.173 +	}
   6.174 +	gl_mult_matrixf(mf);
   6.175 +}
   6.176 +
   6.177 +void gl_translatef(float x, float y, float z)
   6.178 +{
   6.179 +	float mat[] = MAT_IDENT;
   6.180 +
   6.181 +	mat[12] = x;
   6.182 +	mat[13] = y;
   6.183 +	mat[14] = z;
   6.184 +
   6.185 +	gl_mult_matrixf(mat);
   6.186 +}
   6.187 +
   6.188 +void gl_rotatef(float angle, float x, float y, float z)
   6.189 +{
   6.190 +	float mat[] = MAT_IDENT;
   6.191 +
   6.192 +	float angle_rad = M_PI * angle / 180.0;
   6.193 +	float sina = sin(angle_rad);
   6.194 +	float cosa = cos(angle_rad);
   6.195 +	float one_minus_cosa = 1.0 - cosa;
   6.196 +	float nxsq = x * x;
   6.197 +	float nysq = y * y;
   6.198 +	float nzsq = z * z;
   6.199 +
   6.200 +	mat[0] = nxsq + (1.0 - nxsq) * cosa;
   6.201 +	mat[4] = x * y * one_minus_cosa - z * sina;
   6.202 +	mat[8] = x * z * one_minus_cosa + y * sina;
   6.203 +	mat[1] = x * y * one_minus_cosa + z * sina;
   6.204 +	mat[5] = nysq + (1.0 - nysq) * cosa;
   6.205 +	mat[9] = y * z * one_minus_cosa - x * sina;
   6.206 +	mat[2] = x * z * one_minus_cosa - y * sina;
   6.207 +	mat[6] = y * z * one_minus_cosa + x * sina;
   6.208 +	mat[10] = nzsq + (1.0 - nzsq) * cosa;
   6.209 +
   6.210 +	gl_mult_matrixf(mat);
   6.211 +}
   6.212 +
   6.213 +void gl_scalef(float x, float y, float z)
   6.214 +{
   6.215 +	float mat[] = MAT_IDENT;
   6.216 +
   6.217 +	mat[0] = x;
   6.218 +	mat[5] = y;
   6.219 +	mat[10] = z;
   6.220 +
   6.221 +	gl_mult_matrixf(mat);
   6.222 +}
   6.223 +
   6.224 +void gl_ortho(float left, float right, float bottom, float top, float near, float far)
   6.225 +{
   6.226 +	float mat[] = MAT_IDENT;
   6.227 +
   6.228 +	float dx = right - left;
   6.229 +	float dy = top - bottom;
   6.230 +	float dz = far - near;
   6.231 +
   6.232 +	float tx = -(right + left) / dx;
   6.233 +	float ty = -(top + bottom) / dy;
   6.234 +	float tz = -(far + near) / dz;
   6.235 +
   6.236 +	float sx = 2.0 / dx;
   6.237 +	float sy = 2.0 / dy;
   6.238 +	float sz = -2.0 / dz;
   6.239 +
   6.240 +	mat[0] = sx;
   6.241 +	mat[5] = sy;
   6.242 +	mat[10] = sz;
   6.243 +	mat[12] = tx;
   6.244 +	mat[13] = ty;
   6.245 +	mat[14] = tz;
   6.246 +
   6.247 +	gl_mult_matrixf(mat);
   6.248 +}
   6.249 +
   6.250 +void gl_frustum(float left, float right, float bottom, float top, float near, float far)
   6.251 +{
   6.252 +	float mat[] = MAT_IDENT;
   6.253 +
   6.254 +	float dx = right - left;
   6.255 +	float dy = top - bottom;
   6.256 +	float dz = far - near;
   6.257 +
   6.258 +	float a = (right + left) / dx;
   6.259 +	float b = (top + bottom) / dy;
   6.260 +	float c = -(far + near) / dz;
   6.261 +	float d = -2.0 * far * near / dz;
   6.262 +
   6.263 +	mat[0] = 2.0 * near / dx;
   6.264 +	mat[5] = 2.0 * near / dy;
   6.265 +	mat[8] = a;
   6.266 +	mat[9] = b;
   6.267 +	mat[10] = c;
   6.268 +	mat[11] = -1.0;
   6.269 +	mat[14] = d;
   6.270 +	mat[15] = 0.0;
   6.271 +
   6.272 +	gl_mult_matrixf(mat);
   6.273 +}
   6.274 +
   6.275 +void glu_perspective(float vfov, float aspect, float near, float far)
   6.276 +{
   6.277 +	float vfov_rad = M_PI * vfov / 180.0;
   6.278 +	float x = near * tan(vfov_rad / 2.0);
   6.279 +	gl_frustum(-aspect * x, aspect * x, -x, x, near, far);
   6.280 +}
   6.281 +
   6.282 +int glu_un_project(double winx, double winy, double winz,
   6.283 +		const double *model, const double *proj, const int *viewp,
   6.284 +		double *objx, double *objy, double *objz)
   6.285 +{
   6.286 +	double mvp[16], inv_mvp[16];
   6.287 +
   6.288 +	double ndcx = 2.0 * (winx - viewp[0]) / viewp[2] - 1.0;
   6.289 +	double ndcy = 2.0 * (winy - viewp[1]) / viewp[3] - 1.0;
   6.290 +	double ndcz = 2.0 * winz - 1.0;
   6.291 +
   6.292 +	// calculate modelviewprojection
   6.293 +	gl_matrix_mode(GL_MODELVIEW);
   6.294 +	gl_push_matrix();
   6.295 +	gl_load_matrixd(proj);
   6.296 +	gl_mult_matrixd(model);
   6.297 +	gl_get_doublev(GL_MODELVIEW_MATRIX, mvp);
   6.298 +	gl_pop_matrix();
   6.299 +
   6.300 +	// invert modelviewprojection
   6.301 +	m4_inverse(inv_mvp, mvp);
   6.302 +
   6.303 +	// transform ndc by modelview -> obj
   6.304 +	/**objx = inv_mvp[0] * ndcx + inv_mvp[4] * ndcy + inv_mvp[8] * ndcz + inv_mvp[12];
   6.305 +	*objy = inv_mvp[1] * ndcx + inv_mvp[5] * ndcy + inv_mvp[9] * ndcz + inv_mvp[13];
   6.306 +	*objz = inv_mvp[2] * ndcx + inv_mvp[6] * ndcy + inv_mvp[10] * ndcz + inv_mvp[14];*/
   6.307 +	*objx = inv_mvp[0] * ndcx + inv_mvp[1] * ndcy + inv_mvp[2] * ndcz + inv_mvp[3];
   6.308 +	*objy = inv_mvp[4] * ndcx + inv_mvp[5] * ndcy + inv_mvp[6] * ndcz + inv_mvp[7];
   6.309 +	*objz = inv_mvp[8] * ndcx + inv_mvp[9] * ndcy + inv_mvp[10] * ndcz + inv_mvp[11];
   6.310 +	return 0;
   6.311 +}
   6.312 +
   6.313 +void gl_apply_xform(unsigned int prog)
   6.314 +{
   6.315 +	int loc, mvidx, pidx, tidx, mvtop, ptop, ttop;
   6.316 +
   6.317 +	mvidx = MMODE_IDX(GL_MODELVIEW);
   6.318 +	pidx = MMODE_IDX(GL_PROJECTION);
   6.319 +	tidx = MMODE_IDX(GL_TEXTURE);
   6.320 +
   6.321 +	mvtop = stack_top[mvidx];
   6.322 +	ptop = stack_top[pidx];
   6.323 +	ttop = stack_top[tidx];
   6.324 +
   6.325 +	assert(prog);
   6.326 +
   6.327 +	/*printf("APPLY XFORM\n");*/
   6.328 +
   6.329 +	CHECK_GLERROR;
   6.330 +	if((loc = glGetUniformLocation(prog, "matrix_modelview")) != -1) {
   6.331 +		CHECK_GLERROR;
   6.332 +		/*printf("  MODELVIEW:\n");
   6.333 +		for(i=0; i<16; i+=4) {
   6.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]);
   6.335 +		}*/
   6.336 +		glUniformMatrix4fv(loc, 1, 0, mat_stack[mvidx][mvtop]);
   6.337 +		CHECK_GLERROR;
   6.338 +	}
   6.339 +	CHECK_GLERROR;
   6.340 +
   6.341 +	if((loc = glGetUniformLocation(prog, "matrix_projection")) != -1) {
   6.342 +		CHECK_GLERROR;
   6.343 +		/*printf("  PROJECTION:\n");
   6.344 +		for(i=0; i<16; i+=4) {
   6.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]);
   6.346 +		}*/
   6.347 +		glUniformMatrix4fv(loc, 1, 0, mat_stack[pidx][ptop]);
   6.348 +		CHECK_GLERROR;
   6.349 +	}
   6.350 +	CHECK_GLERROR;
   6.351 +
   6.352 +	if((loc = glGetUniformLocation(prog, "matrix_texture")) != -1) {
   6.353 +		CHECK_GLERROR;
   6.354 +		glUniformMatrix4fv(loc, 1, 0, mat_stack[tidx][ttop]);
   6.355 +		CHECK_GLERROR;
   6.356 +	}
   6.357 +	CHECK_GLERROR;
   6.358 +
   6.359 +	if((loc = glGetUniformLocation(prog, "matrix_normal")) != -1) {
   6.360 +		float nmat[9];
   6.361 +
   6.362 +		CHECK_GLERROR;
   6.363 +
   6.364 +		nmat[0] = mat_stack[mvidx][mvtop][0];
   6.365 +		nmat[1] = mat_stack[mvidx][mvtop][1];
   6.366 +		nmat[2] = mat_stack[mvidx][mvtop][2];
   6.367 +		nmat[3] = mat_stack[mvidx][mvtop][4];
   6.368 +		nmat[4] = mat_stack[mvidx][mvtop][5];
   6.369 +		nmat[5] = mat_stack[mvidx][mvtop][6];
   6.370 +		nmat[6] = mat_stack[mvidx][mvtop][8];
   6.371 +		nmat[7] = mat_stack[mvidx][mvtop][9];
   6.372 +		nmat[8] = mat_stack[mvidx][mvtop][10];
   6.373 +		glUniformMatrix3fv(loc, 1, 0, nmat);
   6.374 +		CHECK_GLERROR;
   6.375 +	}
   6.376 +	CHECK_GLERROR;
   6.377 +
   6.378 +	if((loc = glGetUniformLocation(prog, "matrix_modelview_projection")) != -1) {
   6.379 +		CHECK_GLERROR;
   6.380 +		if(!mvp_valid) {
   6.381 +			/* TODO calc mvp */
   6.382 +		}
   6.383 +		glUniformMatrix4fv(loc, 1, 0, mat_mvp);
   6.384 +		CHECK_GLERROR;
   6.385 +	}
   6.386 +	CHECK_GLERROR;
   6.387 +}
   6.388 +
   6.389 +
   6.390 +/* immediate mode rendering */
   6.391 +void gl_begin(int p)
   6.392 +{
   6.393 +	if(!vert_arr) {
   6.394 +		vert_arr = malloc(MAX_VERTS * sizeof *vert_arr);
   6.395 +		norm_arr = malloc(MAX_VERTS * sizeof *norm_arr);
   6.396 +		texc_arr = malloc(MAX_VERTS * sizeof *texc_arr);
   6.397 +		col_arr = malloc(MAX_VERTS * sizeof *col_arr);
   6.398 +		attr_arr = malloc(MAX_VERTS * sizeof *attr_arr);
   6.399 +		assert(vert_arr && norm_arr && texc_arr && col_arr && attr_arr);
   6.400 +	}
   6.401 +
   6.402 +	prim = p;
   6.403 +	num_verts = vert_calls = 0;
   6.404 +
   6.405 +	glGetIntegerv(GL_CURRENT_PROGRAM, &cur_prog);
   6.406 +	CHECK_GLERROR;
   6.407 +	assert(cur_prog);
   6.408 +
   6.409 +	gl_apply_xform(cur_prog);
   6.410 +	CHECK_GLERROR;
   6.411 +
   6.412 +	vloc = glGetAttribLocation(cur_prog, "attr_vertex");
   6.413 +	CHECK_GLERROR;
   6.414 +	nloc = glGetAttribLocation(cur_prog, "attr_normal");
   6.415 +	CHECK_GLERROR;
   6.416 +	cloc = glGetAttribLocation(cur_prog, "attr_color");
   6.417 +	CHECK_GLERROR;
   6.418 +	tloc = glGetAttribLocation(cur_prog, "attr_texcoord");
   6.419 +	CHECK_GLERROR;
   6.420 +}
   6.421 +
   6.422 +void gl_end(void)
   6.423 +{
   6.424 +	if(num_verts > 0) {
   6.425 +		gl_draw_immediate();
   6.426 +	}
   6.427 +	aloc = -1;
   6.428 +}
   6.429 +
   6.430 +static void gl_draw_immediate(void)
   6.431 +{
   6.432 +	int glprim;
   6.433 +
   6.434 +	if(vloc == -1) {
   6.435 +		fprintf(stderr, "gl_draw_immediate call with vloc == -1\n");
   6.436 +		return;
   6.437 +	}
   6.438 +
   6.439 +	glprim = prim == GL_QUADS ? GL_TRIANGLES : prim;
   6.440 +
   6.441 +	CHECK_GLERROR;
   6.442 +	glVertexAttribPointer(vloc, 4, GL_FLOAT, 0, 0, vert_arr);
   6.443 +	CHECK_GLERROR;
   6.444 +	glEnableVertexAttribArray(vloc);
   6.445 +	CHECK_GLERROR;
   6.446 +
   6.447 +	if(nloc != -1) {
   6.448 +		glVertexAttribPointer(nloc, 3, GL_FLOAT, 0, 0, norm_arr);
   6.449 +		CHECK_GLERROR;
   6.450 +		glEnableVertexAttribArray(nloc);
   6.451 +		CHECK_GLERROR;
   6.452 +	}
   6.453 +
   6.454 +	if(cloc != -1) {
   6.455 +		glVertexAttribPointer(cloc, 4, GL_FLOAT, 1, 0, col_arr);
   6.456 +		CHECK_GLERROR;
   6.457 +		glEnableVertexAttribArray(cloc);
   6.458 +		CHECK_GLERROR;
   6.459 +	}
   6.460 +
   6.461 +	if(tloc != -1) {
   6.462 +		glVertexAttribPointer(tloc, 2, GL_FLOAT, 0, 0, texc_arr);
   6.463 +		CHECK_GLERROR;
   6.464 +		glEnableVertexAttribArray(tloc);
   6.465 +		CHECK_GLERROR;
   6.466 +	}
   6.467 +
   6.468 +	if(aloc != -1) {
   6.469 +		glVertexAttribPointer(aloc, 4, GL_FLOAT, 0, 0, attr_arr);
   6.470 +		CHECK_GLERROR;
   6.471 +		glEnableVertexAttribArray(aloc);
   6.472 +		CHECK_GLERROR;
   6.473 +	}
   6.474 +
   6.475 +	glDrawArrays(glprim, 0, num_verts);
   6.476 +	CHECK_GLERROR;
   6.477 +
   6.478 +	glDisableVertexAttribArray(vloc);
   6.479 +	CHECK_GLERROR;
   6.480 +	if(nloc != -1) {
   6.481 +		glDisableVertexAttribArray(nloc);
   6.482 +		CHECK_GLERROR;
   6.483 +	}
   6.484 +	if(cloc != -1) {
   6.485 +		glDisableVertexAttribArray(cloc);
   6.486 +		CHECK_GLERROR;
   6.487 +	}
   6.488 +	if(tloc != -1) {
   6.489 +		glDisableVertexAttribArray(tloc);
   6.490 +		CHECK_GLERROR;
   6.491 +	}
   6.492 +	if(aloc != -1) {
   6.493 +		glDisableVertexAttribArray(aloc);
   6.494 +		CHECK_GLERROR;
   6.495 +	}
   6.496 +}
   6.497 +
   6.498 +
   6.499 +void gl_vertex2f(float x, float y)
   6.500 +{
   6.501 +	gl_vertex4f(x, y, 0.0f, 1.0f);
   6.502 +}
   6.503 +
   6.504 +void gl_vertex3f(float x, float y, float z)
   6.505 +{
   6.506 +	gl_vertex4f(x, y, z, 1.0f);
   6.507 +}
   6.508 +
   6.509 +void gl_vertex4f(float x, float y, float z, float w)
   6.510 +{
   6.511 +	int i, buffer_full;
   6.512 +
   6.513 +	if(prim == GL_QUADS && vert_calls % 4 == 3) {
   6.514 +		for(i=0; i<2; i++) {
   6.515 +			if(aloc != -1) {
   6.516 +				attr_arr[num_verts] = attr_arr[num_verts - 3 + i];
   6.517 +			}
   6.518 +			if(cloc != -1) {
   6.519 +				col_arr[num_verts] = col_arr[num_verts - 3 + i];
   6.520 +			}
   6.521 +			if(tloc != -1) {
   6.522 +				texc_arr[num_verts] = texc_arr[num_verts - 3 + i];
   6.523 +			}
   6.524 +			if(nloc != -1) {
   6.525 +				norm_arr[num_verts] = norm_arr[num_verts - 3 + i];
   6.526 +			}
   6.527 +			vert_arr[num_verts] = vert_arr[num_verts - 3 + i];
   6.528 +			num_verts++;
   6.529 +		}
   6.530 +	}
   6.531 +
   6.532 +	vert_arr[num_verts].x = x;
   6.533 +	vert_arr[num_verts].y = y;
   6.534 +	vert_arr[num_verts].z = z;
   6.535 +	vert_arr[num_verts].w = w;
   6.536 +
   6.537 +	if(cloc != -1) {
   6.538 +		col_arr[num_verts] = cur_color;
   6.539 +	}
   6.540 +	if(nloc != -1) {
   6.541 +		norm_arr[num_verts] = cur_normal;
   6.542 +	}
   6.543 +	if(tloc != -1) {
   6.544 +		texc_arr[num_verts] = cur_texcoord;
   6.545 +	}
   6.546 +	if(aloc != -1) {
   6.547 +		attr_arr[num_verts] = cur_attrib;
   6.548 +	}
   6.549 +
   6.550 +	vert_calls++;
   6.551 +	num_verts++;
   6.552 +
   6.553 +	if(prim == GL_QUADS) {
   6.554 +		/* leave space for 6 more worst-case and don't allow flushes mid-quad */
   6.555 +		buffer_full = num_verts >= MAX_VERTS - 6 && vert_calls % 4 == 0;
   6.556 +	} else {
   6.557 +		buffer_full = num_verts >= MAX_VERTS - prim;
   6.558 +	}
   6.559 +
   6.560 +	if(buffer_full) {
   6.561 +		gl_draw_immediate();
   6.562 +		gl_begin(prim);	/* reset everything */
   6.563 +	}
   6.564 +}
   6.565 +
   6.566 +
   6.567 +void gl_normal3f(float x, float y, float z)
   6.568 +{
   6.569 +	cur_normal.x = x;
   6.570 +	cur_normal.y = y;
   6.571 +	cur_normal.z = z;
   6.572 +}
   6.573 +
   6.574 +
   6.575 +void gl_color3f(float r, float g, float b)
   6.576 +{
   6.577 +	cur_color.x = r;
   6.578 +	cur_color.y = g;
   6.579 +	cur_color.z = b;
   6.580 +	cur_color.w = 1.0f;
   6.581 +}
   6.582 +
   6.583 +void gl_color4f(float r, float g, float b, float a)
   6.584 +{
   6.585 +	cur_color.x = r;
   6.586 +	cur_color.y = g;
   6.587 +	cur_color.z = b;
   6.588 +	cur_color.w = a;
   6.589 +}
   6.590 +
   6.591 +
   6.592 +void gl_texcoord1f(float s)
   6.593 +{
   6.594 +	cur_texcoord.x = s;
   6.595 +	cur_texcoord.y = 0.0f;
   6.596 +}
   6.597 +
   6.598 +void gl_texcoord2f(float s, float t)
   6.599 +{
   6.600 +	cur_texcoord.x = s;
   6.601 +	cur_texcoord.y = t;
   6.602 +}
   6.603 +
   6.604 +void gl_vertex_attrib2f(int loc, float x, float y)
   6.605 +{
   6.606 +	aloc = loc;
   6.607 +	cur_attrib.x = x;
   6.608 +	cur_attrib.y = y;
   6.609 +	cur_attrib.z = 0.0f;
   6.610 +	cur_attrib.w = 1.0f;
   6.611 +}
   6.612 +
   6.613 +void gl_vertex_attrib3f(int loc, float x, float y, float z)
   6.614 +{
   6.615 +	aloc = loc;
   6.616 +	cur_attrib.x = x;
   6.617 +	cur_attrib.y = y;
   6.618 +	cur_attrib.z = z;
   6.619 +	cur_attrib.w = 1.0f;
   6.620 +}
   6.621 +
   6.622 +void gl_vertex_attrib4f(int loc, float x, float y, float z, float w)
   6.623 +{
   6.624 +	aloc = loc;
   6.625 +	cur_attrib.x = x;
   6.626 +	cur_attrib.y = y;
   6.627 +	cur_attrib.z = z;
   6.628 +	cur_attrib.w = w;
   6.629 +}
   6.630 +
   6.631 +#ifdef GLDEF
   6.632 +#undef glGetFloatv
   6.633 +#endif
   6.634 +
   6.635 +void gl_get_floatv(int what, float *res)
   6.636 +{
   6.637 +	int idx;
   6.638 +
   6.639 +	switch(what) {
   6.640 +	case GL_MODELVIEW_MATRIX:
   6.641 +		idx = MMODE_IDX(GL_MODELVIEW);
   6.642 +		memcpy(res, mat_stack[idx][stack_top[idx]], 16 * sizeof *res);
   6.643 +		break;
   6.644 +
   6.645 +	case GL_PROJECTION_MATRIX:
   6.646 +		idx = MMODE_IDX(GL_PROJECTION);
   6.647 +		memcpy(res, mat_stack[idx][stack_top[idx]], 16 * sizeof *res);
   6.648 +		break;
   6.649 +
   6.650 +	default:
   6.651 +		glGetFloatv(what, res);
   6.652 +	}
   6.653 +}
   6.654 +
   6.655 +void gl_get_doublev(int what, double *res)
   6.656 +{
   6.657 +	int i, idx;
   6.658 +	float tmp[16];
   6.659 +
   6.660 +	switch(what) {
   6.661 +	case GL_MODELVIEW_MATRIX:
   6.662 +		if(1) {
   6.663 +			idx = MMODE_IDX(GL_MODELVIEW);
   6.664 +		} else {
   6.665 +	case GL_PROJECTION_MATRIX:
   6.666 +			idx = MMODE_IDX(GL_PROJECTION);
   6.667 +		}
   6.668 +		for(i=0; i<16; i++) {
   6.669 +			res[i] = mat_stack[idx][stack_top[idx]][i];
   6.670 +		}
   6.671 +		break;
   6.672 +
   6.673 +	default:
   6.674 +		glGetFloatv(what, tmp);
   6.675 +		for(i=0; i<16; i++) {
   6.676 +			res[i] = tmp[i];
   6.677 +		}
   6.678 +	}
   6.679 +}
   6.680 +
   6.681 +
   6.682 +/* ---- matrix inversion stuff ---- */
   6.683 +static void m4_transpose(double *res, double *m)
   6.684 +{
   6.685 +	int i, j;
   6.686 +	double tmp[16];
   6.687 +
   6.688 +	if(res == m) {
   6.689 +		memcpy(tmp, m, 16 * sizeof *m);
   6.690 +		m = tmp;
   6.691 +	}
   6.692 +
   6.693 +	for(i=0; i<4; i++) {
   6.694 +		for(j=0; j<4; j++) {
   6.695 +			res[M(i, j)] = m[M(j, i)];
   6.696 +		}
   6.697 +	}
   6.698 +}
   6.699 +
   6.700 +static double m4_determinant(double *m)
   6.701 +{
   6.702 +	double det11, det12, det13, det14;
   6.703 +
   6.704 +	det11 = (m[M(1, 1)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
   6.705 +			(m[M(1, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) +
   6.706 +			(m[M(1, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)]));
   6.707 +
   6.708 +	det12 =	(m[M(1, 0)] * (m[M(2, 2)] * m[M(3, 3)] - m[M(3, 2)] * m[M(2, 3)])) -
   6.709 +			(m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
   6.710 +			(m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)]));
   6.711 +
   6.712 +	det13 =	(m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) -
   6.713 +			(m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
   6.714 +			(m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
   6.715 +
   6.716 +	det14 =	(m[M(1, 0)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)])) -
   6.717 +			(m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) +
   6.718 +			(m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
   6.719 +
   6.720 +	return m[M(0, 0)] * det11 - m[M(0, 1)] * det12 + m[M(0, 2)] * det13 - m[M(0, 3)] * det14;
   6.721 +}
   6.722 +
   6.723 +static void m4_adjoint(double *res, double *m)
   6.724 +{
   6.725 +	int i, j;
   6.726 +	double coef[16];
   6.727 +
   6.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)])) -
   6.729 +					(m[M(1, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) +
   6.730 +					(m[M(1, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)]));
   6.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)])) -
   6.732 +					(m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
   6.733 +					(m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)]));
   6.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)])) -
   6.735 +					(m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
   6.736 +					(m[M(1, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
   6.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)])) -
   6.738 +					(m[M(1, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) +
   6.739 +					(m[M(1, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
   6.740 +
   6.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)])) -
   6.742 +					(m[M(0, 2)] * (m[M(2, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(2, 3)])) +
   6.743 +					(m[M(0, 3)] * (m[M(2, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(2, 2)]));
   6.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)])) -
   6.745 +					(m[M(0, 2)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
   6.746 +					(m[M(0, 3)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)]));
   6.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)])) -
   6.748 +					(m[M(0, 1)] * (m[M(2, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(2, 3)])) +
   6.749 +					(m[M(0, 3)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
   6.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)])) -
   6.751 +					(m[M(0, 1)] * (m[M(2, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(2, 2)])) +
   6.752 +					(m[M(0, 2)] * (m[M(2, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(2, 1)]));
   6.753 +
   6.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)])) -
   6.755 +					(m[M(0, 2)] * (m[M(1, 1)] * m[M(3, 3)] - m[M(3, 1)] * m[M(1, 3)])) +
   6.756 +					(m[M(0, 3)] * (m[M(1, 1)] * m[M(3, 2)] - m[M(3, 1)] * m[M(1, 2)]));
   6.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)])) -
   6.758 +					(m[M(0, 2)] * (m[M(1, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(1, 3)])) +
   6.759 +					(m[M(0, 3)] * (m[M(1, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(1, 2)]));
   6.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)])) -
   6.761 +					(m[M(0, 1)] * (m[M(1, 0)] * m[M(3, 3)] - m[M(3, 0)] * m[M(1, 3)])) +
   6.762 +					(m[M(0, 3)] * (m[M(1, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(1, 1)]));
   6.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)])) -
   6.764 +					(m[M(0, 1)] * (m[M(1, 0)] * m[M(3, 2)] - m[M(3, 0)] * m[M(1, 2)])) +
   6.765 +					(m[M(0, 2)] * (m[M(1, 0)] * m[M(3, 1)] - m[M(3, 0)] * m[M(1, 1)]));
   6.766 +
   6.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)])) -
   6.768 +					(m[M(0, 2)] * (m[M(1, 1)] * m[M(2, 3)] - m[M(2, 1)] * m[M(1, 3)])) +
   6.769 +					(m[M(0, 3)] * (m[M(1, 1)] * m[M(2, 2)] - m[M(2, 1)] * m[M(1, 2)]));
   6.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)])) -
   6.771 +					(m[M(0, 2)] * (m[M(1, 0)] * m[M(2, 3)] - m[M(2, 0)] * m[M(1, 3)])) +
   6.772 +					(m[M(0, 3)] * (m[M(1, 0)] * m[M(2, 2)] - m[M(2, 0)] * m[M(1, 2)]));
   6.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)])) -
   6.774 +					(m[M(0, 1)] * (m[M(1, 0)] * m[M(2, 3)] - m[M(2, 0)] * m[M(1, 3)])) +
   6.775 +					(m[M(0, 3)] * (m[M(1, 0)] * m[M(2, 1)] - m[M(2, 0)] * m[M(1, 1)]));
   6.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)])) -
   6.777 +					(m[M(0, 1)] * (m[M(1, 0)] * m[M(2, 2)] - m[M(2, 0)] * m[M(1, 2)])) +
   6.778 +					(m[M(0, 2)] * (m[M(1, 0)] * m[M(2, 1)] - m[M(2, 0)] * m[M(1, 1)]));
   6.779 +
   6.780 +	m4_transpose(res, coef);
   6.781 +
   6.782 +	for(i=0; i<4; i++) {
   6.783 +		for(j=0; j<4; j++) {
   6.784 +			res[M(i, j)] = j % 2 ? -res[M(i, j)] : res[M(i, j)];
   6.785 +			if(i % 2) res[M(i, j)] = -res[M(i, j)];
   6.786 +		}
   6.787 +	}
   6.788 +}
   6.789 +
   6.790 +static void m4_inverse(double *res, double *m)
   6.791 +{
   6.792 +	int i, j;
   6.793 +	double adj[16];
   6.794 +	double det;
   6.795 +
   6.796 +	m4_adjoint(adj, m);
   6.797 +	det = m4_determinant(m);
   6.798 +
   6.799 +	for(i=0; i<4; i++) {
   6.800 +		for(j=0; j<4; j++) {
   6.801 +			res[M(i, j)] = adj[M(i, j)] / det;
   6.802 +		}
   6.803 +	}
   6.804 +}
   6.805 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/sanegl.h	Sun May 31 06:02:08 2015 +0300
     7.3 @@ -0,0 +1,154 @@
     7.4 +/*
     7.5 +SaneGL - a small library to bring back sanity to OpenGL ES 2.x
     7.6 +Copyright (C) 2011-2013  John Tsiombikas <nuclear@member.fsf.org>
     7.7 +
     7.8 +This program is free software: you can redistribute it and/or modify
     7.9 +it under the terms of the GNU General Public License as published by
    7.10 +the Free Software Foundation, either version 3 of the License, or
    7.11 +(at your option) any later version.
    7.12 +
    7.13 +This program is distributed in the hope that it will be useful,
    7.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.16 +GNU General Public License for more details.
    7.17 +
    7.18 +You should have received a copy of the GNU General Public License
    7.19 +along with this program.  If not, see <http://www.gnu.org/licenses/>.
    7.20 +*/
    7.21 +
    7.22 +#ifndef SANEGL_H_
    7.23 +#define SANEGL_H_
    7.24 +
    7.25 +#include "opengl.h"
    7.26 +
    7.27 +#ifndef GL_MODELVIEW
    7.28 +#define GL_MODELVIEW		0x1700
    7.29 +#endif
    7.30 +#ifndef GL_PROJECTION
    7.31 +#define GL_PROJECTION		0x1701
    7.32 +#endif
    7.33 +#ifndef GL_TEXTURE
    7.34 +#define GL_TEXTURE			0x1702
    7.35 +#endif
    7.36 +
    7.37 +#ifndef GL_POINTS
    7.38 +#define GL_POINTS			0
    7.39 +#endif
    7.40 +#ifndef GL_LINES
    7.41 +#define GL_LINES			1
    7.42 +#endif
    7.43 +#ifndef GL_TRIANGLES
    7.44 +#define GL_TRIANGLES		4
    7.45 +#endif
    7.46 +#ifndef GL_QUADS
    7.47 +#define GL_QUADS			7
    7.48 +#endif
    7.49 +
    7.50 +/* glGet stuff */
    7.51 +#ifndef GL_VIEWPORT
    7.52 +#define GL_VIEWPORT				0x0BA2
    7.53 +#endif
    7.54 +#ifndef GL_MODELVIEW_MATRIX
    7.55 +#define GL_MODELVIEW_MATRIX		0x0BA6
    7.56 +#endif
    7.57 +#ifndef GL_PROJECTION_MATRIX
    7.58 +#define GL_PROJECTION_MATRIX	0x0BA7
    7.59 +#endif
    7.60 +
    7.61 +#ifdef GLDEF
    7.62 +
    7.63 +#define glEnable			gl_enable
    7.64 +#define glDisable			gl_disable
    7.65 +
    7.66 +#define glMatrixMode		gl_matrix_mode
    7.67 +#define glPushMatrix		gl_push_matrix
    7.68 +#define glPopMatrix			gl_pop_matrix
    7.69 +#define glLoadIdentity		gl_load_identity
    7.70 +#define glLoadMatrixf		gl_load_matrixf
    7.71 +#define glLoadMatrixd		gl_load_matrixd
    7.72 +#define glMultMatrixf		gl_mult_matrixf
    7.73 +#define glMultMatrixd		gl_mult_matrixd
    7.74 +#define glTranslatef		gl_translatef
    7.75 +#define glRotatef			gl_rotatef
    7.76 +#define glScalef			gl_scalef
    7.77 +#define glOrtho				gl_ortho
    7.78 +#define glFrustum			gl_frustum
    7.79 +#define gluPerspective		glu_perspective
    7.80 +#define gluUnProject		glu_un_project
    7.81 +
    7.82 +#define glBegin				gl_begin
    7.83 +#define glEnd				gl_end
    7.84 +#define glVertex2f			gl_vertex2f
    7.85 +#define glVertex3f			gl_vertex3f
    7.86 +#define glVertex4f			gl_vertex4f
    7.87 +#define glNormal3f			gl_normal3f
    7.88 +#define glColor3f			gl_color3f
    7.89 +#define glColor4f			gl_color4f
    7.90 +#define glTexCoord1f		gl_texcoord1f
    7.91 +#define glTexCoord2f		gl_texcoord2f
    7.92 +#define glVertexAttrib2f	gl_vertex_attrib2f
    7.93 +#define glVertexAttrib3f	gl_vertex_attrib3f
    7.94 +#define glVertexAttrib4f	gl_vertex_attrib4f
    7.95 +
    7.96 +#define glGetFloatv			gl_get_floatv
    7.97 +#define glGetDoublev		gl_get_doublev
    7.98 +#endif
    7.99 +
   7.100 +#ifdef __cplusplus
   7.101 +extern "C" {
   7.102 +#endif
   7.103 +
   7.104 +void gl_enable(int state);
   7.105 +void gl_disable(int state);
   7.106 +
   7.107 +/* matrix stuff */
   7.108 +void gl_matrix_mode(int mmode);
   7.109 +void gl_push_matrix(void);
   7.110 +void gl_pop_matrix(void);
   7.111 +void gl_load_identity(void);
   7.112 +void gl_load_matrixf(const float *mat);
   7.113 +void gl_load_matrixd(const double *mat);
   7.114 +void gl_mult_matrixf(const float *mat);
   7.115 +void gl_mult_matrixd(const double *mat);
   7.116 +void gl_translatef(float x, float y, float z);
   7.117 +void gl_rotatef(float angle, float x, float y, float z);
   7.118 +void gl_scalef(float x, float y, float z);
   7.119 +void gl_ortho(float left, float right, float bottom, float top, float near, float far);
   7.120 +void gl_frustum(float left, float right, float bottom, float top, float near, float far);
   7.121 +void glu_perspective(float vfov, float aspect, float near, float far);
   7.122 +int glu_un_project(double winx, double winy, double winz,
   7.123 +		const double *model, const double *proj, const int *viewp,
   7.124 +		double *objx, double *objy, double *objz);
   7.125 +
   7.126 +void gl_apply_xform(unsigned int prog);
   7.127 +
   7.128 +
   7.129 +/* immediate mode rendering */
   7.130 +void gl_begin(int prim);
   7.131 +void gl_end(void);
   7.132 +
   7.133 +void gl_vertex2f(float x, float y);
   7.134 +void gl_vertex3f(float x, float y, float z);
   7.135 +void gl_vertex4f(float x, float y, float z, float w);
   7.136 +
   7.137 +void gl_normal3f(float x, float y, float z);
   7.138 +
   7.139 +void gl_color3f(float r, float g, float b);
   7.140 +void gl_color4f(float r, float g, float b, float a);
   7.141 +
   7.142 +void gl_texcoord1f(float s);
   7.143 +void gl_texcoord2f(float s, float t);
   7.144 +
   7.145 +void gl_vertex_attrib2f(int loc, float x, float y);
   7.146 +void gl_vertex_attrib3f(int loc, float x, float y, float z);
   7.147 +void gl_vertex_attrib4f(int loc, float x, float y, float z, float w);
   7.148 +
   7.149 +/* state retrieval */
   7.150 +void gl_get_floatv(int what, float *res);
   7.151 +void gl_get_doublev(int what, double *res);
   7.152 +
   7.153 +#ifdef __cplusplus
   7.154 +}
   7.155 +#endif
   7.156 +
   7.157 +#endif	/* SANEGL_H_ */