2012-10-14 18 views
5

Zapytałem how to take the screen shot in DirectX i odpowiedź "Użyj GetFrontBufferData()". Jednak "Ta funkcja jest bardzo powolna, z założenia zaprojektowana i nie powinna być używana w żadnej ścieżce krytycznej dla wydajności" została opisana pod adresem MSDN.Jak uzyskać zrzut ekranu pulpitu z bufora tylnego z DirectX

Kiedy zapytałem innych osób, odpowiedź została przesłana: "Przenieś dane bufora wstecznego do pamięci systemowej". Ale nie byłem w stanie znaleźć konkretnej metody.

To jest przykład awarii. Daj mi znać odpowiedni kod.

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

Odpowiedz

2

Nie można uzyskać dane z powrotem buforu tylko funkcja GetBackBuffer odzyskać wskaźnik z tylnym buforze, a nie danych w nim.

  • Bufor przedni. Prostokąt pamięci tłumaczony przez kartę graficzną i wyświetlany na monitorze. W Direct3D aplikacja nigdy nie zapisuje bezpośrednio do bufora przedniego.
  • Back Buffer. Prostokąt z pamięcią, do której aplikacja może bezpośrednio pisać. Bufor wsteczny nigdy nie jest bezpośrednio wyświetlany na monitorze.

Oznacza to, że to, co widziało się na pulpicie, znajduje się w przednim buforze.