【问题标题】:Capture and draw a screenshot using directX使用 directX 捕获和绘制屏幕截图
【发布时间】:2011-04-01 19:59:50
【问题描述】:

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

我的 DirectX 可以满足设备与几个表面一起创建的能力,我可以将它们渲染到屏幕上。我正在使用一个表面F3F3Surf9_SS 来获取桌面截图。

这是我的变量声明和初始化

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,我放在硬盘上的结果位图是一个有效的屏幕截图。

对正确的方法有什么想法吗?

【问题讨论】:

    标签: graphics directx screenshot directx-9


    【解决方案1】:

    这不起作用的原因是 F3D3Surf9_SS 是由 D3DPOOL_SCRATCH 在系统内存中声明的,并且无法像我尝试的那样直接绘制到后台缓冲区。

    所以我的解决方案是使用F3D3Surf9_A表面并使用UpdateSurface将系统内存中的屏幕截图复制到显存中的表面A。

    为了让它工作,我必须做的唯一其他更改是创建与屏幕截图表面相同格式的表面 A:D3DFMT_A8R8G8B8。还必须确保 UpdateSurface 中的目标表面大于源表面。

    注意:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      相关资源
      最近更新 更多