#pragma once #include #include #include #include #include #include #include namespace easy2d { // ============================================================================ // 前向声明 // ============================================================================ class RenderTarget; class RenderBackend; // ============================================================================ // 后处理效果基类 // ============================================================================ class PostProcessEffect { public: PostProcessEffect(const std::string& name); virtual ~PostProcessEffect() = default; // ------------------------------------------------------------------------ // 生命周期 // ------------------------------------------------------------------------ /** * @brief 初始化效果 */ virtual bool init(); /** * @brief 关闭效果 */ virtual void shutdown(); // ------------------------------------------------------------------------ // 渲染 // ------------------------------------------------------------------------ /** * @brief 应用效果 * @param source 输入纹理 * @param target 输出渲染目标 * @param renderer 渲染后端 */ virtual void apply(const Texture& source, RenderTarget& target, RenderBackend& renderer); /** * @brief 设置Shader参数(子类重写) */ virtual void onShaderBind(GLShader& shader) {} // ------------------------------------------------------------------------ // 状态 // ------------------------------------------------------------------------ const std::string& getName() const { return name_; } bool isEnabled() const { return enabled_; } void setEnabled(bool enabled) { enabled_ = enabled; } bool isValid() const { return valid_; } // ------------------------------------------------------------------------ // 链式API // ------------------------------------------------------------------------ PostProcessEffect& withEnabled(bool enabled) { enabled_ = enabled; return *this; } protected: std::string name_; bool enabled_ = true; bool valid_ = false; Ptr shader_; /** * @brief 加载自定义Shader */ bool loadShader(const std::string& vertSource, const std::string& fragSource); bool loadShaderFromFile(const std::string& vertPath, const std::string& fragPath); /** * @brief 渲染全屏四边形 */ void renderFullscreenQuad(); private: static GLuint quadVao_; static GLuint quadVbo_; static bool quadInitialized_; void initQuad(); void destroyQuad(); }; // ============================================================================ // 后处理栈 - 管理多个后处理效果 // ============================================================================ class PostProcessStack { public: PostProcessStack(); ~PostProcessStack(); // ------------------------------------------------------------------------ // 初始化和关闭 // ------------------------------------------------------------------------ bool init(int width, int height); void shutdown(); // ------------------------------------------------------------------------ // 效果管理 // ------------------------------------------------------------------------ /** * @brief 添加效果到栈 */ void addEffect(Ptr effect); /** * @brief 插入效果到指定位置 */ void insertEffect(size_t index, Ptr effect); /** * @brief 移除效果 */ void removeEffect(const std::string& name); void removeEffect(size_t index); /** * @brief 获取效果 */ Ptr getEffect(const std::string& name); Ptr getEffect(size_t index); /** * @brief 清空所有效果 */ void clearEffects(); /** * @brief 获取效果数量 */ size_t getEffectCount() const { return effects_.size(); } // ------------------------------------------------------------------------ // 渲染 // ------------------------------------------------------------------------ /** * @brief 开始捕获场景 */ void beginCapture(); /** * @brief 结束捕获并应用所有效果 */ void endCapture(RenderBackend& renderer); /** * @brief 直接应用效果到纹理 */ void process(const Texture& source, RenderTarget& target, RenderBackend& renderer); // ------------------------------------------------------------------------ // 配置 // ------------------------------------------------------------------------ void resize(int width, int height); bool isValid() const { return valid_; } // ------------------------------------------------------------------------ // 便捷方法 - 添加内置效果 // ------------------------------------------------------------------------ PostProcessStack& addBloom(float intensity = 1.0f, float threshold = 0.8f); PostProcessStack& addBlur(float radius = 2.0f); PostProcessStack& addColorGrading(const Color& tint); PostProcessStack& addVignette(float intensity = 0.5f); PostProcessStack& addChromaticAberration(float amount = 1.0f); private: std::vector> effects_; Ptr renderTargetA_; Ptr renderTargetB_; int width_ = 0; int height_ = 0; bool valid_ = false; bool capturing_ = false; }; // ============================================================================ // 全局后处理管理 // ============================================================================ class PostProcessManager { public: static PostProcessManager& getInstance(); void init(int width, int height); void shutdown(); PostProcessStack& getMainStack() { return mainStack_; } void resize(int width, int height); void beginFrame(); void endFrame(RenderBackend& renderer); private: PostProcessManager() = default; ~PostProcessManager() = default; PostProcessManager(const PostProcessManager&) = delete; PostProcessManager& operator=(const PostProcessManager&) = delete; PostProcessStack mainStack_; bool initialized_ = false; }; // ============================================================================ // 便捷宏 // ============================================================================ #define E2D_POST_PROCESS() ::easy2d::PostProcessManager::getInstance() } // namespace easy2d