Rendering Full Screen Images From Textures

Home | Up | Search | X-Zone News | Services | Book Support | Links | Feedback | Smalltalk MT | The Scrapyard | FAQ | Technical Articles

 

 

Below is the original source code of the CSplash class written for the DirectX 8.0 SDK.

Return to Article

CSplash::CSplash(LPCSTR bmpName,LPDIRECT3DDEVICE8 lpDevice,int scr_width,int scr_height)
{
	// clear the surface count and surface pointer array
	surfCount=0;
	ZeroMemory(surf,sizeof(surf));
	// open image file
	HANDLE file=CreateFile(bmpName,
			   GENERIC_READ,
			   0,
			   NULL,
			   OPEN_EXISTING,
			   FILE_FLAG_SEQUENTIAL_SCAN,
			   NULL);
	if (file==INVALID_HANDLE_VALUE)
		return;
	// get file size and allocate buffer for image
	DWORD imageSize=GetFileSize(file,NULL);
	BYTE *imageBuf=new BYTE[imageSize];
	if (!imageBuf) {
		CloseHandle(file);
		return;
	}
	// read in image data
	DWORD bytesRead;
	ReadFile(file,imageBuf,imageSize,&bytesRead,NULL);
	CloseHandle(file);
	
	// load it
	D3DXIMAGE_INFO info;
	if (FAILED(D3DXCreateTextureFromFileInMemoryEx(lpDevice, imageBuf,bytesRead ,
								 D3DX_DEFAULT,D3DX_DEFAULT,1,0,
								 D3DFMT_UNKNOWN,D3DPOOL_MANAGED,
								 D3DX_FILTER_NONE,D3DX_FILTER_NONE,
								 0,&info,NULL,&surf[0]))) {
				delete imageBuf;
				return;
	}
	if (info.Width<=g_devCaps.MaxTextureWidth&&info.Height<=g_devCaps.MaxTextureHeight) {
		surfCount=1;
		delete imageBuf;
		surfRects[0].left=0;
		surfRects[0].right=scr_width;
		surfRects[0].top=0;
		surfRects[0].bottom=scr_height;
		return;
	}
	// get the texture format
	D3DSURFACE_DESC surfDesc;
	surf[0]->GetLevelDesc(0,&surfDesc);
	// release the texture
	surf[0]->Release();

	// create a surface to hold the entire file
	LPDIRECT3DSURFACE8 tempSurf;
	if (FAILED(lpDevice->CreateImageSurface(surfDesc.Width,surfDesc.Height,
						surfDesc.Format,&tempSurf))) {
		delete imageBuf;
		return;
	}
	// load the image into the surface
	D3DXLoadSurfaceFromFileInMemory(tempSurf,NULL,NULL,imageBuf,bytesRead,
					NULL,D3DX_FILTER_NONE,0,NULL);

	// de-allocate the image buffer
	delete imageBuf;

	// determine number of textures needed on each axis
	int numX=surfDesc.Width/g_devCaps.MaxTextureWidth;
	int numY=surfDesc.Height/g_devCaps.MaxTextureHeight;
	// loop through the rows
	for (int i=0;i<numY;i++) {

		// loop through the columns
		for (int j=0;j<numX;j++) {

			// create the texture
			if (FAILED(D3DXCreateTexture(lpDevice,
							  g_devCaps.MaxTextureWidth,
							  g_devCaps.MaxTextureHeight,
							  1,
							  0,
							  surfDesc.Format,
							  D3DPOOL_MANAGED,
							  &surf[surfCount]))) {
				tempSurf->Release();
				return;
			}
			// generate the screen target rectangle
			surfRects[surfCount].left=j*scr_width/numX;
			surfRects[surfCount].right=(j+1)*scr_width/numX-1;
			surfRects[surfCount].top=i*scr_height/numY;
			surfRects[surfCount].bottom=(i+1)*scr_height/numY-1;

			// generate the image source rectangle
			RECT src;
			src.left=j*surfDesc.Width/numX;
			src.right=(j+1)*surfDesc.Width/numX;
			src.top=i*surfDesc.Height/numY;
			src.bottom=(i+1)*surfDesc.Height/numY;
			// get texture surface
			LPDIRECT3DSURFACE8 targSurf;
			surf[surfCount]->GetSurfaceLevel(0,&targSurf);
			// copy region to texture surface
			D3DXLoadSurfaceFromSurface(targSurf,NULL,NULL,tempSurf,NULL,&src,D3DX_FILTER_NONE,0);

			// release texture surface
			targSurf->Release();

			// increment the surface counter
			surfCount++;
		}
	}

	// release the temp surface
	tempSurf->Release();
}

CSplash::~CSplash()
{
	// clear the image surfaces
	for (int i=0;i<surfCount;i++)
		SafeRelease(surf[i]);
}

BOOL CSplash::draw(LPDIRECT3DDEVICE8 lpDevice)
{
	D3DTLVERTEX rect[4];
 
	// loop through the surfaces
	for (int i=0;i<surfCount;i++) {
		// set the texture
		SetCurrentTexture(surf[i]);
	
		// set the target rectangle
		float l=surfRects[i].left-0.5f;
		float r=surfRects[i].right+0.5f;
		float t=surfRects[i].top-0.5f;
		float b=surfRects[i].bottom+0.5f;
		rect[0]=D3DTLVERTEX(D3DXVECTOR3(l,b,0.1f),1.0f,col,0.0f,1.0f);
		rect[1]=D3DTLVERTEX(D3DXVECTOR3(l,t,0.1f),1.0f,col,0.0f,0.0f);
		rect[2]=D3DTLVERTEX(D3DXVECTOR3(r,b,0.1f),1.0f,col,1.0f,1.0f);
		rect[3]=D3DTLVERTEX(D3DXVECTOR3(r,t,0.1f),1.0f,col,1.0f,0.0f);
		// draw the rectangle
		lpDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, rect, sizeof(D3DTLVERTEX));
	}
}

This site, created by DirectX MVP Robert Dunlop and aided by the work of other volunteers, provides a free on-line resource for DirectX programmers.

Special thanks to WWW.MVPS.ORG, for providing a permanent home for this site.

Visitors Since 1/1/2000: Hit Counter
Last updated: 07/26/05.