--- a/src/shader.c Sun Jun 01 14:59:40 2025 +0200 +++ b/src/shader.c Sun Jun 01 16:35:23 2025 +0200 @@ -43,9 +43,10 @@ * * @param type the shader type (use the GL enum) * @param code the source code + * @param code_pp the optional preprocessor code * @return the compiled shader */ -static unsigned asc_shader_compile(unsigned int type, char const *code) { +static unsigned asc_shader_compile(unsigned int type, const char *code, const char *code_pp) { GLuint id = glCreateShader(type); if (id == 0) { asc_error("glCreateShader failed: %s", glGetError()); @@ -53,8 +54,17 @@ } GLint success; - int length = (int) strlen(code); // must be int because of OpenGL API - glShaderSource(id, 1, &code, &length); + const char *code_array[4]; + GLint length_array[4]; +#define store_str(i, s) do {cxstring cxs = cx_str(s); code_array[i] = cxs.ptr; length_array[i] = (GLint) cxs.length;} while(0) + store_str(0, "#version 400 core\n"); + store_str(1, code_pp); + store_str(2, "\n#line 1\n"); + store_str(3, code); +#undef store_str + + // compile + glShaderSource(id, cx_nmemb(length_array), code_array, length_array); glCompileShader(id); glGetShaderiv(id, GL_COMPILE_STATUS, &success); if (success) { @@ -121,35 +131,14 @@ program->id = 0; } -int asc_shader_sprite_init(AscShaderSprite *sprite) { - AscShaderCodes codes; - if (asc_shader_load_code_files((AscShaderCodeFiles){ - .vtx = "sprite_vtx.glsl", - .frag = "sprite_frag.glsl" - }, &codes)) { - asc_error("Loading sprite shader failed."); - return 1; - } - sprite->program = asc_shader_program_create(codes); - if (asc_has_error()) { - asc_shader_free_codes(codes); - return 1; - } - sprite->depth = glGetUniformLocation(sprite->program.id, "depth"); - sprite->rect_tex = glGetUniformLocation(sprite->program.id, "rect_tex"); - sprite->uv_tex = glGetUniformLocation(sprite->program.id, "uv_tex"); - asc_shader_free_codes(codes); - return 0; -} - AscShaderProgram asc_shader_program_create(AscShaderCodes codes) { unsigned shader[4]; unsigned n = 0; if (codes.vtx) { - shader[n++] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx); + shader[n++] = asc_shader_compile(GL_VERTEX_SHADER, codes.vtx, codes.vtx_pp); } if (codes.frag) { - shader[n++] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag); + shader[n++] = asc_shader_compile(GL_FRAGMENT_SHADER, codes.frag, codes.frag_pp); } const AscShaderProgram prog = asc_shader_link(shader, n); for (unsigned i = 0; i < n; i++) { @@ -158,6 +147,12 @@ return prog; } +void asc_shader_program_use(const AscShaderProgram *shader, const AscCamera *camera) { + glUseProgram(shader->id); + glUniformMatrix4fv(shader->projection, 1, GL_FALSE, camera->projection); + glUniformMatrix4fv(shader->view, 1, GL_FALSE, camera->view); +} + static int asc_shader_load_code_file(const char *filename, char **code) { if (filename == NULL) { *code = NULL; @@ -177,10 +172,12 @@ return *code == NULL ? -1 : 0; } -int asc_shader_load_code_files(AscShaderCodeFiles files, AscShaderCodes *codes) { +int asc_shader_load_code_files(AscShaderCodeInfo info, AscShaderCodes *codes) { int ret = 0; - ret |= asc_shader_load_code_file(files.vtx, &codes->vtx); - ret |= asc_shader_load_code_file(files.frag, &codes->frag); + ret |= asc_shader_load_code_file(info.files.vtx, &codes->vtx); + codes->vtx_pp = info.defines.vtx; + ret |= asc_shader_load_code_file(info.files.frag, &codes->frag); + codes->frag_pp = info.defines.frag; return ret; }