2.5 KiB
2.5 KiB
OpenGLScreenshot::Capture
bool Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) override;
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename);
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename,
int width,
int height);
作用
从 OpenGL 当前呈现目标读取像素并写成 PPM 文件。
核心流程
三个公开重载最终都汇合到同一套同步读回流程:
- 切换当前上下文
device.MakeContextCurrent() - 分配 RGB 像素缓冲
- 调用
glFinish() - 配置
GL_PACK_*像素打包状态 - 根据当前 back buffer 情况选择读取路径
- 调用
glReadPixels(...) - 以
P6PPM 格式写盘,并在写盘时做上下翻转
重载 1: RHI 入口
bool Capture(RHIDevice* device, RHISwapChain* swapChain, const char* filename) override;
当前实现行为
- 直接把
device转成OpenGLDevice* - 直接把
swapChain转成OpenGLSwapChain* - 然后转发到 OpenGL 包装对象重载
注意事项
- 没有运行时类型检查
- 没有空指针保护
重载 2: 使用 swap chain 尺寸
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename);
当前实现行为
- 直接使用
swapChain.GetWidth()和swapChain.GetHeight() - 然后调用完整尺寸重载
重载 3: 显式尺寸
static bool Capture(OpenGLDevice& device,
OpenGLSwapChain& swapChain,
const char* filename,
int width,
int height);
当前实现行为
- 分配
width * height * 3字节的 RGB 缓冲 - 如果内存分配失败,记录错误日志并返回
false - 判断当前 back buffer 是否可以走纹理读取路径:
backBufferTexture != nullptrbackBufferTexture->GetID() != 0backBufferTexture->GetState() != ResourceStates::Common
- 纹理路径下会创建临时
GL_READ_FRAMEBUFFER,把纹理挂到GL_COLOR_ATTACHMENT0后读取 - 否则直接
glReadBuffer(GL_BACK)读取默认后备缓冲 - 打开输出文件失败时返回
false - 写文件时从最后一行开始写,实现图像垂直翻转
输出格式
- 固定输出
P6PPM - 只写 RGB
- 不写 alpha
- 不压缩