DirectX 11 framebuffer capture (C++, no Win32 or D3DX)

前端 未结 3 1863
一个人的身影
一个人的身影 2020-12-08 12:30

I would like to capture the contents of my front or back buffer using DirectX 11 into an array of bytes which I can then use as a texture or as a source for creating a file.

3条回答
  •  鱼传尺愫
    2020-12-08 12:59

    So. A little more experimentation revealed the "problem". By getting the description of the framebuffer texture and using that as the basis to create the new texture the problem was resolved...

    ID3D11Texture2D* pSurface;
    HRESULT hr = m_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &pSurface ) );
    if( pSurface )
    {
        const int width = static_cast(m_window->Bounds.Width * m_dpi / 96.0f);
        const int height = static_cast(m_window->Bounds.Height * m_dpi / 96.0f);
        unsigned int size = width * height;
        if( m_captureData )
        {
            freeFramebufferData( m_captureData );
        }
        m_captureData = new unsigned char[ width * height * 4 ];
    
        ID3D11Texture2D* pNewTexture = NULL;
    
        D3D11_TEXTURE2D_DESC description;
        pSurface->GetDesc( &description );
        description.BindFlags = 0;
        description.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
        description.Usage = D3D11_USAGE_STAGING;
    
        HRESULT hr = m_d3dDevice->CreateTexture2D( &description, NULL, &pNewTexture );
        if( pNewTexture )
        {
            m_d3dContext->CopyResource( pNewTexture, pSurface );
            D3D11_MAPPED_SUBRESOURCE resource;
            unsigned int subresource = D3D11CalcSubresource( 0, 0, 0 );
            HRESULT hr = m_d3dContext->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );
            //resource.pData; // TEXTURE DATA IS HERE
    
            const int pitch = width << 2;
            const unsigned char* source = static_cast< const unsigned char* >( resource.pData );
            unsigned char* dest = m_captureData;
            for( int i = 0; i < height; ++i )
            {
                memcpy( dest, source, width * 4 );
                source += pitch;
                dest += pitch;
            }
    
            m_captureSize = size;
            m_captureWidth = width;
            m_captureHeight = height;
    
            return;
        }
    
        freeFramebufferData( m_captureData );
    }
    

提交回复
热议问题