瀏覽代碼

Introduce several shaders to Simple_Renderer

rexim 2 年之前
父節點
當前提交
b4c1590d78
共有 8 個文件被更改,包括 139 次插入19 次删除
  1. 2 0
      shaders/simple.vert
  2. 0 0
      shaders/simple_color.frag
  3. 19 0
      shaders/simple_epic.frag
  4. 10 0
      shaders/simple_image.frag
  5. 9 0
      src/free_glyph.c
  6. 29 6
      src/main.c
  7. 56 11
      src/simple_renderer.c
  8. 14 2
      src/simple_renderer.h

+ 2 - 0
shaders/simple.vert

@@ -10,6 +10,7 @@ layout(location = 1) in vec4 color;
 layout(location = 2) in vec2 uv;
 
 out vec4 out_color;
+out vec2 out_uv;
 
 vec2 camera_project(vec2 point)
 {
@@ -19,4 +20,5 @@ vec2 camera_project(vec2 point)
 void main() {
     gl_Position = vec4(camera_project(position), 0, 1);
     out_color = color;
+    out_uv = uv;
 }

+ 0 - 0
shaders/simple.frag → shaders/simple_color.frag


+ 19 - 0
shaders/simple_epic.frag

@@ -0,0 +1,19 @@
+#version 330 core
+
+uniform float time;
+uniform vec2 resolution;
+uniform sampler2D image;
+
+in vec2 out_uv;
+
+vec3 hsl2rgb(vec3 c) {
+    vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0);
+    return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
+}
+
+void main() {
+    vec4 tc = texture(image, out_uv);
+    vec2 frag_uv = gl_FragCoord.xy / resolution;
+    vec4 rainbow = vec4(hsl2rgb(vec3((time + frag_uv.x + frag_uv.y), 0.5, 0.5)), 1.0);
+    gl_FragColor = tc.x * rainbow;
+}

+ 10 - 0
shaders/simple_image.frag

@@ -0,0 +1,10 @@
+#version 330 core
+
+uniform sampler2D image;
+
+in vec2 out_uv;
+
+void main() {
+    gl_FragColor = texture(image, out_uv);
+    // gl_FragColor = vec4(out_uv, 0, 1);
+}

+ 9 - 0
src/free_glyph.c

@@ -180,6 +180,15 @@ void free_glyph_buffer_init(Free_Glyph_Buffer *fgb,
                 face->glyph->bitmap.buffer);
             x += face->glyph->bitmap.width;
         }
+
+        #if 0
+        Glyph_Metric metric = fgb->metrics['E'];
+        Vec2f uv_pos = vec2f(metric.tx, 0.0f);
+        Vec2f uv_size = vec2f(metric.bw / (float) fgb->atlas_width, metric.bh / (float) fgb->atlas_height);
+        printf("%f %f\n", uv_pos.x, uv_pos.y);
+        printf("%f %f\n", uv_size.x, uv_size.y);
+        exit(69);
+        #endif
     }
 }
 

+ 29 - 6
src/main.c

