Extra2D/include/renderer/shader.h

156 lines
3.8 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 <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