tavli

changeset 15:b1a195c3ee16

added shaders
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 28 Jun 2015 08:34:24 +0300
parents 283eb6e9f0a3
children d6209903454b
files Makefile sdr/phong-notex.p.glsl sdr/phong.p.glsl sdr/phong.v.glsl src/board.cc src/game.cc src/game.h src/mesh.cc src/mesh.h src/object.cc src/object.h src/scenery.cc src/sdr.c src/sdr.h
diffstat 14 files changed, 586 insertions(+), 13 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Sun Jun 28 07:44:23 2015 +0300
     1.2 +++ b/Makefile	Sun Jun 28 08:34:24 2015 +0300
     1.3 @@ -1,11 +1,13 @@
     1.4  PREFIX ?= /usr/local
     1.5  
     1.6  src = $(wildcard src/*.cc)
     1.7 -obj = $(src:.cc=.o)
     1.8 +csrc = $(wildcard src/*.c)
     1.9 +obj = $(src:.cc=.o) $(csrc:.c=.o)
    1.10  dep = $(obj:.o=.d)
    1.11  
    1.12  bin = tavli
    1.13  
    1.14 +CFLAGS = -pedantic -Wall -g
    1.15  CXXFLAGS = -pedantic -Wall -g
    1.16  LDFLAGS = $(libgl) -lvmath -limago -lm -lpthread
    1.17  
    1.18 @@ -20,6 +22,9 @@
    1.19  
    1.20  -include $(dep)
    1.21  
    1.22 +%.d: %.c
    1.23 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.24 +
    1.25  %.d: %.cc
    1.26  	@$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
    1.27  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/sdr/phong-notex.p.glsl	Sun Jun 28 08:34:24 2015 +0300
     2.3 @@ -0,0 +1,24 @@
     2.4 +/* vi: set ft=glsl */
     2.5 +varying vec3 vdir, ldir, normal;
     2.6 +
     2.7 +#define KD gl_FrontMaterial.diffuse.rgb
     2.8 +#define KS gl_FrontMaterial.specular.rgb
     2.9 +#define SPOW gl_FrontMaterial.shininess
    2.10 +
    2.11 +void main()
    2.12 +{
    2.13 +	vec3 n = normalize(normal);
    2.14 +	vec3 v = normalize(vdir);
    2.15 +	vec3 l = normalize(ldir);
    2.16 +	vec3 h = normalize(l + v);
    2.17 +
    2.18 +	float ndotl = max(dot(n, l), 0.0);
    2.19 +	float ndoth = max(dot(n, h), 0.0);
    2.20 +
    2.21 +	vec3 diffuse = KD * gl_LightSource[0].diffuse.rgb * ndotl;
    2.22 +	vec3 specular = KS * gl_LightSource[0].specular.rgb * pow(ndoth, SPOW);
    2.23 +
    2.24 +	vec3 ambient = gl_LightModel.ambient.rgb * KD;
    2.25 +	gl_FragColor.rgb = ambient + diffuse + specular;
    2.26 +	gl_FragColor.a = gl_FrontMaterial.diffuse.a;
    2.27 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/sdr/phong.p.glsl	Sun Jun 28 08:34:24 2015 +0300
     3.3 @@ -0,0 +1,29 @@
     3.4 +/* vi: set ft=glsl */
     3.5 +uniform sampler2D tex;
     3.6 +
     3.7 +varying vec3 vdir, ldir, normal;
     3.8 +
     3.9 +#define KD gl_FrontMaterial.diffuse.rgb
    3.10 +#define KS gl_FrontMaterial.specular.rgb
    3.11 +#define SPOW gl_FrontMaterial.shininess
    3.12 +
    3.13 +void main()
    3.14 +{
    3.15 +	vec4 texel = texture2D(tex, gl_TexCoord[0].st);
    3.16 +
    3.17 +	vec3 n = normalize(normal);
    3.18 +	vec3 v = normalize(vdir);
    3.19 +	vec3 l = normalize(ldir);
    3.20 +	vec3 h = normalize(l + v);
    3.21 +
    3.22 +	float ndotl = max(dot(n, l), 0.0);
    3.23 +	float ndoth = max(dot(n, h), 0.0);
    3.24 +
    3.25 +	vec3 albedo = KD * texel.rgb;
    3.26 +	vec3 diffuse = albedo * gl_LightSource[0].diffuse.rgb * ndotl;
    3.27 +	vec3 specular = KS * gl_LightSource[0].specular.rgb * pow(ndoth, SPOW);
    3.28 +
    3.29 +	vec3 ambient = gl_LightModel.ambient.rgb * albedo;
    3.30 +	gl_FragColor.rgb = ambient + diffuse + specular;
    3.31 +	gl_FragColor.a = gl_FrontMaterial.diffuse.a * texel.a;
    3.32 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/sdr/phong.v.glsl	Sun Jun 28 08:34:24 2015 +0300
     4.3 @@ -0,0 +1,12 @@
     4.4 +varying vec3 vdir, ldir, normal;
     4.5 +
     4.6 +void main()
     4.7 +{
     4.8 +	gl_Position = ftransform();
     4.9 +
    4.10 +	vec3 vpos = (gl_ModelViewMatrix * gl_Vertex).xyz;
    4.11 +	normal = gl_NormalMatrix * gl_Normal;
    4.12 +	vdir = -vpos;
    4.13 +	ldir = gl_LightSource[0].position.xyz - vpos;
    4.14 +	gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
    4.15 +}
     5.1 --- a/src/board.cc	Sun Jun 28 07:44:23 2015 +0300
     5.2 +++ b/src/board.cc	Sun Jun 28 08:34:24 2015 +0300
     5.3 @@ -221,6 +221,7 @@
     5.4  	opiece->mtl.diffuse = Vector3(0.6, 0.6, 0.6);
     5.5  	opiece->mtl.specular = Vector3(0.8, 0.8, 0.8);
     5.6  	opiece->xform().set_translation(Vector3(0, 0.2, 0));
     5.7 +	opiece->set_shader(sdr_phong_notex);
     5.8  	obj.push_back(opiece);
     5.9  
    5.10  	// meshgen stats
     6.1 --- a/src/game.cc	Sun Jun 28 07:44:23 2015 +0300
     6.2 +++ b/src/game.cc	Sun Jun 28 08:34:24 2015 +0300
     6.3 @@ -3,10 +3,12 @@
     6.4  #include "game.h"
     6.5  #include "board.h"
     6.6  #include "scenery.h"
     6.7 +#include "sdr.h"
     6.8  
     6.9  static void draw_backdrop();
    6.10  
    6.11  int win_width, win_height;
    6.12 +unsigned int sdr_phong, sdr_phong_notex;
    6.13  bool wireframe;
    6.14  
    6.15  static Board board;
    6.16 @@ -15,6 +17,7 @@
    6.17  static bool bnstate[8];
    6.18  static int prev_x, prev_y;
    6.19  
    6.20 +static bool dbg_busyloop;
    6.21  
    6.22  bool game_init()
    6.23  {
    6.24 @@ -28,6 +31,15 @@
    6.25  		glEnable(GL_MULTISAMPLE);
    6.26  	}
    6.27  
    6.28 +	Mesh::use_custom_sdr_attr = false;
    6.29 +
    6.30 +	if(!(sdr_phong = create_program_load("sdr/phong.v.glsl", "sdr/phong.p.glsl"))) {
    6.31 +		return false;
    6.32 +	}
    6.33 +	if(!(sdr_phong_notex = create_program_load("sdr/phong.v.glsl", "sdr/phong-notex.p.glsl"))) {
    6.34 +		return false;
    6.35 +	}
    6.36 +
    6.37  	if(!board.init()) {
    6.38  		return false;
    6.39  	}
    6.40 @@ -59,12 +71,16 @@
    6.41  	glRotatef(cam_phi, 1, 0, 0);
    6.42  	glRotatef(cam_theta, 0, 1, 0);
    6.43  
    6.44 -	float ldir[] = {-1, 2, 1, 0};
    6.45 +	float ldir[] = {-10, 20, 10, 1};
    6.46  	glLightfv(GL_LIGHT0, GL_POSITION, ldir);
    6.47  
    6.48  	draw_backdrop();
    6.49  	draw_scenery();
    6.50  	board.draw();
    6.51 +
    6.52 +	if(dbg_busyloop) {
    6.53 +		redisplay();
    6.54 +	}
    6.55  }
    6.56  
    6.57  static void draw_backdrop()
    6.58 @@ -117,6 +133,11 @@
    6.59  			wireframe = !wireframe;
    6.60  			redisplay();
    6.61  			break;
    6.62 +
    6.63 +		case 'd':
    6.64 +			dbg_busyloop = !dbg_busyloop;
    6.65 +			redisplay();
    6.66 +			break;
    6.67  		}
    6.68  	}
    6.69  }
     7.1 --- a/src/game.h	Sun Jun 28 07:44:23 2015 +0300
     7.2 +++ b/src/game.h	Sun Jun 28 08:34:24 2015 +0300
     7.3 @@ -2,6 +2,7 @@
     7.4  #define GAME_H_
     7.5  
     7.6  extern int win_width, win_height;
     7.7 +extern unsigned int sdr_phong, sdr_phong_notex;
     7.8  
     7.9  extern bool wireframe;
    7.10  
     8.1 --- a/src/mesh.cc	Sun Jun 28 07:44:23 2015 +0300
     8.2 +++ b/src/mesh.cc	Sun Jun 28 08:34:24 2015 +0300
     8.3 @@ -8,6 +8,7 @@
     8.4  
     8.5  #define USE_OLDGL
     8.6  
     8.7 +bool Mesh::use_custom_sdr_attr = true;
     8.8  int Mesh::global_sdr_loc[NUM_MESH_ATTR] = { 0, 1, 2, 3, 4, 5, 6 };
     8.9  /*
    8.10  	(int)SDR_ATTR_VERTEX,
    8.11 @@ -574,7 +575,7 @@
    8.12  		return;
    8.13  	}
    8.14  
    8.15 -	if(cur_sdr) {
    8.16 +	if(cur_sdr && use_custom_sdr_attr) {
    8.17  		// rendering with shaders
    8.18  		if(global_sdr_loc[MESH_ATTR_VERTEX] == -1) {
    8.19  			fprintf(stderr, "%s: shader attribute location for vertices unset\n", __FUNCTION__);
    8.20 @@ -623,7 +624,7 @@
    8.21  		glDrawArrays(GL_TRIANGLES, 0, nverts);
    8.22  	}
    8.23  
    8.24 -	if(cur_sdr) {
    8.25 +	if(cur_sdr && use_custom_sdr_attr) {
    8.26  		// rendered with shaders
    8.27  		for(int i=0; i<NUM_MESH_ATTR; i++) {
    8.28  			int loc = global_sdr_loc[i];
    8.29 @@ -729,7 +730,7 @@
    8.30  	}
    8.31  
    8.32  	glBegin(GL_LINES);
    8.33 -	if(cur_sdr) {
    8.34 +	if(cur_sdr && use_custom_sdr_attr) {
    8.35  		int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX];
    8.36  		if(vert_loc < 0) {
    8.37  			glEnd();
    8.38 @@ -765,7 +766,7 @@
    8.39  	}
    8.40  
    8.41  	glBegin(GL_LINES);
    8.42 -	if(cur_sdr) {
    8.43 +	if(cur_sdr && use_custom_sdr_attr) {
    8.44  		int vert_loc = global_sdr_loc[MESH_ATTR_VERTEX];
    8.45  		if(vert_loc < 0) {
    8.46  			glEnd();
     9.1 --- a/src/mesh.h	Sun Jun 28 07:44:23 2015 +0300
     9.2 +++ b/src/mesh.h	Sun Jun 28 08:34:24 2015 +0300
     9.3 @@ -119,6 +119,8 @@
     9.4  
     9.5  
     9.6  public:
     9.7 +	static bool use_custom_sdr_attr;
     9.8 +
     9.9  	Mesh();
    9.10  	~Mesh();
    9.11  
    10.1 --- a/src/object.cc	Sun Jun 28 07:44:23 2015 +0300
    10.2 +++ b/src/object.cc	Sun Jun 28 08:34:24 2015 +0300
    10.3 @@ -24,6 +24,7 @@
    10.4  {
    10.5  	mesh = 0;
    10.6  	tex = 0;
    10.7 +	sdr = 0;
    10.8  }
    10.9  
   10.10  Object::~Object()
   10.11 @@ -66,6 +67,11 @@
   10.12  	this->tex = tex;
   10.13  }
   10.14  
   10.15 +void Object::set_shader(unsigned int sdr)
   10.16 +{
   10.17 +	this->sdr = sdr;
   10.18 +}
   10.19 +
   10.20  void Object::draw() const
   10.21  {
   10.22  	if(!mesh) return;
   10.23 @@ -73,6 +79,10 @@
   10.24  	glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
   10.25  	rop.setup();
   10.26  
   10.27 +	if(sdr) {
   10.28 +		glUseProgram(sdr);
   10.29 +	}
   10.30 +
   10.31  	if(tex) {
   10.32  		glBindTexture(GL_TEXTURE_2D, tex);
   10.33  		glEnable(GL_TEXTURE_2D);
   10.34 @@ -103,6 +113,10 @@
   10.35  		glPopMatrix();
   10.36  	}
   10.37  
   10.38 +	if(sdr) {
   10.39 +		glUseProgram(0);
   10.40 +	}
   10.41 +
   10.42  	glMatrixMode(GL_MODELVIEW);
   10.43  	glPopMatrix();
   10.44  
    11.1 --- a/src/object.h	Sun Jun 28 07:44:23 2015 +0300
    11.2 +++ b/src/object.h	Sun Jun 28 08:34:24 2015 +0300
    11.3 @@ -27,6 +27,7 @@
    11.4  	Matrix4x4 matrix;
    11.5  	unsigned int tex;
    11.6  	Matrix4x4 tex_matrix;
    11.7 +	unsigned int sdr;
    11.8  
    11.9  public:
   11.10  	Material mtl;
   11.11 @@ -45,6 +46,7 @@
   11.12  	Mesh *get_mesh() const;
   11.13  
   11.14  	void set_texture(unsigned int tex);
   11.15 +	void set_shader(unsigned int sdr);
   11.16  
   11.17  	void draw() const;
   11.18  	void draw_wire(const Vector4 &col = Vector4(1, 1, 1, 1)) const;
    12.1 --- a/src/scenery.cc	Sun Jun 28 07:44:23 2015 +0300
    12.2 +++ b/src/scenery.cc	Sun Jun 28 08:34:24 2015 +0300
    12.3 @@ -7,6 +7,7 @@
    12.4  #include "object.h"
    12.5  #include "revol.h"
    12.6  #include "image.h"
    12.7 +#include "sdr.h"
    12.8  
    12.9  static bool gen_textures();
   12.10  
   12.11 @@ -18,9 +19,9 @@
   12.12  	{3, 0},	// mid 0
   12.13  	{5.8, 0},
   12.14  	{5.99, 0},	// mid 1
   12.15 -	{6, -0.15},
   12.16 -	{6.15, -0.15},	// mid 2
   12.17 -	{6.2, -0.4}
   12.18 +	{6, -0.1},
   12.19 +	{6.1, -0.1},	// mid 2
   12.20 +	{6.13, -0.3}
   12.21  };
   12.22  static const BezCurve table_curve = {
   12.23  	sizeof table_cp / sizeof *table_cp,
   12.24 @@ -39,7 +40,7 @@
   12.25  	Matrix4x4 xform;
   12.26  
   12.27  	Mesh *table = new Mesh;
   12.28 -	gen_revol(table, 48, 12, bezier_revol, bezier_revol_normal, (void*)&table_curve);
   12.29 +	gen_revol(table, 48, 16, bezier_revol, bezier_revol_normal, (void*)&table_curve);
   12.30  	table->texcoord_gen_plane(Vector3(0, 1, 0), Vector3(1, 0, 0));
   12.31  	xform.set_scaling(Vector3(0.5, 0.5, 0.5));
   12.32  	xform.translate(Vector3(1, 1, 0));
   12.33 @@ -51,10 +52,11 @@
   12.34  
   12.35  	Object *otable = new Object;
   12.36  	otable->set_mesh(table);
   12.37 -	otable->mtl.diffuse = Vector3(0.6, 0.6, 0.6);
   12.38 -	otable->mtl.specular = Vector3(0.8, 0.8, 0.8);
   12.39 +	otable->mtl.diffuse = Vector3(1, 1, 1);
   12.40 +	otable->mtl.specular = Vector3(0.7, 0.7, 0.7);
   12.41  	otable->xform().set_translation(Vector3(0, -0.025, 0));
   12.42  	otable->set_texture(img_marble.texture());
   12.43 +	otable->set_shader(sdr_phong);
   12.44  	obj.push_back(otable);
   12.45  
   12.46  
   12.47 @@ -113,7 +115,7 @@
   12.48  			float u = (float)j / (float)img_marble.width;
   12.49  
   12.50  			float marble_val = marble(u, v);
   12.51 -			Vector3 color = lerp(marble_col2, marble_col1, marble_val);
   12.52 +			Vector3 color = lerp(marble_col2, marble_col1, marble_val) * 0.6;
   12.53  
   12.54  			int r = (int)(color.x * 255.0);
   12.55  			int g = (int)(color.y * 255.0);
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/sdr.c	Sun Jun 28 08:34:24 2015 +0300
    13.3 @@ -0,0 +1,407 @@
    13.4 +#include <stdio.h>
    13.5 +#include <stdlib.h>
    13.6 +#include <string.h>
    13.7 +#include <errno.h>
    13.8 +#include <stdarg.h>
    13.9 +#include <assert.h>
   13.10 +#include "opengl.h"
   13.11 +
   13.12 +#if defined(unix) || defined(__unix__)
   13.13 +#include <unistd.h>
   13.14 +#include <sys/stat.h>
   13.15 +#endif	/* unix */
   13.16 +
   13.17 +#include "sdr.h"
   13.18 +
   13.19 +static const char *sdrtypestr(unsigned int sdrtype);
   13.20 +
   13.21 +unsigned int create_vertex_shader(const char *src)
   13.22 +{
   13.23 +	return create_shader(src, GL_VERTEX_SHADER);
   13.24 +}
   13.25 +
   13.26 +unsigned int create_pixel_shader(const char *src)
   13.27 +{
   13.28 +	return create_shader(src, GL_FRAGMENT_SHADER);
   13.29 +}
   13.30 +
   13.31 +unsigned int create_tessctl_shader(const char *src)
   13.32 +{
   13.33 +#ifdef GL_TESS_CONTROL_SHADER
   13.34 +	return create_shader(src, GL_TESS_CONTROL_SHADER);
   13.35 +#else
   13.36 +	return 0;
   13.37 +#endif
   13.38 +}
   13.39 +
   13.40 +unsigned int create_tesseval_shader(const char *src)
   13.41 +{
   13.42 +#ifdef GL_TESS_EVALUATION_SHADER
   13.43 +	return create_shader(src, GL_TESS_EVALUATION_SHADER);
   13.44 +#else
   13.45 +	return 0;
   13.46 +#endif
   13.47 +}
   13.48 +
   13.49 +unsigned int create_geometry_shader(const char *src)
   13.50 +{
   13.51 +#ifdef GL_GEOMETRY_SHADER
   13.52 +	return create_shader(src, GL_GEOMETRY_SHADER);
   13.53 +#else
   13.54 +	return 0;
   13.55 +#endif
   13.56 +}
   13.57 +
   13.58 +unsigned int create_shader(const char *src, unsigned int sdr_type)
   13.59 +{
   13.60 +	unsigned int sdr;
   13.61 +	int success, info_len;
   13.62 +	char *info_str = 0;
   13.63 +	GLenum err;
   13.64 +
   13.65 +	sdr = glCreateShader(sdr_type);
   13.66 +	assert(glGetError() == GL_NO_ERROR);
   13.67 +	glShaderSource(sdr, 1, &src, 0);
   13.68 +	err = glGetError();
   13.69 +	assert(err == GL_NO_ERROR);
   13.70 +	glCompileShader(sdr);
   13.71 +	assert(glGetError() == GL_NO_ERROR);
   13.72 +
   13.73 +	glGetShaderiv(sdr, GL_COMPILE_STATUS, &success);
   13.74 +	assert(glGetError() == GL_NO_ERROR);
   13.75 +	glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len);
   13.76 +	assert(glGetError() == GL_NO_ERROR);
   13.77 +
   13.78 +	if(info_len) {
   13.79 +		if((info_str = malloc(info_len + 1))) {
   13.80 +			glGetShaderInfoLog(sdr, info_len, 0, info_str);
   13.81 +			assert(glGetError() == GL_NO_ERROR);
   13.82 +			info_str[info_len] = 0;
   13.83 +		}
   13.84 +	}
   13.85 +
   13.86 +	if(success) {
   13.87 +		fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str);
   13.88 +	} else {
   13.89 +		fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str);
   13.90 +		glDeleteShader(sdr);
   13.91 +		sdr = 0;
   13.92 +	}
   13.93 +
   13.94 +	free(info_str);
   13.95 +	return sdr;
   13.96 +}
   13.97 +
   13.98 +void free_shader(unsigned int sdr)
   13.99 +{
  13.100 +	glDeleteShader(sdr);
  13.101 +}
  13.102 +
  13.103 +unsigned int load_vertex_shader(const char *fname)
  13.104 +{
  13.105 +	return load_shader(fname, GL_VERTEX_SHADER);
  13.106 +}
  13.107 +
  13.108 +unsigned int load_pixel_shader(const char *fname)
  13.109 +{
  13.110 +	return load_shader(fname, GL_FRAGMENT_SHADER);
  13.111 +}
  13.112 +
  13.113 +unsigned int load_tessctl_shader(const char *fname)
  13.114 +{
  13.115 +#ifdef GL_TESS_CONTROL_SHADER
  13.116 +	return load_shader(fname, GL_TESS_CONTROL_SHADER);
  13.117 +#else
  13.118 +	return 0;
  13.119 +#endif
  13.120 +}
  13.121 +
  13.122 +unsigned int load_tesseval_shader(const char *fname)
  13.123 +{
  13.124 +#ifdef GL_TESS_EVALUATION_SHADER
  13.125 +	return load_shader(fname, GL_TESS_EVALUATION_SHADER);
  13.126 +#else
  13.127 +	return 0;
  13.128 +#endif
  13.129 +}
  13.130 +
  13.131 +unsigned int load_geometry_shader(const char *fname)
  13.132 +{
  13.133 +#ifdef GL_GEOMETRY_SHADER
  13.134 +	return load_shader(fname, GL_GEOMETRY_SHADER);
  13.135 +#else
  13.136 +	return 0;
  13.137 +#endif
  13.138 +}
  13.139 +
  13.140 +unsigned int load_shader(const char *fname, unsigned int sdr_type)
  13.141 +{
  13.142 +	unsigned int sdr;
  13.143 +	size_t filesize;
  13.144 +	FILE *fp;
  13.145 +	char *src;
  13.146 +
  13.147 +	if(!(fp = fopen(fname, "rb"))) {
  13.148 +		fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno));
  13.149 +		return 0;
  13.150 +	}
  13.151 +
  13.152 +	fseek(fp, 0, SEEK_END);
  13.153 +	filesize = ftell(fp);
  13.154 +	fseek(fp, 0, SEEK_SET);
  13.155 +
  13.156 +	if(!(src = malloc(filesize + 1))) {
  13.157 +		fclose(fp);
  13.158 +		return 0;
  13.159 +	}
  13.160 +	fread(src, 1, filesize, fp);
  13.161 +	src[filesize] = 0;
  13.162 +	fclose(fp);
  13.163 +
  13.164 +	fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname);
  13.165 +	sdr = create_shader(src, sdr_type);
  13.166 +
  13.167 +	free(src);
  13.168 +	return sdr;
  13.169 +}
  13.170 +
  13.171 +
  13.172 +/* ---- gpu programs ---- */
  13.173 +
  13.174 +unsigned int create_program(void)
  13.175 +{
  13.176 +	unsigned int prog = glCreateProgram();
  13.177 +	assert(glGetError() == GL_NO_ERROR);
  13.178 +	return prog;
  13.179 +}
  13.180 +
  13.181 +unsigned int create_program_link(unsigned int sdr0, ...)
  13.182 +{
  13.183 +	unsigned int prog, sdr;
  13.184 +	va_list ap;
  13.185 +
  13.186 +	if(!(prog = create_program())) {
  13.187 +		return 0;
  13.188 +	}
  13.189 +
  13.190 +	attach_shader(prog, sdr0);
  13.191 +	if(glGetError()) {
  13.192 +		return 0;
  13.193 +	}
  13.194 +
  13.195 +	va_start(ap, sdr0);
  13.196 +	while((sdr = va_arg(ap, unsigned int))) {
  13.197 +		attach_shader(prog, sdr);
  13.198 +		if(glGetError()) {
  13.199 +			return 0;
  13.200 +		}
  13.201 +	}
  13.202 +	va_end(ap);
  13.203 +
  13.204 +	if(link_program(prog) == -1) {
  13.205 +		free_program(prog);
  13.206 +		return 0;
  13.207 +	}
  13.208 +	return prog;
  13.209 +}
  13.210 +
  13.211 +unsigned int create_program_load(const char *vfile, const char *pfile)
  13.212 +{
  13.213 +	unsigned int vs = 0, ps = 0;
  13.214 +
  13.215 +	if(vfile && *vfile && !(vs = load_vertex_shader(vfile))) {
  13.216 +		return 0;
  13.217 +	}
  13.218 +	if(pfile && *pfile && !(ps = load_pixel_shader(pfile))) {
  13.219 +		return 0;
  13.220 +	}
  13.221 +	return create_program_link(vs, ps, 0);
  13.222 +}
  13.223 +
  13.224 +void free_program(unsigned int sdr)
  13.225 +{
  13.226 +	glDeleteProgram(sdr);
  13.227 +}
  13.228 +
  13.229 +void attach_shader(unsigned int prog, unsigned int sdr)
  13.230 +{
  13.231 +	int err;
  13.232 +
  13.233 +	if(prog && sdr) {
  13.234 +		assert(glGetError() == GL_NO_ERROR);
  13.235 +		glAttachShader(prog, sdr);
  13.236 +		if((err = glGetError()) != GL_NO_ERROR) {
  13.237 +			fprintf(stderr, "failed to attach shader %u to program %u (err: 0x%x)\n", sdr, prog, err);
  13.238 +			abort();
  13.239 +		}
  13.240 +	}
  13.241 +}
  13.242 +
  13.243 +int link_program(unsigned int prog)
  13.244 +{
  13.245 +	int linked, info_len, retval = 0;
  13.246 +	char *info_str = 0;
  13.247 +
  13.248 +	glLinkProgram(prog);
  13.249 +	assert(glGetError() == GL_NO_ERROR);
  13.250 +	glGetProgramiv(prog, GL_LINK_STATUS, &linked);
  13.251 +	assert(glGetError() == GL_NO_ERROR);
  13.252 +	glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len);
  13.253 +	assert(glGetError() == GL_NO_ERROR);
  13.254 +
  13.255 +	if(info_len) {
  13.256 +		if((info_str = malloc(info_len + 1))) {
  13.257 +			glGetProgramInfoLog(prog, info_len, 0, info_str);
  13.258 +			assert(glGetError() == GL_NO_ERROR);
  13.259 +			info_str[info_len] = 0;
  13.260 +		}
  13.261 +	}
  13.262 +
  13.263 +	if(linked) {
  13.264 +		fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str);
  13.265 +	} else {
  13.266 +		fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str);
  13.267 +		retval = -1;
  13.268 +	}
  13.269 +
  13.270 +	free(info_str);
  13.271 +	return retval;
  13.272 +}
  13.273 +
  13.274 +int bind_program(unsigned int prog)
  13.275 +{
  13.276 +	GLenum err;
  13.277 +
  13.278 +	glUseProgram(prog);
  13.279 +	if(prog && (err = glGetError()) != GL_NO_ERROR) {
  13.280 +		/* maybe the program is not linked, try linking first */
  13.281 +		if(err == GL_INVALID_OPERATION) {
  13.282 +			if(link_program(prog) == -1) {
  13.283 +				return -1;
  13.284 +			}
  13.285 +			glUseProgram(prog);
  13.286 +			return glGetError() == GL_NO_ERROR ? 0 : -1;
  13.287 +		}
  13.288 +		return -1;
  13.289 +	}
  13.290 +	return 0;
  13.291 +}
  13.292 +
  13.293 +/* ugly but I'm not going to write the same bloody code over and over */
  13.294 +#define BEGIN_UNIFORM_CODE \
  13.295 +	int loc, curr_prog; \
  13.296 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \
  13.297 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \
  13.298 +		return -1; \
  13.299 +	} \
  13.300 +	if((loc = glGetUniformLocation(prog, name)) != -1)
  13.301 +
  13.302 +#define END_UNIFORM_CODE \
  13.303 +	if((unsigned int)curr_prog != prog) { \
  13.304 +		bind_program(curr_prog); \
  13.305 +	} \
  13.306 +	return loc == -1 ? -1 : 0
  13.307 +
  13.308 +int set_uniform_int(unsigned int prog, const char *name, int val)
  13.309 +{
  13.310 +	BEGIN_UNIFORM_CODE {
  13.311 +		glUniform1i(loc, val);
  13.312 +	}
  13.313 +	END_UNIFORM_CODE;
  13.314 +}
  13.315 +
  13.316 +int set_uniform_float(unsigned int prog, const char *name, float val)
  13.317 +{
  13.318 +	BEGIN_UNIFORM_CODE {
  13.319 +		glUniform1f(loc, val);
  13.320 +	}
  13.321 +	END_UNIFORM_CODE;
  13.322 +}
  13.323 +
  13.324 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y)
  13.325 +{
  13.326 +	BEGIN_UNIFORM_CODE {
  13.327 +		glUniform2f(loc, x, y);
  13.328 +	}
  13.329 +	END_UNIFORM_CODE;
  13.330 +}
  13.331 +
  13.332 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z)
  13.333 +{
  13.334 +	BEGIN_UNIFORM_CODE {
  13.335 +		glUniform3f(loc, x, y, z);
  13.336 +	}
  13.337 +	END_UNIFORM_CODE;
  13.338 +}
  13.339 +
  13.340 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w)
  13.341 +{
  13.342 +	BEGIN_UNIFORM_CODE {
  13.343 +		glUniform4f(loc, x, y, z, w);
  13.344 +	}
  13.345 +	END_UNIFORM_CODE;
  13.346 +}
  13.347 +
  13.348 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat)
  13.349 +{
  13.350 +	BEGIN_UNIFORM_CODE {
  13.351 +		glUniformMatrix4fv(loc, 1, GL_FALSE, mat);
  13.352 +	}
  13.353 +	END_UNIFORM_CODE;
  13.354 +}
  13.355 +
  13.356 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat)
  13.357 +{
  13.358 +	BEGIN_UNIFORM_CODE {
  13.359 +		glUniformMatrix4fv(loc, 1, GL_TRUE, mat);
  13.360 +	}
  13.361 +	END_UNIFORM_CODE;
  13.362 +}
  13.363 +
  13.364 +int get_attrib_loc(unsigned int prog, const char *name)
  13.365 +{
  13.366 +	int loc, curr_prog;
  13.367 +
  13.368 +	glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog);
  13.369 +	if((unsigned int)curr_prog != prog && bind_program(prog) == -1) {
  13.370 +		return -1;
  13.371 +	}
  13.372 +
  13.373 +	loc = glGetAttribLocation(prog, (char*)name);
  13.374 +
  13.375 +	if((unsigned int)curr_prog != prog) {
  13.376 +		bind_program(curr_prog);
  13.377 +	}
  13.378 +	return loc;
  13.379 +}
  13.380 +
  13.381 +void set_attrib_float3(int attr_loc, float x, float y, float z)
  13.382 +{
  13.383 +	glVertexAttrib3f(attr_loc, x, y, z);
  13.384 +}
  13.385 +
  13.386 +static const char *sdrtypestr(unsigned int sdrtype)
  13.387 +{
  13.388 +	switch(sdrtype) {
  13.389 +	case GL_VERTEX_SHADER:
  13.390 +		return "vertex";
  13.391 +	case GL_FRAGMENT_SHADER:
  13.392 +		return "pixel";
  13.393 +#ifdef GL_TESS_CONTROL_SHADER
  13.394 +	case GL_TESS_CONTROL_SHADER:
  13.395 +		return "tessellation control";
  13.396 +#endif
  13.397 +#ifdef GL_TESS_EVALUATION_SHADER
  13.398 +	case GL_TESS_EVALUATION_SHADER:
  13.399 +		return "tessellation evaluation";
  13.400 +#endif
  13.401 +#ifdef GL_GEOMETRY_SHADER
  13.402 +	case GL_GEOMETRY_SHADER:
  13.403 +		return "geometry";
  13.404 +#endif
  13.405 +
  13.406 +	default:
  13.407 +		break;
  13.408 +	}
  13.409 +	return "<unknown>";
  13.410 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/src/sdr.h	Sun Jun 28 08:34:24 2015 +0300
    14.3 @@ -0,0 +1,52 @@
    14.4 +#ifndef SDR_H_
    14.5 +#define SDR_H_
    14.6 +
    14.7 +#ifdef __cplusplus
    14.8 +extern "C" {
    14.9 +#endif	/* __cplusplus */
   14.10 +
   14.11 +/* ---- shaders ---- */
   14.12 +unsigned int create_vertex_shader(const char *src);
   14.13 +unsigned int create_pixel_shader(const char *src);
   14.14 +unsigned int create_tessctl_shader(const char *src);
   14.15 +unsigned int create_tesseval_shader(const char *src);
   14.16 +unsigned int create_geometry_shader(const char *src);
   14.17 +unsigned int create_shader(const char *src, unsigned int sdr_type);
   14.18 +void free_shader(unsigned int sdr);
   14.19 +
   14.20 +unsigned int load_vertex_shader(const char *fname);
   14.21 +unsigned int load_pixel_shader(const char *fname);
   14.22 +unsigned int load_tessctl_shader(const char *fname);
   14.23 +unsigned int load_tesseval_shader(const char *fname);
   14.24 +unsigned int load_geometry_shader(const char *fname);
   14.25 +unsigned int load_shader(const char *src, unsigned int sdr_type);
   14.26 +
   14.27 +int add_shader(const char *fname, unsigned int sdr);
   14.28 +int remove_shader(const char *fname);
   14.29 +
   14.30 +/* ---- gpu programs ---- */
   14.31 +unsigned int create_program(void);
   14.32 +unsigned int create_program_link(unsigned int sdr0, ...);
   14.33 +unsigned int create_program_load(const char *vfile, const char *pfile);
   14.34 +void free_program(unsigned int sdr);
   14.35 +
   14.36 +void attach_shader(unsigned int prog, unsigned int sdr);
   14.37 +int link_program(unsigned int prog);
   14.38 +int bind_program(unsigned int prog);
   14.39 +
   14.40 +int set_uniform_int(unsigned int prog, const char *name, int val);
   14.41 +int set_uniform_float(unsigned int prog, const char *name, float val);
   14.42 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y);
   14.43 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z);
   14.44 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w);
   14.45 +int set_uniform_matrix4(unsigned int prog, const char *name, float *mat);
   14.46 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat);
   14.47 +
   14.48 +int get_attrib_loc(unsigned int prog, const char *name);
   14.49 +void set_attrib_float3(int attr_loc, float x, float y, float z);
   14.50 +
   14.51 +#ifdef __cplusplus
   14.52 +}
   14.53 +#endif	/* __cplusplus */
   14.54 +
   14.55 +#endif	/* SDR_H_ */