Browse Source

Introduce Free_Glyph renderer

rexim 4 years ago
parent
commit
ca556aac64
10 changed files with 274 additions and 45 deletions
  1. 4 0
      README.md
  2. BIN
      VictorMono-Regular.ttf
  3. 1 1
      build.sh
  4. 7 0
      shaders/free_glyph.frag
  5. 14 0
      shaders/free_glyph.vert
  6. 133 0
      src/free_glyph.c
  7. 53 0
      src/free_glyph.h
  8. 55 36
      src/main.c
  9. 6 0
      src/tile_glyph.c
  10. 1 8
      src/tile_glyph.h

+ 4 - 0
README.md

@@ -16,3 +16,7 @@ $ ./ded src\main.c
 > .\build_msvc.bat
 > .\ded.exe src\main.c
 ```
+
+# Font
+
+Victor Mono: https://rubjo.github.io/victor-mono/

BIN
VictorMono-Regular.ttf


+ 1 - 1
build.sh

@@ -6,7 +6,7 @@ CC="${CXX:-cc}"
 PKGS="sdl2 glew"
 CFLAGS="-Wall -Wextra -std=c11 -pedantic -ggdb"
 LIBS=-lm
-SRC="src/main.c src/la.c src/editor.c src/sdl_extra.c src/file.c src/gl_extra.c src/tile_glyph.c"
+SRC="src/main.c src/la.c src/editor.c src/sdl_extra.c src/file.c src/gl_extra.c src/tile_glyph.c src/free_glyph.c"
 
 if [ `uname` = "Darwin" ]; then
     CFLAGS+=" -framework OpenGL"

+ 7 - 0
shaders/free_glyph.frag

@@ -0,0 +1,7 @@
+#version 330 core
+
+uniform sampler2D font;
+
+void main() {
+    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}

+ 14 - 0
shaders/free_glyph.vert

@@ -0,0 +1,14 @@
+#version 330 core
+
+layout(location = 0) in vec2 pos;
+layout(location = 1) in vec2 size;
+layout(location = 2) in int ch;
+layout(location = 3) in vec4 fg_color;
+layout(location = 4) in vec4 bg_color;
+
+out vec2 uv;
+
+void main() {
+    uv = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1));
+    gl_Position = vec4(uv - vec2(0.5), 0.0, 1.0);
+}

+ 133 - 0
src/free_glyph.c

@@ -0,0 +1,133 @@
+#include <assert.h>
+#include <stdbool.h>
+#include "./free_glyph.h"
+#include "./gl_extra.h"
+
+typedef struct {
+    size_t offset;
+    GLint comps;
+    GLenum type;
+} Attr_Def;
+
+static const Attr_Def glyph_attr_defs[COUNT_FREE_GLYPH_ATTRS] = {
+    [FREE_GLYPH_ATTR_POS]   = {
+        .offset = offsetof(Free_Glyph, pos),
+        .comps = 2,
+        .type = GL_FLOAT
+    },
+    [FREE_GLYPH_ATTR_SIZE]   = {
+        .offset = offsetof(Free_Glyph, size),
+        .comps = 2,
+        .type = GL_FLOAT
+    },
+    [FREE_GLYPH_ATTR_CH]    = {
+        .offset = offsetof(Free_Glyph, ch),
+        .comps = 1,
+        .type = GL_INT
+    },
+    [FREE_GLYPH_ATTR_FG_COLOR] = {
+        .offset = offsetof(Free_Glyph, fg_color),
+        .comps = 4,
+        .type = GL_FLOAT
+    },
+    [FREE_GLYPH_ATTR_BG_COLOR] = {
+        .offset = offsetof(Free_Glyph, bg_color),
+        .comps = 4,
+        .type = GL_FLOAT
+    },
+};
+static_assert(COUNT_FREE_GLYPH_ATTRS == 5, "The amount of glyph vertex attributes have changed");
+
+
+void free_glyph_buffer_init(Free_Glyph_Buffer *fgb,
+                            const char *vert_file_path,
+                            const char *frag_file_path)
+{
+    // Init Vertex Attributes
+    {
+        glGenVertexArrays(1, &fgb->vao);
+        glBindVertexArray(fgb->vao);
+
+        glGenBuffers(1, &fgb->vbo);
+        glBindBuffer(GL_ARRAY_BUFFER, fgb->vbo);
+        glBufferData(GL_ARRAY_BUFFER, sizeof(fgb->glyphs), fgb->glyphs, GL_DYNAMIC_DRAW);
+
+        for (Free_Glyph_Attr attr = 0; attr < COUNT_FREE_GLYPH_ATTRS; ++attr) {
+            glEnableVertexAttribArray(attr);
+            switch (glyph_attr_defs[attr].type) {
+            case GL_FLOAT:
+                glVertexAttribPointer(
+                    attr,
+                    glyph_attr_defs[attr].comps,
+                    glyph_attr_defs[attr].type,
+                    GL_FALSE,
+                    sizeof(Free_Glyph),
+                    (void*) glyph_attr_defs[attr].offset);
+                break;
+
+            case GL_INT:
+                glVertexAttribIPointer(
+                    attr,
+                    glyph_attr_defs[attr].comps,
+                    glyph_attr_defs[attr].type,
+                    sizeof(Free_Glyph),
+                    (void*) glyph_attr_defs[attr].offset);
+                break;
+
+            default:
+                assert(false && "unreachable");
+                exit(1);
+            }
+            glVertexAttribDivisor(attr, 1);
+        }
+    }
+
+    // Init Shaders
+    {
+        GLuint vert_shader = 0;
+        if (!compile_shader_file(vert_file_path, GL_VERTEX_SHADER, &vert_shader)) {
+            exit(1);
+        }
+        GLuint frag_shader = 0;
+        if (!compile_shader_file(frag_file_path, GL_FRAGMENT_SHADER, &frag_shader)) {
+            exit(1);
+        }
+
+        GLuint program = 0;
+        if (!link_program(vert_shader, frag_shader, &program)) {
+            exit(1);
+        }
+
+        glUseProgram(program);
+
+        fgb->time_uniform = glGetUniformLocation(program, "time");
+        fgb->resolution_uniform = glGetUniformLocation(program, "resolution");
+        fgb->camera_uniform = glGetUniformLocation(program, "camera");
+    }
+
+}
+
+void free_glyph_buffer_clear(Free_Glyph_Buffer *fgb)
+{
+    (void) fgb;
+    assert(0);
+}
+
+void free_glyph_buffer_push(Free_Glyph_Buffer *fgb, Free_Glyph glyph)
+{
+    (void) fgb;
+    (void) glyph;
+    assert(0);
+}
+
+void free_glyph_buffer_sync(Free_Glyph_Buffer *fgb)
+{
+    (void) fgb;
+    assert(0);
+}
+
+void free_glyph_buffer_draw(Free_Glyph_Buffer *fgb)
+{
+    (void) fgb;
+    assert(0);
+}

+ 53 - 0
src/free_glyph.h

@@ -0,0 +1,53 @@
+#ifndef FREE_GLYPH_H_
+#define FREE_GLYPH_H_
+
+#include <stdlib.h>
+#include "./la.h"
+
+#define GLEW_STATIC
+#include <GL/glew.h>
+
+#define GL_GLEXT_PROTOTYPES
+#include <SDL2/SDL_opengl.h>
+
+typedef struct {
+    Vec2f pos;
+    Vec2f size;
+    int ch;
+    Vec4f fg_color;
+    Vec4f bg_color;
+} Free_Glyph;
+
+typedef enum {
+    FREE_GLYPH_ATTR_POS = 0,
+    FREE_GLYPH_ATTR_SIZE,
+    FREE_GLYPH_ATTR_CH,
+    FREE_GLYPH_ATTR_FG_COLOR,
+    FREE_GLYPH_ATTR_BG_COLOR,
+    COUNT_FREE_GLYPH_ATTRS,
+} Free_Glyph_Attr;
+
+#define FREE_GLYPH_BUFFER_CAP (640 * 1000)
+
+typedef struct {
+    GLuint vao;
+    GLuint vbo;
+
+    GLint time_uniform;
+    GLint resolution_uniform;
+    GLint camera_uniform;
+
+    size_t glyphs_count;
+    Free_Glyph glyphs[FREE_GLYPH_BUFFER_CAP];
+} Free_Glyph_Buffer;
+
+void free_glyph_buffer_init(Free_Glyph_Buffer *fgb,
+                            const char *vert_file_path,
+                            const char *frag_file_path);
+void free_glyph_buffer_clear(Free_Glyph_Buffer *fgb);
+void free_glyph_buffer_push(Free_Glyph_Buffer *fgb, Free_Glyph glyph);
+void free_glyph_buffer_sync(Free_Glyph_Buffer *fgb);
+void free_glyph_buffer_draw(Free_Glyph_Buffer *fgb);
+
+
+#endif // FREE_GLYPH_H_

+ 55 - 36
src/main.c

@@ -19,6 +19,7 @@
 #include "./sdl_extra.h"
 #include "./gl_extra.h"
 #include "./tile_glyph.h"
+#include "./free_glyph.h"
 
 #define SCREEN_WIDTH 800
 #define SCREEN_HEIGHT 600
@@ -68,6 +69,50 @@ void gl_render_cursor(Tile_Glyph_Buffer *tgb)
 }
 
 static Tile_Glyph_Buffer tgb = {0};
+static Free_Glyph_Buffer fgb = {0};
+
+void render_editor_into_tgb(SDL_Window *window, Tile_Glyph_Buffer *tgb, Editor *editor)
+{
+    {
+        int w, h;
+        SDL_GetWindowSize(window, &w, &h);
+        // TODO(#19): update the viewport and the resolution only on actual window change
+        glViewport(0, 0, w, h);
+        glUniform2f(tgb->resolution_uniform, (float) w, (float) h);
+    }
+
+    tile_glyph_buffer_clear(tgb);
+    {
+        for (size_t row = 0; row < editor->size; ++row) {
+            const Line *line = editor->lines + row;
+            tile_glyph_render_line_sized(tgb, line->chars, line->size, vec2i(0, -(int)row), vec4fs(1.0f), vec4fs(0.0f));
+        }
+    }
+    tile_glyph_buffer_sync(tgb);
+
+    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glUniform1f(tgb->time_uniform, (float) SDL_GetTicks() / 1000.0f);
+    glUniform2f(tgb->camera_uniform, camera_pos.x, camera_pos.y);
+
+    tile_glyph_buffer_draw(tgb);
+
+    tile_glyph_buffer_clear(tgb);
+    {
+        gl_render_cursor(tgb);
+    }
+    tile_glyph_buffer_sync(tgb);
+
+    tile_glyph_buffer_draw(tgb);
+}
+
+void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *tgb, Editor *editor)
+{
+    (void) window;
+    (void) tgb;
+    (void) editor;
+}
 
 // OPENGL
 int main(int argc, char **argv)
@@ -133,10 +178,14 @@ int main(int argc, char **argv)
         fprintf(stderr, "WARNING! GLEW_ARB_debug_output is not available");
     }
 
-    tile_glyph_buffer_init(&tgb,
-                           "./charmap-oldschool_white.png",
-                           "./shaders/tile_glyph.vert",
-                           "./shaders/tile_glyph.frag");
+    // tile_glyph_buffer_init(&tgb,
+    //                        "./charmap-oldschool_white.png",
+    //                        "./shaders/tile_glyph.vert",
+    //                        "./shaders/tile_glyph.frag");
+
+    free_glyph_buffer_init(&fgb,
+                           "./shaders/free_glyph.vert",
+                           "./shaders/free_glyph.frag");
 
     bool quit = false;
     while (!quit) {
@@ -237,38 +286,8 @@ int main(int argc, char **argv)
             camera_pos = vec2f_add(camera_pos, vec2f_mul(camera_vel, vec2fs(DELTA_TIME)));
         }
 
-        {
-            int w, h;
-            SDL_GetWindowSize(window, &w, &h);
-            // TODO(#19): update the viewport and the resolution only on actual window change
-            glViewport(0, 0, w, h);
-            glUniform2f(tgb.resolution_uniform, (float) w, (float) h);
-        }
-
-        tile_glyph_buffer_clear(&tgb);
-        {
-            for (size_t row = 0; row < editor.size; ++row) {
-                const Line *line = editor.lines + row;
-                tile_glyph_render_line_sized(&tgb, line->chars, line->size, vec2i(0, -(int)row), vec4fs(1.0f), vec4fs(0.0f));
-            }
-        }
-        tile_glyph_buffer_sync(&tgb);
-
-        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-        glClear(GL_COLOR_BUFFER_BIT);
-
-        glUniform1f(tgb.time_uniform, (float) SDL_GetTicks() / 1000.0f);
-        glUniform2f(tgb.camera_uniform, camera_pos.x, camera_pos.y);
-
-        tile_glyph_buffer_draw(&tgb);
-
-        tile_glyph_buffer_clear(&tgb);
-        {
-            gl_render_cursor(&tgb);
-        }
-        tile_glyph_buffer_sync(&tgb);
-
-        tile_glyph_buffer_draw(&tgb);
+        // render_editor_into_tgb(window, &tgb, &editor);
+        render_editor_into_fgb(window, &fgb, &editor);
 
         SDL_GL_SwapWindow(window);
 

+ 6 - 0
src/tile_glyph.c

@@ -5,6 +5,12 @@
 #include "./tile_glyph.h"
 #include "./gl_extra.h"
 
+typedef struct {
+    size_t offset;
+    GLint comps;
+    GLenum type;
+} Attr_Def;
+
 static const Attr_Def glyph_attr_defs[COUNT_TILE_GLYPH_ATTRS] = {
     [TILE_GLYPH_ATTR_TILE]   = {
         .offset = offsetof(Tile_Glyph, tile),

+ 1 - 8
src/tile_glyph.h

@@ -33,12 +33,6 @@ typedef enum {
     COUNT_TILE_GLYPH_ATTRS,
 } Tile_Glyph_Attr;
 
-typedef struct {
-    size_t offset;
-    GLint comps;
-    GLenum type;
-} Attr_Def;
-
 #define TILE_GLYPH_BUFFER_CAP (640 * 1024)
 
 typedef struct {
@@ -60,14 +54,13 @@ void tile_glyph_buffer_init(Tile_Glyph_Buffer *buffer,
                             const char *texture_file_path,
                             const char *vert_file_path,
                             const char *frag_file_path);
-
 void tile_glyph_buffer_clear(Tile_Glyph_Buffer *buffer);
 void tile_glyph_buffer_push(Tile_Glyph_Buffer *buffer, Tile_Glyph glyph);
 void tile_glyph_buffer_sync(Tile_Glyph_Buffer *buffer);
+void tile_glyph_buffer_draw(Tile_Glyph_Buffer *buffer);
 
 void tile_glyph_render_line_sized(Tile_Glyph_Buffer *buffer, const char *text, size_t text_size, Vec2i tile, Vec4f fg_color, Vec4f bg_color);
 void tile_glyph_render_line(Tile_Glyph_Buffer *buffer, const char *text, Vec2i tile, Vec4f fg_color, Vec4f bg_color);
 
-void tile_glyph_buffer_draw(Tile_Glyph_Buffer *buffer);
 
 #endif // TILE_GLYPH_H_