X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=vrfileman;a=blobdiff_plain;f=src%2Fsdr.c;h=0152a6ea75bf756238603bb18fe7eb7b12d1416b;hp=5ccf7fe2dc9d28b77f54079a1584e7e74cc72e66;hb=7c59a70219aa7bcf80291f41903a9e6fc9b6e073;hpb=5e07bfd4d034dc3d974c8db008c6446e62838d39 diff --git a/src/sdr.c b/src/sdr.c index 5ccf7fe..0152a6e 100644 --- a/src/sdr.c +++ b/src/sdr.c @@ -14,6 +14,8 @@ #include "sdr.h" static const char *sdrtypestr(unsigned int sdrtype); +static int sdrtypeidx(unsigned int sdrtype); + unsigned int create_vertex_shader(const char *src) { @@ -57,11 +59,21 @@ unsigned int create_shader(const char *src, unsigned int sdr_type) unsigned int sdr; int success, info_len; char *info_str = 0; + const char *src_str[3], *header, *footer; + int src_str_count = 0; GLenum err; + if((header = get_shader_header(sdr_type))) { + src_str[src_str_count++] = header; + } + src_str[src_str_count++] = src; + if((footer = get_shader_footer(sdr_type))) { + src_str[src_str_count++] = footer; + } + sdr = glCreateShader(sdr_type); assert(glGetError() == GL_NO_ERROR); - glShaderSource(sdr, 1, &src, 0); + glShaderSource(sdr, src_str_count, src_str, 0); err = glGetError(); assert(err == GL_NO_ERROR); glCompileShader(sdr); @@ -356,7 +368,7 @@ int set_uniform_float4(unsigned int prog, const char *name, float x, float y, fl END_UNIFORM_CODE; } -int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) +int set_uniform_matrix4(unsigned int prog, const char *name, const float *mat) { BEGIN_UNIFORM_CODE { glUniformMatrix4fv(loc, 1, GL_FALSE, mat); @@ -364,7 +376,7 @@ int set_uniform_matrix4(unsigned int prog, const char *name, float *mat) END_UNIFORM_CODE; } -int set_uniform_matrix4_transposed(unsigned int prog, const char *name, float *mat) +int set_uniform_matrix4_transposed(unsigned int prog, const char *name, const float *mat) { BEGIN_UNIFORM_CODE { glUniformMatrix4fv(loc, 1, GL_TRUE, mat); @@ -394,6 +406,116 @@ void set_attrib_float3(int attr_loc, float x, float y, float z) glVertexAttrib3f(attr_loc, x, y, z); } +/* ---- shader composition ---- */ +struct string { + char *text; + int len; +}; + +#define NUM_SHADER_TYPES 5 +static struct string header[NUM_SHADER_TYPES]; +static struct string footer[NUM_SHADER_TYPES]; + +static void clear_string(struct string *str) +{ + free(str->text); + str->text = 0; + str->len = 0; +} + +static void append_string(struct string *str, const char *s) +{ + int len, newlen; + char *newstr; + + if(!s || !*s) return; + + len = strlen(s); + newlen = str->len + len; + if(!(newstr = malloc(newlen + 2))) { /* leave space for a possible newline */ + fprintf(stderr, "shader composition: failed to append string of size %d\n", len); + abort(); + } + + if(str->text) { + memcpy(newstr, str->text, str->len); + } + memcpy(newstr + str->len, s, len + 1); + + if(s[len - 1] != '\n') { + newstr[newlen] = '\n'; + newstr[newlen + 1] = 0; + } + + free(str->text); + str->text = newstr; + str->len = newlen; +} + +void clear_shader_header(unsigned int type) +{ + if(type) { + int idx = sdrtypeidx(type); + clear_string(&header[idx]); + } else { + int i; + for(i=0; i"; } + +static int sdrtypeidx(unsigned int sdrtype) +{ + switch(sdrtype) { + case GL_VERTEX_SHADER: + return 0; + case GL_FRAGMENT_SHADER: + return 1; + case GL_TESS_CONTROL_SHADER: + return 2; + case GL_TESS_EVALUATION_SHADER: + return 3; + case GL_GEOMETRY_SHADER: + return 4; + default: + break; + } + return 0; +}