ATTENTION READERS! Lucky's VB Gaming Site is no longer active. For updated game programming information and tutorials, please visit The Game Programming Wiki!
Special Effects
Too lazy to write a C, C++, or ASM DLL to do your special effects dirty work? Put
blitter Raster Operations (ROPs) to work for you! Maximal results
with minimal effort, that's my motto ;)
There are a number of different ROP constants available to us in VB:
vbSrcPaint - ORs the source and destination image data, giving a
pseudo-alphablending effect.
vbSrcAnd - ANDs the source and destination image data, giving a
pseudo-gamma effect.
vbSrcInvert - XORs the source and destination image data.
vbSrcErase - Inverts the destination image data then ANDs with
the source image data.
vbSrcCopy - Copy the source image data directly onto the destination,
replacing it completely.
vbDstInvert - Inverts the destination image data, and ignores the
source image data completely.
vbNotSrcCopy - Inverts the source image data and copies directly onto
the destination, replacing it completely.
vbNotSrcErase - ORs the source and destination image data and
inverts the result.
Now, we have two methods at our disposal for implementing these various ROPs.
We can use the API BitBlt function, or we can use the DirectX BltFx function.
BltFx will ONLY work if the user's video card supports the ROP in hardware.
BltFx WILL fail otherwise! Where BltFx fails however, BitBlt API can take over;
The BitBlt API will never fail since all operations are carried out via software!
(Important Speed Consideration: When using BltFx, it is ideal to place
surfaces in Video Memory as they can be accessed there most quickly by the video
card's blitter. When using BitBlt API on the other hand, it is ideal to place
surfaces in System Memory, otherwise the data must be fetched from video
memory, modified, and then sent back to video memory. Inefficient!)
It would be nice to know for certain whether the user's video card can support
a specific ROP in hardware or not, and I have written a simple function to do
just that:
Private Function TestROP(ByRef surfBack As DirectDrawSurface7, lngROP As Long) As Boolean
Dim objBltFx As DDBLTFX
Dim rectTemp As RECT
Dim surfTemp As DirectDrawSurface7
Dim udtDDSD As DDSURFACEDESC2
'Create a small temporary surface
udtDDSD.lFlags = DDSD_HEIGHT Or DDSD_WIDTH
udtDDSD.lHeight = 1
udtDDSD.lWidth = 1
Set surfTemp = mdd.CreateSurface(udtDDSD)
'Set the BltFx ROP code
objBltFx.lROP = lngROP
'Our source and dest rectangle
rectTemp.Right = 1
rectTemp.Bottom = 1
'Test the BltFx capability
If surfBack.BltFx(rectTemp, surfTemp, rectTemp, DDBLT_ROP Or DDBLT_WAIT, objBltFx) <> 0 Then
TestROP = False
Else
TestROP = True
End If
End Function
Simply pass this function a reference to your current backbuffer and the ROP constant you're
interested in and it will inform you of the user's hardware capabilities. It does this by
performing a sample BltFx blit and examining the error code returned.
Now that we know if our desired ROP is supported, we can go ahead and perform our blit!
If the ROP is supported, we can use BltFx, like so:
objBltFx is of the DDBLTFX type, and must be loaded with the ROP we wish to
perform (here stored in lngROP). Once we have our DDBLTFX type filled,
we can call the backbuffer's BltFx method, passing our source and dest rectangles, our
desired surface, a few constants (DDBLT_ROP and DDBLT_WAIT) and our objBltFx.
The constant DDBLT_ROP is required, informing BltFx that we wish to use the
lROP member of the DDBLTFX structure.
If we're forced to use the BitBlt API, it can be handled in this fashion:
First we need to acquire the source (surface to be blitted) and destination (backbuffer) DCs.
Once we have them, we feed this data into the BitBlt call, along with our sprite dimensions and
the ROP we desire (lngROP). Afterward we MUST release the DCs, lest we freeze the computer
So there you have it! A few magic little functions and you can employ nifty raster operations in
your games and programs. Download the source to see all of the different
ROPs in action.