156 lines
3.8 KiB
C++
156 lines
3.8 KiB
C++
#pragma once
|
||
|
||
#include <types/ptr/ref_counted.h>
|
||
#include <types/ptr/intrusive_ptr.h>
|
||
#include <types/base/types.h>
|
||
#include <string>
|
||
#include <unordered_map>
|
||
|
||
// 前向声明 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<std::string, GLint> uniformCache_; // Uniform 位置缓存
|
||
};
|
||
|
||
} // namespace extra2d
|