c++ - 在 DirectX 11 中高效捕获帧
问题描述
我试图捕捉我正在玩的游戏的每一帧。市面上有很多优秀的屏幕捕捉软件,其中一个内置于 Windows 10 中。
但是,出于不同的原因,我需要一种自定义方法。我目前正在使用 DirectX Tool KitsSaveWICTextureToFile()
方法来保存 Present() 生成的每一帧。
https://github.com/microsoft/DirectXTK
对于捕获的每一帧,我想用它的适用编号标记文件名的末尾。ScreenShot_0
通过ScreenShot_n.
该方法SaveWICTextureToFile()
为您保存屏幕截图,如下所示:
DirectX::SaveWICTextureToFile(context, backbufferTex, GUID_ContainerFormatJpeg, L"C:/Users/User Name/Desktop/Images/ScreenShot.JPG");
这不允许您按顺序捕获帧。它只是为每一帧重写同一个文件。不过表演非常流畅。在游戏过程中没有任何滞后。
为了尝试为每一帧编写一个文件,我执行了以下操作:
#include <sstream>
int Frame_Number;
//For each Call to Present() do the following:
//Get Device
ID3D11Device* device;
HRESULT gd = pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&device);
assert(gd == S_OK);
//Get context
ID3D11DeviceContext* context;
device->GetImmediateContext(&context);
//get back buffer
ID3D11Texture2D* backbufferTex;
HRESULT gb = pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2d), (LPVOID*)&backbufferTex);
assert(gb == S_OK);
//Set-up Directory
std::wstringstream Image_Directory;
Image_Directory << L"C:/Users/User Name/Desktop/Images/ScreenShot_" << Frame_Number << L".JPG";
//Capture Frame
REFGUID GUID_ContainerFormatJpeg{ 0x19e4a5aa, 0x5662, 0x4fc5, 0xa0, 0xc0, 0x17, 0x58, 0x2, 0x8e, 0x10, 0x57 };
HRESULT hr = DirectX::SaveWICTextureToFile(context, backbufferTex, GUID_ContainerFormatJpeg, Image_Directory.str().c_str());
assert(hr == S_OK);
Frame_Number = Frame_Number + 1;
这行得通,但是性能不稳定。与以前的方法相比,我不再获得流畅的游戏玩法。有人可以推荐一种更有效的方法吗?
解决方案
如果这是在调试版本中完成的,我怀疑 stringstream 的逻辑会导致问题,我建议使用字符数组和 swprintf。如果您跟踪目录的结束位置,那么只需要写出文件名部分就更好了(您可以更进一步,只需要格式化数字和扩展名)。
推荐阅读
- powershell - 已分配变量时报告警告,但在使用时未使用
- reactjs - 如何在循环 map() 中将 framer-motion 与交叉点观察器一起使用?
- html - 尝试初始化 jQRangeSlider cdn 时未捕获的 TypeError
- firebase - Firebase 离线持久性 - 可以进行前期缓存吗?
- r - 有没有办法根据反应元素更新 url
- javascript - 雪花 Javascript 在数组中的两个元素之间计数
- prometheus - grafana中的因变量
- c - 将 unicode 转义码转换为 unicode char
- python - 如何将数据框的 5 列合并为一长列新数据框?
- flutter - Facebook 调解:我们尚未收到投标请求