Search code examples
savedirect3ddirect3d11rendertarget

how to save renderTarget array to file in the direct3D11?


I want to save the renderTarget Array as an image file for debugging.

But failed to save.

Do you know how to save a renderTarget Array as a file?

Below is my code.

    ID3D11RenderTargetView** ppRTVs;

    ...
    //rendering
    ...

    ScratchImage ScratchImage;
    ID3D11Resource* Resource;
    wchar_t fileName[256];

    ppRTVs[0]->GetResource(&Resource);
    HRESULT hr = CaptureTexture(pd3dDevice, pd3dImmediateContext, Resource, ScratchImage);

    if (FAILED(hr)) {
        assert(FALSE);
    }

    for (int i = 0; i < ScratchImage.GetMetadata().arraySize; i++) {

        const Image* singleTexture = ScratchImage.GetImage(0, i, 0);

        swprintf_s(fileName, L"./Screenshots/city/color/texture_%zu.tga", i);
        hr = SaveToTGAFile(*singleTexture, TGA_FLAGS_NONE, fileName); //failed 

        if (FAILED(hr)) { 
            assert(FALSE);
        }
    }

ScratchImage.m_methadata info

width = 1920

height = 1080

depth = 1

arrSize = 4

mipLevel = 11

format = DXGI_FORMAT_R32G32B32A32_FLOAT (2)

dimension = TEX_DIMENSION_TEXTURE2D (3)

I need help.

Thanks.


Solution

  • I think it fails because TGA files don’t support your DXGI_FORMAT_R32G32B32A32_FLOAT format. According to Microsoft, SaveToTGAFile only supports RGBA8, BGRA5551, R8 and A8 pixel formats.

    You have two choices.

    1. Save into another format which does support FP32 pixels. Pretty sure the DDS format supports them, you can write DDS files by calling another function from the same library, SaveDDSTextureToFile. Then search for an image viewer which can view DDS files in that format.

    2. Convert pixels to RGBA8 somehow, then save to TGA. Unfortunately, converting pixel format is relatively tricky, you either need to write and dispatch a compute shader, or write vertex+pixel shaders and render a full-screen triangle. Besides, this step will loose some information in the texture.

    P.S. It’s rarely a good idea to use raw COM pointers like your ID3D11Resource* Resource, too easy to leak memory. Use CComPtr<ID3D11Resource> instead, will release the object automatically in destructor.