2012-10-14 13 views
5

Ho chiesto how to take the screen shot in DirectX e "Use GetFrontBufferData()" ha risposto. Tuttavia, "Questa funzione è molto lenta, di progettazione e non dovrebbe essere utilizzata in alcun percorso critico per le prestazioni" è stata descritta in MSDN.Come ottenere lo screenshot del desktop da back buffer con DirectX

Quando ho chiesto ad altre persone la misura, "Trasferimento dei dati di un back buffer alla memoria di sistema" è stata data risposta. Ma non ero in grado di trovare un metodo concreto.

Questo è un esempio di errore. Per favore fatemi sapere il codice giusto.

#include <stdio.h> 
#include <Windows.h> 
#include <d3d9.h> 
#include <d3dx9tex.h> 

void main() 
{ 
    CoInitialize(NULL); 

    HWND hwnd = GetDesktopWindow(); 

    LPDIRECT3D9 d3d9; 
    D3DDISPLAYMODE ddm; 

    d3d9 = Direct3DCreate9(D3D_SDK_VERSION); 
    d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm); 

    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS)); 
    d3dpp.Windowed = TRUE; 
    d3dpp.SwapEffect = D3DSWAPEFFECT_COPY; 
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 
    d3dpp.BackBufferCount = 1; 
    d3dpp.BackBufferWidth = ddm.Width; 
    d3dpp.BackBufferHeight = ddm.Height; 
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; 
    d3dpp.MultiSampleQuality = 0; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
    d3dpp.hDeviceWindow = hwnd; 
    d3dpp.Flags = D3DPRESENTFLAG_VIDEO; 
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; 

    LPDIRECT3DDEVICE9 dev; 
    d3d9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING ,&d3dpp, &dev); 

    /* Deprecation 
    IDirect3DSurface9* surface = NULL; 
    dev->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL); 
    dev->GetFrontBufferData(0, surface); 
    D3DXSaveSurfaceToFile(L"D:\\test.bmp", D3DXIFF_BMP, surface, NULL, NULL); 
    */ 

    // Transfer the data of a back buffer to the system memory 
    IDirect3DSurface9* surface = NULL; 
    dev->CreateOffscreenPlainSurface(ddm.Width, ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL); 
    LPDIRECT3DSURFACE9 back = NULL; 
    dev->SetRenderTarget(0, surface); 
    dev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &back); 
    dev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,127), 1.0, 0); 
    dev->BeginScene(); 
    dev->StretchRect(surface, NULL, back, NULL, D3DTEXF_NONE); 
    dev->EndScene(); 
    dev->Present(0,0,0,0); 
    D3DXSaveSurfaceToFile(L"D:\\test.bmp", D3DXIFF_BMP, back, NULL, NULL); 


    if(back) back->Release(); 

    dev->Release(); 
    d3d9->Release(); 

    CoUninitialize(); 
} 

risposta

2

Non è possibile ottenere i dati dal back-tampone, la funzione GetBackBuffer recuperare solo un puntatore del buffer di nuovo, non i dati in essa contenuti.

  • Buffer anteriore. Un rettangolo di memoria che viene tradotto dall'adattatore grafico e visualizzato sul monitor. In Direct3D l'applicazione non scrive mai direttamente nel buffer frontale.
  • Buffer posteriore. Un rettangolo di memoria a cui un'applicazione può scrivere direttamente. Il buffer posteriore non viene mai visualizzato direttamente sul monitor.

significa che quello che hai visto sul desktop esiste nel buffer frontale.

Problemi correlati