Extra2D/Extra2D/include/extra2d/graphics/shader/shader_manager.h

252 lines
7.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <extra2d/config/platform_detector.h>
#include <extra2d/graphics/shader/shader_cache.h>
#include <extra2d/graphics/shader/shader_hot_reloader.h>
#include <extra2d/graphics/shader/shader_interface.h>
#include <extra2d/graphics/shader/shader_loader.h>
#include <functional>
#include <unordered_map>
namespace extra2d {
// ============================================================================
// Shader重载回调
// ============================================================================
using ShaderReloadCallback = std::function<void(Ptr<IShader> newShader)>;
// ============================================================================
// Shader管理器 - 统一入口
// ============================================================================
class ShaderManager {
public:
/**
* @brief 获取单例实例
* @return Shader管理器实例引用
*/
static ShaderManager& getInstance();
// ------------------------------------------------------------------------
// 初始化和关闭
// ------------------------------------------------------------------------
/**
* @brief 使用平台默认路径初始化Shader系统
* 自动检测平台并使用正确的路径romfs/sdmc/相对路径)
* @param factory 渲染后端Shader工厂
* @param appName 应用名称(用于缓存目录)
* @return 初始化成功返回true失败返回false
*/
bool init(Ptr<IShaderFactory> factory, const std::string& appName = "extra2d");
/**
* @brief 初始化Shader系统
* @param shaderDir Shader文件目录
* @param cacheDir 缓存目录
* @param factory 渲染后端Shader工厂
* @return 初始化成功返回true失败返回false
*/
bool init(const std::string& shaderDir,
const std::string& cacheDir,
Ptr<IShaderFactory> factory);
/**
* @brief 关闭Shader系统
*/
void shutdown();
/**
* @brief 检查是否已初始化
* @return 已初始化返回true否则返回false
*/
bool isInitialized() const { return initialized_; }
/**
* @brief 检查当前平台是否支持热重载
* Switch平台使用romfs不支持热重载
* @return 支持热重载返回true
*/
bool isHotReloadSupported() const { return hotReloadSupported_; }
// ------------------------------------------------------------------------
// Shader加载
// ------------------------------------------------------------------------
/**
* @brief 从分离文件加载Shader
* @param name Shader名称
* @param vertPath 顶点着色器文件路径
* @param fragPath 片段着色器文件路径
* @return 加载的Shader实例
*/
Ptr<IShader> loadFromFiles(const std::string& name,
const std::string& vertPath,
const std::string& fragPath);
/**
* @brief 从组合文件加载Shader
* @param path 组合Shader文件路径
* @return 加载的Shader实例
*/
Ptr<IShader> loadFromCombinedFile(const std::string& path);
/**
* @brief 从源码加载Shader
* @param name Shader名称
* @param vertSource 顶点着色器源码
* @param fragSource 片段着色器源码
* @return 加载的Shader实例
*/
Ptr<IShader> loadFromSource(const std::string& name,
const std::string& vertSource,
const std::string& fragSource);
/**
* @brief 获取已加载的Shader
* @param name Shader名称
* @return Shader实例不存在返回nullptr
*/
Ptr<IShader> get(const std::string& name) const;
/**
* @brief 检查Shader是否存在
* @param name Shader名称
* @return 存在返回true否则返回false
*/
bool has(const std::string& name) const;
/**
* @brief 移除Shader
* @param name Shader名称
*/
void remove(const std::string& name);
/**
* @brief 清除所有Shader
*/
void clear();
// ------------------------------------------------------------------------
// 热重载
// ------------------------------------------------------------------------
/**
* @brief 注册重载回调
* @param name Shader名称
* @param callback 重载回调函数
*/
void setReloadCallback(const std::string& name, ShaderReloadCallback callback);
/**
* @brief 启用/禁用热重载
* @param enabled 是否启用
*/
void setHotReloadEnabled(bool enabled);
/**
* @brief 检查热重载是否启用
* @return 启用返回true否则返回false
*/
bool isHotReloadEnabled() const;
/**
* @brief 更新热重载系统(主循环调用)
*/
void update();
/**
* @brief 手动重载Shader
* @param name Shader名称
* @return 重载成功返回true失败返回false
*/
bool reload(const std::string& name);
// ------------------------------------------------------------------------
// 内置Shader
// ------------------------------------------------------------------------
/**
* @brief 获取内置Shader
* @param name 内置Shader名称
* @return Shader实例
*/
Ptr<IShader> getBuiltin(const std::string& name);
/**
* @brief 加载所有内置Shader
* @return 加载成功返回true失败返回false
*/
bool loadBuiltinShaders();
// ------------------------------------------------------------------------
// 工具方法
// ------------------------------------------------------------------------
/**
* @brief 获取Shader目录
* @return Shader目录路径
*/
const std::string& getShaderDir() const { return shaderDir_; }
/**
* @brief 获取ShaderLoader
* @return ShaderLoader引用
*/
ShaderLoader& getLoader() { return loader_; }
private:
ShaderManager() = default;
~ShaderManager() = default;
ShaderManager(const ShaderManager&) = delete;
ShaderManager& operator=(const ShaderManager&) = delete;
std::string shaderDir_;
std::string cacheDir_;
Ptr<IShaderFactory> factory_;
ShaderLoader loader_;
struct ShaderInfo {
Ptr<IShader> shader;
ShaderMetadata metadata;
ShaderReloadCallback reloadCallback;
std::string vertSource;
std::string fragSource;
std::vector<std::string> filePaths;
};
std::unordered_map<std::string, ShaderInfo> shaders_;
bool initialized_ = false;
bool hotReloadEnabled_ = false;
bool hotReloadSupported_ = true;
/**
* @brief 从缓存加载Shader
* @param name Shader名称
* @param sourceHash 源码哈希值
* @param vertSource 顶点着色器源码
* @param fragSource 片段着色器源码
* @return Shader实例
*/
Ptr<IShader> loadFromCache(const std::string& name,
const std::string& sourceHash,
const std::string& vertSource,
const std::string& fragSource);
/**
* @brief 创建内置Shader源码
*/
void createBuiltinShaderSources();
/**
* @brief 处理文件变化事件
* @param shaderName Shader名称
* @param event 文件变化事件
*/
void handleFileChange(const std::string& shaderName, const FileChangeEvent& event);
};
// 便捷宏
#define E2D_SHADER_MANAGER() ::extra2d::ShaderManager::getInstance()
} // namespace extra2d