Browse Source

Introduce SHADER_FOR_TEXT

rexim 2 years ago
parent
commit
f813754dd2
7 changed files with 69 additions and 74 deletions
  1. 10 0
      shaders/simple_text.frag
  2. 8 10
      src/editor.c
  3. 23 9
      src/free_glyph.c
  4. 2 1
      src/free_glyph.h
  5. 5 10
      src/main.c
  6. 18 38
      src/simple_renderer.c
  7. 3 6
      src/simple_renderer.h

+ 10 - 0
shaders/simple_text.frag

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

+ 8 - 10
src/editor.c

@@ -184,16 +184,14 @@ void editor_render(SDL_Window *window, Free_Glyph_Atlas *atlas, Simple_Renderer
 
                 if (select_begin_chr <= select_end_chr) {
                     Vec2f select_begin_scr = vec2f(0, -(float)row * FREE_GLYPH_FONT_SIZE);
-                    free_glyph_atlas_render_line_sized(
-                        atlas, sr, editor->data.items + line_chr.begin, select_begin_chr - line_chr.begin,
-                        &select_begin_scr,
-                        false);
+                    free_glyph_atlas_measure_line_sized(
+                        atlas, editor->data.items + line_chr.begin, select_begin_chr - line_chr.begin,
+                        &select_begin_scr);
 
                     Vec2f select_end_scr = select_begin_scr;
-                    free_glyph_atlas_render_line_sized(
-                        atlas, sr, editor->data.items + select_begin_chr, select_end_chr - select_begin_chr,
-                        &select_end_scr,
-                        false);
+                    free_glyph_atlas_measure_line_sized(
+                        atlas, editor->data.items + select_begin_chr, select_end_chr - select_begin_chr,
+                        &select_end_scr);
 
                     Vec4f selection_color = vec4f(.25, .25, .25, 1);
                     simple_renderer_solid_rect(sr, select_begin_scr, vec2f(select_end_scr.x - select_begin_scr.x, FREE_GLYPH_FONT_SIZE), selection_color);
@@ -202,7 +200,7 @@ void editor_render(SDL_Window *window, Free_Glyph_Atlas *atlas, Simple_Renderer
         }
         simple_renderer_flush(sr);
 
-        simple_renderer_set_shader(sr, SHADER_FOR_EPICNESS);
+        simple_renderer_set_shader(sr, SHADER_FOR_TEXT);
         for (size_t row = 0; row < editor->lines.count; ++row) {
             Line line = editor->lines.items[row];
 
@@ -211,7 +209,7 @@ void editor_render(SDL_Window *window, Free_Glyph_Atlas *atlas, Simple_Renderer
             free_glyph_atlas_render_line_sized(
                 atlas, sr, editor->data.items + line.begin, line.end - line.begin,
                 &end,
-                true);
+                vec4fs(1));
             // TODO: the max_line_len should be calculated based on what's visible on the screen right now
             float line_len = fabsf(end.x - begin.x);
             if (line_len > max_line_len) {

+ 23 - 9
src/free_glyph.c

@@ -92,7 +92,22 @@ float free_glyph_atlas_cursor_pos(const Free_Glyph_Atlas *atlas, const char *tex
     return pos.x;
 }
 
-void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer *sr, const char *text, size_t text_size, Vec2f *pos, bool render)
+void free_glyph_atlas_measure_line_sized(Free_Glyph_Atlas *atlas, const char *text, size_t text_size, Vec2f *pos)
+{
+    for (size_t i = 0; i < text_size; ++i) {
+        size_t glyph_index = text[i];
+        // TODO: support for glyphs outside of ASCII range
+        if (glyph_index >= GLYPH_METRICS_CAPACITY) {
+            glyph_index = '?';
+        }
+        Glyph_Metric metric = atlas->metrics[glyph_index];
+
+        pos->x += metric.ax;
+        pos->y += metric.ay;
+    }
+}
+
+void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer *sr, const char *text, size_t text_size, Vec2f *pos, Vec4f color)
 {
     for (size_t i = 0; i < text_size; ++i) {
         size_t glyph_index = text[i];
@@ -109,13 +124,12 @@ void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer
         pos->x += metric.ax;
         pos->y += metric.ay;
 
-        if (render) {
-            simple_renderer_image_rect(
-                sr,
-                vec2f(x2, -y2),
-                vec2f(w, -h),
-                vec2f(metric.tx, 0.0f),
-                vec2f(metric.bw / (float) atlas->atlas_width, metric.bh / (float) atlas->atlas_height));
-        }
+        simple_renderer_image_rect(
+            sr,
+            vec2f(x2, -y2),
+            vec2f(w, -h),
+            vec2f(metric.tx, 0.0f),
+            vec2f(metric.bw / (float) atlas->atlas_width, metric.bh / (float) atlas->atlas_height),
+            color);
     }
 }

+ 2 - 1
src/free_glyph.h

@@ -43,6 +43,7 @@ typedef struct {
 
 void free_glyph_atlas_init(Free_Glyph_Atlas *atlas, FT_Face face);
 float free_glyph_atlas_cursor_pos(const Free_Glyph_Atlas *atlas, const char *text, size_t text_size, Vec2f pos, size_t col);
-void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer *sr, const char *text, size_t text_size, Vec2f *pos, bool render);
+void free_glyph_atlas_measure_line_sized(Free_Glyph_Atlas *atlas, const char *text, size_t text_size, Vec2f *pos);
+void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer *sr, const char *text, size_t text_size, Vec2f *pos, Vec4f color);
 
 #endif // FREE_GLYPH_H_

+ 5 - 10
src/main.c

@@ -66,10 +66,9 @@ void render_file_browser(SDL_Window *window, Free_Glyph_Atlas *atlas, Simple_Ren
     if (fb->cursor < fb->files.count) {
         const Vec2f begin = vec2f(0, -(float)fb->cursor * FREE_GLYPH_FONT_SIZE);
         Vec2f end = begin;
-        free_glyph_atlas_render_line_sized(
-            atlas, sr, fb->files.items[fb->cursor], strlen(fb->files.items[fb->cursor]),
-            &end,
-            false);
+        free_glyph_atlas_measure_line_sized(
+            atlas, fb->files.items[fb->cursor], strlen(fb->files.items[fb->cursor]),
+            &end);
         simple_renderer_solid_rect(sr, begin, vec2f(end.x - begin.x, FREE_GLYPH_FONT_SIZE), vec4f(.25, .25, .25, 1));
     }
     simple_renderer_flush(sr);
@@ -81,7 +80,7 @@ void render_file_browser(SDL_Window *window, Free_Glyph_Atlas *atlas, Simple_Ren
         free_glyph_atlas_render_line_sized(
             atlas, sr, fb->files.items[row], strlen(fb->files.items[row]),
             &end,
-            true);
+            vec4fs(0));
         // TODO: the max_line_len should be calculated based on what's visible on the screen right now
         float line_len = fabsf(end.x - begin.x);
         if (line_len > max_line_len) {
@@ -226,11 +225,7 @@ int main(int argc, char **argv)
     }
 
 
-    simple_renderer_init(&sr,
-                         "./shaders/simple.vert",
-                         "./shaders/simple_color.frag",
-                         "./shaders/simple_image.frag",
-                         "./shaders/simple_epic.frag");
+    simple_renderer_init(&sr);
     free_glyph_atlas_init(&atlas, face);
 
     bool quit = false;

+ 18 - 38
src/simple_renderer.c

@@ -7,6 +7,16 @@
 #include "./simple_renderer.h"
 #include "./common.h"
 
+#define vert_shader_file_path "./shaders/simple.vert"
+
+static_assert(COUNT_SIMPLE_SHADERS == 4, "The amount of fragment shaders has changed");
+const char *frag_shader_file_paths[COUNT_SIMPLE_SHADERS] = {
+    [SHADER_FOR_COLOR] = "./shaders/simple_color.frag",
+    [SHADER_FOR_IMAGE] = "./shaders/simple_image.frag",
+    [SHADER_FOR_TEXT] = "./shaders/simple_text.frag",
+    [SHADER_FOR_EPICNESS] = "./shaders/simple_epic.frag",
+};
+
 static const char *shader_type_as_cstr(GLuint shader)
 {
     switch (shader) {
@@ -118,11 +128,7 @@ static void get_uniform_location(GLuint program, GLint locations[COUNT_UNIFORM_S
     }
 }
 
-void simple_renderer_init(Simple_Renderer *sr,
-                          const char *vert_file_path,
-                          const char *color_frag_file_path,
-                          const char *image_frag_file_path,
-                          const char *epic_frag_file_path)
+void simple_renderer_init(Simple_Renderer *sr)
 {
     sr->camera_scale = 3.0f;
 
@@ -169,42 +175,17 @@ void simple_renderer_init(Simple_Renderer *sr,
 
     // TODO: dynamic shader reloading
 
-    if (!compile_shader_file(vert_file_path, GL_VERTEX_SHADER, &shaders[0])) {
+    if (!compile_shader_file(vert_shader_file_path, GL_VERTEX_SHADER, &shaders[0])) {
         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);
-        }
-    }
-
-    // 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);
-        }
-    }
-
-    // Shader for epicness
-    {
-        if (!compile_shader_file(epic_frag_file_path, GL_FRAGMENT_SHADER, &shaders[1])) {
+    for (int i = 0; i < COUNT_SIMPLE_SHADERS; ++i) {
+        if (!compile_shader_file(frag_shader_file_paths[i], 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__)) {
+        sr->programs[i] = glCreateProgram();
+        attach_shaders_to_program(shaders, sizeof(shaders) / sizeof(shaders[0]), sr->programs[i]);
+        if (!link_program(sr->programs[i], __FILE__, __LINE__)) {
             exit(1);
         }
     }
@@ -244,9 +225,8 @@ 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, Vec2f uvp, Vec2f uvs)
+void simple_renderer_image_rect(Simple_Renderer *sr, Vec2f p, Vec2f s, Vec2f uvp, Vec2f uvs, Vec4f c)
 {
-    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),

+ 3 - 6
src/simple_renderer.h

@@ -34,6 +34,7 @@ typedef struct {
 typedef enum {
     SHADER_FOR_COLOR = 0,
     SHADER_FOR_IMAGE,
+    SHADER_FOR_TEXT,
     SHADER_FOR_EPICNESS, // This is the one that does that cool rainbowish animation
     COUNT_SIMPLE_SHADERS,
 } Simple_Shader;
@@ -57,11 +58,7 @@ typedef struct {
     Vec2f camera_vel;
 } Simple_Renderer;
 
-void simple_renderer_init(Simple_Renderer *sr,
-                          const char *vert_file_path,
-                          const char *color_frag_file_path,
-                          const char *image_frag_file_path,
-                          const char *epic_frag_file_path);
+void simple_renderer_init(Simple_Renderer *sr);
 
 void simple_renderer_vertex(Simple_Renderer *sr,
                             Vec2f p, Vec4f c, Vec2f uv);
@@ -75,7 +72,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, Vec2f uvp, Vec2f uvs);
+void simple_renderer_image_rect(Simple_Renderer *sr, Vec2f p, Vec2f s, Vec2f uvp, Vec2f uvs, Vec4f c);
 void simple_renderer_flush(Simple_Renderer *sr);
 void simple_renderer_sync(Simple_Renderer *sr);
 void simple_renderer_draw(Simple_Renderer *sr);