diff options
Diffstat (limited to 'in_practice/breakout/post_processor.c')
-rw-r--r-- | in_practice/breakout/post_processor.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/in_practice/breakout/post_processor.c b/in_practice/breakout/post_processor.c new file mode 100644 index 0000000..70691c2 --- /dev/null +++ b/in_practice/breakout/post_processor.c @@ -0,0 +1,109 @@ +#include "post_processor.h" +#include "sys.h" +#include "shader.h" +#include "texture.h" + +#include <GL/glew.h> + +struct post_processor init_post_processor(i32 width, i32 height, u32 shader) +{ + struct post_processor processor = {0}; + processor.width = width; + processor.height = height; + glGenFramebuffers(1, &processor.msfbo); + glGenFramebuffers(1, &processor.fbo); + glGenRenderbuffers(1, &processor.rbo); + glBindFramebuffer(GL_FRAMEBUFFER, processor.msfbo); + glBindRenderbuffer(GL_RENDERBUFFER, processor.rbo); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGB, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, processor.rbo); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + die("failed to create msfbo"); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, processor.fbo); + gl_texture_t texture = (gl_texture_t)default_texture; + generate_texture(&texture, width, height, 0); + processor.texture = texture.id; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, processor.texture, 0); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + die("failed to create fbo"); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + u32 vbo; + f32 vertices[] = { + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 0.0f, + 1.0f, -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 1.0f, 1.0f + }; + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glGenVertexArrays(1, &processor.vao); + glBindVertexArray(processor.vao); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(f32), 0); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + processor.shader = shader; + glUseProgram(processor.shader); + uniform_i32(processor.shader, "colorbuffer", 0); + f32 offset = 1.0f / 300.0f; + f32 offsets[] = { + -offset, offset, /* top-left */ + 0.0f, offset, /* top-center */ + offset, offset, /* top-right */ + -offset, 0.0f, /* center-left */ + 0.0f, 0.0f, /* center */ + offset, 0.0f, /* center-right */ + -offset, -offset, /* bottom-left */ + 0.0f, -offset, /* bottom-center */ + offset, -offset /* bottom-right */ + }; + glUniform2fv(glGetUniformLocation(processor.shader, "offsets"), 9, offsets); + i32 edge_kernel[] = { + -1, -1, -1, + -1, 8, -1, + -1, -1, -1 + }; + glUniform1iv(glGetUniformLocation(processor.shader, "edge_kernel"), 9, edge_kernel); + f32 blur_kernel[] = { + 1.0f / 16.0f, 2.0f / 16.0f, 1.0f / 16.0f, + 2.0f / 16.0f, 4.0f / 16.0f, 2.0f / 16.0f, + 1.0f / 16.0f, 2.0f / 16.0f, 1.0f / 16.0f + }; + glUniform1fv(glGetUniformLocation(processor.shader, "blur_kernel"), 9, blur_kernel); + glUseProgram(0); + return processor; +} + +void begin_render(struct post_processor processor) +{ + glBindFramebuffer(GL_FRAMEBUFFER, processor.msfbo); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); +} + +void end_render(struct post_processor processor) +{ + glBindFramebuffer(GL_READ_FRAMEBUFFER, processor.msfbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, processor.fbo); + glBlitFramebuffer(0, 0, processor.width, processor.height, 0, 0, processor.width, processor.height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +} + +void render_post(struct post_processor processor, f32 time) +{ + glUseProgram(processor.shader); + uniform_f32(processor.shader, "time", time); + uniform_i32(processor.shader, "confuse", processor.confuse); + uniform_i32(processor.shader, "chaos", processor.chaos); + uniform_i32(processor.shader, "shake", processor.shake); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, processor.texture); + glBindVertexArray(processor.vao); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + glUseProgram(0); +} |