Get contents of render target into CPU readable memory
-
mercoledì 16 maggio 2012 17:59
I'm struggling to get the contents of my framebuffer into memory for use by the CPU. Has anyone else managed to do this?
Here is my code so far - every call succeeds etc. but the final result is a black + zero alpha texture, which makes me believe I am doing something very wrong.
ID3D11Texture2D* pSurface;
HRESULT hr = m_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), reinterpret_cast< void** >( &pSurface ) );
if( pSurface )
{
const int width = static_cast<int>(m_window->Bounds.Width * m_dpi / 96.0f);
const int height = static_cast<int>(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 =
{
width, height, 1, 1, DXGI_FORMAT_R8G8B8A8_UNORM,
{ 1, 0 }, // DXGI_SAMPLE_DESC
D3D11_USAGE_STAGING,
0, D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE, 0
};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 HEREconst 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 );
}
Tutte le risposte
-
mercoledì 16 maggio 2012 18:05
Fixed with the following:
ID3D11Texture2D* pSurface;
HRESULThr = m_swapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D), reinterpret_cast< void** >( &pSurface ) );
if( pSurface )
{
constintwidth = static_cast<int>(m_window->Bounds.Width * m_dpi / 96.0f);
constintheight = static_cast<int>(m_window->Bounds.Height * m_dpi / 96.0f);
unsignedintsize = width * height;
if( m_captureData )
{
freeFramebufferData( m_captureData );
}
m_captureData =
newunsignedchar[ width * height * 4 ];
ID3D11Texture2D* pNewTexture = NULL;
D3D11_TEXTURE2D_DESCdescription;
pSurface->GetDesc( &description );
description.BindFlags = 0;
description.CPUAccessFlags =
D3D11_CPU_ACCESS_READ| D3D11_CPU_ACCESS_WRITE;
description.Usage =
D3D11_USAGE_STAGING;
HRESULThr = m_d3dDevice->CreateTexture2D( &description, NULL, &pNewTexture );
if( pNewTexture )
{
m_d3dContext->CopyResource( pNewTexture, pSurface );
D3D11_MAPPED_SUBRESOURCEresource;
unsignedintsubresource = D3D11CalcSubresource( 0, 0, 0 );
HRESULThr = m_d3dContext->Map( pNewTexture, subresource, D3D11_MAP_READ_WRITE, 0, &resource );
//resource.pData; // TEXTURE DATA IS HERE
constintpitch = width << 2;
constunsignedchar* source = static_cast< constunsignedchar* >( resource.pData );
unsignedchar* dest = m_captureData;
for( inti = 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 );
}
- Contrassegnato come risposta Semi Essessi mercoledì 16 maggio 2012 18:05
-
giovedì 17 maggio 2012 07:21Moderatore
Thanks for sharing the solution.
Best regards,
Jesse
Jesse Jiang [MSFT]
MSDN Community Support | Feedback to us

