feat: post-processing effects
This commit is contained in:
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user