2012-10-14 45 views
5

Tôi đã yêu cầu how to take the screen shot in DirectX và "Sử dụng GetFrontBufferData()" đã được trả lời. Tuy nhiên, "Chức năng này rất chậm, theo thiết kế, và không nên được sử dụng trong bất kỳ đường dẫn quan trọng nào" được mô tả tại MSDN.Cách lấy ảnh chụp màn hình của màn hình nền từ bộ đệm sau bằng DirectX

Khi tôi hỏi người khác biện pháp, "Chuyển dữ liệu của bộ đệm sau vào bộ nhớ hệ thống" đã được trả lời. Nhưng, tôi không thể tìm ra phương pháp cụ thể.

Đây là ví dụ về lỗi. Vui lòng cho tôi biết mã đúng.

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

Trả lời

2

Bạn không thể lấy dữ liệu từ bộ đệm ngược, hàm GetBackBuffer chỉ truy xuất con trỏ của bộ đệm phía sau chứ không phải dữ liệu trong đó.

  • Bộ đệm mặt trước. Hình chữ nhật của bộ nhớ được dịch bởi bộ điều hợp đồ họa và được hiển thị trên màn hình. Trong Direct3D, ứng dụng không bao giờ ghi trực tiếp vào bộ đệm trước.
  • Bộ đệm sau. Hình chữ nhật của bộ nhớ mà một ứng dụng có thể ghi trực tiếp vào. Bộ đệm sau không bao giờ được hiển thị trực tiếp trên màn hình.

điều đó có nghĩa là những gì bạn thấy trên máy tính để bàn tồn tại trong bộ đệm trước.

Các vấn đề liên quan