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_ */