如何使用DirectX从后台缓冲区获取桌面的屏幕截图

如何使用DirectX从后台缓冲区获取桌面的屏幕截图,directx,screenshot,desktop,capture,directx-9,Directx,Screenshot,Desktop,Capture,Directx 9,我问了一下,回答是“使用GetFrontBufferData()”。但是,“根据设计,此功能非常慢,不应在任何性能关键路径中使用”在中描述 当我向其他人询问这项措施时,“将后缓冲区的数据传输到系统内存”得到了回答。但是,我没有找到一个具体的方法 这是一个失败的例子。请告诉我正确的代码 #include <stdio.h> #include <Windows.h> #include <d3d9.h> #include <d3dx9tex.h> vo

我问了一下,回答是“使用GetFrontBufferData()”。但是,“根据设计,此功能非常慢,不应在任何性能关键路径中使用”在中描述

当我向其他人询问这项措施时,“将后缓冲区的数据传输到系统内存”得到了回答。但是,我没有找到一个具体的方法

这是一个失败的例子。请告诉我正确的代码

#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();
}
#包括
#包括
#包括
#包括
void main()
{
共初始化(空);
HWND HWND=GetDesktopWindow();
LPDIRECT3D9 d3d9;
D3D显示模式ddm;
d3d9=Direct3DCreate9(D3D_SDK_版本);
d3d9->GetAdapterDisplayMode(D3DAAPTER_默认值和ddm);
D3D当前参数d3dpp;
零内存(&d3dpp,sizeof(D3DPRESENT_参数));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=d3dswapeeffect\u拷贝;
d3dpp.BackBufferFormat=D3DFMT_未知;
d3dpp.BackBufferCount=1;
d3dpp.BackBufferWidth=ddm.Width;
d3dpp.BackBufferHeight=ddm.Height;
d3dpp.MultiSampleType=D3DMULTISAMPLE\u无;
d3dpp.MultiSampleQuality=0;
d3dpp.EnableAutoDepthStencil=TRUE;
d3dpp.AutoDepthStencilFormat=D3DFMT_D16;
d3dpp.hDeviceWindow=hwnd;
d3dpp.Flags=D3DPRESENTFLAG_视频;
d3dpp.FullScreen\u RefreshRateInHz=D3DPRESENT\u RATE\u默认值;
d3dpp.PresentationInterval=D3DPPresent\u INTERVAL\u默认值;
LPDIRECT3DDEVICE9开发;
d3d9->CreateDevice(D3DADAPTER_默认值、D3DDEVTYPE_HAL、hwnd、D3DCREATE_软件、垂直处理、d3dpp和开发);
/*贬低
IDirect3DSurface9*surface=NULL;
dev->CreateOffscreenPlainSurface(ddm.Width、ddm.Height、D3DFMT_A8R8G8B8、D3DPOOL_SYSTEMMEM和surface,NULL);
dev->GetFrontBufferData(0,表面);
D3DXSaveSurfaceToFile(L“D:\\test.bmp”,D3DXIFF\U bmp,表面,NULL,NULL);
*/
//将后缓冲区的数据传输到系统内存
IDirect3DSurface9*surface=NULL;
dev->CreateOffscreenPlainSurface(ddm.Width、ddm.Height、D3DFMT_A8R8G8B8、D3DPOOL_SCRATCH和surface,NULL);
LPDIRECT3DSURFACE9 back=NULL;
dev->SetRenderTarget(0,曲面);
dev->GetBackBuffer(0,0,D3DBACKBUFFER\u TYPE\u MONO,&back);
开发->清除(0,空,D3DCLEAR_目标,D3DCOLOR_XRGB(0,0127),1.0,0);
dev->BeginScene();
dev->StretchRect(表面、空、背面、空、D3DTEXF_无);
dev->EndScene();
dev->Present(0,0,0,0);
D3DXSaveSurfaceToFile(L“D:\\test.bmp”,D3DXIFF\u bmp,back,NULL,NULL);
如果(返回)返回->释放();
dev->Release();
d3d9->Release();
coninitialize();
}

您无法从后台缓冲区获取数据,函数GetBackBuffer仅检索后台缓冲区的指针,而不是其中的数据

  • 前缓冲器。由 图形适配器,并显示在监视器上。在Direct3D中 应用程序从不直接写入前端缓冲区
  • 后缓冲区。A. 应用程序可以直接写入的内存矩形。这个 后台缓冲区从不直接显示在监视器上
这意味着您在桌面上看到的内容存在于前缓冲区中