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