@@ -126,20 +126,41 @@ void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Simple_R
 
     simple_renderer_use(sr);
     {
+        float CURSOR_WIDTH = 5.0f;
+        Uint32 CURSOR_BLINK_THRESHOLD = 500;
+        Uint32 CURSOR_BLINK_PERIOD = 1000;
+        Uint32 t = SDL_GetTicks() - last_stroke;
+
+        //////////////////////////////
+
+        simple_renderer_set_shader(sr, SHADER_FOR_EPICNESS);
         glUniform2f(sr->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
         glUniform1f(sr->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
         glUniform2f(sr->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
         glUniform1f(sr->uniforms[UNIFORM_SLOT_CAMERA_SCALE], camera_scale);
 
         sr->verticies_count = 0;
-        float CURSOR_WIDTH = 5.0f;
-        Uint32 CURSOR_BLINK_THRESHOLD = 500;
-        Uint32 CURSOR_BLINK_PERIOD = 1000;
-        Uint32 t = SDL_GetTicks() - last_stroke;
+        if (t < CURSOR_BLINK_THRESHOLD || t/CURSOR_BLINK_PERIOD%2 != 0) {
+            simple_renderer_image_rect(
+                sr,
+                cursor_pos, vec2f(CURSOR_WIDTH, FREE_GLYPH_FONT_SIZE));
+        }
+        simple_renderer_sync(sr);
+        simple_renderer_draw(sr);
+
+        //////////////////////////////
+
+        simple_renderer_set_shader(sr, SHADER_FOR_COLOR);
+        glUniform2f(sr->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
+        glUniform1f(sr->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
+        glUniform2f(sr->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
+        glUniform1f(sr->uniforms[UNIFORM_SLOT_CAMERA_SCALE], camera_scale);
+        sr->verticies_count = 0;
         if (t < CURSOR_BLINK_THRESHOLD || t/CURSOR_BLINK_PERIOD%2 != 0) {
             simple_renderer_solid_rect(
                 sr,
-                cursor_pos, vec2f(CURSOR_WIDTH, FREE_GLYPH_FONT_SIZE),
+                vec2f_add(cursor_pos, vec2f(CURSOR_WIDTH, 0)),
+                vec2f(CURSOR_WIDTH, FREE_GLYPH_FONT_SIZE),
                 vec4fs(1));
         }
         simple_renderer_sync(sr);
@@ -268,7 +289,9 @@ int main(int argc, char **argv)
 
     simple_renderer_init(&sr,
                          "./shaders/simple.vert",
-                         "./shaders/simple.frag");
+                         "./shaders/simple_color.frag",
+                         "./shaders/simple_image.frag",
+                         "./shaders/simple_epic.frag");
 
     bool quit = false;
     while (!quit) {

+ 56 - 11
src/simple_renderer.c

@@ -13,7 +13,9 @@
 
 void simple_renderer_init(Simple_Renderer *sr,
                           const char *vert_file_path,
-                          const char *frag_file_path)
+                          const char *color_frag_file_path,
+                          const char *image_frag_file_path,
+                          const char *epic_frag_file_path)
 {
     {
         glGenVertexArrays(1, &sr->vao);
@@ -55,29 +57,52 @@ void simple_renderer_init(Simple_Renderer *sr,
     }
 
     GLuint shaders[2] = {0};
+
     if (!compile_shader_file(vert_file_path, GL_VERTEX_SHADER, &shaders[0])) {
         exit(1);
     }
-    if (!compile_shader_file(frag_file_path, GL_FRAGMENT_SHADER, &shaders[1])) {
-        exit(1);
-    }
 
-    sr->program = glCreateProgram();
-    attach_shaders_to_program(shaders, sizeof(shaders) / sizeof(shaders[0]), sr->program);
-    if (!link_program(sr->program, __FILE__, __LINE__)) {
-        exit(1);
+    // Shader for color
+    {
+        if (!compile_shader_file(color_frag_file_path, GL_FRAGMENT_SHADER, &shaders[1])) {
+            exit(1);
+        }
+        sr->programs[SHADER_FOR_COLOR] = glCreateProgram();
+        attach_shaders_to_program(shaders, sizeof(shaders) / sizeof(shaders[0]), sr->programs[SHADER_FOR_COLOR]);
+        if (!link_program(sr->programs[SHADER_FOR_COLOR], __FILE__, __LINE__)) {
+            exit(1);
+        }
     }
 
-    glUseProgram(sr->program);
+    // Shader for image
+    {
+        if (!compile_shader_file(image_frag_file_path, GL_FRAGMENT_SHADER, &shaders[1])) {
+            exit(1);
+        }
+        sr->programs[SHADER_FOR_IMAGE] = glCreateProgram();
+        attach_shaders_to_program(shaders, sizeof(shaders) / sizeof(shaders[0]), sr->programs[SHADER_FOR_IMAGE]);
+        if (!link_program(sr->programs[SHADER_FOR_IMAGE], __FILE__, __LINE__)) {
+            exit(1);
+        }
+    }
 
-    get_uniform_location(sr->program, sr->uniforms);
+    // Shader for epicness
+    {
+        if (!compile_shader_file(epic_frag_file_path, GL_FRAGMENT_SHADER, &shaders[1])) {
+            exit(1);
+        }
+        sr->programs[SHADER_FOR_EPICNESS] = glCreateProgram();
+        attach_shaders_to_program(shaders, sizeof(shaders) / sizeof(shaders[0]), sr->programs[SHADER_FOR_EPICNESS]);
+        if (!link_program(sr->programs[SHADER_FOR_EPICNESS], __FILE__, __LINE__)) {
+            exit(1);
+        }
+    }
 }
 
 void simple_renderer_use(const Simple_Renderer *sr)
 {
     glBindVertexArray(sr->vao);
     glBindBuffer(GL_ARRAY_BUFFER, sr->vbo);
-    glUseProgram(sr->program);
 }
 
 void simple_renderer_vertex(Simple_Renderer *sr,
@@ -113,6 +138,19 @@ void simple_renderer_quad(Simple_Renderer *sr,
     simple_renderer_triangle(sr, p1, p2, p3, c1, c2, c3, uv1, uv2, uv3);
 }
 
+void simple_renderer_image_rect(Simple_Renderer *sr, Vec2f p, Vec2f s)
+{
+    // 0.361321 0.000000
+    // 0.372065 0.712121
+
+    Vec4f c = vec4fs(0);
+    simple_renderer_quad(
+        sr,
+        p, vec2f_add(p, vec2f(s.x, 0)), vec2f_add(p, vec2f(0, s.y)), vec2f_add(p, s),
+        c, c, c, c,
+        vec2f(0.361321, 0.000000), vec2f(0.372065, 0), vec2f(0.361321, 0.712121), vec2f(0.372065, 0.712121));
+}
+
 void simple_renderer_solid_rect(Simple_Renderer *sr, Vec2f p, Vec2f s, Vec4f c)
 {
     Vec2f uv = vec2fs(0);
@@ -135,3 +173,10 @@ void simple_renderer_draw(Simple_Renderer *sr)
 {
     glDrawArrays(GL_TRIANGLES, 0, sr->verticies_count);
 }
+
+void simple_renderer_set_shader(Simple_Renderer *sr, Simple_Shader shader)
+{
+    sr->current_shader = shader;
+    glUseProgram(sr->programs[sr->current_shader]);
+    get_uniform_location(sr->programs[sr->current_shader], sr->uniforms);
+}

+ 14 - 2
src/simple_renderer.h

@@ -24,10 +24,18 @@ typedef struct {
 
 #define SIMPLE_VERTICIES_CAP (3*640*1000)
 
+typedef enum {
+    SHADER_FOR_COLOR = 0,
+    SHADER_FOR_IMAGE,
+    SHADER_FOR_EPICNESS,
+    COUNT_SIMPLE_SHADERS,
+} Simple_Shader;
+
 typedef struct {
     GLuint vao;
     GLuint vbo;
-    GLuint program;
+    GLuint programs[COUNT_SIMPLE_SHADERS];
+    Simple_Shader current_shader;
 
     GLint uniforms[COUNT_UNIFORM_SLOTS];
     Simple_Vertex verticies[SIMPLE_VERTICIES_CAP];
@@ -36,11 +44,14 @@ typedef struct {
 
 void simple_renderer_init(Simple_Renderer *sr,
                           const char *vert_file_path,
-                          const char *frag_file_path);
+                          const char *color_frag_file_path,
+                          const char *image_frag_file_path,
+                          const char *epic_frag_file_path);
 
 void simple_renderer_use(const Simple_Renderer *sr);
 void simple_renderer_vertex(Simple_Renderer *sr,
                             Vec2f p, Vec4f c, Vec2f uv);
+void simple_renderer_set_shader(Simple_Renderer *sr, Simple_Shader shader);
 void simple_renderer_triangle(Simple_Renderer *sr,
                               Vec2f p0, Vec2f p1, Vec2f p2,
                               Vec4f c0, Vec4f c1, Vec4f c2,
@@ -50,6 +61,7 @@ void simple_renderer_quad(Simple_Renderer *sr,
                           Vec4f c0, Vec4f c1, Vec4f c2, Vec4f c3,
                           Vec2f uv0, Vec2f uv1, Vec2f uv2, Vec2f uv3);
 void simple_renderer_solid_rect(Simple_Renderer *sr, Vec2f p, Vec2f s, Vec4f c);
+void simple_renderer_image_rect(Simple_Renderer *sr, Vec2f p, Vec2f s);
 void simple_renderer_sync(Simple_Renderer *sr);
 void simple_renderer_draw(Simple_Renderer *sr);