如何使用 DX11 进行屏幕截图?
How do I take a screenshot with DX11?
我正在为 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 工作完美。
使用 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 for some details. If you can't upgrade, you can use a slightly older April 2018 release 支持 VS 2013。
D3DX9, D3DX10, and D3DX11 are all deprecated along with the DirectX SDK generally per MSDN.
我正在为 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 工作完美。
使用 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 for some details. If you can't upgrade, you can use a slightly older April 2018 release 支持 VS 2013。
D3DX9, D3DX10, and D3DX11 are all deprecated along with the DirectX SDK generally per MSDN.