bloboland

changeset 1:cfe68befb7cc

some progress
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 15 Dec 2012 23:43:03 +0200
parents e4818a3300b9
children 1757973feaed
files .hgignore Makefile RUN src/camera.cc src/camera.h src/game.cc src/game.h src/level.cc src/level.h src/main.cc src/opt.cc src/opt.h src/renderer.cc src/renderer.h src/shaders.cc src/shaders.h src/texture.cc src/texture.h src/volume.h src/volume.inl
diffstat 20 files changed, 1348 insertions(+), 6 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Sat Dec 15 23:43:03 2012 +0200
     1.3 @@ -0,0 +1,4 @@
     1.4 +\.o$
     1.5 +\.d$
     1.6 +\.swp$
     1.7 +^blobo$
     2.1 --- a/Makefile	Sat Dec 15 07:52:13 2012 +0200
     2.2 +++ b/Makefile	Sat Dec 15 23:43:03 2012 +0200
     2.3 @@ -4,7 +4,7 @@
     2.4  bin = blobo
     2.5  
     2.6  CXXFLAGS = -ansi -pedantic -Wall -g
     2.7 -LDFLAGS = $(libgl)
     2.8 +LDFLAGS = $(libgl) -lvmath -limago
     2.9  
    2.10  ifeq ($(shell uname -s), Darwin)
    2.11  	libgl = -framework OpenGL -framework GLUT -lGLEW
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/RUN	Sat Dec 15 23:43:03 2012 +0200
     3.3 @@ -0,0 +1,3 @@
     3.4 +#!/bin/sh
     3.5 +
     3.6 +./blobo -world 100x100x32 -genscale 10 $*
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/camera.cc	Sat Dec 15 23:43:03 2012 +0200
     4.3 @@ -0,0 +1,237 @@
     4.4 +#include "opengl.h"
     4.5 +#include "camera.h"
     4.6 +
     4.7 +Camera::Camera()
     4.8 +{
     4.9 +	inval_cache();
    4.10 +}
    4.11 +
    4.12 +Camera::~Camera()
    4.13 +{
    4.14 +}
    4.15 +
    4.16 +void Camera::calc_inv_matrix(Matrix4x4 *mat) const
    4.17 +{
    4.18 +	*mat = matrix().inverse();
    4.19 +}
    4.20 +
    4.21 +void Camera::set_glmat(const Matrix4x4 &mat) const
    4.22 +{
    4.23 +#ifdef SINGLE_PRECISION_MATH
    4.24 +	if(glLoadTransposeMatrixfARB) {
    4.25 +		glLoadTransposeMatrixfARB((float*)&mat);
    4.26 +	} else {
    4.27 +		Matrix4x4 tmat = mat.transposed();
    4.28 +		glLoadMatrixf((float*)&tmat);
    4.29 +	}
    4.30 +#else
    4.31 +	if(glLoadTransposeMatrixdARB) {
    4.32 +		glLoadTransposeMatrixdARB((double*)&mat);
    4.33 +	} else {
    4.34 +		Matrix4x4 tmat = mat.transposed();
    4.35 +		glLoadMatrixd((double*)&tmat);
    4.36 +	}
    4.37 +#endif
    4.38 +}
    4.39 +
    4.40 +const Matrix4x4 &Camera::matrix() const
    4.41 +{
    4.42 +	if(!mcache.valid) {
    4.43 +		calc_matrix(&mcache.mat);
    4.44 +		mcache.valid = true;
    4.45 +	}
    4.46 +	return mcache.mat;
    4.47 +}
    4.48 +
    4.49 +const Matrix4x4 &Camera::inv_matrix() const
    4.50 +{
    4.51 +	if(!mcache_inv.valid) {
    4.52 +		calc_inv_matrix(&mcache_inv.mat);
    4.53 +		mcache_inv.valid = true;
    4.54 +	}
    4.55 +	return mcache_inv.mat;
    4.56 +}
    4.57 +
    4.58 +void Camera::use() const
    4.59 +{
    4.60 +	set_glmat(matrix());
    4.61 +}
    4.62 +
    4.63 +void Camera::use_inverse() const
    4.64 +{
    4.65 +	set_glmat(inv_matrix());
    4.66 +}
    4.67 +
    4.68 +void Camera::input_move(float x, float y, float z)
    4.69 +{
    4.70 +}
    4.71 +
    4.72 +void Camera::input_rotate(float x, float y, float z)
    4.73 +{
    4.74 +}
    4.75 +
    4.76 +void Camera::input_zoom(float factor)
    4.77 +{
    4.78 +}
    4.79 +
    4.80 +
    4.81 +// ---- orbit camera ----
    4.82 +
    4.83 +OrbitCamera::OrbitCamera()
    4.84 +{
    4.85 +	theta = 0.0;
    4.86 +	phi = 0.0;
    4.87 +	rad = 10.0;
    4.88 +
    4.89 +	min_phi = -M_PI / 2;
    4.90 +	max_phi = M_PI / 2;
    4.91 +}
    4.92 +
    4.93 +OrbitCamera::~OrbitCamera()
    4.94 +{
    4.95 +}
    4.96 +
    4.97 +void OrbitCamera::set_distance(float dist)
    4.98 +{
    4.99 +	rad = dist;
   4.100 +}
   4.101 +
   4.102 +#define MIN(a, b)	((a) < (b) ? (a) : (b))
   4.103 +#define MAX(a, b)	((a) > (b) ? (a) : (b))
   4.104 +void OrbitCamera::set_vertical_limits(float a, float b)
   4.105 +{
   4.106 +	a = M_PI * a / 180.0;
   4.107 +	b = M_PI * b / 180.0;
   4.108 +	min_phi = MIN(a, b);
   4.109 +	max_phi = MAX(a, b);
   4.110 +}
   4.111 +
   4.112 +void OrbitCamera::calc_matrix(Matrix4x4 *mat) const
   4.113 +{
   4.114 +	mat->reset_identity();
   4.115 +	mat->translate(Vector3(0, 0, -rad));
   4.116 +	mat->rotate(Vector3(phi, 0, 0));
   4.117 +	mat->rotate(Vector3(0, theta, 0));
   4.118 +}
   4.119 +
   4.120 +void OrbitCamera::calc_inv_matrix(Matrix4x4 *mat) const
   4.121 +{
   4.122 +	mat->reset_identity();
   4.123 +	mat->rotate(Vector3(0, theta, 0));
   4.124 +	mat->rotate(Vector3(phi, 0, 0));
   4.125 +	mat->translate(Vector3(0, 0, -rad));
   4.126 +}
   4.127 +
   4.128 +void OrbitCamera::input_rotate(float x, float y, float z)
   4.129 +{
   4.130 +	theta += x;
   4.131 +	phi += y;
   4.132 +
   4.133 +	if(phi < min_phi)
   4.134 +		phi = min_phi;
   4.135 +	if(phi > max_phi)
   4.136 +		phi = max_phi;
   4.137 +
   4.138 +	inval_cache();
   4.139 +}
   4.140 +
   4.141 +void OrbitCamera::input_zoom(float factor)
   4.142 +{
   4.143 +	rad += factor;
   4.144 +	if(rad < 0.0)
   4.145 +		rad = 0.0;
   4.146 +
   4.147 +	inval_cache();
   4.148 +}
   4.149 +
   4.150 +void FpsCamera::calc_matrix(Matrix4x4 *mat) const
   4.151 +{
   4.152 +	mat->reset_identity();
   4.153 +	mat->translate(Vector3(pos.x, pos.y, pos.z));
   4.154 +	mat->rotate(Vector3(0, theta, 0));
   4.155 +	mat->rotate(Vector3(phi, 0, 0));
   4.156 +}
   4.157 +
   4.158 +void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
   4.159 +{
   4.160 +	mat->reset_identity();
   4.161 +	mat->rotate(Vector3(phi, 0, 0));
   4.162 +	mat->rotate(Vector3(0, theta, 0));
   4.163 +	mat->translate(Vector3(-pos.x, -pos.y, -pos.z));
   4.164 +}
   4.165 +
   4.166 +void FpsCamera::input_move(float x, float y, float z)
   4.167 +{
   4.168 +	pos.x += x * cos(theta) - z * sin(theta);
   4.169 +	pos.z += x * sin(theta) + z * cos(theta);
   4.170 +	pos.y += y;
   4.171 +	inval_cache();
   4.172 +}
   4.173 +
   4.174 +const Vector3 &FpsCamera::get_position() const
   4.175 +{
   4.176 +	return pos;
   4.177 +}
   4.178 +
   4.179 +
   4.180 +FlyCamera::FlyCamera()
   4.181 +{
   4.182 +	pos.z = 10.0f;
   4.183 +}
   4.184 +
   4.185 +void FlyCamera::calc_matrix(Matrix4x4 *mat) const
   4.186 +{
   4.187 +	/*mat->reset_identity();
   4.188 +	mat->translate(-pos);
   4.189 +	*mat = *mat * Matrix4x4(rot.get_rotation_matrix());
   4.190 +	mat->translate(pos);*/
   4.191 +	//mat->translate(-pos.transformed(rot));
   4.192 +
   4.193 +	Matrix3x3 qmat = rot.get_rotation_matrix();
   4.194 +
   4.195 +	Vector3 ivec = qmat.get_row_vector(0);
   4.196 +	Vector3 jvec = qmat.get_row_vector(1);
   4.197 +	Vector3 kvec = qmat.get_row_vector(2);
   4.198 +
   4.199 +	*mat = Matrix4x4(qmat);
   4.200 +	/*Vector3 trans_x = ivec * pos;
   4.201 +	Vector3 trans_y = jvec * pos;
   4.202 +	Vector3 trans_z = kvec * pos;
   4.203 +	Vector3 trans = trans_x + trans_y + trans_z;*/
   4.204 +	Vector3 trans;
   4.205 +	trans.x = dot_product(ivec, pos);
   4.206 +	trans.y = dot_product(jvec, pos);
   4.207 +	trans.z = dot_product(kvec, pos);
   4.208 +	mat->set_column_vector(-trans, 3);
   4.209 +}
   4.210 +
   4.211 +/*void FlyCamera::calc_inv_matrix(Matrix4x4 *mat) const
   4.212 +{
   4.213 +	mat->set_translation(pos);
   4.214 +	*mat = *mat * Matrix4x4(rot.get_rotation_matrix());
   4.215 +}*/
   4.216 +
   4.217 +const Vector3 &FlyCamera::get_position() const
   4.218 +{
   4.219 +	return pos;
   4.220 +}
   4.221 +
   4.222 +const Quaternion &FlyCamera::get_rotation() const
   4.223 +{
   4.224 +	return rot;
   4.225 +}
   4.226 +
   4.227 +void FlyCamera::input_move(float x, float y, float z)
   4.228 +{
   4.229 +	pos += Vector3(x, y, z);
   4.230 +	inval_cache();
   4.231 +}
   4.232 +
   4.233 +void FlyCamera::input_rotate(float x, float y, float z)
   4.234 +{
   4.235 +	Vector3 axis(x, y, z);
   4.236 +	float axis_len = axis.length();
   4.237 +	rot.rotate(axis / axis_len, axis_len);
   4.238 +	rot.normalize();
   4.239 +	inval_cache();
   4.240 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/camera.h	Sat Dec 15 23:43:03 2012 +0200
     5.3 @@ -0,0 +1,87 @@
     5.4 +#ifndef CAMERA_H_
     5.5 +#define CAMERA_H_
     5.6 +
     5.7 +#include "vmath/vmath.h"
     5.8 +
     5.9 +class Camera {
    5.10 +protected:
    5.11 +	mutable struct {
    5.12 +		bool valid;
    5.13 +		Matrix4x4 mat;
    5.14 +	} mcache, mcache_inv;
    5.15 +
    5.16 +	virtual void calc_matrix(Matrix4x4 *mat) const = 0;
    5.17 +	virtual void calc_inv_matrix(Matrix4x4 *mat) const;
    5.18 +
    5.19 +	void inval_cache() { mcache.valid = mcache_inv.valid = false; }
    5.20 +	void set_glmat(const Matrix4x4 &m) const;
    5.21 +
    5.22 +public:
    5.23 +	Camera();
    5.24 +	virtual ~Camera();
    5.25 +
    5.26 +	const Matrix4x4 &matrix() const;
    5.27 +	const Matrix4x4 &inv_matrix() const;
    5.28 +
    5.29 +	void use() const;
    5.30 +	void use_inverse() const;
    5.31 +
    5.32 +	// these do nothing, override to provide input handling
    5.33 +	virtual void input_move(float x, float y, float z);
    5.34 +	virtual void input_rotate(float x, float y, float z);
    5.35 +	virtual void input_zoom(float factor);
    5.36 +};
    5.37 +
    5.38 +class OrbitCamera : public Camera {
    5.39 +protected:
    5.40 +	float theta, phi, rad;
    5.41 +	float min_phi, max_phi;
    5.42 +
    5.43 +	void calc_matrix(Matrix4x4 *mat) const;
    5.44 +	void calc_inv_matrix(Matrix4x4 *mat) const;
    5.45 +
    5.46 +public:
    5.47 +	OrbitCamera();
    5.48 +	virtual ~OrbitCamera();
    5.49 +
    5.50 +	void set_distance(float dist);
    5.51 +	void set_vertical_limits(float a, float b);
    5.52 +
    5.53 +	void input_rotate(float x, float y, float z);
    5.54 +	void input_zoom(float factor);
    5.55 +};
    5.56 +
    5.57 +class FpsCamera : public OrbitCamera {
    5.58 +protected:
    5.59 +	Vector3 pos;
    5.60 +
    5.61 +	void calc_matrix(Matrix4x4 *mat) const;
    5.62 +	void calc_inv_matrix(Matrix4x4 *mat) const;
    5.63 +
    5.64 +public:
    5.65 +	void input_move(float x, float y, float z);
    5.66 +
    5.67 +	const Vector3 &get_position() const;
    5.68 +};
    5.69 +
    5.70 +
    5.71 +class FlyCamera : public Camera {
    5.72 +private:
    5.73 +	Vector3 pos;
    5.74 +	Quaternion rot;
    5.75 +
    5.76 +	void calc_matrix(Matrix4x4 *mat) const;
    5.77 +	//void calc_inv_matrix(Matrix4x4 *mat) const;
    5.78 +
    5.79 +public:
    5.80 +	FlyCamera();
    5.81 +
    5.82 +	const Vector3 &get_position() const;
    5.83 +	const Quaternion &get_rotation() const;
    5.84 +
    5.85 +	void input_move(float x, float y, float z);
    5.86 +	void input_rotate(float x, float y, float z);
    5.87 +};
    5.88 +
    5.89 +
    5.90 +#endif	// CAMERA_H_
     6.1 --- a/src/game.cc	Sat Dec 15 07:52:13 2012 +0200
     6.2 +++ b/src/game.cc	Sat Dec 15 23:43:03 2012 +0200
     6.3 @@ -1,19 +1,89 @@
     6.4  #include "game.h"
     6.5  #include "opengl.h"
     6.6 +#include "level.h"
     6.7 +#include "renderer.h"
     6.8 +#include "camera.h"
     6.9 +
    6.10 +bool keystate[256];
    6.11 +bool bnstate[16];
    6.12 +
    6.13 +static Level *level;
    6.14 +static Renderer *rend;
    6.15 +static FpsCamera cam;
    6.16  
    6.17  bool game_init()
    6.18  {
    6.19 +	printf("initializing OpenGL state\n");
    6.20 +	glEnable(GL_CULL_FACE);
    6.21 +	glEnable(GL_DEPTH_TEST);
    6.22 +	glEnable(GL_LIGHTING);
    6.23 +	glEnable(GL_LIGHT0);
    6.24 +
    6.25 +	printf("initializing renderer\n");
    6.26 +	rend = new Renderer;
    6.27 +	rend->init();
    6.28 +
    6.29 +	printf("generating level\n");
    6.30 +	level = new Level;
    6.31 +	level->generate();
    6.32 +
    6.33 +	cam.input_move(0, 2, 2);
    6.34 +	cam.input_rotate(0, M_PI / 5, 0);
    6.35 +
    6.36  	return true;
    6.37  }
    6.38  
    6.39  void game_shutdown()
    6.40  {
    6.41 +	delete rend;
    6.42 +	delete level;
    6.43  }
    6.44  
    6.45  void game_iter(double dt)
    6.46  {
    6.47 +	float offs = 0.05 * dt;
    6.48 +	float dx = 0, dy = 0;
    6.49 +
    6.50 +	// handle key input
    6.51 +	if(keystate['w'] || keystate['W']) {
    6.52 +		dy -= offs;
    6.53 +	}
    6.54 +	if(keystate['s'] || keystate['S']) {
    6.55 +		dy += offs;
    6.56 +	}
    6.57 +	if(keystate['d'] || keystate['D']) {
    6.58 +		dx += offs;
    6.59 +	}
    6.60 +	if(keystate['a'] || keystate['A']) {
    6.61 +		dx -= offs;
    6.62 +	}
    6.63 +
    6.64 +	cam.input_move(dx, 0, dy);
    6.65  }
    6.66  
    6.67  void game_render()
    6.68  {
    6.69 +	glMatrixMode(GL_MODELVIEW);
    6.70 +	glLoadIdentity();
    6.71 +
    6.72 +	float lpos[] = {-1, 1, 2, 0};
    6.73 +	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
    6.74 +
    6.75 +	cam.use_inverse();
    6.76 +
    6.77 +	rend->render(level);
    6.78  }
    6.79 +
    6.80 +void game_input_shoot(int bn)
    6.81 +{
    6.82 +}
    6.83 +
    6.84 +void game_input_move(float x, float y, float z)
    6.85 +{
    6.86 +	cam.input_move(x, y, z);
    6.87 +}
    6.88 +
    6.89 +void game_input_rot(float x, float y)
    6.90 +{
    6.91 +	cam.input_rotate(x * 6.0, y * 6.0, 0);
    6.92 +}
     7.1 --- a/src/game.h	Sat Dec 15 07:52:13 2012 +0200
     7.2 +++ b/src/game.h	Sat Dec 15 23:43:03 2012 +0200
     7.3 @@ -1,7 +1,11 @@
     7.4  #ifndef GAME_H_
     7.5  #define GAME_H_
     7.6  
     7.7 -bool keystate[256];
     7.8 +#define GAME_MAX_KEYS		256
     7.9 +#define GAME_MAX_BUTTONS	16
    7.10 +
    7.11 +extern bool keystate[GAME_MAX_KEYS];
    7.12 +extern bool bnstate[GAME_MAX_BUTTONS];
    7.13  
    7.14  bool game_init();
    7.15  void game_shutdown();
    7.16 @@ -9,4 +13,8 @@
    7.17  void game_iter(double dt);
    7.18  void game_render();
    7.19  
    7.20 +void game_input_shoot(int bn);
    7.21 +void game_input_move(float x, float y, float z);
    7.22 +void game_input_rot(float x, float y);
    7.23 +
    7.24  #endif	// GAME_H_
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/level.cc	Sat Dec 15 23:43:03 2012 +0200
     8.3 @@ -0,0 +1,64 @@
     8.4 +#include "level.h"
     8.5 +
     8.6 +#include "opt.h"
     8.7 +
     8.8 +Level::Level()
     8.9 +{
    8.10 +	terrain = 0;
    8.11 +}
    8.12 +
    8.13 +Level::~Level()
    8.14 +{
    8.15 +	delete terrain;
    8.16 +}
    8.17 +
    8.18 +void Level::generate()
    8.19 +{
    8.20 +	delete terrain;
    8.21 +
    8.22 +	int xsz = opt.world_size[0];
    8.23 +	int ysz = opt.world_size[1];
    8.24 +	int zsz = opt.world_size[2];
    8.25 +
    8.26 +	terrain = new Volume(xsz, ysz, zsz);
    8.27 +
    8.28 +	for(int i=0; i<xsz; i++) {
    8.29 +		for(int j=0; j<ysz; j++) {
    8.30 +			float x = opt.gen_noise_scale * (float)i / (float)xsz;
    8.31 +			float y = opt.gen_noise_scale * (float)j / (float)ysz;
    8.32 +			float peak = 0.4 * noise2(x, y) * 0.5 + 0.5;
    8.33 +
    8.34 +			for(int k=0; k<zsz; k++) {
    8.35 +				Vector4 voxel(1, 1, 1, 1);
    8.36 +				float z = (float)k / (float)zsz;
    8.37 +
    8.38 +				if(z < 0.1) {
    8.39 +					// lava
    8.40 +					static const Vector4 col1(0.96, 0.3, 0.1, 1);
    8.41 +					static const Vector4 col2(0.96, 0.75, 0.1, 1);
    8.42 +					float t = noise3(x, y, z);
    8.43 +					voxel = lerp(col1, col2, t);
    8.44 +				} else if(z < peak - 0.05) {
    8.45 +					// mud
    8.46 +					voxel = Vector4(0.57, 0.43, 0.29, 1);
    8.47 +				} else if(z < 0.85) {
    8.48 +					// grass
    8.49 +					voxel = Vector4(0.68, 0.95, 0.38);
    8.50 +				}	// else snow (default)
    8.51 +
    8.52 +				voxel.w = z < peak ? 1.0 : 0.0;
    8.53 +				terrain->set_voxel(i, j, k, voxel);
    8.54 +			}
    8.55 +		}
    8.56 +	}
    8.57 +}
    8.58 +
    8.59 +bool Level::load(const char *fname)
    8.60 +{
    8.61 +	return false;
    8.62 +}
    8.63 +
    8.64 +bool Level::save(const char *fname) const
    8.65 +{
    8.66 +	return false;
    8.67 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/level.h	Sat Dec 15 23:43:03 2012 +0200
     9.3 @@ -0,0 +1,21 @@
     9.4 +#ifndef LEVEL_H_
     9.5 +#define LEVEL_H_
     9.6 +
     9.7 +#include <vector>
     9.8 +#include "volume.h"
     9.9 +
    9.10 +class Level {
    9.11 +public:
    9.12 +	Volume *terrain;
    9.13 +	std::vector<Vector3> blobs;
    9.14 +
    9.15 +	Level();
    9.16 +	~Level();
    9.17 +
    9.18 +	void generate();
    9.19 +
    9.20 +	bool load(const char *fname);
    9.21 +	bool save(const char *fname) const;
    9.22 +};
    9.23 +
    9.24 +#endif	// LEVEL_H_
    10.1 --- a/src/main.cc	Sat Dec 15 07:52:13 2012 +0200
    10.2 +++ b/src/main.cc	Sat Dec 15 23:43:03 2012 +0200
    10.3 @@ -1,10 +1,12 @@
    10.4  #include <stdio.h>
    10.5  #include <stdlib.h>
    10.6 +#include <assert.h>
    10.7  #include "opengl.h"
    10.8  #include "game.h"
    10.9  #include "opt.h"
   10.10  
   10.11  static void disp();
   10.12 +static void idle();
   10.13  static void reshape(int x, int y);
   10.14  static void keydown(unsigned char key, int x, int y);
   10.15  static void keyup(unsigned char key, int x, int y);
   10.16 @@ -16,6 +18,9 @@
   10.17  static void spacerot(int x, int y, int z);
   10.18  static void spacebut(int bn, int state);
   10.19  
   10.20 +static int win_xsz, win_ysz, centerx, centery;
   10.21 +static unsigned int prev_msec;
   10.22 +
   10.23  int main(int argc, char **argv)
   10.24  {
   10.25  	glutInit(&argc, argv);
   10.26 @@ -25,10 +30,11 @@
   10.27  	}
   10.28  
   10.29  	glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | (opt.stereo ? GLUT_STEREO : 0));
   10.30 -	glutInitWindowSize(800, 450);
   10.31 +	glutInitWindowSize(opt.xsz, opt.ysz);
   10.32  	glutCreateWindow("bloboland");
   10.33  
   10.34  	glutDisplayFunc(disp);
   10.35 +	glutIdleFunc(idle);
   10.36  	glutReshapeFunc(reshape);
   10.37  	glutKeyboardFunc(keydown);
   10.38  	glutKeyboardUpFunc(keyup);
   10.39 @@ -55,11 +61,17 @@
   10.40  	game_iter((msec - prev_msec) / 1000.0);
   10.41  
   10.42  
   10.43 -	glClear(GL_COLOR_BUFFER_BIT);
   10.44 +	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   10.45  
   10.46  	game_render();
   10.47  
   10.48  	glutSwapBuffers();
   10.49 +	assert(glGetError() == GL_NO_ERROR);
   10.50 +}
   10.51 +
   10.52 +static void idle()
   10.53 +{
   10.54 +	glutPostRedisplay();
   10.55  }
   10.56  
   10.57  static void reshape(int x, int y)
   10.58 @@ -69,6 +81,12 @@
   10.59  	glMatrixMode(GL_PROJECTION);
   10.60  	glLoadIdentity();
   10.61  	gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0);
   10.62 +
   10.63 +	win_xsz = x;
   10.64 +	win_ysz = y;
   10.65 +
   10.66 +	centerx = x / 2;
   10.67 +	centery = y / 2;
   10.68  }
   10.69  
   10.70  static void keydown(unsigned char key, int x, int y)
   10.71 @@ -87,35 +105,73 @@
   10.72  		exit(0);
   10.73  	}
   10.74  
   10.75 -	if(key < sizeof keystate / sizeof *keystate) {
   10.76 +	if(key < GAME_MAX_KEYS) {
   10.77  		keystate[key] = true;
   10.78  	}
   10.79  }
   10.80  
   10.81  static void skeyup(int key, int x, int y)
   10.82  {
   10.83 -	if(key < sizeof keystate / sizeof *keystate) {
   10.84 +	if(key < GAME_MAX_KEYS) {
   10.85  		keystate[key] = false;
   10.86  	}
   10.87  }
   10.88  
   10.89 +
   10.90 +static int prev_x, prev_y;
   10.91 +
   10.92  static void mouse(int bn, int state, int x, int y)
   10.93  {
   10.94 +	int idx = bn - GLUT_LEFT_BUTTON;
   10.95 +
   10.96 +	if(idx < GAME_MAX_BUTTONS) {
   10.97 +		bnstate[idx] = state == GLUT_DOWN;
   10.98 +
   10.99 +		if(state == GLUT_DOWN) {
  10.100 +			game_input_shoot(idx);
  10.101 +		}
  10.102 +	}
  10.103 +	prev_x = x;
  10.104 +	prev_y = y;
  10.105  }
  10.106  
  10.107 +
  10.108  static void motion(int x, int y)
  10.109  {
  10.110 +	/*
  10.111 +	int dx = x - centerx;
  10.112 +	int dy = y - centery;
  10.113 +
  10.114 +	if(!dx && !dy) {
  10.115 +		return;
  10.116 +	}
  10.117 +	game_input_rot(dx * 0.5, dy * 0.5);
  10.118 +
  10.119 +	glutWarpPointer(centerx, centery);
  10.120 +	*/
  10.121 +	int dx = x - prev_x;
  10.122 +	int dy = y - prev_y;
  10.123 +
  10.124 +	prev_x = x;
  10.125 +	prev_y = y;
  10.126 +
  10.127 +	if(bnstate[0]) {
  10.128 +		game_input_rot((float)dx / win_xsz, (float)dy / win_ysz);
  10.129 +	}
  10.130  }
  10.131  
  10.132  static void spacemove(int x, int y, int z)
  10.133  {
  10.134 +	game_input_move(x * 0.1, y * 0.1, z * 0.1);
  10.135  }
  10.136  
  10.137  static void spacerot(int x, int y, int z)
  10.138  {
  10.139 +	game_input_rot(y * 0.1, x * 0.1);
  10.140  }
  10.141  
  10.142  static void spacebut(int bn, int state)
  10.143  {
  10.144 +	game_input_shoot(bn);
  10.145  }
  10.146  
    11.1 --- a/src/opt.cc	Sat Dec 15 07:52:13 2012 +0200
    11.2 +++ b/src/opt.cc	Sat Dec 15 23:43:03 2012 +0200
    11.3 @@ -1,6 +1,55 @@
    11.4 +#include <stdio.h>
    11.5 +#include <string.h>
    11.6 +#include <stdlib.h>
    11.7  #include "opt.h"
    11.8  
    11.9 +Options opt;
   11.10 +
   11.11 +static void default_opt()
   11.12 +{
   11.13 +	opt.xsz = 800;
   11.14 +	opt.ysz = 450;
   11.15 +	opt.stereo = false;
   11.16 +
   11.17 +	opt.world_size[0] = opt.world_size[1] = 128;
   11.18 +	opt.world_size[2] = 64;
   11.19 +
   11.20 +	opt.gen_noise_scale = 1.0f;
   11.21 +}
   11.22 +
   11.23  bool parse_opt(int argc, char **argv)
   11.24  {
   11.25 +	default_opt();
   11.26 +
   11.27 +	for(int i=1; i<argc; i++) {
   11.28 +		if(argv[i][0] == '-') {
   11.29 +			if(strcmp(argv[i], "-size") == 0) {
   11.30 +				if(sscanf(argv[++i], "%dx%d", &opt.xsz, &opt.ysz) != 2) {
   11.31 +					fprintf(stderr, "-size must be followed by <width>x<height>\n");
   11.32 +					return false;
   11.33 +				}
   11.34 +			} else if(strcmp(argv[i], "-world") == 0) {
   11.35 +				if(sscanf(argv[++i], "%dx%dx%d", opt.world_size, opt.world_size + 1, opt.world_size + 2) != 3) {
   11.36 +					fprintf(stderr, "-world must be followed by <width>x<height>x<depth>\n");
   11.37 +					return false;
   11.38 +				}
   11.39 +			} else if(strcmp(argv[i], "-genscale") == 0) {
   11.40 +				char *endp;
   11.41 +				opt.gen_noise_scale = strtod(argv[++i], &endp);
   11.42 +				if(endp == argv[i]) {
   11.43 +					fprintf(stderr, "-genscale must be followed by a scaling factor\n");
   11.44 +					return false;
   11.45 +				}
   11.46 +			} else if(strcmp(argv[i], "-stereo") == 0) {
   11.47 +				opt.stereo = true;
   11.48 +			} else {
   11.49 +				fprintf(stderr, "invalid option: %s\n", argv[i]);
   11.50 +				return false;
   11.51 +			}
   11.52 +		} else {
   11.53 +			fprintf(stderr, "unexpected argument: %s\n", argv[i]);
   11.54 +			return false;
   11.55 +		}
   11.56 +	}
   11.57  	return true;
   11.58  }
    12.1 --- a/src/opt.h	Sat Dec 15 07:52:13 2012 +0200
    12.2 +++ b/src/opt.h	Sat Dec 15 23:43:03 2012 +0200
    12.3 @@ -4,8 +4,14 @@
    12.4  struct Options {
    12.5  	int xsz, ysz;
    12.6  	bool stereo;
    12.7 +
    12.8 +	// initial parameters when generating new worlds
    12.9 +	int world_size[3];
   12.10 +	float gen_noise_scale;
   12.11  };
   12.12  
   12.13 +extern Options opt;
   12.14 +
   12.15  bool parse_opt(int argc, char **argv);
   12.16  
   12.17  #endif	// OPT_H_
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/renderer.cc	Sat Dec 15 23:43:03 2012 +0200
    13.3 @@ -0,0 +1,106 @@
    13.4 +#include "opengl.h"
    13.5 +#include "renderer.h"
    13.6 +
    13.7 +Renderer::Renderer()
    13.8 +{
    13.9 +	leveltex = 0;
   13.10 +	sdrprog = 0;
   13.11 +}
   13.12 +
   13.13 +Renderer::~Renderer()
   13.14 +{
   13.15 +	shutdown();
   13.16 +}
   13.17 +
   13.18 +bool Renderer::init()
   13.19 +{
   13.20 +	sdrprog = new SdrProg;
   13.21 +	/*if(!sdrprog->load("sdr/bloboray.v.glsl", "sdr/bloboray.p.glsl")) {
   13.22 +		return false;
   13.23 +	}*/
   13.24 +
   13.25 +	leveltex = new Texture3D;
   13.26 +
   13.27 +	return true;
   13.28 +}
   13.29 +
   13.30 +void Renderer::shutdown()
   13.31 +{
   13.32 +	delete leveltex;
   13.33 +	delete sdrprog;
   13.34 +}
   13.35 +
   13.36 +static void draw_cube(const Vector3 &pos, float sz);
   13.37 +
   13.38 +void Renderer::render(const Level *lvl) const
   13.39 +{
   13.40 +	Volume *vol = lvl->terrain;
   13.41 +
   13.42 +	glEnable(GL_COLOR_MATERIAL);
   13.43 +	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
   13.44 +
   13.45 +	glBegin(GL_QUADS);
   13.46 +	for(int i=0; i<vol->get_size(0); i++) {
   13.47 +		for(int j=0; j<vol->get_size(1); j++) {
   13.48 +			for(int k=0; k<vol->get_size(2) - 1; k++) {
   13.49 +				Vector4 vox = vol->get_voxel(i, j, k);
   13.50 +				Vector4 next = vol->get_voxel(i, j, k + 1);
   13.51 +
   13.52 +				if(vox.w > 0.1 && next.w < 0.1) {
   13.53 +					glColor3f(vox.x, vox.y, vox.z);
   13.54 +
   13.55 +					float x = ((float)i - vol->get_size(0) / 2) * 0.1;
   13.56 +					float z = ((float)j - vol->get_size(1) / 2) * 0.1;
   13.57 +					float y = ((float)k - vol->get_size(2) / 2) * 0.1;
   13.58 +					draw_cube(Vector3(x, y, z), 0.1);
   13.59 +				}
   13.60 +			}
   13.61 +		}
   13.62 +	}
   13.63 +	glEnd();
   13.64 +
   13.65 +	glDisable(GL_COLOR_MATERIAL);
   13.66 +}
   13.67 +
   13.68 +
   13.69 +static void draw_cube(const Vector3 &pos, float sz)
   13.70 +{
   13.71 +	sz /= 2.0;
   13.72 +
   13.73 +	glNormal3f(0, 0, 1);
   13.74 +	glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz);
   13.75 +	glVertex3f(pos.x + sz, pos.y - sz, pos.z + sz);
   13.76 +	glVertex3f(pos.x + sz, pos.y + sz, pos.z + sz);
   13.77 +	glVertex3f(pos.x - sz, pos.y + sz, pos.z + sz);
   13.78 +
   13.79 +	glNormal3f(1, 0, 0);
   13.80 +	glVertex3f(pos.x + sz, pos.y - sz, pos.z + sz);
   13.81 +	glVertex3f(pos.x + sz, pos.y - sz, pos.z - sz);
   13.82 +	glVertex3f(pos.x + sz, pos.y + sz, pos.z - sz);
   13.83 +	glVertex3f(pos.x + sz, pos.y + sz, pos.z + sz);
   13.84 +
   13.85 +	glNormal3f(0, 0, -1);
   13.86 +	glVertex3f(pos.x + sz, pos.y - sz, pos.z - sz);
   13.87 +	glVertex3f(pos.x - sz, pos.y - sz, pos.z - sz);
   13.88 +	glVertex3f(pos.x - sz, pos.y + sz, pos.z - sz);
   13.89 +	glVertex3f(pos.x + sz, pos.y + sz, pos.z - sz);
   13.90 +
   13.91 +	glNormal3f(-1, 0, 0);
   13.92 +	glVertex3f(pos.x - sz, pos.y - sz, pos.z - sz);
   13.93 +	glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz);
   13.94 +	glVertex3f(pos.x - sz, pos.y + sz, pos.z + sz);
   13.95 +	glVertex3f(pos.x - sz, pos.y + sz, pos.z - sz);
   13.96 +
   13.97 +	glNormal3f(0, 1, 0);
   13.98 +	glVertex3f(pos.x - sz, pos.y + sz, pos.z + sz);
   13.99 +	glVertex3f(pos.x + sz, pos.y + sz, pos.z + sz);
  13.100 +	glVertex3f(pos.x + sz, pos.y + sz, pos.z - sz);
  13.101 +	glVertex3f(pos.x - sz, pos.y + sz, pos.z - sz);
  13.102 +
  13.103 +	glNormal3f(0, -1, 0);
  13.104 +	glVertex3f(pos.x - sz, pos.y - sz, pos.z - sz);
  13.105 +	glVertex3f(pos.x + sz, pos.y - sz, pos.z - sz);
  13.106 +	glVertex3f(pos.x + sz, pos.y - sz, pos.z + sz);
  13.107 +	glVertex3f(pos.x - sz, pos.y - sz, pos.z + sz);
  13.108 +
  13.109 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/renderer.h	Sat Dec 15 23:43:03 2012 +0200
    14.3 @@ -0,0 +1,23 @@
    14.4 +#ifndef RENDERER_H_
    14.5 +#define RENDERER_H_
    14.6 +
    14.7 +#include "shaders.h"
    14.8 +#include "texture.h"
    14.9 +#include "level.h"
   14.10 +
   14.11 +class Renderer {
   14.12 +private:
   14.13 +	mutable Texture3D *leveltex;
   14.14 +	SdrProg *sdrprog;
   14.15 +
   14.16 +public:
   14.17 +	Renderer();
   14.18 +	~Renderer();
   14.19 +
   14.20 +	bool init();
   14.21 +	void shutdown();
   14.22 +
   14.23 +	void render(const Level *lvl) const;
   14.24 +};
   14.25 +
   14.26 +#endif	// RENDERER_H_
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/src/shaders.cc	Sat Dec 15 23:43:03 2012 +0200
    15.3 @@ -0,0 +1,297 @@
    15.4 +#include <stdio.h>
    15.5 +#include <assert.h>
    15.6 +#include <map>
    15.7 +#ifdef _MSC_VER
    15.8 +#include <memory.h>
    15.9 +#else
   15.10 +#include <alloca.h>
   15.11 +#endif
   15.12 +#include <GL/glew.h>
   15.13 +#include "shaders.h"
   15.14 +
   15.15 +Shader::Shader(unsigned int type)
   15.16 +{
   15.17 +	sdr = glCreateShader(type);
   15.18 +	compiled = false;
   15.19 +
   15.20 +	assert(glGetError() == GL_NO_ERROR);
   15.21 +}
   15.22 +
   15.23 +Shader::~Shader()
   15.24 +{
   15.25 +	glDeleteShader(sdr);
   15.26 +}
   15.27 +
   15.28 +void Shader::set_source(const char *src)
   15.29 +{
   15.30 +	glShaderSource(sdr, 1, &src, 0);
   15.31 +	compiled = false;
   15.32 +
   15.33 +	assert(glGetError() == GL_NO_ERROR);
   15.34 +}
   15.35 +
   15.36 +bool Shader::compile()
   15.37 +{
   15.38 +	if(compiled) {
   15.39 +		return true;
   15.40 +	}
   15.41 +
   15.42 +	glCompileShader(sdr);
   15.43 +
   15.44 +	int len;
   15.45 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &len);
   15.46 +	if(len) {
   15.47 +		char *buf = (char*)alloca(len + 1);
   15.48 +		glGetShaderInfoLog(sdr, len, &len, buf);
   15.49 +		fprintf(stderr, "compiler: %s\n", buf);
   15.50 +	}
   15.51 +
   15.52 +	int status;
   15.53 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
   15.54 +	if(!status) {
   15.55 +		fprintf(stderr, "shader compilation failed\n");
   15.56 +		return false;
   15.57 +	}
   15.58 +
   15.59 +	compiled = true;
   15.60 +	return true;
   15.61 +}
   15.62 +
   15.63 +bool Shader::is_compiled() const
   15.64 +{
   15.65 +	return compiled;
   15.66 +}
   15.67 +
   15.68 +bool Shader::load(const char *fname)
   15.69 +{
   15.70 +	FILE *fp;
   15.71 +
   15.72 +	if(!(fp = fopen(fname, "rb"))) {
   15.73 +		fprintf(stderr, "failed to open shader file: %s\n", fname);
   15.74 +		return false;
   15.75 +	}
   15.76 +
   15.77 +	fseek(fp, 0, SEEK_END);
   15.78 +	long sz = ftell(fp);
   15.79 +	rewind(fp);
   15.80 +
   15.81 +	char *buf = new char[sz + 1];
   15.82 +	if((long)fread(buf, 1, sz, fp) < sz) {
   15.83 +		fprintf(stderr, "failed to read shader contents\n");
   15.84 +		fclose(fp);
   15.85 +		return false;
   15.86 +	}
   15.87 +	fclose(fp);
   15.88 +
   15.89 +	set_source(buf);
   15.90 +	delete [] buf;
   15.91 +
   15.92 +	return compile();
   15.93 +}
   15.94 +
   15.95 +// ---- shader manager ----
   15.96 +static std::map<std::string, Shader*> sdrcache;
   15.97 +
   15.98 +Shader *get_shader(const char *fname, unsigned int type)
   15.99 +{
  15.100 +	std::map<std::string, Shader*>::const_iterator it;
  15.101 +
  15.102 +	if((it = sdrcache.find(std::string(fname))) != sdrcache.end()) {
  15.103 +		return it->second;
  15.104 +	}
  15.105 +
  15.106 +	Shader *sdr = new Shader(type);
  15.107 +	if(!sdr->load(fname)) {
  15.108 +		delete sdr;
  15.109 +		return 0;
  15.110 +	}
  15.111 +	sdrcache[fname] = sdr;
  15.112 +	return sdr;
  15.113 +}
  15.114 +
  15.115 +
  15.116 +// ---- class SdrProg ----
  15.117 +
  15.118 +SdrProg::SdrProg()
  15.119 +{
  15.120 +	prog = glCreateProgram();
  15.121 +	linked = false;
  15.122 +	assert(glGetError() == GL_NO_ERROR);
  15.123 +}
  15.124 +
  15.125 +SdrProg::~SdrProg()
  15.126 +{
  15.127 +	glDeleteProgram(prog);
  15.128 +}
  15.129 +
  15.130 +void SdrProg::add_shader(Shader *sdr)
  15.131 +{
  15.132 +	if(sdr->compile()) {
  15.133 +		glAttachShader(prog, sdr->sdr);
  15.134 +		assert(glGetError() == GL_NO_ERROR);
  15.135 +
  15.136 +		shaders.push_back(sdr);
  15.137 +		linked = false;
  15.138 +	}
  15.139 +}
  15.140 +
  15.141 +bool SdrProg::link()
  15.142 +{
  15.143 +	if(linked) {
  15.144 +		return true;
  15.145 +	}
  15.146 +
  15.147 +	glLinkProgram(prog);
  15.148 +
  15.149 +	int len;
  15.150 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
  15.151 +	if(len) {
  15.152 +		char *buf = (char*)alloca(len + 1);
  15.153 +		glGetProgramInfoLog(prog, len, &len, buf);
  15.154 +		assert(glGetError() == GL_NO_ERROR);
  15.155 +		fprintf(stderr, "linker: %s\n", buf);
  15.156 +	}
  15.157 +
  15.158 +	int status;
  15.159 +	glGetProgramiv(prog, GL_LINK_STATUS, &status);
  15.160 +	if(!status) {
  15.161 +		fprintf(stderr, "program linking failed\n");
  15.162 +		return false;
  15.163 +	}
  15.164 +
  15.165 +	linked = true;
  15.166 +	return true;
  15.167 +}
  15.168 +
  15.169 +bool SdrProg::load(const char *vsfname, const char *psfname)
  15.170 +{
  15.171 +	Shader *sdr;
  15.172 +
  15.173 +	if(vsfname) {
  15.174 +		if(!(sdr = get_shader(vsfname, GL_VERTEX_SHADER))) {
  15.175 +			return false;
  15.176 +		}
  15.177 +		add_shader(sdr);
  15.178 +	}
  15.179 +
  15.180 +	if(psfname) {
  15.181 +		if(!(sdr = get_shader(psfname, GL_FRAGMENT_SHADER))) {
  15.182 +			return false;
  15.183 +		}
  15.184 +		add_shader(sdr);
  15.185 +	}
  15.186 +	return link();
  15.187 +}
  15.188 +
  15.189 +int SdrProg::get_uniform_location(const char *name)
  15.190 +{
  15.191 +	bind_program(this);
  15.192 +	return glGetUniformLocation(prog, name);
  15.193 +}
  15.194 +
  15.195 +int SdrProg::get_attribute_location(const char *name)
  15.196 +{
  15.197 +	bind_program(this);
  15.198 +	return glGetAttribLocation(prog, name);
  15.199 +}
  15.200 +
  15.201 +void SdrProg::set_uniform(const char *name, int val)
  15.202 +{
  15.203 +	set_uniform(get_uniform_location(name), val);
  15.204 +}
  15.205 +
  15.206 +void SdrProg::set_uniform(const char *name, float val)
  15.207 +{
  15.208 +	set_uniform(get_uniform_location(name), val);
  15.209 +}
  15.210 +
  15.211 +void SdrProg::set_uniform(const char *name, const Vector2 &v)
  15.212 +{
  15.213 +	set_uniform(get_uniform_location(name), v);
  15.214 +}
  15.215 +
  15.216 +void SdrProg::set_uniform(const char *name, const Vector3 &v)
  15.217 +{
  15.218 +	set_uniform(get_uniform_location(name), v);
  15.219 +}
  15.220 +
  15.221 +void SdrProg::set_uniform(const char *name, const Vector4 &v)
  15.222 +{
  15.223 +	set_uniform(get_uniform_location(name), v);
  15.224 +}
  15.225 +
  15.226 +void SdrProg::set_uniform(const char *name, const Matrix4x4 &mat)
  15.227 +{
  15.228 +	set_uniform(get_uniform_location(name), mat);
  15.229 +}
  15.230 +
  15.231 +
  15.232 +void SdrProg::set_uniform(int loc, int val)
  15.233 +{
  15.234 +	if(loc >= 0) {
  15.235 +		bind_program(this);
  15.236 +		glUniform1i(loc, val);
  15.237 +	}
  15.238 +}
  15.239 +
  15.240 +void SdrProg::set_uniform(int loc, float val)
  15.241 +{
  15.242 +	if(loc >= 0) {
  15.243 +		bind_program(this);
  15.244 +		glUniform1f(loc, val);
  15.245 +	}
  15.246 +}
  15.247 +
  15.248 +void SdrProg::set_uniform(int loc, const Vector2 &v)
  15.249 +{
  15.250 +	if(loc >= 0) {
  15.251 +		bind_program(this);
  15.252 +		glUniform2f(loc, v.x, v.y);
  15.253 +	}
  15.254 +}
  15.255 +
  15.256 +void SdrProg::set_uniform(int loc, const Vector3 &v)
  15.257 +{
  15.258 +	if(loc >= 0) {
  15.259 +		bind_program(this);
  15.260 +		glUniform3f(loc, v.x, v.y, v.z);
  15.261 +	}
  15.262 +}
  15.263 +
  15.264 +void SdrProg::set_uniform(int loc, const Vector4 &v)
  15.265 +{
  15.266 +	if(loc >= 0) {
  15.267 +		bind_program(this);
  15.268 +		glUniform4f(loc, v.x, v.y, v.z, v.w);
  15.269 +	}
  15.270 +}
  15.271 +
  15.272 +void SdrProg::set_uniform(int loc, const Matrix4x4 &mat)
  15.273 +{
  15.274 +	if(loc >= 0) {
  15.275 +		bind_program(this);
  15.276 +		// loading transpose matrix (3rd arg true)
  15.277 +#ifdef SINGLE_PRECISION_MATH
  15.278 +		glUniformMatrix4fv(loc, 1, GL_TRUE, (float*)mat.m);
  15.279 +#else
  15.280 +		glUniformMatrix4dv(loc, 1, GL_TRUE, (double*)mat.m);
  15.281 +#endif
  15.282 +	}
  15.283 +}
  15.284 +
  15.285 +bool bind_program(const SdrProg *prog)
  15.286 +{
  15.287 +	if(!prog) {
  15.288 +		glUseProgram(0);
  15.289 +		return true;
  15.290 +	}
  15.291 +
  15.292 +	if(!((SdrProg*)prog)->link()) {
  15.293 +		return false;
  15.294 +	}
  15.295 +	glUseProgram(prog->prog);
  15.296 +	if(glGetError()) {
  15.297 +		return false;
  15.298 +	}
  15.299 +	return true;
  15.300 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/shaders.h	Sat Dec 15 23:43:03 2012 +0200
    16.3 @@ -0,0 +1,67 @@
    16.4 +#ifndef SDR_H_
    16.5 +#define SDR_H_
    16.6 +
    16.7 +#include <vector>
    16.8 +#include "vmath/vmath.h"
    16.9 +
   16.10 +class Shader {
   16.11 +private:
   16.12 +	bool compiled;
   16.13 +
   16.14 +public:
   16.15 +	unsigned int sdr;
   16.16 +
   16.17 +	Shader(unsigned int type);
   16.18 +	~Shader();
   16.19 +
   16.20 +	void set_source(const char *src);
   16.21 +
   16.22 +	bool compile();
   16.23 +	bool is_compiled() const;
   16.24 +
   16.25 +	bool load(const char *fname);
   16.26 +};
   16.27 +
   16.28 +
   16.29 +// public shader manager interface
   16.30 +Shader *get_shader(const char *fname, unsigned int type);
   16.31 +
   16.32 +
   16.33 +class SdrProg {
   16.34 +private:
   16.35 +	// SdrProg does not own the shader objects
   16.36 +	std::vector<Shader*> shaders;
   16.37 +	bool linked;
   16.38 +
   16.39 +public:
   16.40 +	unsigned int prog;
   16.41 +
   16.42 +	SdrProg();
   16.43 +	~SdrProg();
   16.44 +
   16.45 +	void add_shader(Shader *sdr);
   16.46 +	bool link();
   16.47 +
   16.48 +	bool load(const char *vsfname, const char *psfname);
   16.49 +
   16.50 +	int get_uniform_location(const char *name);
   16.51 +	int get_attribute_location(const char *name);
   16.52 +
   16.53 +	void set_uniform(const char *name, int val);
   16.54 +	void set_uniform(const char *name, float val);
   16.55 +	void set_uniform(const char *name, const Vector2 &v);
   16.56 +	void set_uniform(const char *name, const Vector3 &v);
   16.57 +	void set_uniform(const char *name, const Vector4 &v);
   16.58 +	void set_uniform(const char *name, const Matrix4x4 &mat);
   16.59 +
   16.60 +	void set_uniform(int loc, int val);
   16.61 +	void set_uniform(int loc, float val);
   16.62 +	void set_uniform(int loc, const Vector2 &v);
   16.63 +	void set_uniform(int loc, const Vector3 &v);
   16.64 +	void set_uniform(int loc, const Vector4 &v);
   16.65 +	void set_uniform(int loc, const Matrix4x4 &mat);
   16.66 +};
   16.67 +
   16.68 +bool bind_program(const SdrProg *prog);
   16.69 +
   16.70 +#endif	/* SDR_H_ */
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/texture.cc	Sat Dec 15 23:43:03 2012 +0200
    17.3 @@ -0,0 +1,81 @@
    17.4 +#include "opengl.h"
    17.5 +#include "texture.h"
    17.6 +
    17.7 +void bind_texture(const Texture *tex, int texunit)
    17.8 +{
    17.9 +	static const Texture *curr_tex[8];
   17.10 +
   17.11 +	if(tex == curr_tex[texunit]) {
   17.12 +		return;
   17.13 +	}
   17.14 +
   17.15 +	glActiveTexture(GL_TEXTURE0 + texunit);
   17.16 +	if(tex) {
   17.17 +		glEnable(tex->type);
   17.18 +		glBindTexture(tex->type, tex->tex);
   17.19 +	} else {
   17.20 +		glDisable(tex->type);
   17.21 +	}
   17.22 +	glActiveTexture(GL_TEXTURE0);
   17.23 +
   17.24 +	curr_tex[texunit] = tex;
   17.25 +}
   17.26 +
   17.27 +
   17.28 +Texture::Texture()
   17.29 +{
   17.30 +	type = 0;
   17.31 +
   17.32 +	size[0] = size[1] = size[2] = 0;
   17.33 +
   17.34 +	glGenTextures(1, &tex);
   17.35 +}
   17.36 +
   17.37 +Texture::~Texture()
   17.38 +{
   17.39 +	if(tex) {
   17.40 +		glDeleteTextures(1, &tex);
   17.41 +	}
   17.42 +}
   17.43 +
   17.44 +int Texture::get_size(int idx) const
   17.45 +{
   17.46 +	return idx >= 0 && idx < 3 ? size[idx] : 0;
   17.47 +}
   17.48 +
   17.49 +Texture2D::Texture2D()
   17.50 +{
   17.51 +	type = GL_TEXTURE_2D;
   17.52 +
   17.53 +	glBindTexture(type, tex);
   17.54 +	glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   17.55 +	glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   17.56 +}
   17.57 +
   17.58 +void Texture2D::create(int xsz, int ysz, float *data)
   17.59 +{
   17.60 +	glBindTexture(type, tex);
   17.61 +	glTexImage2D(type, 0, GL_RGBA, xsz, ysz, 0, GL_RGBA, GL_FLOAT, data);
   17.62 +
   17.63 +	size[0] = xsz;
   17.64 +	size[1] = ysz;
   17.65 +}
   17.66 +
   17.67 +Texture3D::Texture3D()
   17.68 +{
   17.69 +	type = GL_TEXTURE_3D;
   17.70 +
   17.71 +	glBindTexture(type, tex);
   17.72 +	glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   17.73 +	glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   17.74 +}
   17.75 +
   17.76 +void Texture3D::create(int xsz, int ysz, int zsz, float *data)
   17.77 +{
   17.78 +	glBindTexture(type, tex);
   17.79 +	glTexImage3D(type, 0, GL_RGBA, xsz, ysz, zsz, 0, GL_RGBA, GL_FLOAT, data);
   17.80 +
   17.81 +	size[0] = xsz;
   17.82 +	size[1] = ysz;
   17.83 +	size[2] = zsz;
   17.84 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/texture.h	Sat Dec 15 23:43:03 2012 +0200
    18.3 @@ -0,0 +1,36 @@
    18.4 +#ifndef TEXTURE_H_
    18.5 +#define TEXTURE_H_
    18.6 +
    18.7 +class Texture {
    18.8 +protected:
    18.9 +	unsigned int type;
   18.10 +	unsigned int tex;
   18.11 +
   18.12 +	int size[3];
   18.13 +
   18.14 +public:
   18.15 +	Texture();
   18.16 +	virtual ~Texture();
   18.17 +
   18.18 +	virtual int get_size(int idx) const;
   18.19 +
   18.20 +	friend void bind_texture(const Texture *tex, int texunit);
   18.21 +};
   18.22 +
   18.23 +void bind_texture(const Texture *tex, int texunit = 0);
   18.24 +
   18.25 +class Texture2D : public Texture {
   18.26 +public:
   18.27 +	Texture2D();
   18.28 +
   18.29 +	void create(int xsz, int ysz, float *data = 0);
   18.30 +};
   18.31 +
   18.32 +class Texture3D : public Texture {
   18.33 +public:
   18.34 +	Texture3D();
   18.35 +
   18.36 +	void create(int xsz, int ysz, int zsz, float *data = 0);
   18.37 +};
   18.38 +
   18.39 +#endif	// TEXTURE_H_
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/volume.h	Sat Dec 15 23:43:03 2012 +0200
    19.3 @@ -0,0 +1,39 @@
    19.4 +#ifndef VOLUME_H_
    19.5 +#define VOLUME_H_
    19.6 +
    19.7 +#include "vmath/vmath.h"
    19.8 +
    19.9 +class Volume {
   19.10 +private:
   19.11 +	int xsz, ysz, zsz;
   19.12 +	int slice_size;
   19.13 +	Vector4 *voxels;
   19.14 +
   19.15 +	Vector4 **slices;
   19.16 +
   19.17 +public:
   19.18 +	inline Volume(int xsz, int ysz, int zsz);
   19.19 +	inline ~Volume();
   19.20 +
   19.21 +	inline int get_size(int idx = -1) const;
   19.22 +
   19.23 +	// access to the voxel data based on voxel coordinates
   19.24 +	inline void set_voxel(int x, int y, int z, const Vector4 &val);
   19.25 +	inline void set_voxel_color(int x, int y, int z, const Vector3 &col);
   19.26 +	inline void set_voxel_alpha(int x, int y, int z, float alpha);
   19.27 +
   19.28 +	inline const Vector4 &get_voxel(int x, int y, int z) const;
   19.29 +	inline const Vector3 get_voxel_color(int x, int y, int z) const;
   19.30 +	inline float get_voxel_alpha(int x, int y, int z) const;
   19.31 +
   19.32 +	// linear access to the voxel data
   19.33 +	inline Vector4 &operator [](int idx);
   19.34 +	inline const Vector4 &operator [](int idx) const;
   19.35 +
   19.36 +	// raw access to the voxel data for building the OpenGL texture directly
   19.37 +	inline const Vector4 *get_data_ptr() const;
   19.38 +};
   19.39 +
   19.40 +#include "volume.inl"
   19.41 +
   19.42 +#endif	// VOLUME_H_
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/volume.inl	Sat Dec 15 23:43:03 2012 +0200
    20.3 @@ -0,0 +1,88 @@
    20.4 +Volume::Volume(int xsz, int ysz, int zsz)
    20.5 +{
    20.6 +	this->xsz = xsz;
    20.7 +	this->ysz = ysz;
    20.8 +	this->zsz = zsz;
    20.9 +	slice_size = xsz * ysz;
   20.10 +
   20.11 +	voxels = new Vector4[xsz * ysz * zsz];
   20.12 +
   20.13 +	// precalculate slice start pointers, cause why not...
   20.14 +	slices = new Vector4*[zsz];
   20.15 +	for(int i=0; i<zsz; i++) {
   20.16 +		slices[i] = voxels + i * slice_size;
   20.17 +	}
   20.18 +}
   20.19 +
   20.20 +Volume::~Volume()
   20.21 +{
   20.22 +	delete [] voxels;
   20.23 +}
   20.24 +
   20.25 +int Volume::get_size(int idx) const
   20.26 +{
   20.27 +	switch(idx) {
   20.28 +	case 0:
   20.29 +		return xsz;
   20.30 +	case 1:
   20.31 +		return ysz;
   20.32 +	case 2:
   20.33 +		return zsz;
   20.34 +	default:
   20.35 +		break;
   20.36 +	}
   20.37 +	return xsz * ysz * zsz;
   20.38 +}
   20.39 +
   20.40 +void Volume::set_voxel(int x, int y, int z, const Vector4 &val)
   20.41 +{
   20.42 +	slices[z][y * xsz + x] = val;
   20.43 +}
   20.44 +
   20.45 +void Volume::set_voxel_color(int x, int y, int z, const Vector3 &col)
   20.46 +{
   20.47 +	Vector4 *ptr = slices[z] + y * xsz + x;
   20.48 +	ptr->x = col.x;
   20.49 +	ptr->y = col.y;
   20.50 +	ptr->z = col.z;
   20.51 +}
   20.52 +
   20.53 +void Volume::set_voxel_alpha(int x, int y, int z, float alpha)
   20.54 +{
   20.55 +	slices[z][y * xsz + x].w = alpha;
   20.56 +}
   20.57 +
   20.58 +
   20.59 +const Vector4 &Volume::get_voxel(int x, int y, int z) const
   20.60 +{
   20.61 +	return slices[z][y * xsz + x];
   20.62 +}
   20.63 +
   20.64 +const Vector3 Volume::get_voxel_color(int x, int y, int z) const
   20.65 +{
   20.66 +	Vector4 *ptr = slices[z] + y * xsz + x;
   20.67 +	return Vector3(ptr->x, ptr->y, ptr->z);
   20.68 +}
   20.69 +
   20.70 +float Volume::get_voxel_alpha(int x, int y, int z) const
   20.71 +{
   20.72 +	return slices[z][y * xsz + x].w;
   20.73 +}
   20.74 +
   20.75 +
   20.76 +Vector4 &Volume::operator [](int idx)
   20.77 +{
   20.78 +	return voxels[idx];
   20.79 +}
   20.80 +
   20.81 +const Vector4 &Volume::operator [](int idx) const
   20.82 +{
   20.83 +	return voxels[idx];
   20.84 +}
   20.85 +
   20.86 +
   20.87 +const Vector4 *Volume::get_data_ptr() const
   20.88 +{
   20.89 +	return voxels;
   20.90 +}
   20.91 +