Ver código fonte

Merge all the renderes into a single one

rexim 3 anos atrás
pai
commit
0c52df5315
3 arquivos alterados com 117 adições e 159 exclusões
  1. 105 143
      main.c
  2. 11 8
      render.conf
  3. 1 8
      shaders/flash.frag

+ 105 - 143
main.c

@@ -161,6 +161,13 @@ static const char *uniform_names[COUNT_UNIFORMS] = {
     [TEX_UNIFORM] = "tex",
 };
 
+typedef enum {
+    PROGRAM_SCENE = 0,
+    PROGRAM_POST0,
+    PROGRAM_POST1,
+    COUNT_PROGRAMS
+} Program;
+
 typedef enum {
     VA_POS = 0,
     VA_UV,
@@ -179,18 +186,17 @@ typedef struct {
     bool reload_failed;
     GLuint vao;
     GLuint vbo;
-    GLuint program;
-    GLint uniforms[COUNT_UNIFORMS];
-    Vertex vertex_buf[VERTEX_BUF_CAP];
+    GLuint programs[COUNT_PROGRAMS];
+    GLint uniforms[COUNT_PROGRAMS][COUNT_UNIFORMS];
     size_t vertex_buf_sz;
-    GLuint texture;
+    Vertex vertex_buf[VERTEX_BUF_CAP];
 } Renderer;
 
 // Global variables (fragile people with CS degree look away)
 static double time = 0.0;
 static bool pause = false;
+static GLuint user_texture = 0;
 static Renderer global_renderer = {0};
-static Renderer ripple_renderer = {0};
 
 void r_vertex(Renderer *r, V2f pos, V2f uv, V4f color)
 {
@@ -231,16 +237,17 @@ void r_sync_buffers(Renderer *r)
 }
 
 void r_sync_uniforms(Renderer *r,
+                     GLuint program,
                      GLfloat resolution_width, GLfloat resolution_height,
                      GLfloat time,
                      GLfloat mouse_x, GLfloat mouse_y,
                      GLint tex_unit)
 {
     static_assert(COUNT_UNIFORMS == 4, "Exhaustive uniform handling in ");
-    glUniform2f(r->uniforms[RESOLUTION_UNIFORM], resolution_width, resolution_height);
-    glUniform1f(r->uniforms[TIME_UNIFORM], time);
-    glUniform2f(r->uniforms[MOUSE_UNIFORM], mouse_x, mouse_y);
-    glUniform1i(r->uniforms[TEX_UNIFORM], tex_unit);
+    glUniform2f(r->uniforms[program][RESOLUTION_UNIFORM], resolution_width, resolution_height);
+    glUniform1f(r->uniforms[program][TIME_UNIFORM], time);
+    glUniform2f(r->uniforms[program][MOUSE_UNIFORM], mouse_x, mouse_y);
+    glUniform1i(r->uniforms[program][TEX_UNIFORM], tex_unit);
 }
 
 bool load_shader_program(const char *vertex_file_path,
@@ -274,8 +281,8 @@ typedef struct {
 Object objects[OBJECTS_CAP];
 size_t objects_count = 0;
 
-static const char *vert_path = NULL;
-static const char *frag_path = NULL;
+static const char *vert_path[COUNT_PROGRAMS] = {0};
+static const char *frag_path[COUNT_PROGRAMS] = {0};
 static const char *texture_path = NULL;
 static float follow_scale = 1.0f;
 static float object_size = 100.0f;
@@ -314,8 +321,10 @@ void reload_render_conf(const char *render_conf_path)
 
     String_View content = sv_from_cstr(render_conf);
 
-    vert_path = NULL;
-    frag_path = NULL;
+    for (Program p = 0; p < COUNT_PROGRAMS; ++p) {
+        vert_path[p] = NULL;
+        frag_path[p] = NULL;
+    }
     texture_path = NULL;
     for (int row = 0; content.count > 0; row++) {
         String_View line = sv_chop_by_delim(&content, '\n');
@@ -344,15 +353,21 @@ void reload_render_conf(const char *render_conf_path)
             // There is always something after `value`. It's either `\n` or `\0`. With all of these
             // invariats in place writing to `value.data[value.count]` should be safe.
 
-            if (sv_eq(key, SV("vert"))) {
-                vert_path = value.data;
-                printf("Vertex Path: %s\n", vert_path);
-            } else if (sv_eq(key, SV("frag"))) {
-                frag_path = value.data;
-                printf("Fragment Path: %s\n", frag_path);
+            static_assert(COUNT_PROGRAMS == 3, "Exhaustive handling of shader programs in config parsing");
+            if (sv_eq(key, SV("vert[SCENE]"))) {
+                vert_path[PROGRAM_SCENE] = value.data;
+            } else if (sv_eq(key, SV("frag[SCENE]"))) {
+                frag_path[PROGRAM_SCENE] = value.data;
+            } else if (sv_eq(key, SV("vert[POST0]"))) {
+                vert_path[PROGRAM_POST0] = value.data;
+            } else if (sv_eq(key, SV("frag[POST0]"))) {
+                frag_path[PROGRAM_POST0] = value.data;
+            } else if (sv_eq(key, SV("vert[POST1]"))) {
+                vert_path[PROGRAM_POST1] = value.data;
+            } else if (sv_eq(key, SV("frag[POST1]"))) {
+                frag_path[PROGRAM_POST1] = value.data;
             } else if (sv_eq(key, SV("texture"))) {
                 texture_path = value.data;
-                printf("Texture Path: %s\n", texture_path);
             } else if (sv_eq(key, SV("follow_scale"))) {
                 follow_scale = strtof(value.data, NULL);
             } else if (sv_eq(key, SV("object_size"))) {
@@ -372,12 +387,15 @@ void reload_render_conf(const char *render_conf_path)
                 printf("%s:%d:%ld: ERROR: unsupported key `"SV_Fmt"`\n",
                        render_conf_path, row, key.data - line_start,
                        SV_Arg(key));
+                continue;
             }
+
+            printf(SV_Fmt" = %s\n", SV_Arg(key), value.data);
         }
     }
 }
 
-bool r_reload_textures(Renderer *r)
+bool reload_user_textures(void)
 {
     int texture_width, texture_height;
     unsigned char *texture_pixels = stbi_load(texture_path, &texture_width, &texture_height, NULL, 4);
@@ -387,10 +405,10 @@ bool r_reload_textures(Renderer *r)
         return false;
     }
 
-    glDeleteTextures(1, &r->texture);
-    glGenTextures(1, &r->texture);
+    glDeleteTextures(1, &user_texture);
+    glGenTextures(1, &user_texture);
     glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, r->texture);
+    glBindTexture(GL_TEXTURE_2D, user_texture);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -413,60 +431,41 @@ bool r_reload_textures(Renderer *r)
     return true;
 }
 
