feat: post-processing effects

This commit is contained in:
MihailRis
2025-04-05 00:41:25 +03:00
parent 22e97b1766
commit ba170035ef
19 changed files with 216 additions and 84 deletions
+43 -7
View File
@@ -4,13 +4,15 @@
#include "Texture.hpp"
#include "Framebuffer.hpp"
#include "DrawContext.hpp"
#include "PostEffect.hpp"
#include "assets/Assets.hpp"
#include <stdexcept>
PostProcessing::PostProcessing() {
// Fullscreen quad mesh bulding
float vertices[] {
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f
};
VertexAttribute attrs[] {{2}, {0}};
@@ -23,22 +25,56 @@ void PostProcessing::use(DrawContext& context) {
const auto& vp = context.getViewport();
if (fbo) {
fbo->resize(vp.x, vp.y);
fboSecond->resize(vp.x, vp.y);
} else {
fbo = std::make_unique<Framebuffer>(vp.x, vp.y);
fboSecond = std::make_unique<Framebuffer>(vp.x, vp.y);
}
context.setFramebuffer(fbo.get());
}
void PostProcessing::render(const DrawContext& context, Shader* screenShader) {
void PostProcessing::render(
const DrawContext& context, const Assets& assets, float timer
) {
if (fbo == nullptr) {
throw std::runtime_error("'use(...)' was never called");
}
int totalPasses = 0;
for (const auto& effect : effectSlots) {
totalPasses += (effect != nullptr && effect->isActive());
}
const auto& viewport = context.getViewport();
screenShader->use();
screenShader->uniform2i("u_screenSize", viewport);
fbo->getTexture()->bind();
quadMesh->draw();
if (totalPasses == 0) {
auto& effect = assets.require<PostEffect>("default");
effect.use();
fbo->getTexture()->bind();
quadMesh->draw();
return;
}
int currentPass = 1;
for (const auto& effect : effectSlots) {
if (effect == nullptr || !effect->isActive()) {
continue;
}
auto& shader = effect->use();
const auto& viewport = context.getViewport();
shader.uniform1i("u_screen", 0);
shader.uniform2i("u_screenSize", viewport);
shader.uniform1f("u_timer", timer);
fbo->getTexture()->bind();
if (currentPass < totalPasses) {
fboSecond->bind();
}
quadMesh->draw();
if (currentPass < totalPasses) {
fboSecond->unbind();
std::swap(fbo, fboSecond);
}
currentPass++;
}
}
std::unique_ptr<ImageData> PostProcessing::toImage() {