Transparent GDI Sprite Library
Use basic Windows GDI functions to draw fast-moving transparent sprites
This VB library aims to make it simple to add fast, animated graphics using transparent sprites, something which is either missing or dismally slow using VB's standard methods. The source code provides a complete screen saver, and a simpler (and somewhat smaller) sample which animates a large number of asteroids around a non-firing, invunerable spaceship. These demonstrate how the sprite library can be quickly incorporated into an application.
Transparent bitmaps are not only used for games or screen savers; Windows uses them extensively for icons and also the ImageList common control has built in functions specifically for creating transparent bitmaps.
Drawing Bitmaps Transparently
There are three methods to draw a bitmap transparently. The first is to write custom drawing code which loops through all the bits in the bitmap and only draws pixels which aren't the background colour of the bitmap. The second is to use the TransparentBlt API call added to Windows 98/2000 and later operating systems. Both of these methods are fine, but if you need code which runs under every OS then another technique is needed.
The third method is to take advantage of the API BitBlt method. The grunt of BitBlt is implemented in the graphics card driver and is usually extremely quick (even under Windows 95). To make use of it to draw transparently, we need to process the bitmap to create what are know as the Sprite and the Mask bitmaps to draw with.
Creating Sprites and Masks
To create a sprite and a mask you need to do three things:
Having done this, the bitmap can be drawn transparently in two BitBlt operations:
Thus the bitmap can be drawn transparently. The following series of pictures shows the process in detail:
Creating Sprite and Mask from the Bitmap
ORing the Mask onto the Background
ANDing the Sprite to get the Transparency Effect
That demonstrates the way to achieve transparent sprites, but you can do more if you want truly flicker-free drawing.
Achieving Flicker-Free Animation
When moving sprites, it becomes necessary to redraw the previous background under the sprite before moving it to its new position (unless you want to obtain a trail effect). This makes flicker a problem - generally you have to draw an area where the new sprite will be with the background and then draw the sprite in its new position over the top. This almost always results in flickering.
To prevent this occuring, you can create a buffer (normally called a Stage) to make all the changes in, maintaining the screen with the sprite in place for as long as possible. When it comes to redrawing the sprite in its new position, you can then make a minimum of calls to transfer the new position and erase the old position simultaneously. You don't get any flicker this way because all the updates you do are draw an image in which the new sprite is in place.
The code loop for this type of animation with my sprite library is always as follows:
The loop is shown pictorially below:
Restore the background behind the sprites into the stage
This step is repeating for all other sprites in the scene:
Move the sprite to its new position in the stage
At this point the previous background area behind the sprite is stored so it can be restored next time round the loop. Note the background could be modified at this point if we wanted, provided you remember which rectangles have been updated so they can be copied in at the last point in the loop.
Draw The Sprite Transparently
Repeat for all sprites in the screen onto the stage:
Finally, Copy All Changes to the Screen
Ideally you can minimise the number of changes which need to be drawn. In this case the changed sprite and the background can be drawn together:
Check it Out
That's the principle of the sprite library. The code shows how to achieve all the above effects using GDI calls. The mask creation routine in the code is quite neat and can easily be pulled out and used elsewhere. This technique makes mask creation very quick: to do it, you first create a monochrome DC (using CreateCompatibleDC with a hDC of 0) and then select a monochrome bitmap into it. Use SetBkColor to set the back 'colour' of the monochrome DC to the colour you want to be the mask colour, and then when you BitBlt any bitmap into it, Windows automatically maps all pixels of this colour to black. You just need to invert it to get the mask.
To Install BlobSaver
If you want to try BlobSaver as a screen saver, just copy BlobSaver.scr, all the associated gif files and backdrop.jpg into your Windows directory. You can modify the images used to display the backdrop, or the sprite images with your own files by editing the registry entries which the screen saver creates under
The sprite files should split into 7x5 images to display correctly.