aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-05-26 17:34:58 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-05-26 17:34:58 +0200
commit52bc19527838f2cac481a89cefd18cfea6e1a2d2 (patch)
treeaed452488b766f9e0f02d6e5237d6eecf0e8e909
parent33deac9462906c5e7b084665df3194cfa5e73249 (diff)
WIP add framebuffer
-rw-r--r--main.c34
-rw-r--r--makefile2
-rw-r--r--output.frag12
-rw-r--r--output.vert12
-rw-r--r--uniform.c22
-rw-r--r--uniform.h9
-rw-r--r--visuals.frag26
7 files changed, 91 insertions, 26 deletions
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 <GLFW/glfw3.h>
#include <GL/gl.h>
-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 <https://www.shadertoy.com/view/4djSRW>
-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;
}