2012-10-14 19 views
5

Ich fragte how to take the screen shot in DirectX und "GetFrontBufferData() verwenden" wurde beantwortet. "Diese Funktion ist jedoch sehr langsam, von Entwurf und sollte nicht in irgendeinem leistungskritischen Pfad verwendet werden" wurde unter MSDN beschrieben.Wie bekomme ich den Screenshot des Desktops von Backbuffer mit DirectX

Als ich andere Personen fragte, wurde die Maßnahme "Transfer der Daten eines Rückpuffers in den Systemspeicher" beantwortet. Aber ich konnte keine konkrete Methode finden.

Dies ist ein Beispiel für einen Fehler. Bitte lassen Sie mich den richtigen Code wissen.

#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(); 
} 

Antwort

2

Sie können die Daten aus Back-Puffer erhalten, die Funktion GetBackBuffer nur einen Zeiger des hinteren Puffer abrufen, die Daten nicht in ihm.

  • Frontpuffer. Ein Rechteck des Speichers, der durch die Grafikkarte und auf dem Monitor übersetzt. In Direct3D schreibt eine Anwendung nie direkt in den Front-Puffer.
  • Back Buffer. Ein Rechteck des Speichers, in den eine Anwendung direkt schreiben kann. Der Backbuffer wird niemals direkt auf dem Monitor angezeigt.

das bedeutet, was Sie auf dem Desktop sah existiert in Front-Puffer.