diff options
Diffstat (limited to 'src/shader.c')
-rw-r--r-- | src/shader.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/src/shader.c b/src/shader.c index f8d7eb2..ba4db80 100644 --- a/src/shader.c +++ b/src/shader.c @@ -1,15 +1,18 @@ #include "../include/shader.h" +#include "../include/egl.h" #include <stdio.h> #include <assert.h> +static bool print_compile_errors = false; + static int min_int(int a, int b) { return a < b ? a : b; } -static unsigned int loader_shader(gsr_egl *egl, unsigned int type, const char *source) { +static unsigned int load_shader(gsr_egl *egl, unsigned int type, const char *source) { unsigned int shader_id = egl->glCreateShader(type); if(shader_id == 0) { - fprintf(stderr, "gsr error: loader_shader: failed to create shader, error: %d\n", egl->glGetError()); + fprintf(stderr, "gsr error: load_shader: failed to create shader, error: %d\n", egl->glGetError()); return 0; } @@ -22,10 +25,10 @@ static unsigned int loader_shader(gsr_egl *egl, unsigned int type, const char *s int info_length = 0; egl->glGetShaderiv(shader_id, GL_INFO_LOG_LENGTH, &info_length); - if(info_length > 1) { + if(info_length > 1 && print_compile_errors) { char info_log[4096]; egl->glGetShaderInfoLog(shader_id, min_int(4096, info_length), NULL, info_log); - fprintf(stderr, "gsr error: loader shader: failed to compile shader, error:\n%s\n", info_log); + fprintf(stderr, "gsr error: load_shader: failed to compile shader, error:\n%s\nshader source:\n%s\n", info_log, source); } egl->glDeleteShader(shader_id); @@ -35,28 +38,36 @@ static unsigned int loader_shader(gsr_egl *egl, unsigned int type, const char *s return shader_id; } -static unsigned int load_program(gsr_egl *egl, const char *vertex_shader, const char *fragment_shader) { +static unsigned int load_program(gsr_egl *egl, const char *vertex_shader, const char *fragment_shader, const char *compute_shader) { unsigned int vertex_shader_id = 0; unsigned int fragment_shader_id = 0; + unsigned int compute_shader_id = 0; unsigned int program_id = 0; int linked = 0; + bool success = false; if(vertex_shader) { - vertex_shader_id = loader_shader(egl, GL_VERTEX_SHADER, vertex_shader); + vertex_shader_id = load_shader(egl, GL_VERTEX_SHADER, vertex_shader); if(vertex_shader_id == 0) - goto err; + goto done; } if(fragment_shader) { - fragment_shader_id = loader_shader(egl, GL_FRAGMENT_SHADER, fragment_shader); + fragment_shader_id = load_shader(egl, GL_FRAGMENT_SHADER, fragment_shader); if(fragment_shader_id == 0) - goto err; + goto done; + } + + if(compute_shader) { + compute_shader_id = load_shader(egl, GL_COMPUTE_SHADER, compute_shader); + if(compute_shader_id == 0) + goto done; } program_id = egl->glCreateProgram(); if(program_id == 0) { fprintf(stderr, "gsr error: load_program: failed to create shader program, error: %d\n", egl->glGetError()); - goto err; + goto done; } if(vertex_shader_id) @@ -65,6 +76,9 @@ static unsigned int load_program(gsr_egl *egl, const char *vertex_shader, const if(fragment_shader_id) egl->glAttachShader(program_id, fragment_shader_id); + if(compute_shader_id) + egl->glAttachShader(program_id, compute_shader_id); + egl->glLinkProgram(program_id); egl->glGetProgramiv(program_id, GL_LINK_STATUS, &linked); @@ -78,37 +92,36 @@ static unsigned int load_program(gsr_egl *egl, const char *vertex_shader, const fprintf(stderr, "gsr error: load program: linking shader program failed, error:\n%s\n", info_log); } - goto err; + goto done; } - if(fragment_shader_id) - egl->glDeleteShader(fragment_shader_id); - if(vertex_shader_id) - egl->glDeleteShader(vertex_shader_id); - - return program_id; + success = true; + done: - err: - if(program_id) - egl->glDeleteProgram(program_id); + if(!success) { + if(program_id) + egl->glDeleteProgram(program_id); + } + if(compute_shader_id) + egl->glDeleteShader(compute_shader_id); if(fragment_shader_id) egl->glDeleteShader(fragment_shader_id); if(vertex_shader_id) egl->glDeleteShader(vertex_shader_id); - return 0; + return program_id; } -int gsr_shader_init(gsr_shader *self, gsr_egl *egl, const char *vertex_shader, const char *fragment_shader) { +int gsr_shader_init(gsr_shader *self, gsr_egl *egl, const char *vertex_shader, const char *fragment_shader, const char *compute_shader) { assert(egl); self->egl = egl; self->program_id = 0; - if(!vertex_shader && !fragment_shader) { - fprintf(stderr, "gsr error: gsr_shader_init: vertex shader and fragment shader can't be NULL at the same time\n"); + if(!vertex_shader && !fragment_shader && !compute_shader) { + fprintf(stderr, "gsr error: gsr_shader_init: vertex, fragment shader and compute shaders can't be NULL at the same time\n"); return -1; } - self->program_id = load_program(self->egl, vertex_shader, fragment_shader); + self->program_id = load_program(self->egl, vertex_shader, fragment_shader, compute_shader); if(self->program_id == 0) return -1; @@ -140,3 +153,7 @@ void gsr_shader_use(gsr_shader *self) { void gsr_shader_use_none(gsr_shader *self) { self->egl->glUseProgram(0); } + +void gsr_shader_enable_debug_output(bool enable) { + print_compile_errors = enable; +} |