intravenous

changeset 3:94d4c60af435

some progress
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 22 Apr 2012 03:35:18 +0300
parents 472c28b8b875
children c6a6a64df6de
files sdr/vein.p.glsl sdr/vein.v.glsl src/cockpit.cc src/cockpit.h src/game.cc src/geom.cc src/geom.h src/main.cc src/opengl.cc src/opengl.h src/sdr.c src/sdr.h src/ship.cc src/ship.h src/sys.c src/sys.h src/tex.c src/tex.h src/vein.cc src/vein.h
diffstat 20 files changed, 748 insertions(+), 27 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/sdr/vein.p.glsl	Sun Apr 22 03:35:18 2012 +0300
     1.3 @@ -0,0 +1,15 @@
     1.4 +varying vec3 vpos, vnorm;
     1.5 +varying vec3 ldir, vdir;
     1.6 +
     1.7 +void main()
     1.8 +{
     1.9 +	vec3 n = normalize(vnorm);
    1.10 +	vec3 l = normalize(ldir);
    1.11 +	vec3 v = normalize(vdir);
    1.12 +	vec3 h = normalize(l + v);
    1.13 +
    1.14 +	vec3 diff = vec3(0.8, 0.25, 0.2) * max(dot(l, n), 0.0);
    1.15 +	vec3 spec = vec3(0.6, 0.4, 0.32) * pow(max(dot(h, n), 0.0), 60.0);
    1.16 +
    1.17 +	gl_FragColor = vec4(diff + spec, 1.0);
    1.18 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/sdr/vein.v.glsl	Sun Apr 22 03:35:18 2012 +0300
     2.3 @@ -0,0 +1,26 @@
     2.4 +attribute vec3 attr_tang;
     2.5 +
     2.6 +varying vec3 vpos, vnorm;
     2.7 +varying vec3 ldir, vdir;
     2.8 +
     2.9 +void main()
    2.10 +{
    2.11 +	gl_Position = ftransform();
    2.12 +	vpos = (gl_ModelViewMatrix * gl_Vertex).xyz;
    2.13 +	vec3 norm = gl_NormalMatrix * gl_Normal;
    2.14 +	vec3 tang = gl_NormalMatrix * attr_tang;
    2.15 +
    2.16 +	vec3 n = normalize(norm);
    2.17 +	vec3 t = normalize(tang);
    2.18 +	vec3 b = cross(n, t);
    2.19 +
    2.20 +	mat3 tbn_mat = mat3(
    2.21 +			t.x, b.x, n.x,
    2.22 +			t.y, b.y, n.y,
    2.23 +			t.z, b.z, n.z);
    2.24 +	ldir = tbn_mat * (gl_LightSource[0].position.xyz - vpos);
    2.25 +	vdir = tbn_mat * -vpos;
    2.26 +	vnorm = n;
    2.27 +
    2.28 +	gl_TexCoord[0] = gl_MultiTexCoord0;
    2.29 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/cockpit.cc	Sun Apr 22 03:35:18 2012 +0300
     3.3 @@ -0,0 +1,52 @@
     3.4 +#include "opengl.h"
     3.5 +#include "cockpit.h"
     3.6 +#include "tex.h"
     3.7 +
     3.8 +static unsigned int tex;
     3.9 +
    3.10 +bool cockpit_init()
    3.11 +{
    3.12 +	if(!(tex = load_texture("data/cockpit.png"))) {
    3.13 +		return false;
    3.14 +	}
    3.15 +	return true;
    3.16 +}
    3.17 +
    3.18 +void cockpit_destroy()
    3.19 +{
    3.20 +	free_texture(tex);
    3.21 +}
    3.22 +
    3.23 +void cockpit_draw()
    3.24 +{
    3.25 +	glPushAttrib(GL_ENABLE_BIT);
    3.26 +	glDisable(GL_LIGHTING);
    3.27 +
    3.28 +	glEnable(GL_BLEND);
    3.29 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    3.30 +
    3.31 +	bind_texture(tex);
    3.32 +
    3.33 +	glMatrixMode(GL_MODELVIEW);
    3.34 +	glPushMatrix();
    3.35 +	glLoadIdentity();
    3.36 +	glMatrixMode(GL_PROJECTION);
    3.37 +	glPushMatrix();
    3.38 +	glLoadIdentity();
    3.39 +
    3.40 +	glBegin(GL_QUADS);
    3.41 +	glColor3f(1, 1, 1);
    3.42 +	glTexCoord2f(0, 1); glVertex2f(-1, -1);
    3.43 +	glTexCoord2f(1, 1); glVertex2f(1, -1);
    3.44 +	glTexCoord2f(1, 0); glVertex2f(1, 1);
    3.45 +	glTexCoord2f(0, 0); glVertex2f(-1, 1);
    3.46 +	glEnd();
    3.47 +
    3.48 +	glPopMatrix();
    3.49 +	glMatrixMode(GL_MODELVIEW);
    3.50 +	glPopMatrix();
    3.51 +
    3.52 +	bind_texture(0);
    3.53 +
    3.54 +	glPopAttrib();
    3.55 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/cockpit.h	Sun Apr 22 03:35:18 2012 +0300
     4.3 @@ -0,0 +1,9 @@
     4.4 +#ifndef COCKPIT_H_
     4.5 +#define COCKPIT_H_
     4.6 +
     4.7 +bool cockpit_init();
     4.8 +void cockpit_destroy();
     4.9 +
    4.10 +void cockpit_draw();
    4.11 +
    4.12 +#endif	// COCKPIT_H_
     5.1 --- a/src/game.cc	Sat Apr 21 23:03:36 2012 +0300
     5.2 +++ b/src/game.cc	Sun Apr 22 03:35:18 2012 +0300
     5.3 @@ -4,6 +4,7 @@
     5.4  #include "vein.h"
     5.5  #include "ship.h"
     5.6  #include "camera.h"
     5.7 +#include "cockpit.h"
     5.8  
     5.9  static Vein *vein;
    5.10  static Ship ship;
    5.11 @@ -19,20 +20,28 @@
    5.12  {
    5.13  	glEnable(GL_DEPTH_TEST);
    5.14  	glEnable(GL_CULL_FACE);
    5.15 -	glEnable(GL_LIGHTING);
    5.16 -	glEnable(GL_LIGHT0);
    5.17  
    5.18  	float lpos[] = {-1, 1, 1, 0};
    5.19  	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
    5.20  
    5.21 -	// initialize the only level (vein)
    5.22 +	// initialize the cockpit
    5.23 +	if(!cockpit_init()) {
    5.24 +		return false;
    5.25 +	}
    5.26 +
    5.27 +	// initialize the only level
    5.28  	vein = new Vein;
    5.29 +	if(!vein->init()) {
    5.30 +		return false;
    5.31 +	}
    5.32  
    5.33  	return true;
    5.34  }
    5.35  
    5.36  void game_shutdown()
    5.37  {
    5.38 +	delete vein;
    5.39 +	cockpit_destroy();
    5.40  	exit(0);
    5.41  }
    5.42  
    5.43 @@ -54,19 +63,18 @@
    5.44  	if(keystate['s'] || keystate['S']) {
    5.45  		ship.accelerate(-1.0 * dt);
    5.46  	}
    5.47 -	// XXX change to mouselook
    5.48  	if(keystate['d'] || keystate['D']) {
    5.49 -		ship.turn(-1.0 * dt, 0.0);
    5.50 +		ship.accelerate_side(1.0 * dt);
    5.51  	}
    5.52  	if(keystate['a'] || keystate['A']) {
    5.53 -		ship.turn(1.0 * dt, 0.0);
    5.54 +		ship.accelerate_side(-1.0 * dt);
    5.55  	}
    5.56 -	if(keystate['e'] || keystate['E']) {
    5.57 +	/*if(keystate['e'] || keystate['E']) {
    5.58  		ship.turn(0.0, 1.0 * dt);
    5.59  	}
    5.60  	if(keystate['c'] || keystate['C']) {
    5.61  		ship.turn(0.0, -1.0 * dt);
    5.62 -	}
    5.63 +	}*/
    5.64  
    5.65  	ship.update(dt);
    5.66  
    5.67 @@ -76,14 +84,20 @@
    5.68  void game_draw()
    5.69  {
    5.70  	glMatrixMode(GL_MODELVIEW);
    5.71 -	dbgcam.use();
    5.72  
    5.73  	if(dbg_inside) {
    5.74  		load_gl_matrix(ship.get_matrix().inverse());
    5.75 +	} else {
    5.76 +		dbgcam.use();
    5.77  	}
    5.78  
    5.79  	vein->draw(ship.get_position());
    5.80 -	ship.dbg_draw();
    5.81 +
    5.82 +	if(!dbg_inside) {
    5.83 +		ship.dbg_draw();
    5.84 +	} else {
    5.85 +		cockpit_draw();
    5.86 +	}
    5.87  }
    5.88  
    5.89  void game_input_keyb(int key, int state)
    5.90 @@ -96,6 +110,13 @@
    5.91  
    5.92  		case '\b':
    5.93  			dbg_inside = !dbg_inside;
    5.94 +			if(dbg_inside) {
    5.95 +				glutPassiveMotionFunc(game_input_mmotion);
    5.96 +				glutSetCursor(GLUT_CURSOR_NONE);
    5.97 +			} else {
    5.98 +				glutPassiveMotionFunc(0);
    5.99 +				glutSetCursor(GLUT_CURSOR_INHERIT);
   5.100 +			}
   5.101  			break;
   5.102  
   5.103  		default:
   5.104 @@ -122,15 +143,28 @@
   5.105  
   5.106  void game_input_mmotion(int x, int y)
   5.107  {
   5.108 +	static bool ignore_next;
   5.109  	int dx = x - prev_x;
   5.110  	int dy = y - prev_y;
   5.111  	prev_x = x;
   5.112  	prev_y = y;
   5.113  
   5.114 -	if(bnstate[0]) {
   5.115 -		dbgcam.input_rotate(10.0 * dx / win_xsz, 10.0 * dy / win_ysz, 0);
   5.116 +	if(ignore_next) {
   5.117 +		ignore_next = false;
   5.118 +		return;
   5.119  	}
   5.120 -	if(bnstate[2]) {
   5.121 -		dbgcam.input_zoom(10.0 * dy / win_ysz);
   5.122 +
   5.123 +	if(dbg_inside) {
   5.124 +		ship.turn((float)-dx / win_xsz, (float)-dy / win_ysz);
   5.125 +
   5.126 +		ignore_next = true;
   5.127 +		glutWarpPointer(win_xsz / 2, win_ysz / 2);
   5.128 +	} else {
   5.129 +		if(bnstate[0]) {
   5.130 +			dbgcam.input_rotate(10.0 * dx / win_xsz, 10.0 * dy / win_ysz, 0);
   5.131 +		}
   5.132 +		if(bnstate[2]) {
   5.133 +			dbgcam.input_zoom(10.0 * dy / win_ysz);
   5.134 +		}
   5.135  	}
   5.136  }
     6.1 --- a/src/geom.cc	Sat Apr 21 23:03:36 2012 +0300
     6.2 +++ b/src/geom.cc	Sun Apr 22 03:35:18 2012 +0300
     6.3 @@ -7,7 +7,7 @@
     6.4  #define ELEM_TYPE		GL_DOUBLE
     6.5  #endif
     6.6  
     6.7 -void draw_mesh(unsigned int prim, int num_verts, const Vertex *vbuf, const unsigned int *ibuf)
     6.8 +void draw_mesh(unsigned int prim, int num_verts, const Vertex *vbuf, const unsigned int *ibuf, int attr_tang_loc)
     6.9  {
    6.10  	glEnableClientState(GL_VERTEX_ARRAY);
    6.11  	glVertexPointer(3, ELEM_TYPE, sizeof *vbuf, &vbuf->pos);
    6.12 @@ -18,6 +18,11 @@
    6.13  	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    6.14  	glTexCoordPointer(2, ELEM_TYPE, sizeof *vbuf, &vbuf->tc);
    6.15  
    6.16 +	if(attr_tang_loc >= 0) {
    6.17 +		glEnableVertexAttribArrayARB(attr_tang_loc);
    6.18 +		glVertexAttribPointerARB(attr_tang_loc, 3, ELEM_TYPE, GL_FALSE, sizeof *vbuf, &vbuf->tang);
    6.19 +	}
    6.20 +
    6.21  	if(ibuf) {
    6.22  		glDrawElements(prim, num_verts, GL_UNSIGNED_INT, ibuf);
    6.23  	} else {
    6.24 @@ -27,6 +32,10 @@
    6.25  	glDisableClientState(GL_VERTEX_ARRAY);
    6.26  	glDisableClientState(GL_NORMAL_ARRAY);
    6.27  	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    6.28 +
    6.29 +	if(attr_tang_loc >= 0) {
    6.30 +		glDisableVertexAttribArrayARB(attr_tang_loc);
    6.31 +	}
    6.32  #if 0
    6.33  	glBegin(GL_QUADS);
    6.34  	for(int i=0; i<count; i++) {
     7.1 --- a/src/geom.h	Sat Apr 21 23:03:36 2012 +0300
     7.2 +++ b/src/geom.h	Sun Apr 22 03:35:18 2012 +0300
     7.3 @@ -9,6 +9,6 @@
     7.4  	Vector2 tc;
     7.5  };
     7.6  
     7.7 -void draw_mesh(unsigned int prim, int count, const Vertex *vbuf, const unsigned int *ibuf);
     7.8 +void draw_mesh(unsigned int prim, int count, const Vertex *vbuf, const unsigned int *ibuf, int tang_attr_loc = -1);
     7.9  
    7.10  #endif	// GEOM_H_
     8.1 --- a/src/main.cc	Sat Apr 21 23:03:36 2012 +0300
     8.2 +++ b/src/main.cc	Sun Apr 22 03:35:18 2012 +0300
     8.3 @@ -30,6 +30,8 @@
     8.4  	glutMouseFunc(mouse);
     8.5  	glutMotionFunc(motion);
     8.6  
     8.7 +	glewInit();
     8.8 +
     8.9  	if(!game_init()) {
    8.10  		return 1;
    8.11  	}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/opengl.cc	Sun Apr 22 03:35:18 2012 +0300
     9.3 @@ -0,0 +1,39 @@
     9.4 +#include "opengl.h"
     9.5 +
     9.6 +void load_gl_matrix(const Matrix4x4 &mat)
     9.7 +{
     9.8 +#ifdef SINGLE_PRECISION_MATH
     9.9 +	if(glLoadTransposeMatrixfARB) {
    9.10 +		glLoadTransposeMatrixfARB((float*)&mat);
    9.11 +	} else {
    9.12 +		Matrix4x4 tmat = mat.transposed();
    9.13 +		glLoadMatrixf((float*)&tmat);
    9.14 +	}
    9.15 +#else
    9.16 +	if(glLoadTransposeMatrixdARB) {
    9.17 +		glLoadTransposeMatrixdARB((double*)&mat);
    9.18 +	} else {
    9.19 +		Matrix4x4 tmat = mat.transposed();
    9.20 +		glLoadMatrixd((double*)&tmat);
    9.21 +	}
    9.22 +#endif
    9.23 +}
    9.24 +
    9.25 +void mult_gl_matrix(const Matrix4x4 &mat)
    9.26 +{
    9.27 +#ifdef SINGLE_PRECISION_MATH
    9.28 +	if(glMultTransposeMatrixfARB) {
    9.29 +		glMultTransposeMatrixfARB((float*)&mat);
    9.30 +	} else {
    9.31 +		Matrix4x4 tmat = mat.transposed();
    9.32 +		glMultMatrixf((float*)&tmat);
    9.33 +	}
    9.34 +#else
    9.35 +	if(glMultTransposeMatrixdARB) {
    9.36 +		glMultTransposeMatrixdARB((double*)&mat);
    9.37 +	} else {
    9.38 +		Matrix4x4 tmat = mat.transposed();
    9.39 +		glMultMatrixd((double*)&tmat);
    9.40 +	}
    9.41 +#endif
    9.42 +}
    10.1 --- a/src/opengl.h	Sat Apr 21 23:03:36 2012 +0300
    10.2 +++ b/src/opengl.h	Sun Apr 22 03:35:18 2012 +0300
    10.3 @@ -9,9 +9,11 @@
    10.4  #include <GLUT/glut.h>
    10.5  #endif
    10.6  
    10.7 +#ifdef __cplusplus
    10.8  #include <vmath/vmath.h>
    10.9  
   10.10  void load_gl_matrix(const Matrix4x4 &mat);
   10.11  void mult_gl_matrix(const Matrix4x4 &mat);
   10.12 +#endif	/* __cplusplus */
   10.13  
   10.14  #endif	/* OPENGL_H_ */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/sdr.c	Sun Apr 22 03:35:18 2012 +0300
    11.3 @@ -0,0 +1,328 @@
    11.4 +#include <stdio.h>
    11.5 +#include <stdlib.h>
    11.6 +#include <string.h>
    11.7 +#include <errno.h>
    11.8 +#include <assert.h>
    11.9 +#include <GL/glew.h>
   11.10 +
   11.11 +#if defined(unix) || defined(__unix__)
   11.12 +#include <unistd.h>
   11.13 +#include <sys/stat.h>
   11.14 +#endif	/* unix */
   11.15 +
   11.16 +#include "sdr.h"
   11.17 +
   11.18 +unsigned int create_vertex_shader(const char *src)
   11.19 +{
   11.20 +	return create_shader(src, GL_VERTEX_SHADER);
   11.21 +}
   11.22 +
   11.23 +unsigned int create_pixel_shader(const char *src)
   11.24 +{
   11.25 +	return create_shader(src, GL_FRAGMENT_SHADER);
   11.26 +}
   11.27 +
   11.28 +unsigned int create_shader(const char *src, unsigned int sdr_type)
   11.29 +{
   11.30 +	unsigned int sdr;
   11.31 +	int success, info_len;
   11.32 +	char *info_str = 0;
   11.33 +	GLenum err;
   11.34 +
   11.35 +	sdr = glCreateShader(sdr_type);
   11.36 +	assert(glGetError() == GL_NO_ERROR);
   11.37 +	glShaderSource(sdr, 1, &src, 0);
   11.38 +	err = glGetError();
   11.39 +	assert(err == GL_NO_ERROR);
   11.40 +	glCompileShader(sdr);
   11.41 +	assert(glGetError() == GL_NO_ERROR);
   11.42 +
   11.43 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &success);
   11.44 +	assert(glGetError() == GL_NO_ERROR);
   11.45 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
   11.46 +	assert(glGetError() == GL_NO_ERROR);
   11.47 +
   11.48 +	if(info_len) {
   11.49 +		if((info_str = malloc(info_len + 1))) {
   11.50 +			glGetShaderInfoLog(sdr, info_len, 0, info_str);
   11.51 +			assert(glGetError() == GL_NO_ERROR);
   11.52 +		}
   11.53 +	}
   11.54 +
   11.55 +	if(success) {
   11.56 +		fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
   11.57 +	} else {
   11.58 +		fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
   11.59 +		glDeleteShader(sdr);
   11.60 +		sdr = 0;
   11.61 +	}
   11.62 +
   11.63 +	free(info_str);
   11.64 +	return sdr;
   11.65 +}
   11.66 +
   11.67 +void free_shader(unsigned int sdr)
   11.68 +{
   11.69 +	glDeleteShader(sdr);
   11.70 +}
   11.71 +
   11.72 +unsigned int load_vertex_shader(const char *fname)
   11.73 +{
   11.74 +	return load_shader(fname, GL_VERTEX_SHADER);
   11.75 +}
   11.76 +
   11.77 +unsigned int load_pixel_shader(const char *fname)
   11.78 +{
   11.79 +	return load_shader(fname, GL_FRAGMENT_SHADER);
   11.80 +}
   11.81 +
   11.82 +unsigned int load_shader(const char *fname, unsigned int sdr_type)
   11.83 +{
   11.84 +#if defined(unix) || defined(__unix__)
   11.85 +	struct stat st;
   11.86 +#endif
   11.87 +	unsigned int sdr;
   11.88 +	size_t filesize;
   11.89 +	FILE *fp;
   11.90 +	char *src;
   11.91 +
   11.92 +	if(!(fp = fopen(fname, "r"))) {
   11.93 +		fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
   11.94 +		return 0;
   11.95 +	}
   11.96 +
   11.97 +#if defined(unix) || defined(__unix__)
   11.98 +	fstat(fileno(fp), &st);
   11.99 +	filesize = st.st_size;
  11.100 +#else
  11.101 +	fseek(fp, 0, SEEK_END);
  11.102 +	filesize = ftell(fp);
  11.103 +	fseek(fp, 0, SEEK_SET);
  11.104 +#endif	/* unix */
  11.105 +
  11.106 +	if(!(src = malloc(filesize + 1))) {
  11.107 +		fclose(fp);
  11.108 +		return 0;
  11.109 +	}
  11.110 +	fread(src, 1, filesize, fp);
  11.111 +	src[filesize] = 0;
  11.112 +	fclose(fp);
  11.113 +
  11.114 +	fprintf(stderr, "compiling %s shader: %s... ", (sdr_type == GL_VERTEX_SHADER ? "vertex" : "pixel"), fname);
  11.115 +	sdr = create_shader(src, sdr_type);
  11.116 +
  11.117 +	free(src);
  11.118 +	return sdr;
  11.119 +}
  11.120 +
  11.121 +
  11.122 +unsigned int get_vertex_shader(const char *fname)
  11.123 +{
  11.124 +	return get_shader(fname, GL_VERTEX_SHADER);
  11.125 +}
  11.126 +
  11.127 +unsigned int get_pixel_shader(const char *fname)
  11.128 +{
  11.129 +	return get_shader(fname, GL_FRAGMENT_SHADER);
  11.130 +}
  11.131 +
  11.132 +unsigned int get_shader(const char *fname, unsigned int sdr_type)
  11.133 +{
  11.134 +	unsigned int sdr;
  11.135 +	if(!(sdr = load_shader(fname, sdr_type))) {
  11.136 +		return 0;
  11.137 +	}
  11.138 +	return sdr;
  11.139 +}
  11.140 +
  11.141 +
  11.142 +/* ---- gpu programs ---- */
  11.143 +
  11.144 +unsigned int create_program(void)
  11.145 +{
  11.146 +	unsigned int prog = glCreateProgram();
  11.147 +	assert(glGetError() == GL_NO_ERROR);
  11.148 +	return prog;
  11.149 +}
  11.150 +
  11.151 +unsigned int create_program_link(unsigned int vs, unsigned int ps)
  11.152 +{
  11.153 +	unsigned int prog;
  11.154 +
  11.155 +	if(!(prog = create_program())) {
  11.156 +		return 0;
  11.157 +	}
  11.158 +
  11.159 +	if(vs) {
  11.160 +		attach_shader(prog, vs);
  11.161 +		assert(glGetError() == GL_NO_ERROR);
  11.162 +	}
  11.163 +	if(ps) {
  11.164 +		attach_shader(prog, ps);
  11.165 +		assert(glGetError() == GL_NO_ERROR);
  11.166 +	}
  11.167 +
  11.168 +	if(link_program(prog) == -1) {
  11.169 +		free_program(prog);
  11.170 +		return 0;
  11.171 +	}
  11.172 +	return prog;
  11.173 +}
  11.174 +
  11.175 +unsigned int create_program_load(const char *vfile, const char *pfile)
  11.176 +{
  11.177 +	unsigned int vs = 0, ps = 0;
  11.178 +
  11.179 +	if(vfile && !(vs = get_vertex_shader(vfile))) {
  11.180 +		return 0;
  11.181 +	}
  11.182 +	if(pfile && !(ps = get_pixel_shader(pfile))) {
  11.183 +		return 0;
  11.184 +	}
  11.185 +	return create_program_link(vs, ps);
  11.186 +}
  11.187 +
  11.188 +void free_program(unsigned int sdr)
  11.189 +{
  11.190 +	glDeleteProgram(sdr);
  11.191 +}
  11.192 +
  11.193 +void attach_shader(unsigned int prog, unsigned int sdr)
  11.194 +{
  11.195 +	glAttachShader(prog, sdr);
  11.196 +	assert(glGetError() == GL_NO_ERROR);
  11.197 +}
  11.198 +
  11.199 +int link_program(unsigned int prog)
  11.200 +{
  11.201 +	int linked, info_len, retval = 0;
  11.202 +	char *info_str = 0;
  11.203 +
  11.204 +	glLinkProgram(prog);
  11.205 +	assert(glGetError() == GL_NO_ERROR);
  11.206 +	glGetProgramiv(prog, GL_LINK_STATUS, &linked);
  11.207 +	assert(glGetError() == GL_NO_ERROR);
  11.208 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
  11.209 +	assert(glGetError() == GL_NO_ERROR);
  11.210 +
  11.211 +	if(info_len) {
  11.212 +		if((info_str = malloc(info_len + 1))) {
  11.213 +			glGetProgramInfoLog(prog, info_len, 0, info_str);
  11.214 +			assert(glGetError() == GL_NO_ERROR);
  11.215 +		}
  11.216 +	}
  11.217 +
  11.218 +	if(linked) {
  11.219 +		fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
  11.220 +	} else {
  11.221 +		fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
  11.222 +		retval = -1;
  11.223 +	}
  11.224 +
  11.225 +	free(info_str);
  11.226 +	return retval;
  11.227 +}
  11.228 +
  11.229 +int bind_program(unsigned int prog)
  11.230 +{
  11.231 +	GLenum err;
  11.232 +
  11.233 +	glUseProgram(prog);
  11.234 +	if(prog && (err = glGetError()) != GL_NO_ERROR) {
  11.235 +		/* maybe the program is not linked, try linking first */
  11.236 +		if(err == GL_INVALID_OPERATION) {
  11.237 +			if(link_program(prog) == -1) {
  11.238 +				return -1;
  11.239 +			}
  11.240 +			glUseProgram(prog);
  11.241 +			return glGetError() == GL_NO_ERROR ? 0 : -1;
  11.242 +		}
  11.243 +		return -1;
  11.244 +	}
  11.245 +	return 0;
  11.246 +}
  11.247 +
  11.248 +/* ugly but I'm not going to write the same bloody code over and over */
  11.249 +#define BEGIN_UNIFORM_CODE \
  11.250 +	int loc, curr_prog; \
  11.251 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \
  11.252 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \
  11.253 +		return -1; \
  11.254 +	} \
  11.255 +	if((loc = glGetUniformLocation(prog, name)) != -1)
  11.256 +
  11.257 +#define END_UNIFORM_CODE \
  11.258 +	if((unsigned int)curr_prog != prog) { \
  11.259 +		bind_program(curr_prog); \
  11.260 +	} \
  11.261 +	return loc == -1 ? -1 : 0
  11.262 +
  11.263 +int set_uniform_int(unsigned int prog, const char *name, int val)
  11.264 +{
  11.265 +	BEGIN_UNIFORM_CODE {
  11.266 +		glUniform1i(loc, val);
  11.267 +	}
  11.268 +	END_UNIFORM_CODE;
  11.269 +}
  11.270 +
  11.271 +int set_uniform_float(unsigned int prog, const char *name, float val)
  11.272 +{
  11.273 +	BEGIN_UNIFORM_CODE {
  11.274 +		glUniform1f(loc, val);
  11.275 +	}
  11.276 +	END_UNIFORM_CODE;
  11.277 +}
  11.278 +
  11.279 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z)
  11.280 +{
  11.281 +	BEGIN_UNIFORM_CODE {
  11.282 +		glUniform3f(loc, x, y, z);
  11.283 +	}
  11.284 +	END_UNIFORM_CODE;
  11.285 +}
  11.286 +
  11.287 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w)
  11.288 +{
  11.289 +	BEGIN_UNIFORM_CODE {
  11.290 +		glUniform4f(loc, x, y, z, w);
  11.291 +	}
  11.292 +	END_UNIFORM_CODE;
  11.293 +}
  11.294 +
  11.295 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat)
  11.296 +{
  11.297 +	BEGIN_UNIFORM_CODE {
  11.298 +		glUniformMatrix4fv(loc, 1, GL_FALSE, mat);
  11.299 +	}
  11.300 +	END_UNIFORM_CODE;
  11.301 +}
  11.302 +
  11.303 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat)
  11.304 +{
  11.305 +	BEGIN_UNIFORM_CODE {
  11.306 +		glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
  11.307 +	}
  11.308 +	END_UNIFORM_CODE;
  11.309 +}
  11.310 +
  11.311 +int get_attrib_loc(unsigned int prog, const char *name)
  11.312 +{
  11.313 +	int loc, curr_prog;
  11.314 +
  11.315 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
  11.316 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) {
  11.317 +		return -1;
  11.318 +	}
  11.319 +
  11.320 +	loc = glGetAttribLocation(prog, (char*)name);
  11.321 +
  11.322 +	if((unsigned int)curr_prog != prog) {
  11.323 +		bind_program(curr_prog);
  11.324 +	}
  11.325 +	return loc;
  11.326 +}
  11.327 +
  11.328 +void set_attrib_float3(int attr_loc, float x, float y, float z)
  11.329 +{
  11.330 +	glVertexAttrib3f(attr_loc, x, y, z);
  11.331 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/sdr.h	Sun Apr 22 03:35:18 2012 +0300
    12.3 @@ -0,0 +1,49 @@
    12.4 +#ifndef SDR_H_
    12.5 +#define SDR_H_
    12.6 +
    12.7 +#ifdef __cplusplus
    12.8 +extern "C" {
    12.9 +#endif	/* __cplusplus */
   12.10 +
   12.11 +/* ---- shaders ---- */
   12.12 +unsigned int create_vertex_shader(const char *src);
   12.13 +unsigned int create_pixel_shader(const char *src);
   12.14 +unsigned int create_shader(const char *src, unsigned int sdr_type);
   12.15 +void free_shader(unsigned int sdr);
   12.16 +
   12.17 +unsigned int load_vertex_shader(const char *fname);
   12.18 +unsigned int load_pixel_shader(const char *fname);
   12.19 +unsigned int load_shader(const char *src, unsigned int sdr_type);
   12.20 +
   12.21 +unsigned int get_vertex_shader(const char *fname);
   12.22 +unsigned int get_pixel_shader(const char *fname);
   12.23 +unsigned int get_shader(const char *fname, unsigned int sdr_type);
   12.24 +
   12.25 +int add_shader(const char *fname, unsigned int sdr);
   12.26 +int remove_shader(const char *fname);
   12.27 +
   12.28 +/* ---- gpu programs ---- */
   12.29 +unsigned int create_program(void);
   12.30 +unsigned int create_program_link(unsigned int vs, unsigned int ps);
   12.31 +unsigned int create_program_load(const char *vfile, const char *pfile);
   12.32 +void free_program(unsigned int sdr);
   12.33 +
   12.34 +void attach_shader(unsigned int prog, unsigned int sdr);
   12.35 +int link_program(unsigned int prog);
   12.36 +int bind_program(unsigned int prog);
   12.37 +
   12.38 +int set_uniform_int(unsigned int prog, const char *name, int val);
   12.39 +int set_uniform_float(unsigned int prog, const char *name, float val);
   12.40 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z);
   12.41 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w);
   12.42 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat);
   12.43 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat);
   12.44 +
   12.45 +int get_attrib_loc(unsigned int prog, const char *name);
   12.46 +void set_attrib_float3(int attr_loc, float x, float y, float z);
   12.47 +
   12.48 +#ifdef __cplusplus
   12.49 +}
   12.50 +#endif	/* __cplusplus */
   12.51 +
   12.52 +#endif	/* SDR_H_ */
    13.1 --- a/src/ship.cc	Sat Apr 21 23:03:36 2012 +0300
    13.2 +++ b/src/ship.cc	Sun Apr 22 03:35:18 2012 +0300
    13.3 @@ -11,6 +11,11 @@
    13.4  	velocity += get_direction() * a;
    13.5  }
    13.6  
    13.7 +void Ship::accelerate_side(double a)
    13.8 +{
    13.9 +	velocity += get_right() * a;
   13.10 +}
   13.11 +
   13.12  void Ship::turn(double yaw, double pitch)
   13.13  {
   13.14  	Quaternion qyaw(Vector3(0, 1, 0), yaw);
   13.15 @@ -37,6 +42,12 @@
   13.16  	return dir.transformed(rot);
   13.17  }
   13.18  
   13.19 +Vector3 Ship::get_right() const
   13.20 +{
   13.21 +	static const Vector3 dir{1, 0, 0};
   13.22 +	return dir.transformed(rot);
   13.23 +}
   13.24 +
   13.25  Matrix4x4 Ship::get_matrix() const
   13.26  {
   13.27  	Matrix3x3 rmat = rot.get_rotation_matrix().transposed();
    14.1 --- a/src/ship.h	Sat Apr 21 23:03:36 2012 +0300
    14.2 +++ b/src/ship.h	Sun Apr 22 03:35:18 2012 +0300
    14.3 @@ -8,19 +8,20 @@
    14.4  private:
    14.5  	Vector3 pos, velocity;
    14.6  	Quaternion rot;
    14.7 -	//double theta, phi;
    14.8  	double friction;
    14.9  
   14.10  public:
   14.11  	Ship();
   14.12  
   14.13  	void accelerate(double a);
   14.14 +	void accelerate_side(double a);
   14.15  	void turn(double yaw, double pitch);
   14.16  
   14.17  	void update(time_sec_t dt);
   14.18  
   14.19  	const Vector3 &get_position() const;
   14.20  	Vector3 get_direction() const;
   14.21 +	Vector3 get_right() const;
   14.22  
   14.23  	Matrix4x4 get_matrix() const;
   14.24  
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/sys.c	Sun Apr 22 03:35:18 2012 +0300
    15.3 @@ -0,0 +1,20 @@
    15.4 +#include "sys.h"
    15.5 +
    15.6 +#if defined(__unix__)
    15.7 +#include <X11/Xlib.h>
    15.8 +#elif defined(WIN32)
    15.9 +#include <windows.h>
   15.10 +#elif defined(__APPLE__)
   15.11 +#error "not ported to mac yet"
   15.12 +#else
   15.13 +#error "unrecognized or unsupported platform"
   15.14 +#endif
   15.15 +
   15.16 +int sys_lock_mouse(void)
   15.17 +{
   15.18 +	return -1;
   15.19 +}
   15.20 +
   15.21 +void sys_unlock_mouse(void)
   15.22 +{
   15.23 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/sys.h	Sun Apr 22 03:35:18 2012 +0300
    16.3 @@ -0,0 +1,15 @@
    16.4 +#ifndef SYS_H_
    16.5 +#define SYS_H_
    16.6 +
    16.7 +#ifdef __cplusplus
    16.8 +extern "C" {
    16.9 +#endif
   16.10 +
   16.11 +int sys_lock_mouse(void);
   16.12 +void sys_unlock_mouse(void);
   16.13 +
   16.14 +#ifdef __cplusplus
   16.15 +}
   16.16 +#endif
   16.17 +
   16.18 +#endif	/* SYS_H_ */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/tex.c	Sun Apr 22 03:35:18 2012 +0300
    17.3 @@ -0,0 +1,65 @@
    17.4 +#include <imago2.h>
    17.5 +#include "opengl.h"
    17.6 +
    17.7 +static void bind_common(GLenum type, unsigned int tex, int tex_unit);
    17.8 +
    17.9 +unsigned int load_texture(const char *fname)
   17.10 +{
   17.11 +	unsigned int tex;
   17.12 +	struct img_pixmap img;
   17.13 +	int intfmt, fmt, type;
   17.14 +
   17.15 +	img_init(&img);
   17.16 +	if(img_load(&img, fname) == -1) {
   17.17 +		fprintf(stderr, "failed to load texture: %s\n", fname);
   17.18 +		return 0;
   17.19 +	}
   17.20 +	intfmt = img_glintfmt(&img);
   17.21 +	fmt = img_glfmt(&img);
   17.22 +	type = img_gltype(&img);
   17.23 +
   17.24 +	glGenTextures(1, &tex);
   17.25 +	glBindTexture(GL_TEXTURE_2D, tex);
   17.26 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   17.27 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   17.28 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   17.29 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
   17.30 +	glTexImage2D(GL_TEXTURE_2D, 0, intfmt, img.width, img.height, 0, fmt, type, img.pixels);
   17.31 +	img_destroy(&img);
   17.32 +	return tex;
   17.33 +}
   17.34 +
   17.35 +unsigned int load_texture_cube(const char *fname)
   17.36 +{
   17.37 +	/* TODO implement */
   17.38 +	return 0;
   17.39 +}
   17.40 +
   17.41 +void free_texture(unsigned int tex)
   17.42 +{
   17.43 +	if(tex && glIsTexture(tex)) {
   17.44 +		glDeleteTextures(1, &tex);
   17.45 +	}
   17.46 +}
   17.47 +
   17.48 +void bind_texture(unsigned int tex, int tex_unit)
   17.49 +{
   17.50 +	bind_common(GL_TEXTURE_2D, tex, tex_unit);
   17.51 +}
   17.52 +
   17.53 +void bind_texture_cube(unsigned int tex, int tex_unit)
   17.54 +{
   17.55 +	bind_common(GL_TEXTURE_CUBE_MAP, tex, tex_unit);
   17.56 +}
   17.57 +
   17.58 +static void bind_common(GLenum type, unsigned int tex, int tex_unit)
   17.59 +{
   17.60 +	glActiveTextureARB(GL_TEXTURE0 + (GLenum)tex_unit);
   17.61 +	if(tex) {
   17.62 +		glBindTexture(type, tex);
   17.63 +		glEnable(type);
   17.64 +	} else {
   17.65 +		glDisable(type);
   17.66 +	}
   17.67 +	glActiveTextureARB(GL_TEXTURE0);
   17.68 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/tex.h	Sun Apr 22 03:35:18 2012 +0300
    18.3 @@ -0,0 +1,21 @@
    18.4 +#ifndef TEX_H_
    18.5 +#define TEX_H_
    18.6 +
    18.7 +#ifdef __cplusplus
    18.8 +extern "C" {
    18.9 +#define TEX_DEFARG(arg, val) arg = val
   18.10 +#else
   18.11 +#define TEX_DEFARG(arg, val) arg
   18.12 +#endif
   18.13 +
   18.14 +unsigned int load_texture(const char *fname);
   18.15 +void free_texture(unsigned int tex);
   18.16 +
   18.17 +void bind_texture(unsigned int tex, int TEX_DEFARG(tex_unit, 0));
   18.18 +void bind_texture_cube(unsigned int tex, int TEX_DEFARG(tex_unit, 0));
   18.19 +
   18.20 +#ifdef __cplusplus
   18.21 +}
   18.22 +#endif
   18.23 +
   18.24 +#endif	/* TEX_H_ */
    19.1 --- a/src/vein.cc	Sat Apr 21 23:03:36 2012 +0300
    19.2 +++ b/src/vein.cc	Sun Apr 22 03:35:18 2012 +0300
    19.3 @@ -1,3 +1,4 @@
    19.4 +#include <stdio.h>
    19.5  #ifndef _MSC_VER
    19.6  #include <alloca.h>
    19.7  #else
    19.8 @@ -5,11 +6,12 @@
    19.9  #endif
   19.10  #include "vein.h"
   19.11  #include "geom.h"
   19.12 +#include "sdr.h"
   19.13  
   19.14  Vein::Vein()
   19.15  {
   19.16 -	gen_dist = 8.0;
   19.17 -	subdiv = 8;
   19.18 +	gen_dist = 16.0;
   19.19 +	subdiv = 16;
   19.20  	ring_subdiv = 16;
   19.21  	rad = 1.0;
   19.22  
   19.23 @@ -23,14 +25,16 @@
   19.24  
   19.25  Vector3 Vein::calc_center(const Vector3 &ppos) const
   19.26  {
   19.27 -	// TODO add variation
   19.28 -	return Vector3(0.0, 0.0, ppos.z);
   19.29 +	Vector3 pt{0, 0, ppos.z};
   19.30 +	pt.x = sin(ppos.z * 0.75);
   19.31 +	pt.y = cos(ppos.z * 0.2) * 0.6;
   19.32 +	return pt;
   19.33  }
   19.34  
   19.35  Vector3 Vein::calc_dir(const Vector3 &ppos) const
   19.36  {
   19.37 -	// TODO add variation
   19.38 -	return Vector3(0, 0, 1);
   19.39 +	Vector3 dir = calc_center(ppos + Vector3(0, 0, 0.01)) - calc_center(ppos - Vector3(0, 0, 0.01));
   19.40 +	return dir.normalized();
   19.41  }
   19.42  
   19.43  void Vein::build_idxbuf()
   19.44 @@ -53,6 +57,18 @@
   19.45  	}
   19.46  }
   19.47  
   19.48 +bool Vein::init()
   19.49 +{
   19.50 +	if(!(sdr = create_program_load("sdr/vein.v.glsl", "sdr/vein.p.glsl"))) {
   19.51 +		fprintf(stderr, "failed to load vein shaders\n");
   19.52 +		return false;
   19.53 +	}
   19.54 +	if((attr_tang_loc = get_attrib_loc(sdr, "attr_tang")) == -1) {
   19.55 +		fprintf(stderr, "can't find tangent attribute!\n");
   19.56 +	}
   19.57 +	return true;
   19.58 +}
   19.59 +
   19.60  void Vein::draw(const Vector3 &ppos) const
   19.61  {
   19.62  	float start_z = ppos.z - gen_dist / 2.0;
   19.63 @@ -75,16 +91,17 @@
   19.64  		up = cross_product(dir, right);
   19.65  
   19.66  		Matrix3x3 vrot{right, up, dir};
   19.67 -		//Quaternion vrot(dri, dtheta);
   19.68 +		vrot.transpose();
   19.69  
   19.70  		float theta = 0.0, dtheta = 2.0 * M_PI / ring_subdiv;
   19.71  		for(int j=0; j<ring_subdiv; j++) {
   19.72 -			Vector3 vec = Vector3{-cos(theta) * rad, sin(theta) * rad, 0.0} + cent;
   19.73 +			Vector3 vec = Vector3{-cos(theta) * rad, sin(theta) * rad, 0.0};
   19.74  			vec.transform(vrot);
   19.75 +			vec += cent;
   19.76  
   19.77  			vptr->pos = vec;
   19.78  			vptr->norm = cent - vec;
   19.79 -			vptr->tang = Vector3();	// TODO
   19.80 +			vptr->tang = dir;
   19.81  			vptr->tc = Vector2();	// TODO
   19.82  			vptr++;
   19.83  
   19.84 @@ -100,5 +117,7 @@
   19.85  	}
   19.86  
   19.87  	// awesome, now draw it
   19.88 -	draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf);
   19.89 +	bind_program(sdr);
   19.90 +	draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf, attr_tang_loc);
   19.91 +	bind_program(0);
   19.92  }
    20.1 --- a/src/vein.h	Sat Apr 21 23:03:36 2012 +0300
    20.2 +++ b/src/vein.h	Sun Apr 22 03:35:18 2012 +0300
    20.3 @@ -10,6 +10,8 @@
    20.4  	int subdiv, ring_subdiv;
    20.5  
    20.6  	unsigned int *idxbuf;
    20.7 +	unsigned int sdr;
    20.8 +	int attr_tang_loc;
    20.9  
   20.10  	Vector3 calc_center(const Vector3 &ppos) const;
   20.11  	Vector3 calc_dir(const Vector3 &ppos) const;
   20.12 @@ -20,6 +22,8 @@
   20.13  	Vein();
   20.14  	~Vein();
   20.15  
   20.16 +	bool init();
   20.17 +
   20.18  	void draw(const Vector3 &player_pos) const;
   20.19  };
   20.20