【问题标题】:How do I take a screenshot with DX11?如何使用 DX11 截屏?
【发布时间】:2018-06-14 05:28:14
【问题描述】:

我正在为 DX11 游戏编写插件,我需要截取屏幕截图并将其保存到文件中。我发现了一些使用函数D3DX11SaveTextureToFile 的代码sn-ps,但我就是无法让它工作。到目前为止,这是我所拥有的:(为简单起见,删除了错误检查和不相关的代码)

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 完美运行。

【问题讨论】:

    标签: c++ directx directx-11


    【解决方案1】:

    使用DirectX Tool Kit 中的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。

    根据MSDN,D3DX9、D3DX10 和 D3DX11 连同 DirectX SDK 均已弃用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-11
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多