diff -r d3598c834f9b -r 3628cc3c0483 src/shader.c --- 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; }