From 52bc19527838f2cac481a89cefd18cfea6e1a2d2 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Sun, 26 May 2024 17:34:58 +0200 Subject: WIP add framebuffer --- main.c | 34 +++++++++++++++++++++++++++++++--- makefile | 2 ++ output.frag | 12 ++++++++++++ output.vert | 12 ++++++++++++ uniform.c | 22 ++++++++++++---------- uniform.h | 9 +++++++-- visuals.frag | 26 +++++++++++++++----------- 7 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 output.frag create mode 100644 output.vert diff --git a/main.c b/main.c index 705c35f..b2847b1 100644 --- a/main.c +++ b/main.c @@ -8,6 +8,7 @@ #include "fill_vert.h" #include "visuals_frag.h" +#include "output_frag.h" void resize_handler(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); @@ -68,18 +69,45 @@ int main(int argc, char** argv) { glewInit(); init_tri(); - GLuint shader = link_shaders( + + GLuint visuals = link_shaders( vert_shader(fill_vert, fill_vert_size), frag_shader(visuals_frag, visuals_frag_size) ); - init_uniform(shader, window); + uniforms_t * visuals_uniforms = init_uniforms(visuals, window); + + GLuint output = link_shaders( + vert_shader(fill_vert, fill_vert_size), + frag_shader(output_frag, output_frag_size) + ); + uniforms_t * output_uniforms = init_uniforms(output, window); + + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + GLuint last_frame; + glGenTextures(1, &last_frame); + glBindTexture(GL_TEXTURE_2D, last_frame); + // todo: what to do when the size changes? + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, last_frame, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + die("can't initialize framebuffer??\n"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glUseProgram(visuals); // main draw loop while (!glfwWindowShouldClose(window)) { glfwPollEvents(); - update_uniform(); + update_uniforms(visuals_uniforms); + // glBindFramebuffer(GL_FRAMEBUFFER, fbo); glDrawArrays(GL_TRIANGLES, 0, 3); + // glBindFramebuffer(GL_FRAMEBUFFER, 0); glfwSwapBuffers(window); } diff --git a/makefile b/makefile index ef01ae8..d22eaec 100644 --- a/makefile +++ b/makefile @@ -17,11 +17,13 @@ main: die.o main: shader.o main: visuals_frag.o main: fill_vert.o +main: output_frag.o main: uniform.o # fix compile order main.o: fill_vert.h main.o: visuals_frag.h +main.o: output_frag.h %.s %.h &: %.spv ./blob $< $* diff --git a/output.frag b/output.frag new file mode 100644 index 0000000..df4d103 --- /dev/null +++ b/output.frag @@ -0,0 +1,12 @@ +#version 460 core + +out vec4 color; +in vec4 gl_FragCoord; + +uniform ivec2 window; +uniform sampler2D buf; + +void main() { + color = texture(buf, gl_FragCoord.xy / window.xy); +} + diff --git a/output.vert b/output.vert new file mode 100644 index 0000000..df4d103 --- /dev/null +++ b/output.vert @@ -0,0 +1,12 @@ +#version 460 core + +out vec4 color; +in vec4 gl_FragCoord; + +uniform ivec2 window; +uniform sampler2D buf; + +void main() { + color = texture(buf, gl_FragCoord.xy / window.xy); +} + diff --git a/uniform.c b/uniform.c index 6c66b7a..a6a7772 100644 --- a/uniform.c +++ b/uniform.c @@ -6,19 +6,21 @@ int time_start = 0; GLFWwindow* window = NULL; -GLint u_time, u_window; -void init_uniform(GLuint shader, GLFWwindow* _window) { +uniforms_t * init_uniforms(GLuint shader, GLFWwindow* _window) { window = _window; + time_start = time(NULL); - u_time = glGetUniformLocation(shader, "time"); - u_window = glGetUniformLocation(shader, "window"); + uniforms_t * uniforms = malloc(sizeof(uniforms_t)); - time_start = time(NULL); + uniforms->time = glGetUniformLocation(shader, "time"); + uniforms->window = glGetUniformLocation(shader, "window"); + + return uniforms; } /** @brief update `uniform float time` */ -static void update_u_time() { +static void update_u_time(GLuint u_time) { struct timeval t; gettimeofday(&t, NULL); t.tv_sec -= time_start; @@ -27,14 +29,14 @@ static void update_u_time() { } /** @brief update `uniform ivec2 window` */ -static void update_u_window() { +static void update_u_window(GLuint u_window) { int width, height; glfwGetWindowSize(window, &width, &height); glUniform2i(u_window, width, height); } -void update_uniform() { - update_u_time(); - update_u_window(); +void update_uniforms(uniforms_t * uniforms) { + update_u_time(uniforms->time); + update_u_window(uniforms->window); } diff --git a/uniform.h b/uniform.h index d7c58b3..0132078 100644 --- a/uniform.h +++ b/uniform.h @@ -5,6 +5,11 @@ #include #include -void init_uniform(GLuint shader, GLFWwindow* window); -void update_uniform(); +typedef struct { + GLint time; + GLint window; +} uniforms_t; + +uniforms_t * init_uniforms(GLuint shader, GLFWwindow* window); +void update_uniforms(uniforms_t * uniforms); diff --git a/visuals.frag b/visuals.frag index d680834..35f9a6a 100644 --- a/visuals.frag +++ b/visuals.frag @@ -1,18 +1,22 @@ -#version 330 core +#version 460 core + +out vec4 color; +in vec4 gl_FragCoord; uniform float time; uniform ivec2 window; - -// adapted from -float hash12(vec2 p) { - vec3 p3 = fract(vec3(p.xyx) * .1031); - p3 += dot(p3, p3.yzx + 33.33); - return fract((p3.x + p3.y) * p3.z); -} +uniform sampler2D buf; void main() { - vec2 uv = gl_FragCoord.xy / window; - vec2 pos = gl_FragCoord.xy + time; - gl_FragColor = vec4(hash12(pos), uv.xy, 1.0); + vec2 point = vec2(sin(time), cos(time)) * 0.7; + point.x *= float(window.y) / float(window.x); // adjust for aspect ratio + point = ((point + 1.0) / 2.0) * window.xy; // convert to screen coords + float r = 20.0; // circle radius + + color = vec4(0.0); + if (length(gl_FragCoord.xy - point) < r) + color = vec4(1.0); + + color += texture(buf, gl_FragCoord.xy / window.xy) * 0.90; } -- cgit v1.2.3