fractorb
changeset 0:6e849d7377ff
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 18 Nov 2017 20:04:16 +0200 |
parents | |
children | 436f82447c44 |
files | .hgignore Makefile mbrot.glsl src/main.c src/opengl.h src/sdr.c src/sdr.h vertex.glsl |
diffstat | 8 files changed, 810 insertions(+), 0 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/.hgignore Sat Nov 18 20:04:16 2017 +0200 1.3 @@ -0,0 +1,4 @@ 1.4 +\.o$ 1.5 +\.d$ 1.6 +\.swp$ 1.7 +^fractorb$
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/Makefile Sat Nov 18 20:04:16 2017 +0200 2.3 @@ -0,0 +1,13 @@ 2.4 +src = $(wildcard src/*.c) 2.5 +obj = $(src:.c=.o) 2.6 +bin = fractorb 2.7 + 2.8 +CFLAGS = -pedantic -Wall -g 2.9 +LDFLAGS = -lGL -lglut -lGLEW -lm 2.10 + 2.11 +$(bin): $(obj) 2.12 + $(CC) -o $@ $(obj) $(LDFLAGS) 2.13 + 2.14 +.PHONY: clean 2.15 +clean: 2.16 + rm -f $(obj) $(bin)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/mbrot.glsl Sat Nov 18 20:04:16 2017 +0200 3.3 @@ -0,0 +1,30 @@ 3.4 +// vi:ft=glsl: 3.5 +#define ITER 96 3.6 + 3.7 +uniform float view_scale; 3.8 +uniform vec2 view_center; 3.9 + 3.10 +float mbrot_dist_point(in vec2 c, in vec2 p) 3.11 +{ 3.12 + vec2 z = c; 3.13 + float mindist_sq = 8192.0; 3.14 + 3.15 + for(int i=0; i<ITER; i++) { 3.16 + float x = (z.x * z.x - z.y * z.y) + c.x; 3.17 + float y = (z.x * z.y + z.x * z.y) + c.y; 3.18 + 3.19 + z = vec2(x, y); 3.20 + mindist_sq = min(mindist_sq, dot(z, z)); 3.21 + } 3.22 + 3.23 + return sqrt(mindist_sq); 3.24 +} 3.25 + 3.26 +void main() 3.27 +{ 3.28 + vec2 c = gl_TexCoord[0].xy * view_scale - view_center; 3.29 + float m = 1.0 - mbrot_dist_point(c, vec2(0.0, 0.0)); 3.30 + 3.31 + gl_FragColor.rgb = vec3(m, m, m); 3.32 + gl_FragColor.a = 1.0; 3.33 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/main.c Sat Nov 18 20:04:16 2017 +0200 4.3 @@ -0,0 +1,95 @@ 4.4 +#include <stdio.h> 4.5 +#include <stdlib.h> 4.6 +#include <GL/glew.h> 4.7 +#include <GL/glut.h> 4.8 +#include "sdr.h" 4.9 + 4.10 +int init(void); 4.11 +void cleanup(void); 4.12 +void disp(void); 4.13 +void reshape(int x, int y); 4.14 +void keyb(unsigned char key, int x, int y); 4.15 +void mouse(int bn, int st, int x, int y); 4.16 +void motion(int x, int y); 4.17 + 4.18 +static float aspect; 4.19 +static int mouse_x, mouse_y; 4.20 +static unsigned int prog_mbrot; 4.21 + 4.22 +int main(int argc, char **argv) 4.23 +{ 4.24 + glutInit(&argc, argv); 4.25 + glutInitWindowSize(1280, 800); 4.26 + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 4.27 + glutCreateWindow("fractorb"); 4.28 + 4.29 + glutDisplayFunc(disp); 4.30 + glutReshapeFunc(reshape); 4.31 + glutKeyboardFunc(keyb); 4.32 + glutMouseFunc(mouse); 4.33 + glutMotionFunc(motion); 4.34 + 4.35 + if(init() == -1) { 4.36 + return 1; 4.37 + } 4.38 + atexit(cleanup); 4.39 + 4.40 + glutMainLoop(); 4.41 + return 0; 4.42 +} 4.43 + 4.44 + 4.45 +int init(void) 4.46 +{ 4.47 + glewInit(); 4.48 + 4.49 + if(!(prog_mbrot = create_program_load("vertex.glsl", "mbrot.glsl"))) { 4.50 + return -1; 4.51 + } 4.52 + set_uniform_float(prog_mbrot, "view_scale", 1.1); 4.53 + set_uniform_float2(prog_mbrot, "view_center", 0.7, 0); 4.54 + return 0; 4.55 +} 4.56 + 4.57 +void cleanup(void) 4.58 +{ 4.59 + free_program(prog_mbrot); 4.60 +} 4.61 + 4.62 +void disp(void) 4.63 +{ 4.64 + glUseProgram(prog_mbrot); 4.65 + 4.66 + glBegin(GL_QUADS); 4.67 + glTexCoord2f(-aspect, 1); glVertex2f(-1, -1); 4.68 + glTexCoord2f(aspect, 1); glVertex2f(1, -1); 4.69 + glTexCoord2f(aspect, -1); glVertex2f(1, 1); 4.70 + glTexCoord2f(-aspect, -1); glVertex2f(-1, 1); 4.71 + glEnd(); 4.72 + 4.73 + glutSwapBuffers(); 4.74 +} 4.75 + 4.76 +void reshape(int x, int y) 4.77 +{ 4.78 + glViewport(0, 0, x, y); 4.79 + 4.80 + aspect = (float)x / (float)y; 4.81 +} 4.82 + 4.83 +void keyb(unsigned char key, int x, int y) 4.84 +{ 4.85 + if(key == 27) { 4.86 + exit(0); 4.87 + } 4.88 +} 4.89 + 4.90 +void mouse(int bn, int st, int x, int y) 4.91 +{ 4.92 +} 4.93 + 4.94 +void motion(int x, int y) 4.95 +{ 4.96 + mouse_x = x; 4.97 + mouse_y = y; 4.98 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/opengl.h Sat Nov 18 20:04:16 2017 +0200 5.3 @@ -0,0 +1,33 @@ 5.4 +#ifndef OPENGL_H_ 5.5 +#define OPENGL_H_ 5.6 + 5.7 +#ifdef HAVE_CONFIG_H_ 5.8 +#include "config.h" 5.9 +#endif 5.10 + 5.11 +#if defined(IPHONE) || defined(__IPHONE__) 5.12 +#include <OpenGLES/ES2/gl.h> 5.13 + 5.14 +#define glClearDepth glClearDepthf 5.15 +#define GLDEF 5.16 +#include "sanegl.h" 5.17 + 5.18 +#elif defined(ANDROID) 5.19 +#include <GLES2/gl2.h> 5.20 +#include <GLES2/gl2ext.h> 5.21 +#define GLDEF 5.22 +#include "sanegl.h" 5.23 + 5.24 +#else 5.25 + 5.26 +#include <GL/glew.h> 5.27 + 5.28 +#ifdef __APPLE__ 5.29 +#include <GLUT/glut.h> 5.30 +#else 5.31 +#include <GL/glut.h> 5.32 +#endif /* __APPLE__ */ 5.33 + 5.34 +#endif /* IPHONE */ 5.35 + 5.36 +#endif /* OPENGL_H_ */
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/sdr.c Sat Nov 18 20:04:16 2017 +0200 6.3 @@ -0,0 +1,562 @@ 6.4 +#include <stdio.h> 6.5 +#include <stdlib.h> 6.6 +#include <string.h> 6.7 +#include <errno.h> 6.8 +#include <stdarg.h> 6.9 +#include <assert.h> 6.10 +#include "opengl.h" 6.11 + 6.12 +#if defined(unix) || defined(__unix__) 6.13 +#include <unistd.h> 6.14 +#include <sys/stat.h> 6.15 +#endif /* unix */ 6.16 + 6.17 +#include "sdr.h" 6.18 + 6.19 +static const char *sdrtypestr(unsigned int sdrtype); 6.20 +static int sdrtypeidx(unsigned int sdrtype); 6.21 + 6.22 + 6.23 +unsigned int create_vertex_shader(const char *src) 6.24 +{ 6.25 + return create_shader(src, GL_VERTEX_SHADER); 6.26 +} 6.27 + 6.28 +unsigned int create_pixel_shader(const char *src) 6.29 +{ 6.30 + return create_shader(src, GL_FRAGMENT_SHADER); 6.31 +} 6.32 + 6.33 +unsigned int create_tessctl_shader(const char *src) 6.34 +{ 6.35 +#ifdef GL_TESS_CONTROL_SHADER 6.36 + return create_shader(src, GL_TESS_CONTROL_SHADER); 6.37 +#else 6.38 + return 0; 6.39 +#endif 6.40 +} 6.41 + 6.42 +unsigned int create_tesseval_shader(const char *src) 6.43 +{ 6.44 +#ifdef GL_TESS_EVALUATION_SHADER 6.45 + return create_shader(src, GL_TESS_EVALUATION_SHADER); 6.46 +#else 6.47 + return 0; 6.48 +#endif 6.49 +} 6.50 + 6.51 +unsigned int create_geometry_shader(const char *src) 6.52 +{ 6.53 +#ifdef GL_GEOMETRY_SHADER 6.54 + return create_shader(src, GL_GEOMETRY_SHADER); 6.55 +#else 6.56 + return 0; 6.57 +#endif 6.58 +} 6.59 + 6.60 +unsigned int create_shader(const char *src, unsigned int sdr_type) 6.61 +{ 6.62 + unsigned int sdr; 6.63 + int success, info_len; 6.64 + char *info_str = 0; 6.65 + const char *src_str[3], *header, *footer; 6.66 + int src_str_count = 0; 6.67 + GLenum err; 6.68 + 6.69 + if((header = get_shader_header(sdr_type))) { 6.70 + src_str[src_str_count++] = header; 6.71 + } 6.72 + src_str[src_str_count++] = src; 6.73 + if((footer = get_shader_footer(sdr_type))) { 6.74 + src_str[src_str_count++] = footer; 6.75 + } 6.76 + 6.77 + sdr = glCreateShader(sdr_type); 6.78 + assert(glGetError() == GL_NO_ERROR); 6.79 + glShaderSource(sdr, src_str_count, src_str, 0); 6.80 + err = glGetError(); 6.81 + assert(err == GL_NO_ERROR); 6.82 + glCompileShader(sdr); 6.83 + assert(glGetError() == GL_NO_ERROR); 6.84 + 6.85 + glGetShaderiv(sdr, GL_COMPILE_STATUS, &success); 6.86 + assert(glGetError() == GL_NO_ERROR); 6.87 + glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &info_len); 6.88 + assert(glGetError() == GL_NO_ERROR); 6.89 + 6.90 + if(info_len) { 6.91 + if((info_str = malloc(info_len + 1))) { 6.92 + glGetShaderInfoLog(sdr, info_len, 0, info_str); 6.93 + assert(glGetError() == GL_NO_ERROR); 6.94 + info_str[info_len] = 0; 6.95 + } 6.96 + } 6.97 + 6.98 + if(success) { 6.99 + fprintf(stderr, info_str ? "done: %s\n" : "done\n", info_str); 6.100 + } else { 6.101 + fprintf(stderr, info_str ? "failed: %s\n" : "failed\n", info_str); 6.102 + glDeleteShader(sdr); 6.103 + sdr = 0; 6.104 + } 6.105 + 6.106 + free(info_str); 6.107 + return sdr; 6.108 +} 6.109 + 6.110 +void free_shader(unsigned int sdr) 6.111 +{ 6.112 + glDeleteShader(sdr); 6.113 +} 6.114 + 6.115 +unsigned int load_vertex_shader(const char *fname) 6.116 +{ 6.117 + return load_shader(fname, GL_VERTEX_SHADER); 6.118 +} 6.119 + 6.120 +unsigned int load_pixel_shader(const char *fname) 6.121 +{ 6.122 + return load_shader(fname, GL_FRAGMENT_SHADER); 6.123 +} 6.124 + 6.125 +unsigned int load_tessctl_shader(const char *fname) 6.126 +{ 6.127 +#ifdef GL_TESS_CONTROL_SHADER 6.128 + return load_shader(fname, GL_TESS_CONTROL_SHADER); 6.129 +#else 6.130 + return 0; 6.131 +#endif 6.132 +} 6.133 + 6.134 +unsigned int load_tesseval_shader(const char *fname) 6.135 +{ 6.136 +#ifdef GL_TESS_EVALUATION_SHADER 6.137 + return load_shader(fname, GL_TESS_EVALUATION_SHADER); 6.138 +#else 6.139 + return 0; 6.140 +#endif 6.141 +} 6.142 + 6.143 +unsigned int load_geometry_shader(const char *fname) 6.144 +{ 6.145 +#ifdef GL_GEOMETRY_SHADER 6.146 + return load_shader(fname, GL_GEOMETRY_SHADER); 6.147 +#else 6.148 + return 0; 6.149 +#endif 6.150 +} 6.151 + 6.152 +unsigned int load_shader(const char *fname, unsigned int sdr_type) 6.153 +{ 6.154 + unsigned int sdr; 6.155 + size_t filesize; 6.156 + FILE *fp; 6.157 + char *src; 6.158 + 6.159 + if(!(fp = fopen(fname, "rb"))) { 6.160 + fprintf(stderr, "failed to open shader %s: %s\n", fname, strerror(errno)); 6.161 + return 0; 6.162 + } 6.163 + 6.164 + fseek(fp, 0, SEEK_END); 6.165 + filesize = ftell(fp); 6.166 + fseek(fp, 0, SEEK_SET); 6.167 + 6.168 + if(!(src = malloc(filesize + 1))) { 6.169 + fclose(fp); 6.170 + return 0; 6.171 + } 6.172 + fread(src, 1, filesize, fp); 6.173 + src[filesize] = 0; 6.174 + fclose(fp); 6.175 + 6.176 + fprintf(stderr, "compiling %s shader: %s... ", sdrtypestr(sdr_type), fname); 6.177 + sdr = create_shader(src, sdr_type); 6.178 + 6.179 + free(src); 6.180 + return sdr; 6.181 +} 6.182 + 6.183 + 6.184 +/* ---- gpu programs ---- */ 6.185 + 6.186 +unsigned int create_program(void) 6.187 +{ 6.188 + unsigned int prog = glCreateProgram(); 6.189 + assert(glGetError() == GL_NO_ERROR); 6.190 + return prog; 6.191 +} 6.192 + 6.193 +unsigned int create_program_link(unsigned int sdr0, ...) 6.194 +{ 6.195 + unsigned int prog, sdr; 6.196 + va_list ap; 6.197 + 6.198 + if(!(prog = create_program())) { 6.199 + return 0; 6.200 + } 6.201 + 6.202 + attach_shader(prog, sdr0); 6.203 + if(glGetError()) { 6.204 + return 0; 6.205 + } 6.206 + 6.207 + va_start(ap, sdr0); 6.208 + while((sdr = va_arg(ap, unsigned int))) { 6.209 + attach_shader(prog, sdr); 6.210 + if(glGetError()) { 6.211 + return 0; 6.212 + } 6.213 + } 6.214 + va_end(ap); 6.215 + 6.216 + if(link_program(prog) == -1) { 6.217 + free_program(prog); 6.218 + return 0; 6.219 + } 6.220 + return prog; 6.221 +} 6.222 + 6.223 +unsigned int create_program_load(const char *vfile, const char *pfile) 6.224 +{ 6.225 + unsigned int vs = 0, ps = 0; 6.226 + 6.227 + if(vfile && *vfile && !(vs = load_vertex_shader(vfile))) { 6.228 + return 0; 6.229 + } 6.230 + if(pfile && *pfile && !(ps = load_pixel_shader(pfile))) { 6.231 + return 0; 6.232 + } 6.233 + return create_program_link(vs, ps, 0); 6.234 +} 6.235 + 6.236 +void free_program(unsigned int sdr) 6.237 +{ 6.238 + glDeleteProgram(sdr); 6.239 +} 6.240 + 6.241 +void attach_shader(unsigned int prog, unsigned int sdr) 6.242 +{ 6.243 + int err; 6.244 + 6.245 + if(prog && sdr) { 6.246 + assert(glGetError() == GL_NO_ERROR); 6.247 + glAttachShader(prog, sdr); 6.248 + if((err = glGetError()) != GL_NO_ERROR) { 6.249 + fprintf(stderr, "failed to attach shader %u to program %u (err: 0x%x)\n", sdr, prog, err); 6.250 + abort(); 6.251 + } 6.252 + } 6.253 +} 6.254 + 6.255 +int link_program(unsigned int prog) 6.256 +{ 6.257 + int linked, info_len, retval = 0; 6.258 + char *info_str = 0; 6.259 + 6.260 + glLinkProgram(prog); 6.261 + assert(glGetError() == GL_NO_ERROR); 6.262 + glGetProgramiv(prog, GL_LINK_STATUS, &linked); 6.263 + assert(glGetError() == GL_NO_ERROR); 6.264 + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &info_len); 6.265 + assert(glGetError() == GL_NO_ERROR); 6.266 + 6.267 + if(info_len) { 6.268 + if((info_str = malloc(info_len + 1))) { 6.269 + glGetProgramInfoLog(prog, info_len, 0, info_str); 6.270 + assert(glGetError() == GL_NO_ERROR); 6.271 + info_str[info_len] = 0; 6.272 + } 6.273 + } 6.274 + 6.275 + if(linked) { 6.276 + fprintf(stderr, info_str ? "linking done: %s\n" : "linking done\n", info_str); 6.277 + } else { 6.278 + fprintf(stderr, info_str ? "linking failed: %s\n" : "linking failed\n", info_str); 6.279 + retval = -1; 6.280 + } 6.281 + 6.282 + free(info_str); 6.283 + return retval; 6.284 +} 6.285 + 6.286 +int bind_program(unsigned int prog) 6.287 +{ 6.288 + GLenum err; 6.289 + 6.290 + glUseProgram(prog); 6.291 + if(prog && (err = glGetError()) != GL_NO_ERROR) { 6.292 + /* maybe the program is not linked, try linking first */ 6.293 + if(err == GL_INVALID_OPERATION) { 6.294 + if(link_program(prog) == -1) { 6.295 + return -1; 6.296 + } 6.297 + glUseProgram(prog); 6.298 + return glGetError() == GL_NO_ERROR ? 0 : -1; 6.299 + } 6.300 + return -1; 6.301 + } 6.302 + return 0; 6.303 +} 6.304 + 6.305 +/* ugly but I'm not going to write the same bloody code over and over */ 6.306 +#define BEGIN_UNIFORM_CODE \ 6.307 + int loc, curr_prog; \ 6.308 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); \ 6.309 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { \ 6.310 + return -1; \ 6.311 + } \ 6.312 + if((loc = glGetUniformLocation(prog, name)) != -1) 6.313 + 6.314 +#define END_UNIFORM_CODE \ 6.315 + if((unsigned int)curr_prog != prog) { \ 6.316 + bind_program(curr_prog); \ 6.317 + } \ 6.318 + return loc == -1 ? -1 : 0 6.319 + 6.320 +int get_uniform_loc(unsigned int prog, const char *name) 6.321 +{ 6.322 + int loc, curr_prog; 6.323 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 6.324 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 6.325 + return -1; 6.326 + } 6.327 + loc = glGetUniformLocation(prog, name); 6.328 + if((unsigned int)curr_prog != prog) { 6.329 + bind_program(curr_prog); 6.330 + } 6.331 + return loc; 6.332 +} 6.333 + 6.334 +int set_uniform_int(unsigned int prog, const char *name, int val) 6.335 +{ 6.336 + BEGIN_UNIFORM_CODE { 6.337 + glUniform1i(loc, val); 6.338 + } 6.339 + END_UNIFORM_CODE; 6.340 +} 6.341 + 6.342 +int set_uniform_float(unsigned int prog, const char *name, float val) 6.343 +{ 6.344 + BEGIN_UNIFORM_CODE { 6.345 + glUniform1f(loc, val); 6.346 + } 6.347 + END_UNIFORM_CODE; 6.348 +} 6.349 + 6.350 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y) 6.351 +{ 6.352 + BEGIN_UNIFORM_CODE { 6.353 + glUniform2f(loc, x, y); 6.354 + } 6.355 + END_UNIFORM_CODE; 6.356 +} 6.357 + 6.358 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z) 6.359 +{ 6.360 + BEGIN_UNIFORM_CODE { 6.361 + glUniform3f(loc, x, y, z); 6.362 + } 6.363 + END_UNIFORM_CODE; 6.364 +} 6.365 + 6.366 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w) 6.367 +{ 6.368 + BEGIN_UNIFORM_CODE { 6.369 + glUniform4f(loc, x, y, z, w); 6.370 + } 6.371 + END_UNIFORM_CODE; 6.372 +} 6.373 + 6.374 +int set_uniform_matrix4(unsigned int prog, const char *name, const float *mat) 6.375 +{ 6.376 + BEGIN_UNIFORM_CODE { 6.377 + glUniformMatrix4fv(loc, 1, GL_FALSE, mat); 6.378 + } 6.379 + END_UNIFORM_CODE; 6.380 +} 6.381 + 6.382 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, const float *mat) 6.383 +{ 6.384 + BEGIN_UNIFORM_CODE { 6.385 + glUniformMatrix4fv(loc, 1, GL_TRUE, mat); 6.386 + } 6.387 + END_UNIFORM_CODE; 6.388 +} 6.389 + 6.390 +int get_attrib_loc(unsigned int prog, const char *name) 6.391 +{ 6.392 + int loc, curr_prog; 6.393 + 6.394 + glGetIntegerv(GL_CURRENT_PROGRAM, &curr_prog); 6.395 + if((unsigned int)curr_prog != prog && bind_program(prog) == -1) { 6.396 + return -1; 6.397 + } 6.398 + 6.399 + loc = glGetAttribLocation(prog, (char*)name); 6.400 + 6.401 + if((unsigned int)curr_prog != prog) { 6.402 + bind_program(curr_prog); 6.403 + } 6.404 + return loc; 6.405 +} 6.406 + 6.407 +void set_attrib_float3(int attr_loc, float x, float y, float z) 6.408 +{ 6.409 + glVertexAttrib3f(attr_loc, x, y, z); 6.410 +} 6.411 + 6.412 +/* ---- shader composition ---- */ 6.413 +struct string { 6.414 + char *text; 6.415 + int len; 6.416 +}; 6.417 + 6.418 +#define NUM_SHADER_TYPES 5 6.419 +static struct string header[NUM_SHADER_TYPES]; 6.420 +static struct string footer[NUM_SHADER_TYPES]; 6.421 + 6.422 +static void clear_string(struct string *str) 6.423 +{ 6.424 + free(str->text); 6.425 + str->text = 0; 6.426 + str->len = 0; 6.427 +} 6.428 + 6.429 +static void append_string(struct string *str, const char *s) 6.430 +{ 6.431 + int len, newlen; 6.432 + char *newstr; 6.433 + 6.434 + if(!s || !*s) return; 6.435 + 6.436 + len = strlen(s); 6.437 + newlen = str->len + len; 6.438 + if(!(newstr = malloc(newlen + 2))) { /* leave space for a possible newline */ 6.439 + fprintf(stderr, "shader composition: failed to append string of size %d\n", len); 6.440 + abort(); 6.441 + } 6.442 + 6.443 + if(str->text) { 6.444 + memcpy(newstr, str->text, str->len); 6.445 + } 6.446 + memcpy(newstr + str->len, s, len + 1); 6.447 + 6.448 + if(s[len - 1] != '\n') { 6.449 + newstr[newlen] = '\n'; 6.450 + newstr[newlen + 1] = 0; 6.451 + } 6.452 + 6.453 + free(str->text); 6.454 + str->text = newstr; 6.455 + str->len = newlen; 6.456 +} 6.457 + 6.458 +void clear_shader_header(unsigned int type) 6.459 +{ 6.460 + if(type) { 6.461 + int idx = sdrtypeidx(type); 6.462 + clear_string(&header[idx]); 6.463 + } else { 6.464 + int i; 6.465 + for(i=0; i<NUM_SHADER_TYPES; i++) { 6.466 + clear_string(&header[i]); 6.467 + } 6.468 + } 6.469 +} 6.470 + 6.471 +void clear_shader_footer(unsigned int type) 6.472 +{ 6.473 + if(type) { 6.474 + int idx = sdrtypeidx(type); 6.475 + clear_string(&footer[idx]); 6.476 + } else { 6.477 + int i; 6.478 + for(i=0; i<NUM_SHADER_TYPES; i++) { 6.479 + clear_string(&footer[i]); 6.480 + } 6.481 + } 6.482 +} 6.483 + 6.484 +void add_shader_header(unsigned int type, const char *s) 6.485 +{ 6.486 + if(type) { 6.487 + int idx = sdrtypeidx(type); 6.488 + append_string(&header[idx], s); 6.489 + } else { 6.490 + int i; 6.491 + for(i=0; i<NUM_SHADER_TYPES; i++) { 6.492 + append_string(&header[i], s); 6.493 + } 6.494 + } 6.495 +} 6.496 + 6.497 +void add_shader_footer(unsigned int type, const char *s) 6.498 +{ 6.499 + if(type) { 6.500 + int idx = sdrtypeidx(type); 6.501 + append_string(&footer[idx], s); 6.502 + } else { 6.503 + int i; 6.504 + for(i=0; i<NUM_SHADER_TYPES; i++) { 6.505 + append_string(&footer[i], s); 6.506 + } 6.507 + } 6.508 +} 6.509 + 6.510 +const char *get_shader_header(unsigned int type) 6.511 +{ 6.512 + int idx = sdrtypeidx(type); 6.513 + return header[idx].text; 6.514 +} 6.515 + 6.516 +const char *get_shader_footer(unsigned int type) 6.517 +{ 6.518 + int idx = sdrtypeidx(type); 6.519 + return footer[idx].text; 6.520 +} 6.521 + 6.522 +static const char *sdrtypestr(unsigned int sdrtype) 6.523 +{ 6.524 + switch(sdrtype) { 6.525 + case GL_VERTEX_SHADER: 6.526 + return "vertex"; 6.527 + case GL_FRAGMENT_SHADER: 6.528 + return "pixel"; 6.529 +#ifdef GL_TESS_CONTROL_SHADER 6.530 + case GL_TESS_CONTROL_SHADER: 6.531 + return "tessellation control"; 6.532 +#endif 6.533 +#ifdef GL_TESS_EVALUATION_SHADER 6.534 + case GL_TESS_EVALUATION_SHADER: 6.535 + return "tessellation evaluation"; 6.536 +#endif 6.537 +#ifdef GL_GEOMETRY_SHADER 6.538 + case GL_GEOMETRY_SHADER: 6.539 + return "geometry"; 6.540 +#endif 6.541 + 6.542 + default: 6.543 + break; 6.544 + } 6.545 + return "<unknown>"; 6.546 +} 6.547 + 6.548 +static int sdrtypeidx(unsigned int sdrtype) 6.549 +{ 6.550 + switch(sdrtype) { 6.551 + case GL_VERTEX_SHADER: 6.552 + return 0; 6.553 + case GL_FRAGMENT_SHADER: 6.554 + return 1; 6.555 + case GL_TESS_CONTROL_SHADER: 6.556 + return 2; 6.557 + case GL_TESS_EVALUATION_SHADER: 6.558 + return 3; 6.559 + case GL_GEOMETRY_SHADER: 6.560 + return 4; 6.561 + default: 6.562 + break; 6.563 + } 6.564 + return 0; 6.565 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/src/sdr.h Sat Nov 18 20:04:16 2017 +0200 7.3 @@ -0,0 +1,68 @@ 7.4 +#ifndef SDR_H_ 7.5 +#define SDR_H_ 7.6 + 7.7 +#ifdef __cplusplus 7.8 +extern "C" { 7.9 +#endif /* __cplusplus */ 7.10 + 7.11 +/* ---- shaders ---- */ 7.12 +unsigned int create_vertex_shader(const char *src); 7.13 +unsigned int create_pixel_shader(const char *src); 7.14 +unsigned int create_tessctl_shader(const char *src); 7.15 +unsigned int create_tesseval_shader(const char *src); 7.16 +unsigned int create_geometry_shader(const char *src); 7.17 +unsigned int create_shader(const char *src, unsigned int sdr_type); 7.18 +void free_shader(unsigned int sdr); 7.19 + 7.20 +unsigned int load_vertex_shader(const char *fname); 7.21 +unsigned int load_pixel_shader(const char *fname); 7.22 +unsigned int load_tessctl_shader(const char *fname); 7.23 +unsigned int load_tesseval_shader(const char *fname); 7.24 +unsigned int load_geometry_shader(const char *fname); 7.25 +unsigned int load_shader(const char *src, unsigned int sdr_type); 7.26 + 7.27 +int add_shader(const char *fname, unsigned int sdr); 7.28 +int remove_shader(const char *fname); 7.29 + 7.30 +/* ---- gpu programs ---- */ 7.31 +unsigned int create_program(void); 7.32 +unsigned int create_program_link(unsigned int sdr0, ...); 7.33 +unsigned int create_program_load(const char *vfile, const char *pfile); 7.34 +void free_program(unsigned int sdr); 7.35 + 7.36 +void attach_shader(unsigned int prog, unsigned int sdr); 7.37 +int link_program(unsigned int prog); 7.38 +int bind_program(unsigned int prog); 7.39 + 7.40 +int get_uniform_loc(unsigned int prog, const char *name); 7.41 + 7.42 +int set_uniform_int(unsigned int prog, const char *name, int val); 7.43 +int set_uniform_float(unsigned int prog, const char *name, float val); 7.44 +int set_uniform_float2(unsigned int prog, const char *name, float x, float y); 7.45 +int set_uniform_float3(unsigned int prog, const char *name, float x, float y, float z); 7.46 +int set_uniform_float4(unsigned int prog, const char *name, float x, float y, float z, float w); 7.47 +int set_uniform_matrix4(unsigned int prog, const char *name, const float *mat); 7.48 +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, const float *mat); 7.49 + 7.50 +int get_attrib_loc(unsigned int prog, const char *name); 7.51 +void set_attrib_float3(int attr_loc, float x, float y, float z); 7.52 + 7.53 +/* ---- shader composition ---- */ 7.54 + 7.55 +/* clear shader header/footer text. 7.56 + * pass the shader type to clear, or 0 to clear all types */ 7.57 +void clear_shader_header(unsigned int type); 7.58 +void clear_shader_footer(unsigned int type); 7.59 +/* append text to the header/footer of a specific shader type 7.60 + * or use type 0 to add it to all shade types */ 7.61 +void add_shader_header(unsigned int type, const char *s); 7.62 +void add_shader_footer(unsigned int type, const char *s); 7.63 +/* get the current header/footer text for a specific shader type */ 7.64 +const char *get_shader_header(unsigned int type); 7.65 +const char *get_shader_footer(unsigned int type); 7.66 + 7.67 +#ifdef __cplusplus 7.68 +} 7.69 +#endif /* __cplusplus */ 7.70 + 7.71 +#endif /* SDR_H_ */