-bool r_reload_shaders(Renderer *r, const char *vert_path, const char *frag_path)
+bool r_reload_shaders(Renderer *r)
 {
-    glDeleteProgram(r->program);
+    for (Program p = 0; p < COUNT_PROGRAMS; ++p) {
+        glDeleteProgram(r->programs[p]);
 
-    if (!load_shader_program(vert_path, frag_path, &r->program)) return false;
+        if (!load_shader_program(vert_path[p], frag_path[p], &r->programs[p])) return false;
 
-    glUseProgram(r->program);
+        glUseProgram(r->programs[p]);
 
-    for (Uniform index = 0; index < COUNT_UNIFORMS; ++index) {
-        r->uniforms[index] = glGetUniformLocation(r->program, uniform_names[index]);
+        for (Uniform index = 0; index < COUNT_UNIFORMS; ++index) {
+            r->uniforms[p][index] = glGetUniformLocation(r->programs[p], uniform_names[index]);
+        }
     }
 
     printf("Successfully reloaded the Shaders\n");
     return true;
 }
 
-bool r_reload(Renderer *r, const char *vert_path, const char *frag_path)
+bool r_reload(Renderer *r)
 {
     r->reload_failed = true;
-
-    if (!r_reload_shaders(r, vert_path, frag_path)) return false;
-    if (!r_reload_textures(r)) return false;
-
+    if (!r_reload_shaders(r)) return false;
     r->reload_failed = false;
 
     return true;
 }
 
-typedef struct {
-    float t;
-    float dt;
-    V4f color;
-
-    GLuint framebuffer;
-    GLuint texture;
-    GLuint program;
-    GLuint tex_uniform;
-    GLuint color_uniform;
-    GLuint t_uniform;
-    GLuint time_uniform;
-} Flash;
-
-static Flash global_flash = {0};
+static GLuint scene_framebuffer = {0};
+static GLuint scene_texture = 0;
 
-#define FLASH_SPEED 2.0f
-#define FLASH_RED_V4F COLOR_RED_V4F
-#define FLASH_GREEN_V4F COLOR_GREEN_V4F
-#define FLASH_BLUE_V4F COLOR_BLUE_V4F
-
-void flash_init(Flash *flash)
+void scene_framebuffer_init(void)
 {
-    glGenTextures(1, &flash->texture);
+    glGenTextures(1, &scene_texture);
     glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, flash->texture);
+    glBindTexture(GL_TEXTURE_2D, scene_texture);
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -484,9 +483,9 @@ void flash_init(Flash *flash)
         GL_UNSIGNED_BYTE,
         NULL);
 
