BltFast Edge Clipping

Background

Clipping is used in to mark areas where pixels are not to be drawn. A problem when dealing with sprites is displaying them when they are only partially visible at the edge of the screen. Giving BltFast a negative coordinate causes it not to display the sprite rather than partially displaying it, so we have to do some additional checks.

Zest is Best implements a simple clipper but a new program that I am writing requires more control. I couldn't find a function in the DirectX documentation and the standard clipping object does not work with the BltFast function.

I hope that other DirectX programmers find this useful.

Notes

1. This function displays the output on a back buffer called lpDDSBack.
lpDDSBack is defined as LPDIRECTDRAWSURFACE lpDDSBack; and is standard DirectX surface.
2. If source color keys have been set up for transparent blitting, then this can be used by passing bColorKey as true.
3. lpdds is the source surface containing the graphics to be blitted.
4. x and y are the destination coordinates and top, left, width and height define the sprite position for the source buffer. If the sprite is blitted on the edge of the screen then it will be clipped properly.

Code


void clipBltFast2(LPDIRECTDRAWSURFACE lpdds,int x,int y,int top,int left,int w,int h,bool bColorKey)
{
	RECT r;
	bool rightAdjusted=false,bottomAdjusted=false;

	if(x<0)
	{
		r.left=left+abs(x);
		r.right=r.left+(w-abs(x));
		x=0;
		rightAdjusted=true;
	}
	else if(x+w>=width)
	{
		r.left=left;
		r.right=r.left+(width-x);
		rightAdjusted=true;
	}
	else
	{
		r.left=left;
	}

	if(y<0)
	{
		r.top=top+abs(y);
		r.bottom=r.top+(h-abs(y));
		y=0;
		bottomAdjusted=true;
	}
	else if(y+h>=height)
	{
		r.top=top;
		r.bottom=r.top+(height-y);
		bottomAdjusted=true;
	}
	else
	{
		r.top=top;
	}

	if(rightAdjusted==false)
		r.right=r.left+w;
	if(bottomAdjusted==false)
		r.bottom=r.top+h;

	if(bColorKey==true)
		lpDDSBack->BltFast(x,y,lpdds,&r,DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
	else
		lpDDSBack->BltFast(x,y,lpdds,&r,DDBLTFAST_WAIT);
}

Back to index.