#pragma once #include #include #include #include #include // 前向声明 OpenGL 类型 typedef unsigned int GLuint; typedef int GLint; typedef unsigned int GLenum; namespace extra2d { /** * @brief 着色器类 * * 管理 OpenGL 着色器程序的编译、链接和使用 * 支持从文件或源码加载 */ class Shader : public RefCounted { public: /** * @brief 默认构造函数 */ Shader(); /** * @brief 析构函数 */ ~Shader() override; /** * @brief 从文件加载着色器 * @param vsPath 顶点着色器文件路径 * @param fsPath 片段着色器文件路径 * @return 加载是否成功 */ bool loadFromFile(const std::string& vsPath, const std::string& fsPath); /** * @brief 从源码加载着色器 * @param vsSource 顶点着色器源码 * @param fsSource 片段着色器源码 * @return 加载是否成功 */ bool loadFromSource(const std::string& vsSource, const std::string& fsSource); /** * @brief 绑定着色器程序 */ void bind() const; /** * @brief 解绑着色器程序 */ void unbind() const; /** * @brief 设置 Uniform Block 绑定槽位 * @param name Uniform Block 名称 * @param binding 绑定槽位 */ void setUniformBlock(const std::string& name, uint32_t binding); /** * @brief 设置 int 类型 uniform * @param name uniform 名称 * @param value 值 */ void setInt(const std::string& name, int value); /** * @brief 设置 float 类型 uniform * @param name uniform 名称 * @param value 值 */ void setFloat(const std::string& name, float value); /** * @brief 设置 vec2 类型 uniform * @param name uniform 名称 * @param x X 分量 * @param y Y 分量 */ void setVec2(const std::string& name, float x, float y); /** * @brief 设置 vec4 类型 uniform * @param name uniform 名称 * @param x X 分量 * @param y Y 分量 * @param z Z 分量 * @param w W 分量 */ void setVec4(const std::string& name, float x, float y, float z, float w); /** * @brief 设置 mat4 类型 uniform * @param name uniform 名称 * @param value 矩阵数据指针(16个float) */ void setMat4(const std::string& name, const float* value); /** * @brief 获取着色器程序 ID * @return OpenGL 程序 ID */ GLuint getProgram() const { return program_; } /** * @brief 检查是否已加载 * @return 是否已加载 */ bool isLoaded() const { return program_ != 0; } private: /** * @brief 编译着色器 * @param type 着色器类型 * @param source 源码 * @return 着色器对象,失败返回 0 */ GLuint compileShader(GLenum type, const std::string& source); /** * @brief 链接着色器程序 * @param vertexShader 顶点着色器 * @param fragmentShader 片段着色器 * @return 链接是否成功 */ bool linkProgram(GLuint vertexShader, GLuint fragmentShader); /** * @brief 获取 uniform 位置 * @param name uniform 名称 * @return uniform 位置,不存在返回 -1 */ GLint getUniformLocation(const std::string& name); /** * @brief 添加版本声明(如果不存在) * @param source 源码 * @param type 着色器类型 * @return 处理后的源码 */ std::string addVersionIfNeeded(const std::string& source, GLenum type); private: GLuint program_ = 0; // OpenGL 程序对象 std::unordered_map uniformCache_; // Uniform 位置缓存 }; } // namespace extra2d