-
Notifications
You must be signed in to change notification settings - Fork 409
ScreenGrab
A Direct3D 12 2D texture save routine for generating a "screenshot" from a render target texture. There is a function that will dump the 2D texture to a .DDS
file, and another that will write using WIC (BMP
, JPEG
, PNG
, TIFF
, GIF
, JPEG-XR / HD Photo, or other WIC supported file container).
These writers do not support array textures, 1D textures, 3D volume textures, or cubemaps. Mipmaps are also ignored. For those scenarios, use the DirectXTex library functionality. The ScreenGrab module is really designed to make a quick and light-weight solution for capturing screenshots at runtime.
MSAA textures are resolved before being written.
#include <ScreenGrab.h>
The library assumes that the client code will have already called CoInitialize
, CoInitializeEx
, or Windows::Foundation::Initialize
as needed by the application before calling any Windows Imaging Component functionality.
For a Universal Windows Platform (UWP) app, the Windows Runtime and COM is initialized by the C/C++ Run-Time. For a classic Windows desktop application you have to do this explicitly:
#if (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)
Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
// error
#else
HRESULT hr = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
if (FAILED(hr))
// error
#endif
The library assumes that the client code will have already called CoInitialize
, CoInitializeEx
, or Windows::Foundation::Initialize
as needed by the application before calling any Windows Imaging Component functionality.
For a Universal Windows Platform (UWP) app, the Windows Runtime and COM is initialized by the C/C++ Run-Time. For a classic Windows desktop application you have to do this explicitly:
#if (_WIN32_WINNT >= 0x0A00 /*_WIN32_WINNT_WIN10*/)
Microsoft::WRL::Wrappers::RoInitializeWrapper initialize(RO_INIT_MULTITHREADED);
if (FAILED(initialize))
// error
#else
HRESULT hr = CoInitializeEx(nullptr, COINITBASE_MULTITHREADED);
if (FAILED(hr))
// error
#endif
Saves a texture to a DDS
file on disk. It performs no format conversions, but will try to favor writing legacy .DDS
files when possible for improved tool support.
HRESULT SaveDDSTextureToFile(
ID3D12CommandQueue* pCommandQueue,
ID3D12Resource* pSource,
const wchar_t* fileName,
D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET);
Saves a texture to a WIC-supported bitmap file on disk. The caller provides the desired WIC container format via guidContainerFormat and can optionally specify a desired WIC pixel format via targetFormat (which will result in E_FAIL
if the requested pixel format is not supported by the WIC codec). If no WIC pixel format GUID is provided as the targetFormat parameter, it will default to a non-alpha format since 'screenshots' usually ignore the alpha channel in render targets.
HRESULT SaveWICTextureToFile(
ID3D12CommandQueue* pCommandQ,
ID3D12Resource* pSource,
REFGUID guidContainerFormat,
const wchar_t* fileName,
D3D12_RESOURCE_STATES beforeState = D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATES afterState = D3D12_RESOURCE_STATE_RENDER_TARGET,
const GUID* targetFormat = nullptr,
std::function<void __cdecl(IPropertyBag2*)> setCustomProps = nullptr);
m_screenshot = m_deviceResources->GetRenderTarget();
m_deviceResources->Present();
if (m_screenshot)
{
DX::ThrowIfFailed(
SaveDDSTextureToFile(m_deviceResources->GetCommandQueue(), m_screenshot.Get(),
L"screenshot.dds",
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT)
);
DX::ThrowIfFailed(
SaveWICTextureToFile(m_deviceResources->GetCommandQueue(), m_screenshot.Get(),
GUID_ContainerFormatJpeg, L"screenshot.jpg",
D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_PRESENT)
);
}
The pSource
resource must be put into the COPY_SOURCE
state before calling these functions, which is why it takes a before and after state.
This function is blocking as it waits for a fence for the copy to finish. Be sure that you've submitted the command list for drawing the render target to the same command-queue that you use for the screengrab.
-
JPEG-XR / HD Photo supports nearly all WIC pixel formats including floating-point for both encoding and decoding.
-
TIFF can contain floating-point data (128bpp or 96bpp), but the WIC built-in codec can only decode such images. It always converts floating-point data to unorm when encoding.
-
Paletted WIC formats are not supported for writing by the
SaveWICTextureToFile
function.
Since WIC2 is available on Windows 10, it is always used by DirectX Tool Kit for DirectX 12.
All content and source code for this package are subject to the terms of the MIT License.
This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.
- Universal Windows Platform apps
- Windows desktop apps
- Windows 11
- Windows 10
- Xbox One
- Xbox Series X|S
- x86
- x64
- ARM64
- Visual Studio 2022
- Visual Studio 2019 (16.11)
- clang/LLVM v12 - v18
- MinGW 12.2, 13.2
- CMake 3.20