How to use off screen surfaces to load an image resource in Directx

In this study, we will use the off screen surface in DirectX to load an image resource into the main window.

Firstly, the image loading we use is done using GDIplus.

Below, we will specifically introduce how to use an off screen surface.

Firstly, a data structure DDSURFACEDESC2 ddsd needs to be used;

Set the identification bits of this data structure to.

Ddsd. ddsCaps. dwCaps= DDSAPS_ OFFSCREENPLAIN.

The specific code is as follows:

	//create an off screen surface 
	ZeroMemory(&ddsd, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
	ddsd.dwWidth =1024	;
	ddsd.dwHeight = 768;
	if (FAILED(g_Lpdd->CreateSurface(&ddsd, &g_BmpSurface, NULL))){
		return;
	}
	//Bitmap* bmp = Bitmap::FromFile(_T("./test.png"));
	Image *image = Image::FromFile(_T("./test.png"));
	HDC dc;
	g_BmpSurface->GetDC(&dc);
	Graphics graphics(dc);
	graphics.Clear(Color(255, 0, 0, 0));
		graphics.DrawImage(image,50, 50);
	//Pen p(Color(255, 255, 0, 0));
	//graphics.DrawLine(&p, 0, 0, 100, 100);
	
	g_BmpSurface->ReleaseDC(dc);
	//delete bmp;
	delete image;
The above completes the loading of data for a basic off screen surface

So how do we use it ?

It's time to load on the back surface.

Firstly, the interface used.

//DirectX Main Surface LPDICTDRAWSURFACE7 g_ MainSurface
//DirectX Back Surface LPDICTDRAWSURFACE7 g_ BackSurface
//Off screen surface
LPDICTDRAWSURFACE7 g_ BmpSurface.

Here is the specific code used:

	RECT destRc, sourceRc;
	SetRect(&destRc, 0, 0, 791, 543);
	SetRect(&sourceRc, 50, 50, 791, 543);
	HRESULT hr;
	hr = g_BackSurface->Blt(NULL, g_BmpSurface, &sourceRc, DDBLT_WAIT, NULL);
	if (hr == DDERR_SURFACELOST){
		Restore();
	}
	//main surface flipping 
	hr = g_MainSurface->Flip(g_BackSurface, NULL);
	if (hr == DDERR_SURFACELOST){
		Restore();
	}

Code to prevent page loss.

void Restore()
{
	g_BmpSurface->Restore();
	g_BackSurface->Restore();
	g_MainSurface->Restore();
	//Bitmap* bmp = Bitmap::FromFile(_T("./test.png"));
	Image *image = Image::FromFile(_T("./test.png"));
	HDC dc;
	g_BmpSurface->GetDC(&dc);
	Graphics graphics(dc);
	graphics.Clear(Color(255, 0, 0, 0));
	graphics.DrawImage(image, 50, 50);
	//Pen p(Color(255, 255, 0, 0));
	//graphics.DrawLine(&p, 0, 0, 100, 100);
	g_BmpSurface->ReleaseDC(dc);
	//delete bmp;
	delete image;
}
There are several things to pay attention to during use:

1. The size of the off screen surface must be set to the full screen size, otherwise a flashing state may occur.

2. The higher the refresh rate of the display mode, the less likely it is for the screen to flash.

3. The setting of the image resource area and destination area is correct in order to display the image in the correct position.