# OpenGLShader **命名空间**: `XCEngine::RHI` **类型**: `class` **头文件**: `XCEngine/RHI/OpenGL/OpenGLShader.h` **描述**: OpenGL 后端的 shader / program 封装器,负责 GLSL 源码读取、编译、链接,以及一套轻量级的 uniform 反射查询。 ## 概览 `OpenGLShader` 当前同时承担两类职责: - 单阶段 shader 的编译入口 - 完整 graphics / compute program 的最终持有者 它不是“离线 shader 资产系统”,也不是“可复用的原生 shader object 缓存”。当前实现更偏向运行时直接把 GLSL 文本编译成 program,然后尽快给命令列表和管线状态对象使用。 ## 主要能力 - 直接从字符串编译 vertex / fragment / geometry / compute - 从文件读取 GLSL 源码 - 通过 `target`、扩展名或源码内容推断阶段类型 - 暴露 program ID 给后端专用路径 - 懒加载 uniform 反射信息 ## 当前实现的真实行为 - [CompileFromFile](CompileFromFile.md) 的通用 RHI 入口会忽略 `entryPoint` - [Compile](Compile.md) 的通用 RHI 入口同样忽略 `entryPoint` - 单文件 / 单源码编译路径依赖启发式类型推断 - 图形 program 的双阶段/三阶段重载不会更新 `m_type` - 失败日志通过 `std::cout` 输出 - 当前实现不保证“重复编译同一对象”时的资源清理完整性 ## 设计背景 在跨后端 RHI 里,D3D12/Vulkan 往往会把 shader bytecode、pipeline 创建和反射拆得更细;而 OpenGL 更常见的运行时模型是“把 GLSL 文本直接交给驱动编译”。`OpenGLShader` 采用的是后一种思路: - 先保证最短路径可编译、可绑定、可调试 - 再通过 `GetUniformInfos()` 提供最基本的反射 - 把复杂的 shader 资产管线留给更高层系统未来扩展 这种设计对原型阶段、测试样例和教学型 API 文档尤其友好,因为调用链短、可见性高。 ## 生命周期 - [OpenGLShader()](Constructor.md) 初始化为空 program - 通过 [Compile](Compile.md)、[CompileFromFile](CompileFromFile.md) 或 [CompileCompute](CompileCompute.md) 创建 program - 通过 [Use](Use.md) 绑定到当前上下文 - 通过 [GetUniformInfos](GetUniformInfos.md) / [GetUniformLocation](GetUniformLocation.md) 查询反射信息 - [Shutdown](Shutdown.md) 删除 program 并清空缓存 ## 当前限制 - 只支持 GLSL 文本编译 - 没有 include、宏预处理、变体缓存或离线编译 - `GetType()` 对图形 program 不是严格可靠的语义来源 - 失败路径的临时对象清理较粗糙 - 路径窄化逻辑不适合复杂 Unicode 文件名 ## 关键方法 - [Compile](Compile.md) - [CompileFromFile](CompileFromFile.md) - [CompileCompute](CompileCompute.md) - [Use](Use.md) - [GetUniformInfos](GetUniformInfos.md) ## 相关文档 - [OpenGLDevice](../OpenGLDevice/OpenGLDevice.md) - [OpenGLPipelineState](../OpenGLPipelineState/OpenGLPipelineState.md) - [OpenGLCommandList](../OpenGLCommandList/OpenGLCommandList.md)