--- a/src/shader.c Wed Jun 18 23:55:08 2025 +0200 +++ b/src/shader.c Thu Jun 19 19:22:07 2025 +0200 @@ -44,32 +44,43 @@ * @param type the shader type (use the GL enum) * @param code the source code * @param code_pp the optional preprocessor code + * @param code_pp_list list of optional preprocessor code + * @param code_pp_list_select selection flags for the preprocessor code list * @return the compiled shader */ -static unsigned asc_shader_compile(unsigned int type, const char *code, const char *code_pp) { +static unsigned asc_shader_compile(unsigned int type, const char *code, const char *code_pp, + const char * const *code_pp_list, unsigned short code_pp_list_select) { GLuint id = glCreateShader(type); if (id == 0) { asc_error("glCreateShader failed: %s", glGetError()); return 0; } - // some drivers don't like NULL strings, even when length is zero - if (code_pp == NULL) code_pp = ""; + GLint success; + const char *code_array[20]; + GLsizei code_count = 0; + code_array[code_count++] = "#version 400 core\n"; + if (code_pp != NULL) code_array[code_count++] = code_pp; + unsigned test_flag = 1; + unsigned select_index = 0; + while (test_flag <= code_pp_list_select) { + if (asc_test_flag(code_pp_list_select, test_flag)) { + code_array[code_count++] = code_pp_list[select_index]; + } + select_index++; + test_flag <<= 1; + } + code_array[code_count++] = "\n#line 1\n"; + code_array[code_count++] = code; - GLint success; - const char *code_array[4] = { - "#version 400 core\n", - code_pp, - "\n#line 1\n", - code - }; - GLint length_array[4]; - for (unsigned int i = 0; i < cx_nmemb(length_array); i++) { + // compute the lengths + GLint length_array[20]; + for (int i = 0; i < code_count ; i++) { length_array[i] = (GLint) strlen(code_array[i]); } // compile - glShaderSource(id, cx_nmemb(length_array), code_array, length_array); + glShaderSource(id, code_count, code_array, length_array); glCompileShader(id); glGetShaderiv(id, GL_COMPILE_STATUS, &success); if (success) { @@ -145,10 +156,10 @@ unsigned shader[2]; unsigned n = 0; if (codes.vtx) { - shader[n++] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx, codes.vtx_pp); + 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); + shader[n++] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag, codes.frag_pp, codes.frag_pp_list, codes.frag_pp_list_select); } if (asc_shader_link(shader, n, prog)) { cxFreeDefault(prog); @@ -197,8 +208,12 @@ int ret = 0; ret |= asc_shader_load_code_file(info.files.vtx, &codes->vtx); codes->vtx_pp = info.defines.vtx; + codes->vtx_pp_list = info.defines.vtx_list; + codes->vtx_pp_list_select = info.defines.vtx_list_select; ret |= asc_shader_load_code_file(info.files.frag, &codes->frag); codes->frag_pp = info.defines.frag; + codes->frag_pp_list = info.defines.frag_list; + codes->frag_pp_list_select = info.defines.frag_list_select; return ret; }