我正在尝试让DirectX(DX9)抓取桌面的屏幕截图并立即将其缩小(缩小尺寸)到我的表单。
我让DirectX工作到设备创建的容量以及一些表面,我可以将它们渲染到屏幕。我使用一个表面F3F3Surf9_SS
来获取桌面截图。
这是我对varaibles的声明和初始化
F3D3Surf9_SS : IDirect3DSurface9; //Surface SS
F3D3Surf9_A : IDirect3DSurface9; //Surface A
F3D3Surf9_B : IDirect3DSurface9; //Surface B
...
FDirect3D9.CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,Form1.Handle,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,@D3DPresentParams,
FDirect3DDevice9);
FDirect3DDevice9.CreateOffscreenPlainSurface(1360,768,D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,F3D3Surf9_A,nil);
D3DXLoadSurfaceFromFile(F3D3Surf9_A,nil,nil,'D:\Images\Pillar.bmp',nil,
D3DX_DEFAULT,0,nil);
FDirect3DDevice9.CreateOffscreenPlainSurface(1360,768,D3DFMT_X8R8G8B8,
D3DPOOL_DEFAULT,F3D3Surf9_B,nil);
D3DXLoadSurfaceFromFile(F3D3Surf9_B,nil,nil,'D:\Images\Niagra.bmp',nil,
D3DX_DEFAULT,0,nil);
FDirect3DDevice9.CreateOffscreenPlainSurface(Screen.Width,Screen.Height,D3DFMT_A8R8G8B8,
D3DPOOL_SCRATCH,F3D3Surf9_SS,nil);
这是我用来抓取然后渲染屏幕截图的代码
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绘制到屏幕上,那么它可以工作,但它不适用于Surface SS。但是我知道Surface SS有截图,因为如果我调用D3DXSaveSurfaceToFile
,我放在硬盘上的结果位图就是一个有效的屏幕截图。
有关正确方法的任何想法吗?
答案 0 :(得分:3)
这不起作用的原因是F3D3Surf9_SS
是由D3DPOOL_SCRATCH在系统内存中声明的,并且不能像我试图的那样直接绘制到后台缓冲区。
所以我的解决方案是使用F3D3Surf9_A
曲面并使用UpdateSurface
将系统内存中的屏幕截图复制到视频内存中的曲面A.
我必须做的唯一其他改变就是创建Surface A,其格式与屏幕截图相同:D3DFMT_A8R8G8B8
。还必须确保UpdateSurface中的目标表面大于源表面。
注意: