Commit: 17cdb1108111ff4ebdd0f01e9c76890aca6a4945
Parent: 8bf48859b5e39e7bce1c9bd8260621863c0c71f6
Author: Randy Palamar
Date: Tue, 22 Oct 2024 06:58:16 -0600
add basic rectangle drawing shader
this will be used for UI (and fixing the debug overlay)
Diffstat:
5 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/frag_for_rects.glsl b/frag_for_rects.glsl
@@ -0,0 +1,14 @@
+#version 430 core
+
+layout(location = 0) in vec2 fragment_pixel_coordinate;
+layout(location = 1) in vec2 fragment_texture_coordinate;
+layout(location = 2) in vec4 fragment_colour;
+
+layout(location = 0) out vec4 colour;
+
+layout(location = 3) uniform sampler2D u_texslot;
+
+void main()
+{
+ colour = fragment_colour * texture(u_texslot, fragment_texture_coordinate);
+}
diff --git a/frag_post.glsl b/frag_post.glsl
@@ -12,7 +12,7 @@ layout(location = 4) uniform float u_param;
void main()
{
vec2 texture_coord = fragment_texture_coordinate;
- //if (mod(tex_coord.y + u_param, 0.005) < 0.0005) {
+ //if (mod(texture_coord.y + u_param, 0.005) < 0.0005) {
if (false) {
vec4 tint = vec4(0.1, 0.1, 0.1, 1);
colour = mix(texture(u_texslot, texture_coord), tint, 0.5);
diff --git a/main.c b/main.c
@@ -91,6 +91,19 @@ error_callback(int code, const char *desc)
fprintf(stderr, "GLFW Error (0x%04X): %s\n", code, desc);
}
+static u32
+gen_2D_texture(iv2 size, u32 format, u32 filter, u32 *rgba)
+{
+ /* TODO: logging */
+ u32 result;
+ glGenTextures(1, &result);
+ glBindTexture(GL_TEXTURE_2D, result);
+ glTexImage2D(GL_TEXTURE_2D, 0, format, size.w, size.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgba);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ return result;
+}
+
static void
init_window(Term *t, Arena arena, iv2 window_size)
{
@@ -164,13 +177,10 @@ init_window(Term *t, Arena arena, iv2 window_size)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * ARRAY_COUNT(rpb->positions) * sizeof(i32),
element_indices, GL_STATIC_DRAW);
- glGenTextures(1, &t->gl.glyph_bitmap_tex);
- glBindTexture(GL_TEXTURE_2D, t->gl.glyph_bitmap_tex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- t->gl.glyph_bitmap_dim.w, t->gl.glyph_bitmap_dim.h,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ u32 white = 0xFFFFFFFF;
+
+ t->gl.default_tex = gen_2D_texture((iv2){.x = 1, .y = 1}, GL_RGBA, GL_NEAREST, &white);
+ t->gl.glyph_bitmap_tex = gen_2D_texture(t->gl.glyph_bitmap_dim, GL_RGBA, GL_NEAREST, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -182,14 +192,8 @@ init_window(Term *t, Arena arena, iv2 window_size)
t->gl.fb_tex_unit = 1;
glActiveTexture(GL_TEXTURE0 + t->gl.fb_tex_unit);
- glGenTextures(1, &t->gl.fb_tex);
- glBindTexture(GL_TEXTURE_2D, t->gl.fb_tex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- t->gl.window_size.w, t->gl.window_size.h,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
+ iv2 ws = {.x = t->gl.window_size.w, .y = t->gl.window_size.h};
+ t->gl.fb_tex = gen_2D_texture(ws, GL_RGBA, GL_NEAREST, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, t->gl.fb_tex, 0);
glGenBuffers(1, &t->gl.render_shader_ubo);
@@ -197,6 +201,8 @@ init_window(Term *t, Arena arena, iv2 window_size)
glBufferData(GL_UNIFORM_BUFFER, sizeof(ShaderParameters), 0, GL_DYNAMIC_DRAW);
glBindBufferBase(GL_UNIFORM_BUFFER, 0, t->gl.render_shader_ubo);
+ glActiveTexture(GL_TEXTURE0);
+
t->gl.flags |= INIT_DEBUG;
}
@@ -256,14 +262,24 @@ program_from_shader_text(s8 vertex, s8 fragment, Arena a)
static void
check_shaders(GLCtx *gl, Arena a)
{
- static char *fs_name[SHADER_LAST] = {"frag_render.glsl", "frag_post.glsl"};
- static char *vs_name[SHADER_LAST] = {"vert_for_rects.glsl", "vert_for_rects.glsl"};
+ static char *fs_name[SHADER_LAST] = {
+ "frag_render.glsl",
+ "frag_for_rects.glsl",
+ "frag_post.glsl",
+ };
+ static char *vs_name[SHADER_LAST] = {
+ "vert_for_rects.glsl",
+ "vert_for_rects.glsl",
+ "vert_for_rects.glsl",
+ };
+
static os_file_stats fs_stats[SHADER_LAST], vs_stats[SHADER_LAST];
static struct {
char *name;
u32 flag;
} map[SHADER_LAST] = {
- [SHADER_RENDER] = {.name = "Render", .flag = UPDATE_RENDER_UNIFORMS},
+ [SHADER_RENDER] = {.name = "Render", .flag = 0},
+ [SHADER_RECTS] = {.name = "Rects", .flag = 0},
[SHADER_POST] = {.name = "Post", .flag = UPDATE_POST_UNIFORMS},
};
diff --git a/util.h b/util.h
@@ -183,8 +183,7 @@ typedef struct {
size last_line_idx;
} TermView;
-#define GL_RENDER_UNIFORMS \
- X(Pmat)
+#define SHADER_PMAT_LOC 0
#define GL_POST_UNIFORMS \
X(Pmat) \
@@ -197,7 +196,6 @@ enum gl_flags {
NEEDS_FULL_REFILL = 1 << 2,
UPDATE_RENDER_BUFFER = 1 << 3,
- UPDATE_RENDER_UNIFORMS = 1 << 27,
UPDATE_POST_UNIFORMS = 1 << 28,
INIT_DEBUG = 1 << 29,
DRAW_DEBUG_OVERLAY = 1 << 30,
@@ -213,6 +211,7 @@ enum win_mode {
enum shader_stages {
SHADER_RENDER,
+ SHADER_RECTS,
SHADER_POST,
SHADER_LAST
};
@@ -244,15 +243,13 @@ typedef struct {
u32 fb, fb_tex, fb_tex_unit;
+ u32 default_tex;
+
u32 programs[SHADER_LAST];
#define X(name) i32 name;
union {
- struct { GL_RENDER_UNIFORMS };
- i32 uniforms[7];
- } render;
- union {
struct { GL_POST_UNIFORMS };
- i32 uniforms[4];
+ i32 uniforms[3];
} post;
#undef X
diff --git a/vtgl.c b/vtgl.c
@@ -48,10 +48,9 @@ set_projection_matrix(GLCtx *gl)
0.0, 0.0, 0.0, 1.0,
};
- glUseProgram(gl->programs[SHADER_RENDER]);
- glUniformMatrix4fv(gl->render.Pmat, 1, GL_TRUE, pmat);
- glUseProgram(gl->programs[SHADER_POST]);
- glUniformMatrix4fv(gl->post.Pmat, 1, GL_TRUE, pmat);
+ glProgramUniformMatrix4fv(gl->programs[SHADER_RENDER], SHADER_PMAT_LOC, 1, GL_TRUE, pmat);
+ glProgramUniformMatrix4fv(gl->programs[SHADER_RECTS], SHADER_PMAT_LOC, 1, GL_TRUE, pmat);
+ glProgramUniformMatrix4fv(gl->programs[SHADER_POST], SHADER_PMAT_LOC, 1, GL_TRUE, pmat);
}
static v2
@@ -127,11 +126,7 @@ update_uniforms(Term *t, enum shader_stages stage)
{
switch (stage) {
case SHADER_RENDER:
- #define X(name) \
- t->gl.render.name = glGetUniformLocation(t->gl.programs[stage], "u_" #name);
- GL_RENDER_UNIFORMS
- #undef X
- t->gl.flags &= ~UPDATE_RENDER_UNIFORMS;
+ case SHADER_RECTS:
break;
case SHADER_POST:
#define X(name) \
@@ -771,8 +766,6 @@ do_terminal(Term *t, f32 dt)
{
dt_for_frame = dt;
- if (t->gl.flags & UPDATE_RENDER_UNIFORMS)
- update_uniforms(t, SHADER_RENDER);
if (t->gl.flags & UPDATE_POST_UNIFORMS)
update_uniforms(t, SHADER_POST);
@@ -784,6 +777,11 @@ do_terminal(Term *t, f32 dt)
t->gl.flags &= ~INIT_DEBUG;
}
+ /* NOTE: this needs to be bound for blitting lines because that function can
+ * access the font cache.
+ * TODO: cleanup */
+ glBindTexture(GL_TEXTURE_2D, t->gl.glyph_bitmap_tex);
+
size parsed_lines = 0;
if (os_child_data_available(t->child)) {
RingBuf *rb = &t->views[t->view_idx].log;
@@ -856,6 +854,16 @@ do_terminal(Term *t, f32 dt)
push_rect(rpb, &t->gl, (Rect){.size = t->gl.window_size}, (v4){0}, 1);
flush_render_push_buffer(rpb, &t->gl);
+
+ #if 0
+ /* NOTE: this happens at the end so that ui stuff doesn't go through the post
+ * processing/effects shader */
+ glUseProgram(t->gl.programs[SHADER_RECTS]);
+ glBindTexture(GL_TEXTURE_2D, t->gl.default_tex);
+ push_rect(rpb, &t->gl, (Rect){.size = {.w = 300, .h = 200}}, (v4){.r = 0.5, .a = 1}, 0);
+ push_rect(rpb, &t->gl, (Rect){.pos = {.x = 300, .y = 200}, .size = {.w = 300, .h = 200}}, (v4){.g = 0.5, .a = 1}, 0);
+ flush_render_push_buffer(rpb, &t->gl);
+ #endif
}
#ifdef _DEBUG