-    glGenFramebuffers(1, &flash->framebuffer);
-    glBindFramebuffer(GL_FRAMEBUFFER, flash->framebuffer);
-    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, flash->texture, 0);
+    glGenFramebuffers(1, &scene_framebuffer);
+    glBindFramebuffer(GL_FRAMEBUFFER, scene_framebuffer);
+    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, scene_texture, 0);
 
     GLenum draw_buffers = GL_COLOR_ATTACHMENT0;
     glDrawBuffers(1, &draw_buffers);
@@ -497,45 +496,9 @@ void flash_init(Flash *flash)
         exit(1);
     }
 
-    if (!load_shader_program("./shaders/flash.vert", "./shaders/flash.frag", &flash->program)) {
-        exit(1);
-    }
-    glUseProgram(flash->program);
-
-    flash->tex_uniform = glGetUniformLocation(flash->program, "tex");
-    flash->color_uniform = glGetUniformLocation(flash->program, "color");
-    flash->t_uniform = glGetUniformLocation(flash->program, "t");
-    flash->time_uniform = glGetUniformLocation(flash->program, "time");
-
-    glUniform1i(flash->tex_uniform, 1);
-    glUniform4f(flash->color_uniform, 1.0, 0.0, 0.0, 1.0);
-
     printf("Successfully created the debug framebuffer\n");
 }
 
