226 lines
6.8 KiB
C++
226 lines
6.8 KiB
C++
#pragma once
|
||
|
||
#include <easy2d/core/types.h>
|
||
#include <easy2d/core/color.h>
|
||
#include <easy2d/graphics/texture.h>
|
||
#include <easy2d/graphics/opengl/gl_shader.h>
|
||
#include <string>
|
||
#include <functional>
|
||
#include <vector>
|
||
|
||
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<GLShader> 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<PostProcessEffect> effect);
|
||
|
||
/**
|
||
* @brief 插入效果到指定位置
|
||
*/
|
||
void insertEffect(size_t index, Ptr<PostProcessEffect> effect);
|
||
|
||
/**
|
||
* @brief 移除效果
|
||
*/
|
||
void removeEffect(const std::string& name);
|
||
void removeEffect(size_t index);
|
||
|
||
/**
|
||
* @brief 获取效果
|
||
*/
|
||
Ptr<PostProcessEffect> getEffect(const std::string& name);
|
||
Ptr<PostProcessEffect> 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<Ptr<PostProcessEffect>> effects_;
|
||
Ptr<RenderTarget> renderTargetA_;
|
||
Ptr<RenderTarget> 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
|