--- 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); }