我正在为DX11游戏编写插件,我需要截取屏幕截图并将其保存到文件中。我找到了一些使用函数D3DX11SaveTextureToFile
的代码片段,但我无法让它工作。这是我到目前为止所做的:(为简单起见,错误检查和不相关的代码被删除)
void screenshot(IDXGISwapChain *pSwapChain)
{
ID3D11Device *pDevice;
pSwapChain->GetDevice(__uuidof(ID3D11Device), reinterpret_cast<void **>(&pDevice));
ID3D11DeviceContext *pContext;
pDevice->GetImmediateContext(&pContext);
ID3D11Texture2D *pBackBuffer;
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void **>(&pBackBuffer));
D3D11_TEXTURE2D_DESC txtDesc;
pBackBuffer->GetDesc(&txtDesc);
txtDesc.Usage = D3D11_USAGE_STAGING;
txtDesc.BindFlags = 0;
txtDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
// txtDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM
ID3D11Texture2D *pBackBufferStaging;
pDevice->CreateTexture2D(&txtDesc, nullptr, &pBackBufferStaging);
pContext->CopyResource(pBackBufferStaging, pBackBuffer);
HRESULT hr = D3DX11SaveTextureToFileA(pContext, pBackBufferStaging, D3DX11_IFF_PNG, "E:\\screenshot.png");
// hr == E_FAIL
pBackBufferStaging->Release();
pBackBuffer->Release();
}
我遇到了E_FAIL
错误,经过一些研究后,D3DX11SaveTextureToFile
似乎不支持我假设的游戏使用的纹理格式DXGI_FORMAT_B8G8R8A8_UNORM
。如果我手动将格式设置为类似DXGI_FORMAT_R8G8B8A8_UNORM
的函数,则函数将成功,但我将获得黑色图像。我认为CopyResource
要求源和目标具有相同的格式。
我知道有DirectXTK库,但我坚持使用VS2013,如果我正确读取它的自述文件,DirectXTK似乎不支持它。
修改
DirectXTK / DirectXTex完美运行。
答案 0 :(得分:1)
使用 DirectX工具包中的ScreenGrab模块是您最好的选择。它可以写出DDS
文件或WIC支持的各种格式,包括JPG
:
using namespace DirectX;
using namespace Microsoft::WRL;
ComPtr<ID3D11Texture2D> backBuffer;
HRESULT hr = swapChain->GetBuffer( 0,
__uuidof( ID3D11Texture2D ),
reinterpret_cast<LPVOID*>( backBuffer.GetAddressOf() ) );
if ( SUCCEEDED(hr) )
{
hr = SaveWICTextureToFile( immContext.Get(), backBuffer.Get(),
GUID_ContainerFormatJpeg, L"SCREENSHOT.JPG" );
}
DX::ThrowIfFailed(hr);
我最近从我的GitHub项目中删除了对Visual Studio 2013的支持 - 有关详细信息,请参阅this blog post。如果您无法升级,则可以使用稍早于2018年4月release的版本,该版本支持VS 2013.
D3DX9,D3DX10和D3DX11通常每{... 3}}都与DirectX SDK一起弃用。