commit ef90e5418796ab4dee68a4e07c6fbb293b24fa01
parent c7e0bcc15394e84d2ead6c3eb7522b5141525d81
Author: rexim <reximkut@gmail.com>
Date: Mon, 9 Jan 2023 01:07:14 +0700
Merge branch 'remove-free-glyph-renderer'
Diffstat:
9 files changed, 211 insertions(+), 301 deletions(-)
diff --git a/shaders/simple.vert b/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;
}
diff --git a/shaders/simple.frag b/shaders/simple_color.frag
diff --git a/shaders/simple_epic.frag b/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;
+}
diff --git a/shaders/simple_image.frag b/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);
+}
diff --git a/src/free_glyph.c b/src/free_glyph.c
@@ -3,225 +3,84 @@
#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_UV_POS] = {
- .offset = offsetof(Free_Glyph, uv_pos),
- .comps = 2,
- .type = GL_FLOAT
- },
- [FREE_GLYPH_ATTR_UV_SIZE] = {
- .offset = offsetof(Free_Glyph, uv_size),
- .comps = 2,
- .type = GL_FLOAT
- },
- [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 == 6, "The amount of glyph vertex attributes have changed");
-
-
-void free_glyph_buffer_init(Free_Glyph_Buffer *fgb,
- FT_Face face,
- const char *vert_file_path,
- const char *frag_file_path)
+void free_glyph_atlas_init(Free_Glyph_Atlas *atlas, FT_Face face)
{
- // 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 shaders[3] = {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);
- }
- if (!compile_shader_file("./shaders/camera.vert", GL_VERTEX_SHADER, &shaders[2])) {
+ for (int i = 32; i < 128; ++i) {
+ if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
+ fprintf(stderr, "ERROR: could not load glyph of a character with code %d\n", i);
exit(1);
}
- fgb->program = glCreateProgram();
- attach_shaders_to_program(shaders, sizeof(shaders) / sizeof(shaders[0]), fgb->program);
- if (!link_program(fgb->program, __FILE__, __LINE__)) {
- exit(1);
+ atlas->atlas_width += face->glyph->bitmap.width;
+ if (atlas->atlas_height < face->glyph->bitmap.rows) {
+ atlas->atlas_height = face->glyph->bitmap.rows;
}
-
- glUseProgram(fgb->program);
- get_uniform_location(fgb->program, fgb->uniforms);
}
- // Glyph Texture Atlas
- {
- for (int i = 32; i < 128; ++i) {
- if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
- fprintf(stderr, "ERROR: could not load glyph of a character with code %d\n", i);
- exit(1);
- }
-
- fgb->atlas_width += face->glyph->bitmap.width;
- if (fgb->atlas_height < face->glyph->bitmap.rows) {
- fgb->atlas_height = face->glyph->bitmap.rows;
- }
+ glActiveTexture(GL_TEXTURE0);
+ glGenTextures(1, &atlas->glyphs_texture);
+ glBindTexture(GL_TEXTURE_2D, atlas->glyphs_texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glTexImage2D(
+ GL_TEXTURE_2D,
+ 0,
+ GL_RED,
+ (GLsizei) atlas->atlas_width,
+ (GLsizei) atlas->atlas_height,
+ 0,
+ GL_RED,
+ GL_UNSIGNED_BYTE,
+ NULL);
+
+ int x = 0;
+ for (int i = 32; i < 128; ++i) {
+ if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
+ fprintf(stderr, "ERROR: could not load glyph of a character with code %d\n", i);
+ exit(1);
}
- glActiveTexture(GL_TEXTURE0);
- glGenTextures(1, &fgb->glyphs_texture);
- glBindTexture(GL_TEXTURE_2D, fgb->glyphs_texture);
+ if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)) {
+ fprintf(stderr, "ERROR: could not render glyph of a character with code %d\n", i);
+ exit(1);
+ }
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ atlas->metrics[i].ax = face->glyph->advance.x >> 6;
+ atlas->metrics[i].ay = face->glyph->advance.y >> 6;
+ atlas->metrics[i].bw = face->glyph->bitmap.width;
+ atlas->metrics[i].bh = face->glyph->bitmap.rows;
+ atlas->metrics[i].bl = face->glyph->bitmap_left;
+ atlas->metrics[i].bt = face->glyph->bitmap_top;
+ atlas->metrics[i].tx = (float) x / (float) atlas->atlas_width;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(
+ glTexSubImage2D(
GL_TEXTURE_2D,
0,
- GL_RED,
- (GLsizei) fgb->atlas_width,
- (GLsizei) fgb->atlas_height,
+ x,
0,
+ face->glyph->bitmap.width,
+ face->glyph->bitmap.rows,
GL_RED,
GL_UNSIGNED_BYTE,
- NULL);
-
- int x = 0;
- for (int i = 32; i < 128; ++i) {
- if (FT_Load_Char(face, i, FT_LOAD_RENDER)) {
- fprintf(stderr, "ERROR: could not load glyph of a character with code %d\n", i);
- exit(1);
- }
-
- if (FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL)) {
- fprintf(stderr, "ERROR: could not render glyph of a character with code %d\n", i);
- exit(1);
- }
-
- fgb->metrics[i].ax = face->glyph->advance.x >> 6;
- fgb->metrics[i].ay = face->glyph->advance.y >> 6;
- fgb->metrics[i].bw = face->glyph->bitmap.width;
- fgb->metrics[i].bh = face->glyph->bitmap.rows;
- fgb->metrics[i].bl = face->glyph->bitmap_left;
- fgb->metrics[i].bt = face->glyph->bitmap_top;
- fgb->metrics[i].tx = (float) x / (float) fgb->atlas_width;
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexSubImage2D(
- GL_TEXTURE_2D,
- 0,
- x,
- 0,
- face->glyph->bitmap.width,
- face->glyph->bitmap.rows,
- GL_RED,
- GL_UNSIGNED_BYTE,
- face->glyph->bitmap.buffer);
- x += face->glyph->bitmap.width;
- }
+ face->glyph->bitmap.buffer);
+ x += face->glyph->bitmap.width;
}
}
-void free_glyph_buffer_use(const Free_Glyph_Buffer *fgb)
-{
- glBindVertexArray(fgb->vao);
- glBindBuffer(GL_ARRAY_BUFFER, fgb->vbo);
- glUseProgram(fgb->program);
-}
-
-void free_glyph_buffer_clear(Free_Glyph_Buffer *fgb)
-{
- fgb->glyphs_count = 0;
-}
-
-void free_glyph_buffer_push(Free_Glyph_Buffer *fgb, Free_Glyph glyph)
-{
- assert(fgb->glyphs_count < FREE_GLYPH_BUFFER_CAP);
- fgb->glyphs[fgb->glyphs_count++] = glyph;
-}
-
-void free_glyph_buffer_sync(Free_Glyph_Buffer *fgb)
-{
- glBufferSubData(GL_ARRAY_BUFFER,
- 0,
- fgb->glyphs_count * sizeof(Free_Glyph),
- fgb->glyphs);
-}
-
-void free_glyph_buffer_draw(Free_Glyph_Buffer *fgb)
-{
- glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei) fgb->glyphs_count);
-}
-
-float free_glyph_buffer_cursor_pos(const Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f pos, size_t col)
+float free_glyph_atlas_cursor_pos(const Free_Glyph_Atlas *atlas, const char *text, size_t text_size, Vec2f pos, size_t col)
{
for (size_t i = 0; i < text_size; ++i) {
if (i == col) {
return pos.x;
}
- Glyph_Metric metric = fgb->metrics[(int) text[i]];
+ Glyph_Metric metric = atlas->metrics[(int) text[i]];
pos.x += metric.ax;
pos.y += metric.ay;
}
@@ -229,10 +88,10 @@ float free_glyph_buffer_cursor_pos(const Free_Glyph_Buffer *fgb, const char *tex
return pos.x;
}
-void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f *pos, Vec4f fg_color, Vec4f bg_color)
+void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer *sr, const char *text, size_t text_size, Vec2f *pos)
{
for (size_t i = 0; i < text_size; ++i) {
- Glyph_Metric metric = fgb->metrics[(int) text[i]];
+ Glyph_Metric metric = atlas->metrics[(int) text[i]];
float x2 = pos->x + metric.bl;
float y2 = -pos->y - metric.bt;
float w = metric.bw;
@@ -241,13 +100,22 @@ void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *tex
pos->x += metric.ax;
pos->y += metric.ay;
+ /*
Free_Glyph glyph = {0};
glyph.pos = vec2f(x2, -y2);
glyph.size = vec2f(w, -h);
glyph.uv_pos = vec2f(metric.tx, 0.0f);
- glyph.uv_size = vec2f(metric.bw / (float) fgb->atlas_width, metric.bh / (float) fgb->atlas_height);
+ glyph.uv_size = vec2f(metric.bw / (float) atlas->atlas_width, metric.bh / (float) atlas->atlas_height);
glyph.fg_color = fg_color;
glyph.bg_color = bg_color;
- free_glyph_buffer_push(fgb, glyph);
+ free_glyph_buffer_push(atlas, glyph);
+ */
+
+ 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));
}
}
diff --git a/src/free_glyph.h b/src/free_glyph.h
@@ -13,30 +13,11 @@
#include <ft2build.h>
#include FT_FREETYPE_H
-#include "./uniforms.h"
+#include "simple_renderer.h"
// https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Text_Rendering_02
typedef struct {
- Vec2f pos;
- Vec2f size;
- Vec2f uv_pos;
- Vec2f uv_size;
- Vec4f fg_color;
- Vec4f bg_color;
-} Free_Glyph;
-
-typedef enum {
- FREE_GLYPH_ATTR_POS = 0,
- FREE_GLYPH_ATTR_SIZE,
- FREE_GLYPH_ATTR_UV_POS,
- FREE_GLYPH_ATTR_UV_SIZE,
- FREE_GLYPH_ATTR_FG_COLOR,
- FREE_GLYPH_ATTR_BG_COLOR,
- COUNT_FREE_GLYPH_ATTRS,
-} Free_Glyph_Attr;
-
-typedef struct {
float ax; // advance.x
float ay; // advance.y
@@ -49,39 +30,15 @@ typedef struct {
float tx; // x offset of glyph in texture coordinates
} Glyph_Metric;
-#define FREE_GLYPH_BUFFER_CAP (640 * 1000)
-
typedef struct {
- GLuint vao;
- GLuint vbo;
- GLuint program;
-
FT_UInt atlas_width;
FT_UInt atlas_height;
-
GLuint glyphs_texture;
-
- GLint uniforms[COUNT_UNIFORM_SLOTS];
-
- size_t glyphs_count;
- Free_Glyph glyphs[FREE_GLYPH_BUFFER_CAP];
-
Glyph_Metric metrics[128];
-} Free_Glyph_Buffer;
-
-void free_glyph_buffer_init(Free_Glyph_Buffer *fgb,
- FT_Face face,
- const char *vert_file_path,
- const char *frag_file_path);
-void free_glyph_buffer_use(const Free_Glyph_Buffer *fgb);
-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);
-
-float free_glyph_buffer_cursor_pos(const Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f pos, size_t col);
-
-void free_glyph_buffer_render_line_sized(Free_Glyph_Buffer *fgb, const char *text, size_t text_size, Vec2f *pos, Vec4f fg_color, Vec4f bg_color);
+} Free_Glyph_Atlas;
+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);
#endif // FREE_GLYPH_H_
diff --git a/src/main.c b/src/main.c
@@ -66,48 +66,46 @@ void MessageCallback(GLenum source,
type, severity, message);
}
-static Free_Glyph_Buffer fgb = {0};
+static Free_Glyph_Atlas atlas = {0};
static Simple_Renderer sr = {0};
#define FREE_GLYPH_FONT_SIZE 64
#define ZOOM_OUT_GLYPH_THRESHOLD 30
-void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Simple_Renderer *sr, Editor *editor)
+void render_editor(SDL_Window *window, Free_Glyph_Atlas *atlas, Simple_Renderer *sr, Editor *editor)
{
int w, h;
SDL_GetWindowSize(window, &w, &h);
float max_line_len = 0.0f;
- free_glyph_buffer_use(fgb);
- {
- glUniform2f(fgb->uniforms[UNIFORM_SLOT_RESOLUTION], (float) w, (float) h);
- glUniform1f(fgb->uniforms[UNIFORM_SLOT_TIME], (float) SDL_GetTicks() / 1000.0f);
- glUniform2f(fgb->uniforms[UNIFORM_SLOT_CAMERA_POS], camera_pos.x, camera_pos.y);
- glUniform1f(fgb->uniforms[UNIFORM_SLOT_CAMERA_SCALE], camera_scale);
-
- free_glyph_buffer_clear(fgb);
+ simple_renderer_use(sr);
- {
- for (size_t row = 0; row < editor->lines.count; ++row) {
- Line line = editor->lines.items[row];
-
- const Vec2f begin = vec2f(0, -(float)row * FREE_GLYPH_FONT_SIZE);
- Vec2f end = begin;
- free_glyph_buffer_render_line_sized(
- fgb, editor->data.items + line.begin, line.end - line.begin,
- &end,
- vec4fs(1.0f), vec4fs(0.0f));
- // 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) {
- max_line_len = line_len;
- }
+ // Render text
+ 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);
+ {
+ for (size_t row = 0; row < editor->lines.count; ++row) {
+ Line line = editor->lines.items[row];
+
+ const Vec2f begin = vec2f(0, -(float)row * FREE_GLYPH_FONT_SIZE);
+ Vec2f end = begin;
+ free_glyph_atlas_render_line_sized(
+ atlas, sr, editor->data.items + line.begin, line.end - line.begin,
+ &end);
+ // 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) {
+ max_line_len = line_len;
}
}
- free_glyph_buffer_sync(fgb);
- free_glyph_buffer_draw(fgb);
+ simple_renderer_sync(sr);
+ simple_renderer_draw(sr);
+ sr->verticies_count = 0;
}
Vec2f cursor_pos = vec2fs(0.0f);
@@ -116,36 +114,40 @@ void render_editor_into_fgb(SDL_Window *window, Free_Glyph_Buffer *fgb, Simple_R
Line line = editor->lines.items[cursor_row];
size_t cursor_col = editor->cursor - line.begin;
cursor_pos.y = -(float) cursor_row * FREE_GLYPH_FONT_SIZE;
- cursor_pos.x = free_glyph_buffer_cursor_pos(
- fgb,
+ cursor_pos.x = free_glyph_atlas_cursor_pos(
+ atlas,
editor->data.items + line.begin, line.end - line.begin,
vec2f(0.0, cursor_pos.y),
cursor_col
);
}
- simple_renderer_use(sr);
+ // Render cursor
+ 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);
{
- 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;
+
+ 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),
vec4fs(1));
}
+
simple_renderer_sync(sr);
simple_renderer_draw(sr);
+ sr->verticies_count = 0;
}
+ // Update camera
{
float target_scale = 3.0f;
if (max_line_len > 0.0f) {
@@ -261,14 +263,12 @@ int main(int argc, char **argv)
}
- free_glyph_buffer_init(&fgb,
- face,
- "./shaders/free_glyph.vert",
- "./shaders/free_glyph.frag");
-
simple_renderer_init(&sr,
"./shaders/simple.vert",
- "./shaders/simple.frag");
+ "./shaders/simple_color.frag",
+ "./shaders/simple_image.frag",
+ "./shaders/simple_epic.frag");
+ free_glyph_atlas_init(&atlas, face);
bool quit = false;
while (!quit) {
@@ -357,7 +357,7 @@ int main(int argc, char **argv)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
- render_editor_into_fgb(window, &fgb, &sr, &editor);
+ render_editor(window, &atlas, &sr, &editor);
SDL_GL_SwapWindow(window);
diff --git a/src/simple_renderer.c b/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,16 @@ 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)
+{
+ 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,
+ uvp, vec2f_add(uvp, vec2f(uvs.x, 0)), vec2f_add(uvp, vec2f(0, uvs.y)), vec2f_add(uvp, uvs));
+}
+
void simple_renderer_solid_rect(Simple_Renderer *sr, Vec2f p, Vec2f s, Vec4f c)
{
Vec2f uv = vec2fs(0);
@@ -135,3 +170,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);
+}
diff --git a/src/simple_renderer.h b/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, Vec2f uvp, Vec2f uvs);
void simple_renderer_sync(Simple_Renderer *sr);
void simple_renderer_draw(Simple_Renderer *sr);