Extra2D/include/renderer/shader.h

180 lines
5.8 KiB
C
Raw Normal View History

2026-02-11 19:40:26 +08:00
#pragma once
#include <core/color.h>
#include <core/types.h>
#include <graphics/opengl/gl_shader.h>
2026-02-11 19:40:26 +08:00
#include <functional>
#include <string>
#include <unordered_map>
namespace extra2d {
// ============================================================================
// Shader参数绑定回调
// ============================================================================
using ShaderBindCallback = std::function<void(GLShader &)>;
// ============================================================================
// Shader系统 - 管理所有Shader的加载、缓存和热重载
// ============================================================================
class ShaderSystem {
public:
// ------------------------------------------------------------------------
// 单例访问
// ------------------------------------------------------------------------
static ShaderSystem &getInstance();
// ------------------------------------------------------------------------
// 初始化和关闭
// ------------------------------------------------------------------------
bool init();
void shutdown();
// ------------------------------------------------------------------------
// Shader加载
// ------------------------------------------------------------------------
/**
* @brief Shader
* @param name Shader名称
* @param vertPath
* @param fragPath
* @return Shadernullptr
*/
Ptr<GLShader> loadFromFile(const std::string &name,
const std::string &vertPath,
const std::string &fragPath);
/**
* @brief Shader
* @param name Shader名称
* @param vertSource
* @param fragSource
* @return Shadernullptr
*/
Ptr<GLShader> loadFromSource(const std::string &name,
const std::string &vertSource,
const std::string &fragSource);
/**
* @brief Shader
* @param name Shader名称
* @return Shadernullptr
*/
Ptr<GLShader> get(const std::string &name);
/**
* @brief Shader是否存在
*/
bool has(const std::string &name) const;
// ------------------------------------------------------------------------
// Shader移除
// ------------------------------------------------------------------------
void remove(const std::string &name);
void clear();
// ------------------------------------------------------------------------
// 热重载支持
// ------------------------------------------------------------------------
/**
* @brief /
*/
void setFileWatching(bool enable);
bool isFileWatching() const { return fileWatching_; }
/**
* @brief
*/
void updateFileWatching();
/**
* @brief Shader
*/
bool reload(const std::string &name);
/**
* @brief Shader
*/
void reloadAll();
// ------------------------------------------------------------------------
// 内置Shader获取
// ------------------------------------------------------------------------
Ptr<GLShader> getBuiltinSpriteShader();
Ptr<GLShader> getBuiltinParticleShader();
Ptr<GLShader> getBuiltinPostProcessShader();
Ptr<GLShader> getBuiltinShapeShader();
// ------------------------------------------------------------------------
// 工具方法
// ------------------------------------------------------------------------
/**
* @brief
*/
static std::string readFile(const std::string &filepath);
/**
* @brief Shader文件的最后修改时间
*/
static uint64_t getFileModifiedTime(const std::string &filepath);
private:
ShaderSystem() = default;
~ShaderSystem() = default;
ShaderSystem(const ShaderSystem &) = delete;
ShaderSystem &operator=(const ShaderSystem &) = delete;
struct ShaderInfo {
Ptr<GLShader> shader;
std::string vertPath;
std::string fragPath;
uint64_t vertModifiedTime;
uint64_t fragModifiedTime;
bool isBuiltin;
};
std::unordered_map<std::string, ShaderInfo> shaders_;
bool fileWatching_ = false;
float watchTimer_ = 0.0f;
static constexpr float WATCH_INTERVAL = 1.0f; // 检查间隔(秒)
// 内置Shader缓存
Ptr<GLShader> builtinSpriteShader_;
Ptr<GLShader> builtinParticleShader_;
Ptr<GLShader> builtinPostProcessShader_;
Ptr<GLShader> builtinShapeShader_;
bool loadBuiltinShaders();
void checkAndReload();
};
// ============================================================================
// Shader参数包装器 - 简化Uniform设置
// ============================================================================
class ShaderParams {
public:
explicit ShaderParams(GLShader &shader);
ShaderParams &setBool(const std::string &name, bool value);
ShaderParams &setInt(const std::string &name, int value);
ShaderParams &setFloat(const std::string &name, float value);
ShaderParams &setVec2(const std::string &name, const glm::vec2 &value);
ShaderParams &setVec3(const std::string &name, const glm::vec3 &value);
ShaderParams &setVec4(const std::string &name, const glm::vec4 &value);
ShaderParams &setMat4(const std::string &name, const glm::mat4 &value);
ShaderParams &setColor(const std::string &name, const Color &color);
private:
GLShader &shader_;
};
// ============================================================================
// 便捷宏
// ============================================================================
#define E2D_SHADER_SYSTEM() ::extra2d::ShaderSystem::getInstance()
} // namespace extra2d