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: 11/15/01.