commit b4c1590d78887871c46fcc9ee02653ba6ac4e9d3
parent c7e0bcc15394e84d2ead6c3eb7522b5141525d81
Author: rexim <reximkut@gmail.com>
Date: Mon, 9 Jan 2023 00:33:07 +0700
Introduce several shaders to Simple_Renderer
Diffstat:
8 files changed, 139 insertions(+), 19 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
@@ -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
}
}
diff --git a/src/main.c b/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) {
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,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);
+}
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);
void simple_renderer_sync(Simple_Renderer *sr);
void simple_renderer_draw(Simple_Renderer *sr);