Each DirectX program contains a memory area called a buffer, which stores the video content related to the program, which is called a back buffer in the program ), some programs have more than one background buffer. There is also a buffer. By default, each program can access the front-end buffer. The front-end buffer saves the desktop-related video content, which is essentially a screen image.
Our program can capture the content of the current screen by accessing the front-end buffer. The underlying optimization mechanism of DirectX ensures that our screen capture efficiency is very high, at least higher than that of GDI.
It is very easy to access the front-end buffer in the DirectX program,IDirect3DDevice9
The interface provides
GetFrontBuffer()
Method, it receives
IDirect3DSurface9
The object pointer is used as a parameter, and the content of the front-end buffer is copied to this
Surface
。
IDirect3DSurfce9
Objects can be used
IDirect3DDevice9::CreateImageSurface()
. Once the screen content is saved to this surface, we can useD3DXSaveSurfaceToFile()
Method to directly Save the content to the disk
bmp
File. The sample code is as follows:
Extern idirect3ddevice9 * g_pd3ddevice;
Void capturescreen ()
{
Idirect3dsurface9 * psurface;
G_pd3ddevice à createimagesurface (screenwidth, screenheight,
D3dfmt_a8r8g8b8, & psurface );
G_pd3ddevice-> getfrontbuffer (psurface );
D3dxsavesurfacetofile ("shorttop.bmp", d3dxiff_bmp, psurface,
Null, null );
Psurface-> release ();
}
Above,g_pd3dDevice
Is an initializedIDirect3DDevice
Object. In this example, the captured image is saved to a file. However, we can use
IDirect3DSurface9::LockRect()
It gives us an execution
surface
Memory pointer, that is, the captured image data. We can copy the data to the memory defined by the program to operate on it. See the following code:
Extern void * pbits;
Extern idirect3ddevice9 * g_pd3ddevice;
Idirect3dsurface9 * psurface;
G_pd3ddevice à createimagesurface (screenwidth, screenheight,
D3dfmt_a8r8g8b8, & psurface );
G_pd3ddevice-> getfrontbuffer (psurface );
D3dlocked_rect lockedrect;
Psurface à lockrect (& lockedrect, null,
D3dlock_no_dirty_update | d3dlock_nosyslock |
D3dlock_readonly )));
For (INT I = 0; I <screenheight; I ++)
{
Memcpy (byte *) pbits + I * screenwidth * bitsperpixel/8,
(Byte *) lockedrect. pbits + I * lockedrect. pitch,
Screenwidth * bitsperpixel/8 );
}
G_psurface-> unlockrect ();
Psurface-> release ();
The above pbits is a void *. please ensure that the Group has enough memory space for it first. Bitsperpixel generally uses a 32-bit color. It also depends on the current configuration of your monitor. Note that the surface width is different from the captured screen width. Because of memory alignment (memory alignment by word is usually at a high access validity rate), the surface may have excess bits at the end of each line to align it to the word boundary.lockedRect.Pitch
It provides the number of bytes between the beginning of two consecutive rows. That is to say, we need to move the pointer backward when reading a row.
Pitch
Byte instead
Width
Bytes. You can use the following code to reverse copy
surface
:
For (INT I = 0; I <screenheight; I ++)
{
Memcpy (byte *) pbits + (screenheight-I-1 )*
Screenwidth * bitsperpixel/8,
(Byte *) lockedrect. pbits + I * lockedrect. pitch,
Screenwidth * bitsperpixel/8 );
}
This is useful for top-down bitmap to bottom-up bitmap.
We can also useIDirect3DSurface9
OfGetDC()
Method acquisition
DirectX surface
Of
GDI
Compatible
DC
And then copy its content to our compatibility
DC
. If you are using
DirectX9
Try it.
Finally, note that:
FrontBuffer
Is a relatively slow operation, the design is so, so it should be avoided in the efficiency-critical program.