-void flash_bang(Flash *flash, V4f color)
-{
-    flash->t = 1.0f;
-    flash->dt = -FLASH_SPEED;
-    flash->color = color;
-}
-
-void flash_update(Flash *flash, float delta_time)
-{
-    flash->t += flash->dt * delta_time;
-    if (flash->t <= 0.0f) {
-        flash->t = 0.0f;
-        flash->dt = 0.0f;
-    }
-}
-
-void flash_sync_uniforms(Flash *f)
-{
-    glUniform1f(f->t_uniform, f->t);
-    glUniform4f(f->color_uniform, f->color.x, f->color.y, f->color.z, f->color.w);
-    glUniform1f(f->time_uniform, time);
-}
-
 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
 {
     (void) scancode;
@@ -545,12 +508,8 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
     if (action == GLFW_PRESS) {
         if (key == GLFW_KEY_F5) {
             reload_render_conf("render.conf");
-            if (r_reload(&global_renderer, vert_path, frag_path) &&
-                    r_reload(&ripple_renderer, "shaders/ripple.vert", "shaders/ripple.frag")) {
-                flash_bang(&global_flash, FLASH_GREEN_V4F);
-            } else {
-                flash_bang(&global_flash, FLASH_RED_V4F);
-            }
+            reload_user_textures();
+            r_reload(&global_renderer);
         } else if (key == GLFW_KEY_F6) {
 #define SCREENSHOT_PNG_PATH "screenshot.png"
             printf("Saving the screenshot at %s\n", SCREENSHOT_PNG_PATH);
@@ -567,7 +526,6 @@ void key_callback(GLFWwindow* window, int key, int scancode, int action, int mod
                 fprintf(stderr, "ERROR: could not save %s: %s\n", SCREENSHOT_PNG_PATH, strerror(errno));
             }
             free(pixels);
-            flash_bang(&global_flash, FLASH_BLUE_V4F);
         } else if (key == GLFW_KEY_SPACE) {
             pause = !pause;
         } else if (key == GLFW_KEY_Q) {
@@ -589,7 +547,7 @@ void window_size_callback(GLFWwindow* window, int width, int height)
     (void) window;
     glViewport(0, 0, width, height);
     glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, global_flash.texture);
+    glBindTexture(GL_TEXTURE_2D, scene_texture);
     glTexImage2D(
         GL_TEXTURE_2D,
         0,
@@ -704,15 +662,14 @@ int main(void)
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
-    flash_init(&global_flash);
+    scene_framebuffer_init();
 
     Renderer *r = &global_renderer;
 
-    r_init(r);
-    r_reload(r, vert_path, frag_path);
+    reload_user_textures();
 
-    r_init(&ripple_renderer);
-    r_reload(&ripple_renderer, "shaders/ripple.vert", "shaders/ripple.frag");
+    r_init(r);
+    r_reload(r);
 
     glfwSetKeyCallback(window, key_callback);
     glfwSetFramebufferSizeCallback(window, window_size_callback);
@@ -728,45 +685,50 @@ int main(void)
         xpos = xpos - width * 0.5f;
         ypos = (height - ypos) - height * 0.5f;
 
-        glBindFramebuffer(GL_FRAMEBUFFER, global_flash.framebuffer);
-        {
-            glClear(GL_COLOR_BUFFER_BIT);
-            glBindVertexArray(r->vao);
-            glBindBuffer(GL_ARRAY_BUFFER, r->vbo);
-            glUseProgram(r->program);
-            r_clear(r);
-            r_sync_uniforms(r, width, height, time, xpos, ypos, 0);
-            for (size_t i = 0; i < objects_count; ++i) {
-                object_render(r, &objects[i]);
-            }
-            r_sync_buffers(r);
-
-            glDrawArraysInstanced(GL_TRIANGLES, 0, (GLsizei) r->vertex_buf_sz, 1);
-        }
+        if (!r->reload_failed) {
+            static_assert(COUNT_PROGRAMS == 3, "Exhaustive handling of shader programs in the event loop");
+
+            glBindFramebuffer(GL_FRAMEBUFFER, scene_framebuffer);
+            {
+                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+                glClear(GL_COLOR_BUFFER_BIT);
+                glUseProgram(r->programs[PROGRAM_SCENE]);
+                r_clear(r);
+                r_sync_uniforms(r, PROGRAM_SCENE, width, height, time, xpos, ypos, 0);
+                for (size_t i = 0; i < objects_count; ++i) {
+                    object_render(r, &objects[i]);
+                }
+                r_sync_buffers(r);
 
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+                glDrawArraysInstanced(GL_TRIANGLES, 0, (GLsizei) r->vertex_buf_sz, 1);
+            }
 
-        {
+            glBindFramebuffer(GL_FRAMEBUFFER, 0);
+            {
+                glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+                glClear(GL_COLOR_BUFFER_BIT);
+
+#if 0
+                glUseProgram(r->programs[PROGRAM_POST0]);
+                r_sync_uniforms(r, PROGRAM_POST0, width, height, time, xpos, ypos, 1);
+                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+#endif
+
+                glUseProgram(r->programs[PROGRAM_POST1]);
+                r_clear(r);
+                r_sync_uniforms(r, PROGRAM_POST1, width, height, time, xpos, ypos, 1);
+                r_quad_cr(r, v2ff(0.0f), v2f(width * 0.5, height * 0.5), COLOR_BLACK_V4F);
+                r_sync_buffers(r);
+                glDrawArraysInstanced(GL_TRIANGLES, 0, (GLsizei) r->vertex_buf_sz, 1);
+            }
+        } else {
+            glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
             glClear(GL_COLOR_BUFFER_BIT);
-            glUseProgram(global_flash.program);
-            flash_update(&global_flash, delta_time);
-            flash_sync_uniforms(&global_flash);
-            glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
-
-            glBindVertexArray(ripple_renderer.vao);
-            glBindBuffer(GL_ARRAY_BUFFER, ripple_renderer.vbo);
-            glUseProgram(ripple_renderer.program);
-            r_clear(&ripple_renderer);
-            r_sync_uniforms(&ripple_renderer, width, height, time, xpos, ypos, 1);
-            r_quad_cr(&ripple_renderer, v2ff(0.0f), v2f(width * 0.5, height * 0.5), COLOR_BLACK_V4F);
-            r_sync_buffers(&ripple_renderer);
-
-            glDrawArraysInstanced(GL_TRIANGLES, 0, (GLsizei) ripple_renderer.vertex_buf_sz, 1);
         }
 
         if (objects_count > 0) {
-            float follow_x = sin(time * rotate_speed) * rotate_radius;
-            float follow_y = cos(time * rotate_speed) * rotate_radius;
+            float follow_x = xpos + sin(time * rotate_speed) * rotate_radius;
+            float follow_y = ypos + cos(time * rotate_speed) * rotate_radius;
 
             object_update(&objects[0], delta_time, follow_x, follow_y);
             for (size_t i = 1; i < objects_count; ++i) {

+ 11 - 8
render.conf

@@ -1,11 +1,14 @@
-vert = shaders/main.vert
-frag = shaders/main.frag
-texture = assets/tsodinW-345.png
-#texture = assets/pogger.png
-#texture = assets/tsodinSleep-112.png
+vert[SCENE] = shaders/main.vert
+frag[SCENE] = shaders/main.frag
+vert[POST0] = shaders/flash.vert
+frag[POST0] = shaders/flash.frag
+vert[POST1] = shaders/ripple.vert
+frag[POST1] = shaders/ripple.frag
+#texture = assets/tsodinW-345.png
+texture = assets/tsodinSleep-112.png
 
 follow_scale = 1.0
-object_size = 150.0
-rotate_radius = 300.0
+object_size = 75.0
+rotate_radius = 0.0
 rotate_speed = 1.0
-objects_count = 3
+objects_count = 15

+ 1 - 8
shaders/flash.frag

@@ -2,18 +2,11 @@
 
 precision mediump float;
 
-uniform float time;
 uniform sampler2D tex;
-uniform vec4 color;
-uniform float t;
 
 in vec2 uv;
 out vec4 out_color;
 
 void main(void) {
-    vec2 cPos = 2.0*uv - 1.0;
-    float cLength = length(cPos);
-    vec2 tex_uv = uv + (cPos/cLength)*cos(cLength*12.0-time*4.0)*0.03;
-
-    out_color = mix(texture(tex, uv), color, t);
+    out_color = texture(tex, uv);
 }