2.6 KiB
2.6 KiB
OpenGLScreenshot
命名空间: XCEngine::RHI
类型: class
头文件: XCEngine/RHI/OpenGL/OpenGLScreenshot.h
描述: OpenGL 后端的截图工具类,负责从默认帧缓冲或当前 back buffer 纹理读取像素,并保存为 PPM 文件。
概览
OpenGLScreenshot 和 D3D12Screenshot 一样,属于“调试和测试优先”的同步截图工具,而不是完整的产品级截图系统。
它当前支持两条读图路径:
- 如果 swap chain 当前 back buffer 能被当作纹理读取,就临时创建一个
GL_READ_FRAMEBUFFER并从颜色附件读取 - 否则直接从
GL_BACK读默认后备缓冲
随后它会把像素翻转后按 P6 PPM 格式写到磁盘。
设计定位
这个类的目标非常明确:
- 给 RHI 集成测试提供统一截图出口
- 给 OpenGL 示例和调试流程提供最小依赖的抓图工具
- 尽量不引入额外图像编码依赖
因此它的实现风格也很直接:
- 同步
glFinish() - 直接
glReadPixels(...) - 直接
fopen/fwrite
当前实现的真实行为
- Capture 会先
device.MakeContextCurrent() - 像素缓冲按
width * height * 3分配,只读取 RGB - 截图前会调用
glFinish() - 如果 back buffer 纹理存在且
GetState() != ResourceStates::Common,会走临时 FBO 读取路径 - 否则从
GL_BACK读取 - 写文件时会按 OpenGL 常见坐标系差异,把图像做上下翻转
- Shutdown 是空实现,因为对象本身没有持久资源
需要注意的实现细节
- 头文件里声明了私有
SavePPM(...),但当前源码没有实现也没有使用它 - 截图逻辑假定输出是 8-bit RGB,不处理 HDR、浮点格式或压缩格式
- RHI 接口重载内部直接
static_cast到OpenGLDevice*/OpenGLSwapChain*
为什么这样设计
在商业级引擎里,截图系统通常会进一步拆成:
- 异步像素传输
- 编码线程
- PNG/JPG/EXR 等多格式输出
- 调试工具链集成
但在底层 RHI 验证阶段,先保证“结果可抓、问题可定位、依赖够少”更重要。OpenGLScreenshot 正是这类早期实现。
当前限制
- 全程同步,
glFinish()开销明显 - 只输出 PPM
- 没有颜色空间、HDR 或 alpha 处理
- 类型转换依赖调用方保证处在 OpenGL 后端上下文