#pragma once #include #include #include #include "MeshData.hpp" template class Mesh; class Assets; class Framebuffer; class DrawContext; class ImageData; class PostEffect; struct PostProcessingVertex { glm::vec2 position; static constexpr VertexAttribute ATTRIBUTES[] { {VertexAttribute::Type::FLOAT, false, 2}, {{}, 0}}; }; /// @brief Framebuffer with blitting with shaders. /// @attention Current implementation does not support multiple render passes /// for multiple effects. Will be implemented in v0.21 class PostProcessing { /// @brief Main framebuffer (lasy field) std::unique_ptr fbo; std::unique_ptr fboSecond; /// @brief Fullscreen quad mesh as the post-processing canvas std::unique_ptr> quadMesh; std::vector> effectSlots; public: PostProcessing(size_t effectSlotsCount); ~PostProcessing(); /// @brief Prepare and bind framebuffer /// @param context graphics context will be modified void use(DrawContext& context); /// @brief Render fullscreen quad using the passed shader /// with framebuffer texture bound /// @param context graphics context /// @throws std::runtime_error if use(...) wasn't called before void render(const DrawContext& context, const Assets& assets, float timer); void setEffect(size_t slot, std::shared_ptr effect); PostEffect* getEffect(size_t slot); /// @brief Make an image from the last rendered frame std::unique_ptr toImage(); Framebuffer* getFramebuffer() const; };