#include "post_processor.h" #include "sys.h" #include "shader.h" #include "texture.h" #include 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); }