bloboland

changeset 3:a39c301cdcce

terrain raytracing pretty much done
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 16 Dec 2012 14:24:16 +0200
parents 1757973feaed
children 9021a906c5d3
files Makefile README RUN sdr/bloboray.p.glsl sdr/bloboray.v.glsl src/camera.cc src/game.cc src/level.cc src/renderer.cc src/renderer.h src/sdr.c src/sdr.h src/shaders.cc src/shaders.h src/texture.cc src/texture.h
diffstat 16 files changed, 766 insertions(+), 406 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Sun Dec 16 00:37:35 2012 +0200
     1.2 +++ b/Makefile	Sun Dec 16 14:24:16 2012 +0200
     1.3 @@ -1,11 +1,13 @@
     1.4 -src = $(wildcard src/*.cc)
     1.5 -obj = $(src:.cc=.o)
     1.6 +csrc = $(wildcard src/*.c)
     1.7 +ccsrc = $(wildcard src/*.cc)
     1.8 +obj = $(csrc:.c=.o) $(ccsrc:.cc=.o)
     1.9  dep = $(obj:.o=.d)
    1.10  bin = blobo
    1.11  
    1.12  opt = -O3 -ffast-math
    1.13  dbg = -g
    1.14  
    1.15 +CFLAGS = -pedantic -Wall $(opt) $(dbg)
    1.16  CXXFLAGS = -ansi -pedantic -Wall $(opt) $(dbg)
    1.17  LDFLAGS = $(libgl) -lvmath -limago
    1.18  
    1.19 @@ -20,8 +22,11 @@
    1.20  
    1.21  -include $(dep)
    1.22  
    1.23 +%.d: %.c
    1.24 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.25 +
    1.26  %.d: %.cc
    1.27 -	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.28 +	@$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.29  
    1.30  .PHONY: clean
    1.31  clean:
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/README	Sun Dec 16 14:24:16 2012 +0200
     2.3 @@ -0,0 +1,3 @@
     2.4 +bloboland
     2.5 +---------
     2.6 +by John Tsiombikas (nuclear)
     3.1 --- a/RUN	Sun Dec 16 00:37:35 2012 +0200
     3.2 +++ b/RUN	Sun Dec 16 14:24:16 2012 +0200
     3.3 @@ -1,3 +1,3 @@
     3.4  #!/bin/sh
     3.5  
     3.6 -./blobo -world 100x100x32 -genscale 10 $*
     3.7 +./blobo -world 128x128x80 -genscale 10 -size 1024x640 $*
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/sdr/bloboray.p.glsl	Sun Dec 16 14:24:16 2012 +0200
     4.3 @@ -0,0 +1,152 @@
     4.4 +struct Ray {
     4.5 +	vec3 origin;
     4.6 +	vec3 dir;
     4.7 +};
     4.8 +
     4.9 +struct AABBox {
    4.10 +	vec3 vmin, vmax;
    4.11 +};
    4.12 +
    4.13 +struct HitPoint {
    4.14 +	bool hit;
    4.15 +	float t0, t1;
    4.16 +	vec3 pos, normal;
    4.17 +	vec4 color;
    4.18 +};
    4.19 +
    4.20 +vec3 shade(Ray ray, HitPoint hit);
    4.21 +HitPoint intersect_voxels(Ray ray);
    4.22 +HitPoint intersect_aabb(Ray ray, AABBox aabb);
    4.23 +Ray get_primary_ray(float x, float y);
    4.24 +
    4.25 +#define RAY_STEP	0.001
    4.26 +
    4.27 +#define FOV		camprop.x
    4.28 +#define ASPECT	camprop.y
    4.29 +uniform vec4 camprop;
    4.30 +uniform vec3 volsize;
    4.31 +uniform sampler3D voltex;
    4.32 +
    4.33 +//const vec3 worldsize = vec3(4.0, 4.0, 2.0);
    4.34 +const vec3 worldsize = vec3(1.0, 1.0, 0.5);
    4.35 +
    4.36 +void main()
    4.37 +{
    4.38 +	Ray ray = get_primary_ray(gl_TexCoord[0].x, gl_TexCoord[0].y);
    4.39 +
    4.40 +	vec3 color = vec3(0.0, 0.0, 0.0);
    4.41 +	HitPoint hit = intersect_voxels(ray);
    4.42 +	if(hit.hit) {
    4.43 +		color = shade(ray, hit);
    4.44 +	}
    4.45 +
    4.46 +	gl_FragColor = vec4(color, 1.0);
    4.47 +}
    4.48 +
    4.49 +vec3 shade(Ray ray, HitPoint hit)
    4.50 +{
    4.51 +	const vec3 light_pos = vec3(-2, 3, 2);
    4.52 +	vec3 ldir = normalize(light_pos - hit.pos);
    4.53 +
    4.54 +	vec3 vdir = normalize(-ray.dir);
    4.55 +	vec3 hvec = normalize(vdir + ldir);
    4.56 +
    4.57 +	float ndotl = max(dot(hit.normal, ldir), 0.0);
    4.58 +	float ndoth = max(dot(hit.normal, hvec), 0.0);
    4.59 +
    4.60 +	vec3 diffuse = hit.color.xyz * ndotl;
    4.61 +	vec3 specular = vec3(0.4, 0.4, 0.4) * pow(ndoth, 60.0);
    4.62 +
    4.63 +	return diffuse + specular;
    4.64 +}
    4.65 +
    4.66 +vec4 fetch_voxel(vec3 pt)
    4.67 +{
    4.68 +	pt *= 1.0 / worldsize;
    4.69 +	return texture3D(voltex, pt * 0.5 + 0.5);
    4.70 +}
    4.71 +
    4.72 +vec3 calc_voxel_normal(vec3 pt)
    4.73 +{
    4.74 +	vec3 offs = 1.8 / volsize;
    4.75 +	float dfdx = fetch_voxel(pt + vec3(offs.x, 0.0, 0.0)).w - fetch_voxel(pt - vec3(offs.x, 0.0, 0.0)).w;
    4.76 +	float dfdy = fetch_voxel(pt + vec3(0.0, offs.y, 0.0)).w - fetch_voxel(pt - vec3(0.0, offs.y, 0.0)).w;
    4.77 +	float dfdz = fetch_voxel(pt + vec3(0.0, 0.0, offs.z)).w - fetch_voxel(pt - vec3(0.0, 0.0, offs.z)).w;
    4.78 +
    4.79 +	return -normalize(vec3(dfdx, dfdy, dfdz));
    4.80 +}
    4.81 +
    4.82 +HitPoint intersect_voxels(Ray ray)
    4.83 +{
    4.84 +	HitPoint hit;
    4.85 +	//AABBox aabb = AABBox(vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0));
    4.86 +	AABBox aabb = AABBox(-worldsize.xzy, worldsize.xzy);
    4.87 +
    4.88 +
    4.89 +	hit = intersect_aabb(ray, aabb);
    4.90 +	if(!hit.hit) {
    4.91 +		return hit;
    4.92 +	}
    4.93 +
    4.94 +	/* start tracing from the first intersection, or if it's behind
    4.95 +	 * the viewer, start from 0.
    4.96 +	 */
    4.97 +	float dist = max(hit.t0, 0.0);
    4.98 +	float end_dist = hit.t1;
    4.99 +
   4.100 +	while(dist < end_dist) {
   4.101 +		vec3 pt = ray.origin + ray.dir * dist;
   4.102 +		vec4 voxel = fetch_voxel(pt.xzy);
   4.103 +
   4.104 +
   4.105 +		if(voxel.a > 0.5) {
   4.106 +			hit.t0 = dist;
   4.107 +			hit.pos = pt;
   4.108 +			hit.normal = calc_voxel_normal(pt.xzy).xzy;
   4.109 +			hit.color = voxel;
   4.110 +			return hit;
   4.111 +		}
   4.112 +
   4.113 +		dist += RAY_STEP;
   4.114 +	}
   4.115 +
   4.116 +	hit.hit = false;
   4.117 +	return hit;
   4.118 +}
   4.119 +
   4.120 +HitPoint intersect_aabb(Ray ray, AABBox aabb)
   4.121 +{
   4.122 +	HitPoint res;
   4.123 +
   4.124 +	vec3 invR = 1.0 / ray.dir;
   4.125 +    vec3 tbot = invR * (aabb.vmin - ray.origin);
   4.126 +    vec3 ttop = invR * (aabb.vmax - ray.origin);
   4.127 +    vec3 tmin = min(ttop, tbot);
   4.128 +    vec3 tmax = max(ttop, tbot);
   4.129 +    vec2 t = max(tmin.xx, tmin.yz);
   4.130 +    float t0 = max(t.x, t.y);
   4.131 +    t = min(tmax.xx, tmax.yz);
   4.132 +    float t1 = min(t.x, t.y);
   4.133 +
   4.134 +	if(t0 <= t1) {
   4.135 +		res.hit = true;
   4.136 +		res.t0 = t0;
   4.137 +		res.t1 = t1;
   4.138 +	} else {
   4.139 +		res.hit = false;
   4.140 +	}
   4.141 +	return res;
   4.142 +}
   4.143 +
   4.144 +Ray get_primary_ray(float x, float y)
   4.145 +{
   4.146 +	vec3 dir;
   4.147 +	dir.x = ASPECT * (2.0 * x - 1.0);
   4.148 +	dir.y = 2.0 * y - 1.0;
   4.149 +	dir.z = -1.0 / tan(FOV / 2.0);
   4.150 +
   4.151 +	Ray ray;
   4.152 +	ray.origin = (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)).xyz;
   4.153 +	ray.dir = gl_NormalMatrix * normalize(dir);
   4.154 +	return ray;
   4.155 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/sdr/bloboray.v.glsl	Sun Dec 16 14:24:16 2012 +0200
     5.3 @@ -0,0 +1,5 @@
     5.4 +void main()
     5.5 +{
     5.6 +	gl_Position = gl_Vertex;
     5.7 +	gl_TexCoord[0] = gl_MultiTexCoord0;
     5.8 +}
     6.1 --- a/src/camera.cc	Sun Dec 16 00:37:35 2012 +0200
     6.2 +++ b/src/camera.cc	Sun Dec 16 14:24:16 2012 +0200
     6.3 @@ -148,8 +148,8 @@
     6.4  {
     6.5  	mat->reset_identity();
     6.6  	mat->translate(Vector3(pos.x, pos.y, pos.z));
     6.7 -	mat->rotate(Vector3(0, theta, 0));
     6.8 -	mat->rotate(Vector3(phi, 0, 0));
     6.9 +	mat->rotate(Vector3(0, -theta, 0));
    6.10 +	mat->rotate(Vector3(-phi, 0, 0));
    6.11  }
    6.12  
    6.13  void FpsCamera::calc_inv_matrix(Matrix4x4 *mat) const
     7.1 --- a/src/game.cc	Sun Dec 16 00:37:35 2012 +0200
     7.2 +++ b/src/game.cc	Sun Dec 16 14:24:16 2012 +0200
     7.3 @@ -31,14 +31,16 @@
     7.4  	float lpos[] = {-1, 1, 1, 0};
     7.5  	glLightfv(GL_LIGHT0, GL_POSITION, lpos);
     7.6  
     7.7 -	printf("initializing renderer\n");
     7.8 -	rend = new Renderer;
     7.9 -	rend->init();
    7.10 -
    7.11  	printf("generating level\n");
    7.12  	level = new Level;
    7.13  	level->generate();
    7.14  
    7.15 +	printf("initializing renderer\n");
    7.16 +	rend = new Renderer;
    7.17 +	if(!rend->init(level)) {
    7.18 +		return false;
    7.19 +	}
    7.20 +
    7.21  	cam.input_move(0, 2, 2);
    7.22  	cam.input_rotate(0, M_PI / 5, 0);
    7.23  
    7.24 @@ -75,6 +77,8 @@
    7.25  
    7.26  void game_render()
    7.27  {
    7.28 +	rend->set_aspect((float)win_xsz / (float)win_ysz);
    7.29 +
    7.30  	if(opt.stereo) {
    7.31  		glDrawBuffer(GL_BACK_LEFT);
    7.32  
    7.33 @@ -85,7 +89,7 @@
    7.34  		glLoadIdentity();
    7.35  		view_matrix(-1);
    7.36  
    7.37 -		rend->render(level);
    7.38 +		rend->render();
    7.39  
    7.40  		glDrawBuffer(GL_BACK_RIGHT);
    7.41  
    7.42 @@ -96,7 +100,7 @@
    7.43  		glLoadIdentity();
    7.44  		view_matrix(1);
    7.45  
    7.46 -		rend->render(level);
    7.47 +		rend->render();
    7.48  	} else {
    7.49  		glMatrixMode(GL_PROJECTION);
    7.50  		glLoadIdentity();
    7.51 @@ -105,7 +109,7 @@
    7.52  		glLoadIdentity();
    7.53  		view_matrix(0);
    7.54  
    7.55 -		rend->render(level);
    7.56 +		rend->render();
    7.57  	}
    7.58  }
    7.59  
    7.60 @@ -128,7 +132,7 @@
    7.61  {
    7.62  	float offs = stereo_eye_sep * eye * 0.5;
    7.63  	glTranslatef(-offs, 0, 0);
    7.64 -	cam.use_inverse();
    7.65 +	cam.use();
    7.66  }
    7.67  
    7.68  static void proj_matrix(int eye)
     8.1 --- a/src/level.cc	Sun Dec 16 00:37:35 2012 +0200
     8.2 +++ b/src/level.cc	Sun Dec 16 14:24:16 2012 +0200
     8.3 @@ -12,6 +12,19 @@
     8.4  	delete terrain;
     8.5  }
     8.6  
     8.7 +static float terrain_func(float x, float y, float z)
     8.8 +{
     8.9 +	float nx = (x * 2.0 - 1.0) * 0.9;
    8.10 +	float ny = (y * 2.0 - 1.0) * 0.9;
    8.11 +	float valley = nx * nx + ny * ny;
    8.12 +
    8.13 +	float s = opt.gen_noise_scale;
    8.14 +	float noise = 0.2 * fbm2(x * s, y * s, 3) * (valley + 0.25);
    8.15 +	float grad = 0.75 - z + noise + valley * 0.4;
    8.16 +
    8.17 +	return grad;
    8.18 +}
    8.19 +
    8.20  void Level::generate()
    8.21  {
    8.22  	delete terrain;
    8.23 @@ -24,29 +37,33 @@
    8.24  
    8.25  	for(int i=0; i<xsz; i++) {
    8.26  		for(int j=0; j<ysz; j++) {
    8.27 -			float x = opt.gen_noise_scale * (float)i / (float)xsz;
    8.28 -			float y = opt.gen_noise_scale * (float)j / (float)ysz;
    8.29 -			float peak = 0.4 * noise2(x, y) * 0.5 + 0.5;
    8.30 +			float x = (float)i / (float)xsz;
    8.31 +			float y = (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 +				float alpha = terrain_func(x, y, z);
    8.39 +
    8.40  				if(z < 0.1) {
    8.41  					// lava
    8.42  					static const Vector4 col1(0.96, 0.3, 0.1, 1);
    8.43  					static const Vector4 col2(0.96, 0.75, 0.1, 1);
    8.44 -					float t = noise3(x, y, z);
    8.45 +					float t = noise3(x, y, z) * 0.5 + 0.5;
    8.46  					voxel = lerp(col1, col2, t);
    8.47 -				} else if(z < peak - 0.05) {
    8.48 -					// mud
    8.49 -					voxel = Vector4(0.57, 0.43, 0.29, 1);
    8.50 -				} else if(z < 0.85) {
    8.51 -					// grass
    8.52 -					voxel = Vector4(0.68, 0.95, 0.38);
    8.53 +				} else if(z < 0.8) {
    8.54 +					if(alpha < 0.56) {
    8.55 +						// grass
    8.56 +						voxel = Vector4(0.68, 0.95, 0.38);
    8.57 +					} else {
    8.58 +						// mud
    8.59 +						voxel = Vector4(0.57, 0.43, 0.29, 1);
    8.60 +					}
    8.61  				}	// else snow (default)
    8.62  
    8.63 -				voxel.w = z < peak ? 1.0 : 0.0;
    8.64 +				voxel.w = alpha;
    8.65  				terrain->set_voxel(i, j, k, voxel);
    8.66  			}
    8.67  		}
     9.1 --- a/src/renderer.cc	Sun Dec 16 00:37:35 2012 +0200
     9.2 +++ b/src/renderer.cc	Sun Dec 16 14:24:16 2012 +0200
     9.3 @@ -1,10 +1,16 @@
     9.4  #include "opengl.h"
     9.5  #include "renderer.h"
     9.6 +#include "sdr.h"
     9.7  
     9.8  Renderer::Renderer()
     9.9  {
    9.10  	leveltex = 0;
    9.11  	sdrprog = 0;
    9.12 +
    9.13 +	level = 0;
    9.14 +
    9.15 +	fov = M_PI / 4.0;
    9.16 +	aspect = 1.0;
    9.17  }
    9.18  
    9.19  Renderer::~Renderer()
    9.20 @@ -12,14 +18,18 @@
    9.21  	shutdown();
    9.22  }
    9.23  
    9.24 -bool Renderer::init()
    9.25 +bool Renderer::init(Level *level)
    9.26  {
    9.27 -	sdrprog = new SdrProg;
    9.28 -	/*if(!sdrprog->load("sdr/bloboray.v.glsl", "sdr/bloboray.p.glsl")) {
    9.29 +	if(!(sdrprog = create_program_load("sdr/bloboray.v.glsl", "sdr/bloboray.p.glsl"))) {
    9.30  		return false;
    9.31 -	}*/
    9.32 +	}
    9.33 +
    9.34 +	Volume *vol = level->terrain;
    9.35  
    9.36  	leveltex = new Texture3D;
    9.37 +	leveltex->create(vol->get_size(0), vol->get_size(1), vol->get_size(2));
    9.38 +
    9.39 +	this->level = level;
    9.40  
    9.41  	return true;
    9.42  }
    9.43 @@ -27,16 +37,48 @@
    9.44  void Renderer::shutdown()
    9.45  {
    9.46  	delete leveltex;
    9.47 -	delete sdrprog;
    9.48 +	if(sdrprog) {
    9.49 +		free_program(sdrprog);
    9.50 +	}
    9.51 +}
    9.52 +
    9.53 +void Renderer::set_fov(float fov)
    9.54 +{
    9.55 +	this->fov = fov;
    9.56 +}
    9.57 +
    9.58 +void Renderer::set_aspect(float aspect)
    9.59 +{
    9.60 +	this->aspect = aspect;
    9.61  }
    9.62  
    9.63  static void draw_cube(const Vector3 &pos, float sz);
    9.64  
    9.65 -void Renderer::render(const Level *lvl) const
    9.66 +void Renderer::render() const
    9.67  {
    9.68 -	Volume *vol = lvl->terrain;
    9.69 +	leveltex->update((float*)level->terrain->get_data_ptr());
    9.70 +	bind_texture(leveltex);
    9.71  
    9.72 -	glEnable(GL_COLOR_MATERIAL);
    9.73 +	set_uniform_float3(sdrprog, "volsize", level->terrain->get_size(0),
    9.74 +			level->terrain->get_size(1), level->terrain->get_size(2));
    9.75 +	set_uniform_float4(sdrprog, "camprop", fov, aspect, 0, 0);
    9.76 +	bind_program(sdrprog);
    9.77 +
    9.78 +	glBegin(GL_QUADS);
    9.79 +	glTexCoord2f(0, 0);
    9.80 +	glVertex2f(-1, -1);
    9.81 +	glTexCoord2f(1, 0);
    9.82 +	glVertex2f(1, -1);
    9.83 +	glTexCoord2f(1, 1);
    9.84 +	glVertex2f(1, 1);
    9.85 +	glTexCoord2f(0, 1);
    9.86 +	glVertex2f(-1, 1);
    9.87 +	glEnd();
    9.88 +
    9.89 +	bind_program(0);
    9.90 +	bind_texture(0);
    9.91 +
    9.92 +	/*glEnable(GL_COLOR_MATERIAL);
    9.93  	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    9.94  
    9.95  	glBegin(GL_QUADS);
    9.96 @@ -60,6 +102,7 @@
    9.97  	glEnd();
    9.98  
    9.99  	glDisable(GL_COLOR_MATERIAL);
   9.100 +	*/
   9.101  }
   9.102  
   9.103  
    10.1 --- a/src/renderer.h	Sun Dec 16 00:37:35 2012 +0200
    10.2 +++ b/src/renderer.h	Sun Dec 16 14:24:16 2012 +0200
    10.3 @@ -1,23 +1,28 @@
    10.4  #ifndef RENDERER_H_
    10.5  #define RENDERER_H_
    10.6  
    10.7 -#include "shaders.h"
    10.8  #include "texture.h"
    10.9  #include "level.h"
   10.10  
   10.11  class Renderer {
   10.12  private:
   10.13 -	mutable Texture3D *leveltex;
   10.14 -	SdrProg *sdrprog;
   10.15 +	Level *level;
   10.16 +	Texture3D *leveltex;
   10.17 +	unsigned int sdrprog;
   10.18 +
   10.19 +	float fov, aspect;
   10.20  
   10.21  public:
   10.22  	Renderer();
   10.23  	~Renderer();
   10.24  
   10.25 -	bool init();
   10.26 +	bool init(Level *lvl);
   10.27  	void shutdown();
   10.28  
   10.29 -	void render(const Level *lvl) const;
   10.30 +	void set_fov(float fov);
   10.31 +	void set_aspect(float aspect);
   10.32 +
   10.33 +	void render() const;
   10.34  };
   10.35  
   10.36  #endif	// RENDERER_H_
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/sdr.c	Sun Dec 16 14:24:16 2012 +0200
    11.3 @@ -0,0 +1,410 @@
    11.4 +#include <stdio.h>
    11.5 +#include <stdlib.h>
    11.6 +#include <string.h>
    11.7 +#include <errno.h>
    11.8 +#include <stdarg.h>
    11.9 +#include <assert.h>
   11.10 +#include <GL/glew.h>
   11.11 +
   11.12 +#if defined(unix) || defined(__unix__)
   11.13 +#include <unistd.h>
   11.14 +#include <sys/stat.h>
   11.15 +#endif	/* unix */
   11.16 +
   11.17 +#include "sdr.h"
   11.18 +
   11.19 +static const char *sdrtypestr(unsigned int sdrtype);
   11.20 +
   11.21 +unsigned int create_vertex_shader(const char *src)
   11.22 +{
   11.23 +	return create_shader(src, GL_VERTEX_SHADER);
   11.24 +}
   11.25 +
   11.26 +unsigned int create_pixel_shader(const char *src)
   11.27 +{
   11.28 +	return create_shader(src, GL_FRAGMENT_SHADER);
   11.29 +}
   11.30 +
   11.31 +unsigned int create_tessctl_shader(const char *src)
   11.32 +{
   11.33 +	return create_shader(src, GL_TESS_CONTROL_SHADER);
   11.34 +}
   11.35 +
   11.36 +unsigned int create_tesseval_shader(const char *src)
   11.37 +{
   11.38 +	return create_shader(src, GL_TESS_EVALUATION_SHADER);
   11.39 +}
   11.40 +
   11.41 +unsigned int create_geometry_shader(const char *src)
   11.42 +{
   11.43 +	return create_shader(src, GL_GEOMETRY_SHADER);
   11.44 +}
   11.45 +
   11.46 +unsigned int create_shader(const char *src, unsigned int sdr_type)
   11.47 +{
   11.48 +	unsigned int sdr;
   11.49 +	int success, info_len;
   11.50 +	char *info_str = 0;
   11.51 +	GLenum err;
   11.52 +
   11.53 +	sdr = glCreateShader(sdr_type);
   11.54 +	assert(glGetError() == GL_NO_ERROR);
   11.55 +	glShaderSource(sdr, 1, &src, 0);
   11.56 +	err = glGetError();
   11.57 +	assert(err == GL_NO_ERROR);
   11.58 +	glCompileShader(sdr);
   11.59 +	assert(glGetError() == GL_NO_ERROR);
   11.60 +
   11.61 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &success);
   11.62 +	assert(glGetError() == GL_NO_ERROR);
   11.63 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
   11.64 +	assert(glGetError() == GL_NO_ERROR);
   11.65 +
   11.66 +	if(info_len) {
   11.67 +		if((info_str = malloc(info_len + 1))) {
   11.68 +			glGetShaderInfoLog(sdr, info_len, 0, info_str);
   11.69 +			assert(glGetError() == GL_NO_ERROR);
   11.70 +		}
   11.71 +	}
   11.72 +
   11.73 +	if(success) {
   11.74 +		fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
   11.75 +	} else {
   11.76 +		fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
   11.77 +		glDeleteShader(sdr);
   11.78 +		sdr = 0;
   11.79 +	}
   11.80 +
   11.81 +	free(info_str);
   11.82 +	return sdr;
   11.83 +}
   11.84 +
   11.85 +void free_shader(unsigned int sdr)
   11.86 +{
   11.87 +	glDeleteShader(sdr);
   11.88 +}
   11.89 +
   11.90 +unsigned int load_vertex_shader(const char *fname)
   11.91 +{
   11.92 +	return load_shader(fname, GL_VERTEX_SHADER);
   11.93 +}
   11.94 +
   11.95 +unsigned int load_pixel_shader(const char *fname)
   11.96 +{
   11.97 +	return load_shader(fname, GL_FRAGMENT_SHADER);
   11.98 +}
   11.99 +
  11.100 +unsigned int load_tessctl_shader(const char *fname)
  11.101 +{
  11.102 +	return load_shader(fname, GL_TESS_CONTROL_SHADER);
  11.103 +}
  11.104 +
  11.105 +unsigned int load_tesseval_shader(const char *fname)
  11.106 +{
  11.107 +	return load_shader(fname, GL_TESS_EVALUATION_SHADER);
  11.108 +}
  11.109 +
  11.110 +unsigned int load_geometry_shader(const char *fname)
  11.111 +{
  11.112 +	return load_shader(fname, GL_GEOMETRY_SHADER);
  11.113 +}
  11.114 +
  11.115 +unsigned int load_shader(const char *fname, unsigned int sdr_type)
  11.116 +{
  11.117 +#if defined(unix) || defined(__unix__)
  11.118 +	struct stat st;
  11.119 +#endif
  11.120 +	unsigned int sdr;
  11.121 +	size_t filesize;
  11.122 +	FILE *fp;
  11.123 +	char *src;
  11.124 +
  11.125 +	if(!(fp = fopen(fname, "r"))) {
  11.126 +		fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
  11.127 +		return 0;
  11.128 +	}
  11.129 +
  11.130 +#if defined(unix) || defined(__unix__)
  11.131 +	fstat(fileno(fp), &st);
  11.132 +	filesize = st.st_size;
  11.133 +#else
  11.134 +	fseek(fp, 0, SEEK_END);
  11.135 +	filesize = ftell(fp);
  11.136 +	fseek(fp, 0, SEEK_SET);
  11.137 +#endif	/* unix */
  11.138 +
  11.139 +	if(!(src = malloc(filesize + 1))) {
  11.140 +		fclose(fp);
  11.141 +		return 0;
  11.142 +	}
  11.143 +	fread(src, 1, filesize, fp);
  11.144 +	src[filesize] = 0;
  11.145 +	fclose(fp);
  11.146 +
  11.147 +	fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname);
  11.148 +	sdr = create_shader(src, sdr_type);
  11.149 +
  11.150 +	free(src);
  11.151 +	return sdr;
  11.152 +}
  11.153 +
  11.154 +
  11.155 +unsigned int get_vertex_shader(const char *fname)
  11.156 +{
  11.157 +	return get_shader(fname, GL_VERTEX_SHADER);
  11.158 +}
  11.159 +
  11.160 +unsigned int get_pixel_shader(const char *fname)
  11.161 +{
  11.162 +	return get_shader(fname, GL_FRAGMENT_SHADER);
  11.163 +}
  11.164 +
  11.165 +unsigned int get_tessctl_shader(const char *fname)
  11.166 +{
  11.167 +	return get_shader(fname, GL_TESS_CONTROL_SHADER);
  11.168 +}
  11.169 +
  11.170 +unsigned int get_tesseval_shader(const char *fname)
  11.171 +{
  11.172 +	return get_shader(fname, GL_TESS_EVALUATION_SHADER);
  11.173 +}
  11.174 +
  11.175 +unsigned int get_geometry_shader(const char *fname)
  11.176 +{
  11.177 +	return get_shader(fname, GL_GEOMETRY_SHADER);
  11.178 +}
  11.179 +
  11.180 +unsigned int get_shader(const char *fname, unsigned int sdr_type)
  11.181 +{
  11.182 +	unsigned int sdr;
  11.183 +	if(!(sdr = load_shader(fname, sdr_type))) {
  11.184 +		return 0;
  11.185 +	}
  11.186 +	return sdr;
  11.187 +}
  11.188 +
  11.189 +
  11.190 +/* ---- gpu programs ---- */
  11.191 +
  11.192 +unsigned int create_program(void)
  11.193 +{
  11.194 +	unsigned int prog = glCreateProgram();
  11.195 +	assert(glGetError() == GL_NO_ERROR);
  11.196 +	return prog;
  11.197 +}
  11.198 +
  11.199 +unsigned int create_program_link(unsigned int sdr0, ...)
  11.200 +{
  11.201 +	unsigned int prog, sdr;
  11.202 +	va_list ap;
  11.203 +
  11.204 +	if(!(prog = create_program())) {
  11.205 +		return 0;
  11.206 +	}
  11.207 +
  11.208 +	attach_shader(prog, sdr0);
  11.209 +	if(glGetError()) {
  11.210 +		return 0;
  11.211 +	}
  11.212 +
  11.213 +	va_start(ap, sdr0);
  11.214 +	while((sdr = va_arg(ap, unsigned int))) {
  11.215 +		attach_shader(prog, sdr);
  11.216 +		if(glGetError()) {
  11.217 +			return 0;
  11.218 +		}
  11.219 +	}
  11.220 +	va_end(ap);
  11.221 +
  11.222 +	if(link_program(prog) == -1) {
  11.223 +		free_program(prog);
  11.224 +		return 0;
  11.225 +	}
  11.226 +	return prog;
  11.227 +}
  11.228 +
  11.229 +unsigned int create_program_load(const char *vfile, const char *pfile)
  11.230 +{
  11.231 +	unsigned int vs = 0, ps = 0;
  11.232 +
  11.233 +	if(vfile && *vfile && !(vs = get_vertex_shader(vfile))) {
  11.234 +		return 0;
  11.235 +	}
  11.236 +	if(pfile && *pfile && !(ps = get_pixel_shader(pfile))) {
  11.237 +		return 0;
  11.238 +	}
  11.239 +	return create_program_link(vs, ps, 0);
  11.240 +}
  11.241 +
  11.242 +void free_program(unsigned int sdr)
  11.243 +{
  11.244 +	glDeleteProgram(sdr);
  11.245 +}
  11.246 +
  11.247 +void attach_shader(unsigned int prog, unsigned int sdr)
  11.248 +{
  11.249 +	glAttachShader(prog, sdr);
  11.250 +	assert(glGetError() == GL_NO_ERROR);
  11.251 +}
  11.252 +
  11.253 +int link_program(unsigned int prog)
  11.254 +{
  11.255 +	int linked, info_len, retval = 0;
  11.256 +	char *info_str = 0;
  11.257 +
  11.258 +	glLinkProgram(prog);
  11.259 +	assert(glGetError() == GL_NO_ERROR);
  11.260 +	glGetProgramiv(prog, GL_LINK_STATUS, &linked);
  11.261 +	assert(glGetError() == GL_NO_ERROR);
  11.262 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
  11.263 +	assert(glGetError() == GL_NO_ERROR);
  11.264 +
  11.265 +	if(info_len) {
  11.266 +		if((info_str = malloc(info_len + 1))) {
  11.267 +			glGetProgramInfoLog(prog, info_len, 0, info_str);
  11.268 +			assert(glGetError() == GL_NO_ERROR);
  11.269 +		}
  11.270 +	}
  11.271 +
  11.272 +	if(linked) {
  11.273 +		fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
  11.274 +	} else {
  11.275 +		fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
  11.276 +		retval = -1;
  11.277 +	}
  11.278 +
  11.279 +	free(info_str);
  11.280 +	return retval;
  11.281 +}
  11.282 +
  11.283 +int bind_program(unsigned int prog)
  11.284 +{
  11.285 +	GLenum err;
  11.286 +
  11.287 +	glUseProgram(prog);
  11.288 +	if(prog && (err = glGetError()) != GL_NO_ERROR) {
  11.289 +		/* maybe the program is not linked, try linking first */
  11.290 +		if(err == GL_INVALID_OPERATION) {
  11.291 +			if(link_program(prog) == -1) {
  11.292 +				return -1;
  11.293 +			}
  11.294 +			glUseProgram(prog);
  11.295 +			return glGetError() == GL_NO_ERROR ? 0 : -1;
  11.296 +		}
  11.297 +		return -1;
  11.298 +	}
  11.299 +	return 0;
  11.300 +}
  11.301 +
  11.302 +/* ugly but I'm not going to write the same bloody code over and over */
  11.303 +#define BEGIN_UNIFORM_CODE \
  11.304 +	int loc, curr_prog; \
  11.305 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \
  11.306 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \
  11.307 +		return -1; \
  11.308 +	} \
  11.309 +	if((loc = glGetUniformLocation(prog, name)) != -1)
  11.310 +
  11.311 +#define END_UNIFORM_CODE \
  11.312 +	if((unsigned int)curr_prog != prog) { \
  11.313 +		bind_program(curr_prog); \
  11.314 +	} \
  11.315 +	return loc == -1 ? -1 : 0
  11.316 +
  11.317 +int set_uniform_int(unsigned int prog, const char *name, int val)
  11.318 +{
  11.319 +	BEGIN_UNIFORM_CODE {
  11.320 +		glUniform1i(loc, val);
  11.321 +	}
  11.322 +	END_UNIFORM_CODE;
  11.323 +}
  11.324 +
  11.325 +int set_uniform_float(unsigned int prog, const char *name, float val)
  11.326 +{
  11.327 +	BEGIN_UNIFORM_CODE {
  11.328 +		glUniform1f(loc, val);
  11.329 +	}
  11.330 +	END_UNIFORM_CODE;
  11.331 +}
  11.332 +
  11.333 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y)
  11.334 +{
  11.335 +	BEGIN_UNIFORM_CODE {
  11.336 +		glUniform2f(loc, x, y);
  11.337 +	}
  11.338 +	END_UNIFORM_CODE;
  11.339 +}
  11.340 +
  11.341 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z)
  11.342 +{
  11.343 +	BEGIN_UNIFORM_CODE {
  11.344 +		glUniform3f(loc, x, y, z);
  11.345 +	}
  11.346 +	END_UNIFORM_CODE;
  11.347 +}
  11.348 +
  11.349 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w)
  11.350 +{
  11.351 +	BEGIN_UNIFORM_CODE {
  11.352 +		glUniform4f(loc, x, y, z, w);
  11.353 +	}
  11.354 +	END_UNIFORM_CODE;
  11.355 +}
  11.356 +
  11.357 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat)
  11.358 +{
  11.359 +	BEGIN_UNIFORM_CODE {
  11.360 +		glUniformMatrix4fv(loc, 1, GL_FALSE, mat);
  11.361 +	}
  11.362 +	END_UNIFORM_CODE;
  11.363 +}
  11.364 +
  11.365 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat)
  11.366 +{
  11.367 +	BEGIN_UNIFORM_CODE {
  11.368 +		glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
  11.369 +	}
  11.370 +	END_UNIFORM_CODE;
  11.371 +}
  11.372 +
  11.373 +int get_attrib_loc(unsigned int prog, const char *name)
  11.374 +{
  11.375 +	int loc, curr_prog;
  11.376 +
  11.377 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
  11.378 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) {
  11.379 +		return -1;
  11.380 +	}
  11.381 +
  11.382 +	loc = glGetAttribLocation(prog, (char*)name);
  11.383 +
  11.384 +	if((unsigned int)curr_prog != prog) {
  11.385 +		bind_program(curr_prog);
  11.386 +	}
  11.387 +	return loc;
  11.388 +}
  11.389 +
  11.390 +void set_attrib_float3(int attr_loc, float x, float y, float z)
  11.391 +{
  11.392 +	glVertexAttrib3f(attr_loc, x, y, z);
  11.393 +}
  11.394 +
  11.395 +static const char *sdrtypestr(unsigned int sdrtype)
  11.396 +{
  11.397 +	switch(sdrtype) {
  11.398 +	case GL_VERTEX_SHADER:
  11.399 +		return "vertex";
  11.400 +	case GL_FRAGMENT_SHADER:
  11.401 +		return "pixel";
  11.402 +	case GL_TESS_CONTROL_SHADER:
  11.403 +		return "tessellation control";
  11.404 +	case GL_TESS_EVALUATION_SHADER:
  11.405 +		return "tessellation evaluation";
  11.406 +	case GL_GEOMETRY_SHADER:
  11.407 +		return "geometry";
  11.408 +
  11.409 +	default:
  11.410 +		break;
  11.411 +	}
  11.412 +	return "<unknown>";
  11.413 +}
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/src/sdr.h	Sun Dec 16 14:24:16 2012 +0200
    12.3 @@ -0,0 +1,59 @@
    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_tessctl_shader(const char *src);
   12.15 +unsigned int create_tesseval_shader(const char *src);
   12.16 +unsigned int create_geometry_shader(const char *src);
   12.17 +unsigned int create_shader(const char *src, unsigned int sdr_type);
   12.18 +void free_shader(unsigned int sdr);
   12.19 +
   12.20 +unsigned int load_vertex_shader(const char *fname);
   12.21 +unsigned int load_pixel_shader(const char *fname);
   12.22 +unsigned int load_tessctl_shader(const char *fname);
   12.23 +unsigned int load_tesseval_shader(const char *fname);
   12.24 +unsigned int load_geometry_shader(const char *fname);
   12.25 +unsigned int load_shader(const char *src, unsigned int sdr_type);
   12.26 +
   12.27 +unsigned int get_vertex_shader(const char *fname);
   12.28 +unsigned int get_pixel_shader(const char *fname);
   12.29 +unsigned int get_tessctl_shader(const char *fname);
   12.30 +unsigned int get_tesseval_shader(const char *fname);
   12.31 +unsigned int get_geometry_shader(const char *fname);
   12.32 +unsigned int get_shader(const char *fname, unsigned int sdr_type);
   12.33 +
   12.34 +int add_shader(const char *fname, unsigned int sdr);
   12.35 +int remove_shader(const char *fname);
   12.36 +
   12.37 +/* ---- gpu programs ---- */
   12.38 +unsigned int create_program(void);
   12.39 +unsigned int create_program_link(unsigned int sdr0, ...);
   12.40 +unsigned int create_program_load(const char *vfile, const char *pfile);
   12.41 +void free_program(unsigned int sdr);
   12.42 +
   12.43 +void attach_shader(unsigned int prog, unsigned int sdr);
   12.44 +int link_program(unsigned int prog);
   12.45 +int bind_program(unsigned int prog);
   12.46 +
   12.47 +int set_uniform_int(unsigned int prog, const char *name, int val);
   12.48 +int set_uniform_float(unsigned int prog, const char *name, float val);
   12.49 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y);
   12.50 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z);
   12.51 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w);
   12.52 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat);
   12.53 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat);
   12.54 +
   12.55 +int get_attrib_loc(unsigned int prog, const char *name);
   12.56 +void set_attrib_float3(int attr_loc, float x, float y, float z);
   12.57 +
   12.58 +#ifdef __cplusplus
   12.59 +}
   12.60 +#endif	/* __cplusplus */
   12.61 +
   12.62 +#endif	/* SDR_H_ */
    13.1 --- a/src/shaders.cc	Sun Dec 16 00:37:35 2012 +0200
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,297 +0,0 @@
    13.4 -#include <stdio.h>
    13.5 -#include <assert.h>
    13.6 -#include <map>
    13.7 -#ifdef _MSC_VER
    13.8 -#include <memory.h>
    13.9 -#else
   13.10 -#include <alloca.h>
   13.11 -#endif
   13.12 -#include <GL/glew.h>
   13.13 -#include "shaders.h"
   13.14 -
   13.15 -Shader::Shader(unsigned int type)
   13.16 -{
   13.17 -	sdr = glCreateShader(type);
   13.18 -	compiled = false;
   13.19 -
   13.20 -	assert(glGetError() == GL_NO_ERROR);
   13.21 -}
   13.22 -
   13.23 -Shader::~Shader()
   13.24 -{
   13.25 -	glDeleteShader(sdr);
   13.26 -}
   13.27 -
   13.28 -void Shader::set_source(const char *src)
   13.29 -{
   13.30 -	glShaderSource(sdr, 1, &src, 0);
   13.31 -	compiled = false;
   13.32 -
   13.33 -	assert(glGetError() == GL_NO_ERROR);
   13.34 -}
   13.35 -
   13.36 -bool Shader::compile()
   13.37 -{
   13.38 -	if(compiled) {
   13.39 -		return true;
   13.40 -	}
   13.41 -
   13.42 -	glCompileShader(sdr);
   13.43 -
   13.44 -	int len;
   13.45 -	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &len);
   13.46 -	if(len) {
   13.47 -		char *buf = (char*)alloca(len + 1);
   13.48 -		glGetShaderInfoLog(sdr, len, &len, buf);
   13.49 -		fprintf(stderr, "compiler: %s\n", buf);
   13.50 -	}
   13.51 -
   13.52 -	int status;
   13.53 -	glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
   13.54 -	if(!status) {
   13.55 -		fprintf(stderr, "shader compilation failed\n");
   13.56 -		return false;
   13.57 -	}
   13.58 -
   13.59 -	compiled = true;
   13.60 -	return true;
   13.61 -}
   13.62 -
   13.63 -bool Shader::is_compiled() const
   13.64 -{
   13.65 -	return compiled;
   13.66 -}
   13.67 -
   13.68 -bool Shader::load(const char *fname)
   13.69 -{
   13.70 -	FILE *fp;
   13.71 -
   13.72 -	if(!(fp = fopen(fname, "rb"))) {
   13.73 -		fprintf(stderr, "failed to open shader file: %s\n", fname);
   13.74 -		return false;
   13.75 -	}
   13.76 -
   13.77 -	fseek(fp, 0, SEEK_END);
   13.78 -	long sz = ftell(fp);
   13.79 -	rewind(fp);
   13.80 -
   13.81 -	char *buf = new char[sz + 1];
   13.82 -	if((long)fread(buf, 1, sz, fp) < sz) {
   13.83 -		fprintf(stderr, "failed to read shader contents\n");
   13.84 -		fclose(fp);
   13.85 -		return false;
   13.86 -	}
   13.87 -	fclose(fp);
   13.88 -
   13.89 -	set_source(buf);
   13.90 -	delete [] buf;
   13.91 -
   13.92 -	return compile();
   13.93 -}
   13.94 -
   13.95 -// ---- shader manager ----
   13.96 -static std::map<std::string, Shader*> sdrcache;
   13.97 -
   13.98 -Shader *get_shader(const char *fname, unsigned int type)
   13.99 -{
  13.100 -	std::map<std::string, Shader*>::const_iterator it;
  13.101 -
  13.102 -	if((it = sdrcache.find(std::string(fname))) != sdrcache.end()) {
  13.103 -		return it->second;
  13.104 -	}
  13.105 -
  13.106 -	Shader *sdr = new Shader(type);
  13.107 -	if(!sdr->load(fname)) {
  13.108 -		delete sdr;
  13.109 -		return 0;
  13.110 -	}
  13.111 -	sdrcache[fname] = sdr;
  13.112 -	return sdr;
  13.113 -}
  13.114 -
  13.115 -
  13.116 -// ---- class SdrProg ----
  13.117 -
  13.118 -SdrProg::SdrProg()
  13.119 -{
  13.120 -	prog = glCreateProgram();
  13.121 -	linked = false;
  13.122 -	assert(glGetError() == GL_NO_ERROR);
  13.123 -}
  13.124 -
  13.125 -SdrProg::~SdrProg()
  13.126 -{
  13.127 -	glDeleteProgram(prog);
  13.128 -}
  13.129 -
  13.130 -void SdrProg::add_shader(Shader *sdr)
  13.131 -{
  13.132 -	if(sdr->compile()) {
  13.133 -		glAttachShader(prog, sdr->sdr);
  13.134 -		assert(glGetError() == GL_NO_ERROR);
  13.135 -
  13.136 -		shaders.push_back(sdr);
  13.137 -		linked = false;
  13.138 -	}
  13.139 -}
  13.140 -
  13.141 -bool SdrProg::link()
  13.142 -{
  13.143 -	if(linked) {
  13.144 -		return true;
  13.145 -	}
  13.146 -
  13.147 -	glLinkProgram(prog);
  13.148 -
  13.149 -	int len;
  13.150 -	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
  13.151 -	if(len) {
  13.152 -		char *buf = (char*)alloca(len + 1);
  13.153 -		glGetProgramInfoLog(prog, len, &len, buf);
  13.154 -		assert(glGetError() == GL_NO_ERROR);
  13.155 -		fprintf(stderr, "linker: %s\n", buf);
  13.156 -	}
  13.157 -
  13.158 -	int status;
  13.159 -	glGetProgramiv(prog, GL_LINK_STATUS, &status);
  13.160 -	if(!status) {
  13.161 -		fprintf(stderr, "program linking failed\n");
  13.162 -		return false;
  13.163 -	}
  13.164 -
  13.165 -	linked = true;
  13.166 -	return true;
  13.167 -}
  13.168 -
  13.169 -bool SdrProg::load(const char *vsfname, const char *psfname)
  13.170 -{
  13.171 -	Shader *sdr;
  13.172 -
  13.173 -	if(vsfname) {
  13.174 -		if(!(sdr = get_shader(vsfname, GL_VERTEX_SHADER))) {
  13.175 -			return false;
  13.176 -		}
  13.177 -		add_shader(sdr);
  13.178 -	}
  13.179 -
  13.180 -	if(psfname) {
  13.181 -		if(!(sdr = get_shader(psfname, GL_FRAGMENT_SHADER))) {
  13.182 -			return false;
  13.183 -		}
  13.184 -		add_shader(sdr);
  13.185 -	}
  13.186 -	return link();
  13.187 -}
  13.188 -
  13.189 -int SdrProg::get_uniform_location(const char *name)
  13.190 -{
  13.191 -	bind_program(this);
  13.192 -	return glGetUniformLocation(prog, name);
  13.193 -}
  13.194 -
  13.195 -int SdrProg::get_attribute_location(const char *name)
  13.196 -{
  13.197 -	bind_program(this);
  13.198 -	return glGetAttribLocation(prog, name);
  13.199 -}
  13.200 -
  13.201 -void SdrProg::set_uniform(const char *name, int val)
  13.202 -{
  13.203 -	set_uniform(get_uniform_location(name), val);
  13.204 -}
  13.205 -
  13.206 -void SdrProg::set_uniform(const char *name, float val)
  13.207 -{
  13.208 -	set_uniform(get_uniform_location(name), val);
  13.209 -}
  13.210 -
  13.211 -void SdrProg::set_uniform(const char *name, const Vector2 &v)
  13.212 -{
  13.213 -	set_uniform(get_uniform_location(name), v);
  13.214 -}
  13.215 -
  13.216 -void SdrProg::set_uniform(const char *name, const Vector3 &v)
  13.217 -{
  13.218 -	set_uniform(get_uniform_location(name), v);
  13.219 -}
  13.220 -
  13.221 -void SdrProg::set_uniform(const char *name, const Vector4 &v)
  13.222 -{
  13.223 -	set_uniform(get_uniform_location(name), v);
  13.224 -}
  13.225 -
  13.226 -void SdrProg::set_uniform(const char *name, const Matrix4x4 &mat)
  13.227 -{
  13.228 -	set_uniform(get_uniform_location(name), mat);
  13.229 -}
  13.230 -
  13.231 -
  13.232 -void SdrProg::set_uniform(int loc, int val)
  13.233 -{
  13.234 -	if(loc >= 0) {
  13.235 -		bind_program(this);
  13.236 -		glUniform1i(loc, val);
  13.237 -	}
  13.238 -}
  13.239 -
  13.240 -void SdrProg::set_uniform(int loc, float val)
  13.241 -{
  13.242 -	if(loc >= 0) {
  13.243 -		bind_program(this);
  13.244 -		glUniform1f(loc, val);
  13.245 -	}
  13.246 -}
  13.247 -
  13.248 -void SdrProg::set_uniform(int loc, const Vector2 &v)
  13.249 -{
  13.250 -	if(loc >= 0) {
  13.251 -		bind_program(this);
  13.252 -		glUniform2f(loc, v.x, v.y);
  13.253 -	}
  13.254 -}
  13.255 -
  13.256 -void SdrProg::set_uniform(int loc, const Vector3 &v)
  13.257 -{
  13.258 -	if(loc >= 0) {
  13.259 -		bind_program(this);
  13.260 -		glUniform3f(loc, v.x, v.y, v.z);
  13.261 -	}
  13.262 -}
  13.263 -
  13.264 -void SdrProg::set_uniform(int loc, const Vector4 &v)
  13.265 -{
  13.266 -	if(loc >= 0) {
  13.267 -		bind_program(this);
  13.268 -		glUniform4f(loc, v.x, v.y, v.z, v.w);
  13.269 -	}
  13.270 -}
  13.271 -
  13.272 -void SdrProg::set_uniform(int loc, const Matrix4x4 &mat)
  13.273 -{
  13.274 -	if(loc >= 0) {
  13.275 -		bind_program(this);
  13.276 -		// loading transpose matrix (3rd arg true)
  13.277 -#ifdef SINGLE_PRECISION_MATH
  13.278 -		glUniformMatrix4fv(loc, 1, GL_TRUE, (float*)mat.m);
  13.279 -#else
  13.280 -		glUniformMatrix4dv(loc, 1, GL_TRUE, (double*)mat.m);
  13.281 -#endif
  13.282 -	}
  13.283 -}
  13.284 -
  13.285 -bool bind_program(const SdrProg *prog)
  13.286 -{
  13.287 -	if(!prog) {
  13.288 -		glUseProgram(0);
  13.289 -		return true;
  13.290 -	}
  13.291 -
  13.292 -	if(!((SdrProg*)prog)->link()) {
  13.293 -		return false;
  13.294 -	}
  13.295 -	glUseProgram(prog->prog);
  13.296 -	if(glGetError()) {
  13.297 -		return false;
  13.298 -	}
  13.299 -	return true;
  13.300 -}
    14.1 --- a/src/shaders.h	Sun Dec 16 00:37:35 2012 +0200
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,67 +0,0 @@
    14.4 -#ifndef SDR_H_
    14.5 -#define SDR_H_
    14.6 -
    14.7 -#include <vector>
    14.8 -#include "vmath/vmath.h"
    14.9 -
   14.10 -class Shader {
   14.11 -private:
   14.12 -	bool compiled;
   14.13 -
   14.14 -public:
   14.15 -	unsigned int sdr;
   14.16 -
   14.17 -	Shader(unsigned int type);
   14.18 -	~Shader();
   14.19 -
   14.20 -	void set_source(const char *src);
   14.21 -
   14.22 -	bool compile();
   14.23 -	bool is_compiled() const;
   14.24 -
   14.25 -	bool load(const char *fname);
   14.26 -};
   14.27 -
   14.28 -
   14.29 -// public shader manager interface
   14.30 -Shader *get_shader(const char *fname, unsigned int type);
   14.31 -
   14.32 -
   14.33 -class SdrProg {
   14.34 -private:
   14.35 -	// SdrProg does not own the shader objects
   14.36 -	std::vector<Shader*> shaders;
   14.37 -	bool linked;
   14.38 -
   14.39 -public:
   14.40 -	unsigned int prog;
   14.41 -
   14.42 -	SdrProg();
   14.43 -	~SdrProg();
   14.44 -
   14.45 -	void add_shader(Shader *sdr);
   14.46 -	bool link();
   14.47 -
   14.48 -	bool load(const char *vsfname, const char *psfname);
   14.49 -
   14.50 -	int get_uniform_location(const char *name);
   14.51 -	int get_attribute_location(const char *name);
   14.52 -
   14.53 -	void set_uniform(const char *name, int val);
   14.54 -	void set_uniform(const char *name, float val);
   14.55 -	void set_uniform(const char *name, const Vector2 &v);
   14.56 -	void set_uniform(const char *name, const Vector3 &v);
   14.57 -	void set_uniform(const char *name, const Vector4 &v);
   14.58 -	void set_uniform(const char *name, const Matrix4x4 &mat);
   14.59 -
   14.60 -	void set_uniform(int loc, int val);
   14.61 -	void set_uniform(int loc, float val);
   14.62 -	void set_uniform(int loc, const Vector2 &v);
   14.63 -	void set_uniform(int loc, const Vector3 &v);
   14.64 -	void set_uniform(int loc, const Vector4 &v);
   14.65 -	void set_uniform(int loc, const Matrix4x4 &mat);
   14.66 -};
   14.67 -
   14.68 -bool bind_program(const SdrProg *prog);
   14.69 -
   14.70 -#endif	/* SDR_H_ */
    15.1 --- a/src/texture.cc	Sun Dec 16 00:37:35 2012 +0200
    15.2 +++ b/src/texture.cc	Sun Dec 16 14:24:16 2012 +0200
    15.3 @@ -3,9 +3,9 @@
    15.4  
    15.5  void bind_texture(const Texture *tex, int texunit)
    15.6  {
    15.7 -	static const Texture *curr_tex[8];
    15.8 +	static const Texture *cur_tex[8];
    15.9  
   15.10 -	if(tex == curr_tex[texunit]) {
   15.11 +	if(tex == cur_tex[texunit]) {
   15.12  		return;
   15.13  	}
   15.14  
   15.15 @@ -14,11 +14,11 @@
   15.16  		glEnable(tex->type);
   15.17  		glBindTexture(tex->type, tex->tex);
   15.18  	} else {
   15.19 -		glDisable(tex->type);
   15.20 +		glDisable(cur_tex[texunit]->type);
   15.21  	}
   15.22  	glActiveTexture(GL_TEXTURE0);
   15.23  
   15.24 -	curr_tex[texunit] = tex;
   15.25 +	cur_tex[texunit] = tex;
   15.26  }
   15.27  
   15.28  
   15.29 @@ -61,6 +61,12 @@
   15.30  	size[1] = ysz;
   15.31  }
   15.32  
   15.33 +void Texture2D::update(float *data)
   15.34 +{
   15.35 +	glBindTexture(type, tex);
   15.36 +	glTexSubImage2D(type, 0, 0, 0, size[0], size[1], GL_RGBA, GL_FLOAT, data);
   15.37 +}
   15.38 +
   15.39  Texture3D::Texture3D()
   15.40  {
   15.41  	type = GL_TEXTURE_3D;
   15.42 @@ -68,6 +74,9 @@
   15.43  	glBindTexture(type, tex);
   15.44  	glTexParameteri(type, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   15.45  	glTexParameteri(type, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   15.46 +	glTexParameteri(type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
   15.47 +	glTexParameteri(type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
   15.48 +	glTexParameteri(type, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
   15.49  }
   15.50  
   15.51  void Texture3D::create(int xsz, int ysz, int zsz, float *data)
   15.52 @@ -79,3 +88,9 @@
   15.53  	size[1] = ysz;
   15.54  	size[2] = zsz;
   15.55  }
   15.56 +
   15.57 +void Texture3D::update(float *data)
   15.58 +{
   15.59 +	glBindTexture(type, tex);
   15.60 +	glTexSubImage3D(type, 0, 0, 0, 0, size[0], size[1], size[2], GL_RGBA, GL_FLOAT, data);
   15.61 +}
    16.1 --- a/src/texture.h	Sun Dec 16 00:37:35 2012 +0200
    16.2 +++ b/src/texture.h	Sun Dec 16 14:24:16 2012 +0200
    16.3 @@ -14,6 +14,8 @@
    16.4  
    16.5  	virtual int get_size(int idx) const;
    16.6  
    16.7 +	virtual void update(float *data) = 0;
    16.8 +
    16.9  	friend void bind_texture(const Texture *tex, int texunit);
   16.10  };
   16.11  
   16.12 @@ -24,6 +26,8 @@
   16.13  	Texture2D();
   16.14  
   16.15  	void create(int xsz, int ysz, float *data = 0);
   16.16 +
   16.17 +	void update(float *data);
   16.18  };
   16.19  
   16.20  class Texture3D : public Texture {
   16.21 @@ -31,6 +35,8 @@
   16.22  	Texture3D();
   16.23  
   16.24  	void create(int xsz, int ysz, int zsz, float *data = 0);
   16.25 +
   16.26 +	void update(float *data);
   16.27  };
   16.28  
   16.29  #endif	// TEXTURE_H_