From 757e64e16f8e643dc90ea4faedc2f9709b6a7dd7 Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 20:39:52 +0700 Subject: [PATCH 1/9] Update viewport according to the window size Also dynamically change the resolution for the shaders --- .gitignore | 1 + src/main.c | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 17d10047..62061e74 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ te +ded SDL2 *.exe *.obj diff --git a/src/main.c b/src/main.c index 76ec7e79..5f3cff85 100644 --- a/src/main.c +++ b/src/main.c @@ -75,7 +75,7 @@ void usage(FILE *stream) // TODO: Delete line // TODO: Split the line on Enter -// #define OPENGL_RENDERER +#define OPENGL_RENDERER #ifdef OPENGL_RENDERER void MessageCallback(GLenum source, @@ -246,8 +246,6 @@ int main(int argc, char **argv) time_uniform = glGetUniformLocation(program, "time"); resolution_uniform = glGetUniformLocation(program, "resolution"); - - glUniform2f(resolution_uniform, SCREEN_WIDTH, SCREEN_HEIGHT); } // Init Font Texture @@ -327,6 +325,13 @@ int main(int argc, char **argv) } } + { + int w, h; + SDL_GetWindowSize(window, &w, &h); + glViewport(0, 0, w, h); + glUniform2f(resolution_uniform, (float) w, (float) h); + } + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -439,7 +444,7 @@ int main(int argc, char **argv) case SDL_MOUSEBUTTONDOWN: { Vec2f mouse_click = vec2f((float) event.button.x, (float) event.button.y); - switch(event.button.button) { + switch(event.button.button) { case SDL_BUTTON_LEFT: { Vec2f cursor_click = vec2f_add(mouse_click, vec2f_sub(camera_pos, vec2f_div(window_size(window), vec2fs(2.0f)))); if(cursor_click.x > 0.0f && cursor_click.y > 0.0f) { From 8d68d0c9765c67fdae6c3c993169eaeabbb8c12b Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 21:35:50 +0700 Subject: [PATCH 2/9] Implement proper tile renderer --- shaders/font.frag | 6 ++-- shaders/font.vert | 11 ++++--- src/la.c | 42 ++++++++++++++++++++++++ src/la.h | 12 +++++++ src/main.c | 81 ++++++++++++++++++++++++++++------------------- 5 files changed, 111 insertions(+), 41 deletions(-) diff --git a/shaders/font.frag b/shaders/font.frag index 747246ef..d9dad406 100644 --- a/shaders/font.frag +++ b/shaders/font.frag @@ -16,11 +16,11 @@ uniform sampler2D font; uniform float time; in vec2 uv; -in float glyph_ch; +flat in int glyph_ch; in vec4 glyph_color; void main() { - int ch = int(glyph_ch); + int ch = glyph_ch; if (!(ASCII_DISPLAY_LOW <= ch && ch <= ASCII_DISPLAY_HIGH)) { ch = 63; } @@ -32,5 +32,5 @@ void main() { vec2 size = vec2(FONT_CHAR_WIDTH_UV, -FONT_CHAR_HEIGHT_UV); vec2 t = pos + size * uv; - gl_FragColor = texture(font, t)* glyph_color; + gl_FragColor = texture(font, t) * glyph_color; } diff --git a/shaders/font.vert b/shaders/font.vert index 58831283..04113d23 100644 --- a/shaders/font.vert +++ b/shaders/font.vert @@ -8,14 +8,14 @@ #define FONT_CHAR_HEIGHT (FONT_HEIGHT / FONT_ROWS) uniform vec2 resolution; +uniform vec2 scale; -layout(location = 0) in vec2 pos; -layout(location = 1) in float scale; -layout(location = 2) in float ch; -layout(location = 3) in vec4 color; +layout(location = 0) in ivec2 tile; +layout(location = 1) in int ch; +layout(location = 2) in vec4 color; out vec2 uv; -out float glyph_ch; +flat out int glyph_ch; out vec4 glyph_color; vec2 project_point(vec2 point) @@ -26,6 +26,7 @@ vec2 project_point(vec2 point) void main() { uv = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1)); vec2 char_size = vec2(float(FONT_CHAR_WIDTH), float(FONT_CHAR_HEIGHT)); + vec2 pos = tile * char_size * scale; gl_Position = vec4(project_point(uv * char_size * scale + pos), 0.0, 1.0); glyph_ch = ch; glyph_color = color; diff --git a/src/la.c b/src/la.c index 3c07f198..853bf10a 100644 --- a/src/la.c +++ b/src/la.c @@ -38,6 +38,48 @@ Vec2f vec2f_div(Vec2f a, Vec2f b) return vec2f(a.x / b.x, a.y / b.y); } +////////////////////////////// + +Vec2i vec2i(int x, int y) +{ + return (Vec2i) { + .x = x, + .y = y, + }; +} + +Vec2i vec2is(int x) +{ + return vec2i(x, x); +} + +Vec2i vec2i_add(Vec2i a, Vec2i b) +{ + return vec2i(a.x + b.x, a.y + b.y); +} + +Vec2i vec2i_sub(Vec2i a, Vec2i b) +{ + return vec2i(a.x - b.x, a.y - b.y); +} + +Vec2i vec2i_mul(Vec2i a, Vec2i b) +{ + return vec2i(a.x * b.x, a.y * b.y); +} + +Vec2i vec2i_mul3(Vec2i a, Vec2i b, Vec2i c) +{ + return vec2i_mul(vec2i_mul(a, b), c); +} + +Vec2i vec2i_div(Vec2i a, Vec2i b) +{ + return vec2i(a.x / b.x, a.y / b.y); +} + +////////////////////////////// + Vec4f vec4f(float x, float y, float z, float w) { return (Vec4f) { diff --git a/src/la.h b/src/la.h index 9247b2a6..25abfd0b 100644 --- a/src/la.h +++ b/src/la.h @@ -13,6 +13,18 @@ Vec2f vec2f_mul(Vec2f a, Vec2f b); Vec2f vec2f_mul3(Vec2f a, Vec2f b, Vec2f c); Vec2f vec2f_div(Vec2f a, Vec2f b); +typedef struct { + int x, y; +} Vec2i; + +Vec2i vec2i(int x, int y); +Vec2i vec2is(int x); +Vec2i vec2i_add(Vec2i a, Vec2i b); +Vec2i vec2i_sub(Vec2i a, Vec2i b); +Vec2i vec2i_mul(Vec2i a, Vec2i b); +Vec2i vec2i_mul3(Vec2i a, Vec2i b, Vec2i c); +Vec2i vec2i_div(Vec2i a, Vec2i b); + typedef struct { float x, y, z, w; } Vec4f; diff --git a/src/main.c b/src/main.c index 5f3cff85..acebaf55 100644 --- a/src/main.c +++ b/src/main.c @@ -75,7 +75,7 @@ void usage(FILE *stream) // TODO: Delete line // TODO: Split the line on Enter -#define OPENGL_RENDERER +// #define OPENGL_RENDERER #ifdef OPENGL_RENDERER void MessageCallback(GLenum source, @@ -96,15 +96,13 @@ void MessageCallback(GLenum source, } typedef struct { - Vec2f pos; - float scale; - float ch; + Vec2i tile; + int ch; Vec4f color; } Glyph; typedef enum { - GLYPH_ATTR_POS = 0, - GLYPH_ATTR_SCALE, + GLYPH_ATTR_TILE = 0, GLYPH_ATTR_CH, GLYPH_ATTR_COLOR, COUNT_GLYPH_ATTRS, @@ -113,27 +111,27 @@ typedef enum { typedef struct { size_t offset; size_t comps; + GLenum type; } Glyph_Attr_Def; static const Glyph_Attr_Def glyph_attr_defs[COUNT_GLYPH_ATTRS] = { - [GLYPH_ATTR_POS] = { - .offset = offsetof(Glyph, pos), + [GLYPH_ATTR_TILE] = { + .offset = offsetof(Glyph, tile), .comps = 2, - }, - [GLYPH_ATTR_SCALE] = { - .offset = offsetof(Glyph, scale), - .comps = 1, + .type = GL_INT }, [GLYPH_ATTR_CH] = { .offset = offsetof(Glyph, ch), .comps = 1, + .type = GL_INT }, [GLYPH_ATTR_COLOR] = { .offset = offsetof(Glyph, color), .comps = 4, + .type = GL_FLOAT }, }; -static_assert(COUNT_GLYPH_ATTRS == 4, "The amount of glyph vertex attributes have changed"); +static_assert(COUNT_GLYPH_ATTRS == 3, "The amount of glyph vertex attributes have changed"); #define GLYPH_BUFFER_CAP 1024 @@ -154,20 +152,14 @@ void glyph_buffer_sync(void) glyph_buffer); } -void gl_render_text(const char *text, size_t text_size, - Vec2f pos, float scale, Vec4f color) +void gl_render_text(const char *text, size_t text_size, Vec2i tile, Vec4f color) { for (size_t i = 0; i < text_size; ++i) { - const Vec2f char_size = vec2f(FONT_CHAR_WIDTH, FONT_CHAR_HEIGHT); - const Glyph glyph = { - .pos = vec2f_add(pos, vec2f_mul3(char_size, - vec2f((float) i, 0.0f), - vec2fs(scale))), - .scale = scale, - .ch = (float) text[i], + glyph_buffer_push((Glyph) { + .tile = vec2i_add(tile, vec2i(i, 0)), + .ch = text[i], .color = color - }; - glyph_buffer_push(glyph); + }); } } @@ -225,6 +217,7 @@ int main(int argc, char **argv) GLint time_uniform; GLint resolution_uniform; + GLint scale_uniform; // Initialize Shaders { @@ -246,6 +239,9 @@ int main(int argc, char **argv) time_uniform = glGetUniformLocation(program, "time"); resolution_uniform = glGetUniformLocation(program, "resolution"); + scale_uniform = glGetUniformLocation(program, "scale"); + + glUniform2f(scale_uniform, 5.0f, 5.0f); } // Init Font Texture @@ -297,20 +293,38 @@ int main(int argc, char **argv) for (Glyph_Attr attr = 0; attr < COUNT_GLYPH_ATTRS; ++attr) { glEnableVertexAttribArray(attr); - glVertexAttribPointer( - attr, - glyph_attr_defs[attr].comps, - GL_FLOAT, - GL_FALSE, - sizeof(Glyph), - (void*) glyph_attr_defs[attr].offset); + switch (glyph_attr_defs[attr].type) { + case GL_FLOAT: + glVertexAttribPointer( + attr, + glyph_attr_defs[attr].comps, + glyph_attr_defs[attr].type, + GL_FALSE, + sizeof(Glyph), + (void*) glyph_attr_defs[attr].offset); + break; + + case GL_INT: + glVertexAttribIPointer( + attr, + glyph_attr_defs[attr].comps, + glyph_attr_defs[attr].type, + sizeof(Glyph), + (void*) glyph_attr_defs[attr].offset); + break; + + default: + assert(false && "unreachable"); + exit(1); + } glVertexAttribDivisor(attr, 1); } } const char *text = "Hello, World"; - Vec4f color = vec4f(1.0f, 0.0f, 0.0f, 1.0f); - gl_render_text(text, strlen(text), vec2fs(0.0f), 5.0f, color); + const char *foobar = "Foo Bar"; + gl_render_text(text, strlen(text), vec2is(0), vec4f(1.0f, 0.0f, 0.0f, 1.0f)); + gl_render_text(foobar, strlen(foobar), vec2i(0, -1), vec4f(0.0f, 1.0f, 0.0f, 1.0f)); glyph_buffer_sync(); bool quit = false; @@ -328,6 +342,7 @@ int main(int argc, char **argv) { int w, h; SDL_GetWindowSize(window, &w, &h); + // TODO: update the viewport and the resolution only on actual window change glViewport(0, 0, w, h); glUniform2f(resolution_uniform, (float) w, (float) h); } From 386b030ea1c85fec3907d0ae3355ae466118cc57 Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 22:07:48 +0700 Subject: [PATCH 3/9] Introduce bg_color vert attrib for glyphs --- shaders/font.frag | 6 ++++-- shaders/font.vert | 10 +++++++--- src/main.c | 33 +++++++++++++++++++++++---------- 3 files changed, 34 insertions(+), 15 deletions(-) diff --git a/shaders/font.frag b/shaders/font.frag index d9dad406..bc19d31a 100644 --- a/shaders/font.frag +++ b/shaders/font.frag @@ -17,7 +17,8 @@ uniform float time; in vec2 uv; flat in int glyph_ch; -in vec4 glyph_color; +in vec4 glyph_fg_color; +in vec4 glyph_bg_color; void main() { int ch = glyph_ch; @@ -32,5 +33,6 @@ void main() { vec2 size = vec2(FONT_CHAR_WIDTH_UV, -FONT_CHAR_HEIGHT_UV); vec2 t = pos + size * uv; - gl_FragColor = texture(font, t) * glyph_color; + vec4 tc = texture(font, t); + gl_FragColor = glyph_bg_color * (1.0 - tc.x) + tc.x * glyph_fg_color; } diff --git a/shaders/font.vert b/shaders/font.vert index 04113d23..d6e847cc 100644 --- a/shaders/font.vert +++ b/shaders/font.vert @@ -12,11 +12,13 @@ uniform vec2 scale; layout(location = 0) in ivec2 tile; layout(location = 1) in int ch; -layout(location = 2) in vec4 color; +layout(location = 2) in vec4 fg_color; +layout(location = 3) in vec4 bg_color; out vec2 uv; flat out int glyph_ch; -out vec4 glyph_color; +out vec4 glyph_fg_color; +out vec4 glyph_bg_color; vec2 project_point(vec2 point) { @@ -29,5 +31,7 @@ void main() { vec2 pos = tile * char_size * scale; gl_Position = vec4(project_point(uv * char_size * scale + pos), 0.0, 1.0); glyph_ch = ch; - glyph_color = color; + + glyph_fg_color = fg_color; + glyph_bg_color = bg_color; } diff --git a/src/main.c b/src/main.c index acebaf55..e4981065 100644 --- a/src/main.c +++ b/src/main.c @@ -75,7 +75,7 @@ void usage(FILE *stream) // TODO: Delete line // TODO: Split the line on Enter -// #define OPENGL_RENDERER +#define OPENGL_RENDERER #ifdef OPENGL_RENDERER void MessageCallback(GLenum source, @@ -98,13 +98,15 @@ void MessageCallback(GLenum source, typedef struct { Vec2i tile; int ch; - Vec4f color; + Vec4f fg_color; + Vec4f bg_color; } Glyph; typedef enum { GLYPH_ATTR_TILE = 0, GLYPH_ATTR_CH, - GLYPH_ATTR_COLOR, + GLYPH_ATTR_FG_COLOR, + GLYPH_ATTR_BG_COLOR, COUNT_GLYPH_ATTRS, } Glyph_Attr; @@ -125,13 +127,18 @@ static const Glyph_Attr_Def glyph_attr_defs[COUNT_GLYPH_ATTRS] = { .comps = 1, .type = GL_INT }, - [GLYPH_ATTR_COLOR] = { - .offset = offsetof(Glyph, color), + [GLYPH_ATTR_FG_COLOR] = { + .offset = offsetof(Glyph, fg_color), + .comps = 4, + .type = GL_FLOAT + }, + [GLYPH_ATTR_BG_COLOR] = { + .offset = offsetof(Glyph, bg_color), .comps = 4, .type = GL_FLOAT }, }; -static_assert(COUNT_GLYPH_ATTRS == 3, "The amount of glyph vertex attributes have changed"); +static_assert(COUNT_GLYPH_ATTRS == 4, "The amount of glyph vertex attributes have changed"); #define GLYPH_BUFFER_CAP 1024 @@ -152,17 +159,23 @@ void glyph_buffer_sync(void) glyph_buffer); } -void gl_render_text(const char *text, size_t text_size, Vec2i tile, Vec4f color) +void gl_render_text_sized(const char *text, size_t text_size, Vec2i tile, Vec4f fg_color, Vec4f bg_color) { for (size_t i = 0; i < text_size; ++i) { glyph_buffer_push((Glyph) { .tile = vec2i_add(tile, vec2i(i, 0)), .ch = text[i], - .color = color + .fg_color = fg_color, + .bg_color = bg_color, }); } } +void gl_render_text(const char *text, Vec2i tile, Vec4f fg_color, Vec4f bg_color) +{ + gl_render_text_sized(text, strlen(text), tile, fg_color, bg_color); +} + int main(int argc, char **argv) { (void) argc; @@ -323,8 +336,8 @@ int main(int argc, char **argv) const char *text = "Hello, World"; const char *foobar = "Foo Bar"; - gl_render_text(text, strlen(text), vec2is(0), vec4f(1.0f, 0.0f, 0.0f, 1.0f)); - gl_render_text(foobar, strlen(foobar), vec2i(0, -1), vec4f(0.0f, 1.0f, 0.0f, 1.0f)); + gl_render_text(text, vec2is(0), vec4f(1.0f, 0.0f, 0.0f, 1.0f), vec4fs(1.0f)); + gl_render_text(foobar, vec2i(0, -1), vec4f(0.0f, 1.0f, 0.0f, 1.0f), vec4fs(0.0f)); glyph_buffer_sync(); bool quit = false; From e23d49af72402351acb1e68a0d8a8d25e1d2601f Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 22:58:41 +0700 Subject: [PATCH 4/9] Fully integrate OpenGL renderer with the editor --- shaders/font.frag | 12 +++- shaders/font.vert | 5 +- src/main.c | 140 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 145 insertions(+), 12 deletions(-) diff --git a/shaders/font.frag b/shaders/font.frag index bc19d31a..496f9df6 100644 --- a/shaders/font.frag +++ b/shaders/font.frag @@ -20,6 +20,11 @@ flat in int glyph_ch; in vec4 glyph_fg_color; in vec4 glyph_bg_color; +float map01(float x) +{ + return (x + 1) / 2.0; +} + void main() { int ch = glyph_ch; if (!(ASCII_DISPLAY_LOW <= ch && ch <= ASCII_DISPLAY_HIGH)) { @@ -34,5 +39,10 @@ void main() { vec2 t = pos + size * uv; vec4 tc = texture(font, t); - gl_FragColor = glyph_bg_color * (1.0 - tc.x) + tc.x * glyph_fg_color; + vec4 rainbow = vec4( + map01(sin(time + uv.x)), + map01(cos(time + uv.y)), + map01(sin(time + uv.x + uv.y)), + 1.0); + gl_FragColor = glyph_bg_color * (1.0 - tc.x) + tc.x * glyph_fg_color * rainbow; } diff --git a/shaders/font.vert b/shaders/font.vert index d6e847cc..3f5520b6 100644 --- a/shaders/font.vert +++ b/shaders/font.vert @@ -9,6 +9,8 @@ uniform vec2 resolution; uniform vec2 scale; +uniform float time; +uniform vec2 camera; layout(location = 0) in ivec2 tile; layout(location = 1) in int ch; @@ -22,13 +24,14 @@ out vec4 glyph_bg_color; vec2 project_point(vec2 point) { - return 2.0 * point / resolution; + return 2.0 * (point - camera) / resolution; } void main() { uv = vec2(float(gl_VertexID & 1), float((gl_VertexID >> 1) & 1)); vec2 char_size = vec2(float(FONT_CHAR_WIDTH), float(FONT_CHAR_HEIGHT)); vec2 pos = tile * char_size * scale; + gl_Position = vec4(project_point(uv * char_size * scale + pos), 0.0, 1.0); glyph_ch = ch; diff --git a/src/main.c b/src/main.c index e4981065..98182071 100644 --- a/src/main.c +++ b/src/main.c @@ -140,11 +140,16 @@ static const Glyph_Attr_Def glyph_attr_defs[COUNT_GLYPH_ATTRS] = { }; static_assert(COUNT_GLYPH_ATTRS == 4, "The amount of glyph vertex attributes have changed"); -#define GLYPH_BUFFER_CAP 1024 +#define GLYPH_BUFFER_CAP (640 * 1024) Glyph glyph_buffer[GLYPH_BUFFER_CAP]; size_t glyph_buffer_count = 0; +void glyph_buffer_clear(void) +{ + glyph_buffer_count = 0; +} + void glyph_buffer_push(Glyph glyph) { assert(glyph_buffer_count < GLYPH_BUFFER_CAP); @@ -176,10 +181,29 @@ void gl_render_text(const char *text, Vec2i tile, Vec4f fg_color, Vec4f bg_color gl_render_text_sized(text, strlen(text), tile, fg_color, bg_color); } +void gl_render_cursor() +{ + const char *c = editor_char_under_cursor(&editor); + Vec2i tile = vec2i(editor.cursor_col, -(int) editor.cursor_row); + gl_render_text_sized(c ? c : " ", 1, tile, vec4fs(0.0f), vec4fs(1.0f)); +} + +// OPENGL int main(int argc, char **argv) { - (void) argc; - (void) argv; + const char *file_path = NULL; + + if (argc > 1) { + file_path = argv[1]; + } + + if (file_path) { + FILE *file = fopen(file_path, "r"); + if (file != NULL) { + editor_load_from_file(&editor, file); + fclose(file); + } + } scc(SDL_Init(SDL_INIT_VIDEO)); @@ -231,6 +255,7 @@ int main(int argc, char **argv) GLint time_uniform; GLint resolution_uniform; GLint scale_uniform; + GLint camera_uniform; // Initialize Shaders { @@ -253,8 +278,9 @@ int main(int argc, char **argv) time_uniform = glGetUniformLocation(program, "time"); resolution_uniform = glGetUniformLocation(program, "resolution"); scale_uniform = glGetUniformLocation(program, "scale"); + camera_uniform = glGetUniformLocation(program, "camera"); - glUniform2f(scale_uniform, 5.0f, 5.0f); + glUniform2f(scale_uniform, FONT_SCALE, FONT_SCALE); } // Init Font Texture @@ -334,14 +360,9 @@ int main(int argc, char **argv) } } - const char *text = "Hello, World"; - const char *foobar = "Foo Bar"; - gl_render_text(text, vec2is(0), vec4f(1.0f, 0.0f, 0.0f, 1.0f), vec4fs(1.0f)); - gl_render_text(foobar, vec2i(0, -1), vec4f(0.0f, 1.0f, 0.0f, 1.0f), vec4fs(0.0f)); - glyph_buffer_sync(); - bool quit = false; while (!quit) { + const Uint32 start = SDL_GetTicks(); SDL_Event event = {0}; while (SDL_PollEvent(&event)) { switch (event.type) { @@ -349,9 +370,83 @@ int main(int argc, char **argv) quit = true; } break; + + case SDL_KEYDOWN: { + switch (event.key.keysym.sym) { + case SDLK_BACKSPACE: { + editor_backspace(&editor); + } + break; + + case SDLK_F2: { + if (file_path) { + editor_save_to_file(&editor, file_path); + } + } + break; + + case SDLK_RETURN: { + editor_insert_new_line(&editor); + } + break; + + case SDLK_DELETE: { + editor_delete(&editor); + } + break; + + case SDLK_UP: { + if (editor.cursor_row > 0) { + editor.cursor_row -= 1; + } + } + break; + + case SDLK_DOWN: { + editor.cursor_row += 1; + } + break; + + case SDLK_LEFT: { + if (editor.cursor_col > 0) { + editor.cursor_col -= 1; + } + } + break; + + case SDLK_RIGHT: { + editor.cursor_col += 1; + } + break; + } + } + break; + + case SDL_TEXTINPUT: { + editor_insert_text_before_cursor(&editor, event.text.text); + } + break; + + case SDL_MOUSEBUTTONDOWN: { + // TODO: mouse click is broken, because the coordinates need to be mapped differently + // The feature was initially introduced in #14 + } + break; } } + { + const Vec2f cursor_pos = + vec2f((float) editor.cursor_col * FONT_CHAR_WIDTH * FONT_SCALE, + (float) (-(int)editor.cursor_row) * FONT_CHAR_HEIGHT * FONT_SCALE); + + camera_vel = vec2f_mul( + vec2f_sub(cursor_pos, camera_pos), + vec2fs(2.0f)); + + camera_pos = vec2f_add(camera_pos, vec2f_mul(camera_vel, vec2fs(DELTA_TIME))); + } + { int w, h; SDL_GetWindowSize(window, &w, &h); @@ -360,19 +455,44 @@ int main(int argc, char **argv) glUniform2f(resolution_uniform, (float) w, (float) h); } + glyph_buffer_clear(); + { + for (size_t row = 0; row < editor.size; ++row) { + const Line *line = editor.lines + row; + gl_render_text_sized(line->chars, line->size, vec2i(0, -row), vec4fs(1.0f), vec4fs(0.0f)); + } + } + glyph_buffer_sync(); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUniform1f(time_uniform, (float) SDL_GetTicks() / 1000.0f); + glUniform2f(camera_uniform, camera_pos.x, camera_pos.y); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, glyph_buffer_count); + + glyph_buffer_clear(); + { + gl_render_cursor(); + } + glyph_buffer_sync(); glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, glyph_buffer_count); SDL_GL_SwapWindow(window); + + const Uint32 duration = SDL_GetTicks() - start; + const Uint32 delta_time_ms = 1000 / FPS; + if (duration < delta_time_ms) { + SDL_Delay(delta_time_ms - duration); + } } return 0; } #else +// SDL int main(int argc, char **argv) { const char *file_path = NULL; From 8fcb2a80f889be068dbb45bc2ea17644e3c138b3 Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 23:05:24 +0700 Subject: [PATCH 5/9] Add rainbow to the fragment shader --- shaders/font.frag | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/shaders/font.frag b/shaders/font.frag index 496f9df6..197c23bb 100644 --- a/shaders/font.frag +++ b/shaders/font.frag @@ -14,6 +14,7 @@ uniform sampler2D font; uniform float time; +uniform vec2 resolution; in vec2 uv; flat in int glyph_ch; @@ -25,6 +26,11 @@ float map01(float x) return (x + 1) / 2.0; } +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() { int ch = glyph_ch; if (!(ASCII_DISPLAY_LOW <= ch && ch <= ASCII_DISPLAY_HIGH)) { @@ -39,10 +45,7 @@ void main() { vec2 t = pos + size * uv; vec4 tc = texture(font, t); - vec4 rainbow = vec4( - map01(sin(time + uv.x)), - map01(cos(time + uv.y)), - map01(sin(time + uv.x + uv.y)), - 1.0); + 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 = glyph_bg_color * (1.0 - tc.x) + tc.x * glyph_fg_color * rainbow; } From b690ca5d77a24ef0cd26eb8902b8f4675bf58dbd Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 23:08:19 +0700 Subject: [PATCH 6/9] Add TODO(#18) --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 98182071..6bc1a871 100644 --- a/src/main.c +++ b/src/main.c @@ -428,7 +428,7 @@ int main(int argc, char **argv) break; case SDL_MOUSEBUTTONDOWN: { - // TODO: mouse click is broken, because the coordinates need to be mapped differently + // TODO(#18): mouse click is broken, because the coordinates need to be mapped differently // The feature was initially introduced in #14 } break; From 8af97ebc77963a90897b703c29059abf55a20be8 Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 23:08:19 +0700 Subject: [PATCH 7/9] Add TODO(#19) --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 6bc1a871..266eca85 100644 --- a/src/main.c +++ b/src/main.c @@ -450,7 +450,7 @@ int main(int argc, char **argv) { int w, h; SDL_GetWindowSize(window, &w, &h); - // TODO: update the viewport and the resolution only on actual window change + // TODO(#19): update the viewport and the resolution only on actual window change glViewport(0, 0, w, h); glUniform2f(resolution_uniform, (float) w, (float) h); } From 59b4be066f275c910231bcc29d64d1d8ffbcfaec Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 23:13:01 +0700 Subject: [PATCH 8/9] Try to fix MSVC build --- src/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index 266eca85..3608f177 100644 --- a/src/main.c +++ b/src/main.c @@ -112,7 +112,7 @@ typedef enum { typedef struct { size_t offset; - size_t comps; + GLint comps; GLenum type; } Glyph_Attr_Def; @@ -168,7 +168,7 @@ void gl_render_text_sized(const char *text, size_t text_size, Vec2i tile, Vec4f { for (size_t i = 0; i < text_size; ++i) { glyph_buffer_push((Glyph) { - .tile = vec2i_add(tile, vec2i(i, 0)), + .tile = vec2i_add(tile, vec2i((int) i, 0)), .ch = text[i], .fg_color = fg_color, .bg_color = bg_color, @@ -184,7 +184,7 @@ void gl_render_text(const char *text, Vec2i tile, Vec4f fg_color, Vec4f bg_color void gl_render_cursor() { const char *c = editor_char_under_cursor(&editor); - Vec2i tile = vec2i(editor.cursor_col, -(int) editor.cursor_row); + Vec2i tile = vec2i((int) editor.cursor_col, -(int) editor.cursor_row); gl_render_text_sized(c ? c : " ", 1, tile, vec4fs(0.0f), vec4fs(1.0f)); } @@ -459,7 +459,7 @@ int main(int argc, char **argv) { for (size_t row = 0; row < editor.size; ++row) { const Line *line = editor.lines + row; - gl_render_text_sized(line->chars, line->size, vec2i(0, -row), vec4fs(1.0f), vec4fs(0.0f)); + gl_render_text_sized(line->chars, line->size, vec2i(0, -(int)row), vec4fs(1.0f), vec4fs(0.0f)); } } glyph_buffer_sync(); @@ -470,7 +470,7 @@ int main(int argc, char **argv) glUniform1f(time_uniform, (float) SDL_GetTicks() / 1000.0f); glUniform2f(camera_uniform, camera_pos.x, camera_pos.y); - glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, glyph_buffer_count); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei) glyph_buffer_count); glyph_buffer_clear(); { @@ -478,7 +478,7 @@ int main(int argc, char **argv) } glyph_buffer_sync(); - glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, glyph_buffer_count); + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei) glyph_buffer_count); SDL_GL_SwapWindow(window); From 3e22d613b1be36d35a1885151139f302bbf6a9eb Mon Sep 17 00:00:00 2001 From: rexim Date: Tue, 6 Jul 2021 23:18:18 +0700 Subject: [PATCH 9/9] Try to fix MSVC build again --- src/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main.c b/src/main.c index 3608f177..af1aba45 100644 --- a/src/main.c +++ b/src/main.c @@ -285,9 +285,9 @@ int main(int argc, char **argv) // Init Font Texture { - const char *file_path = "charmap-oldschool_white.png"; + const char *font_file_path = "charmap-oldschool_white.png"; int width, height, n; - unsigned char *pixels = stbi_load(file_path, &width, &height, &n, STBI_rgb_alpha); + unsigned char *pixels = stbi_load(font_file_path, &width, &height, &n, STBI_rgb_alpha); if (pixels == NULL) { fprintf(stderr, "ERROR: could not load file %s: %s\n", file_path, stbi_failure_reason());