src/shader.c

changeset 222
2cb9a71df7a6
parent 221
14eddd43b3f7
child 223
4f32c7755138
--- a/src/shader.c	Wed Jul 23 00:27:46 2025 +0200
+++ b/src/shader.c	Thu Jul 24 20:58:00 2025 +0200
@@ -154,27 +154,48 @@
     cxFreeDefault(program);
 }
 
-bool asc_shader_invalid(const AscShaderProgram *program) {
+static bool asc_shader_invalid(const AscShaderProgram *program) {
     return program == NULL || program->gl_id == 0;
 }
 
-AscShaderProgram *asc_shader_create(AscShaderCodes codes, size_t mem_size) {
-    AscShaderProgram *prog = cxZallocDefault(mem_size);
-    unsigned shader[2];
-    unsigned n = 0;
-    // 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);
+AscShaderProgram *asc_shader_create(AscShaderCodeInfo code_info, size_t mem_size, asc_shader_init_func init_func, int flags) {
+    AscShaderCodes codes;
+    if (asc_shader_load_code_files(code_info, &codes)) {
+        asc_error("Loading shader failed.");
+        return NULL;
     }
-    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);
+    AscShaderProgram *shader_program = cxZallocDefault(mem_size);
+    {
+        unsigned shader[2];
+        unsigned n = 0;
+        // 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);
+        }
+        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);
+        }
+        asc_shader_link(shader, n, shader_program);
     }
-    asc_shader_link(shader, n, prog);
-    return prog;
+    asc_shader_free_codes(codes);
+    if (asc_error_catch_gl("Compile and link shader") || asc_shader_invalid(shader_program)) {
+        asc_shader_free(shader_program);
+        return NULL;
+    }
+
+    init_func(shader_program, flags);
+
+    if (asc_error_catch_gl("Initializing shader")) {
+        asc_shader_free(shader_program);
+        return NULL;
+    }
+
+    return shader_program;
 }
 
+
 int asc_shader_use(const AscShaderProgram *shader, const AscCamera *camera) {
-    if (shader == NULL) {
+    if (asc_shader_invalid(shader)) {
         asc_active_glctx->active_program = 0;
         glUseProgram(0);
         return 0;
@@ -270,6 +291,10 @@
     return glGetUniformLocation(shader->gl_id, name);
 }
 
+void asc_shader_init_uniform_loc(AscShaderProgram *shader, off_t mem_offset, const char *name) {
+    *((asc_uniform_loc*)((char *) shader + mem_offset)) = glGetUniformLocation(shader->gl_id, name);
+}
+
 void asc_shader_upload_model_matrix(const AscShaderProgram *shader, const AscSceneNode *node) {
     glUniformMatrix4fv(shader->model, 1,GL_FALSE, node->world_transform);
 }

mercurial