src/shader.c

changeset 137
f8e6e0ae61a8
parent 122
1b118cd3e369
--- 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;
 }
 

mercurial