Take screenshot of DirectX full-screen application

Viewed 36321

This boggles me. DirectX bypasses everything and talks directly to the device driver, thus GDI and other usual methods won't work - unless Aero is disabled (or unavailable), all that appears is a black rectangle at the top left of the screen. I have tried what other have suggested on several forums, using DirectX to get the back buffer and save it, but I get the same result:

device->GetFrontBufferData(0, surface); D3DXSaveSurfaceToFile("fileName", D3DXIFF_BMP, surface, NULL, NULL);

Is there any way to get a screenshot of another full-screen DirectX application when Aero is enabled?

7 Answers

Have a look at Detours.

Using Detours, you can instrument calls like Direct3DCreate9, IDirect3D9::CreateDevice and IDirect3D9::Present in which you perform the operations necessary to setup and then do a frame capture.

This is a snippet of the code I used as test just now, it seems to work.

width and height are the size of the SCREEN in windowed mode not the windows. So for me they are set to 1280 x 1024 and not the window I'm rendering to's size.

You'd need to replace mEngine->getDevice() with some way of getting your IDirect3DDevice9 too. I just inserted this code into a random d3d app I had to make it easier to test. But I can confirm that it captures both the output from that app AND another d3d app running at the same time.

Oh I've assumed this is D3D9 as you didn't say, I'm not sure about d3d10 or 11

IDirect3DSurface9* surface;
mEngine->getDevice()->CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8,     D3DPOOL_SCRATCH, &surface, NULL);
mEngine->getDevice()->GetFrontBufferData(0, surface);
D3DXSaveSurfaceToFile("c:\\tmp\\output.jpg", D3DXIFF_JPG, surface, NULL, NULL);
surface->Release();

There is an open source program like fraps: taksi but looks outdated

Related