aboutsummaryrefslogtreecommitdiff
path: root/src/shader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader.c')
-rw-r--r--src/shader.c67
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;
+}