src/shader.c

changeset 163
3628cc3c0483
parent 162
d3598c834f9b
--- a/src/shader.c	Sun Jun 22 11:15:53 2025 +0200
+++ b/src/shader.c	Sun Jun 22 11:36:37 2025 +0200
@@ -99,20 +99,23 @@
 /**
  * This function links shaders into a program.
  *
- * The ID of the returned program will be zero when something went wrong.
+ * The OpenGL ID of the program will be zero when something went wrong.
  *
  * @param shader the shader IDs to link
  * @param n the number of shaders
  * @param prog the struct where to store the result
- * @retval zero success
- * @retval non-zero failure
  */
-static int asc_shader_link(unsigned shader[], unsigned n, AscShaderProgram *prog) {
+static void asc_shader_link(unsigned shader[], unsigned n, AscShaderProgram *prog) {
+    prog->gl_id = 0;
     GLint success;
     GLint id = glCreateProgram();
     if (id <= 0) {
+        for (unsigned i = 0; i < n; i++) {
+            asc_dprintf("Delete shader: %u", shader[i]);
+            glDeleteShader(shader[i]);
+        }
         asc_error("glCreateProgram failed: %s", glGetError());
-        return -1;
+        return;
     }
     for (unsigned i = 0; i < n; i++) {
         glAttachShader(id, shader[i]);
@@ -120,6 +123,7 @@
     glLinkProgram(id);
     glGetProgramiv(id, GL_LINK_STATUS, &success);
     for (unsigned i = 0; i < n; i++) {
+        asc_dprintf("Delete shader: %u", shader[i]);
         glDeleteShader(shader[i]);
     }
     if (success) {
@@ -129,14 +133,12 @@
         prog->model = glGetUniformLocation(id, "model");
         prog->view = glGetUniformLocation(id, "view");
         prog->projection = glGetUniformLocation(id, "projection");
-        return 0;
     } else {
         char *log = malloc(1024);
         glGetProgramInfoLog(id, 1024, NULL, log);
         glDeleteProgram(id);
         asc_error("Linking shader program %u failed.\n%s", id, log);
         free(log);
-        return -1;
     }
 }
 
@@ -151,32 +153,22 @@
     cxFreeDefault(program);
 }
 
+bool asc_shader_invalid(const AscShaderProgram *program) {
+    return program == NULL || program->gl_id == 0;
+}
+
 void *asc_shader_create(AscShaderCodes codes, size_t mem_size) {
     AscShaderProgram *prog = cxZallocDefault(mem_size);
     unsigned shader[2];
     unsigned n = 0;
-    bool shader_compile_error = false;
     // TODO: clean up this pp mess by introducing proper nested structs
     if (codes.vtx) {
-        shader[n] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx, codes.vtx_pp, codes.vtx_pp_list, codes.vtx_pp_list_select);
-        shader_compile_error |= shader[n] == 0;
-        n++;
+        shader[n++] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx, codes.vtx_pp, codes.vtx_pp_list, codes.vtx_pp_list_select);
     }
     if (codes.frag) {
-        shader[n] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag, codes.frag_pp, codes.frag_pp_list, codes.frag_pp_list_select);
-        shader_compile_error |= shader[n] == 0;
-        n++;
+        shader[n++] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag, codes.frag_pp, codes.frag_pp_list, codes.frag_pp_list_select);
     }
-    if (shader_compile_error || asc_shader_link(shader, n, prog)) {
-        cxFreeDefault(prog);
-        prog = NULL;
-    }
-    for (unsigned i = 0; i < n; i++) {
-        if (shader[i] > 0) {
-            asc_dprintf("Delete shader: %u", shader[i]);
-            glDeleteShader(shader[i]);
-        }
-    }
+    asc_shader_link(shader, n, prog);
     return prog;
 }
 

mercurial