Graphics 使用directX捕获并绘制屏幕截图

Graphics 使用directX捕获并绘制屏幕截图,graphics,directx,screenshot,directx-9,Graphics,Directx,Screenshot,Directx 9,我正试图让DirectX(DX9)抓取桌面的屏幕截图,并立即将其(以更小的尺寸)绘制到我的表单中 我有DirectX的工作能力,该设备是随着一些表面创建的,我可以把它们渲染到屏幕上。我正在使用一个surfacef3surf9\u SS获取桌面屏幕截图 下面是我对变量的声明和初始化 F3D3Surf9_SS : IDirect3DSurface9; //Surface SS F3D3Surf9_A : IDirect3DSurface9; //Surface A F3D3Surf9_B : ID

我正试图让DirectX(DX9)抓取桌面的屏幕截图,并立即将其(以更小的尺寸)绘制到我的表单中

我有DirectX的工作能力,该设备是随着一些表面创建的,我可以把它们渲染到屏幕上。我正在使用一个surface
f3surf9\u SS
获取桌面屏幕截图

下面是我对变量的声明和初始化

F3D3Surf9_SS : IDirect3DSurface9; //Surface SS
F3D3Surf9_A : IDirect3DSurface9;  //Surface A
F3D3Surf9_B : IDirect3DSurface9;  //Surface B

下面是我用来抓取并渲染屏幕截图的代码

FDIrect3DDevice9.BeginScene;

FDirect3DDevice9.Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),0,0);
FDirect3DDevice9.GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, BackBuffer);

FDirect3DDevice9.GetFrontBufferData(0,F3D3Surf9_SS);  //Get the screen shot

FDirect3DDevice9.StretchRect(F3D3Surf9_SS,nil,BackBuffer,nil,D3DTEXF_NONE); //Draw it

FDIrect3DDevice9.EndScene;
FDirect3DDevice9.Present(nil,nil,0,nil);
然而,这不起作用

图像不会被绘制到屏幕上。如果我把表面A或B画到屏幕上,这是可行的,但对表面SS不起作用。但是,我知道Surface SS中有屏幕截图,因为如果我调用
D3DXSaveSurfaceToFile
,我放在硬盘上的结果位图就是一个有效的屏幕截图


关于正确的方法有什么想法吗?

这不起作用的原因是,
F3D3Surf9\u SS
是由D3DPOOL\u SCRATCH在系统内存中声明的,不能像我尝试的那样直接绘制到后缓冲区

因此,我的解决方案是使用
F3D3Surf9_A
曲面,并使用
UpdateSurface
将系统内存中的屏幕截图复制到视频内存中的曲面A中

我唯一需要做的另一个改变是以与屏幕截图相同的格式创建一个表面:
D3DFMT_A8R8G8B8
。还必须确保UpdateSurface中的目标曲面比源曲面大

注:

  • 这是缓慢的,因为我们正在从视频内存读取到系统内存,然后直接返回到视频内存
  • 我的应用程序需要这个,因为我想捕获操作系统和其他应用程序在屏幕上显示的所有内容,但如果您只是担心自己的应用程序,那么还有更好的选择
  • 如果您知道一种不将FrontBufferData放入系统内存的方法(这是我看到它工作的唯一方法),请告诉我
FDIrect3DDevice9.BeginScene;

FDirect3DDevice9.Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),0,0);
FDirect3DDevice9.GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO, BackBuffer);

FDirect3DDevice9.GetFrontBufferData(0,F3D3Surf9_SS);  //Get the screen shot

FDirect3DDevice9.StretchRect(F3D3Surf9_SS,nil,BackBuffer,nil,D3DTEXF_NONE); //Draw it

FDIrect3DDevice9.EndScene;
FDirect3DDevice9.Present(nil,nil,0,nil);