The new vbAccelerator Site - more VB and .NET Code and Controls
Source Code
4 vbMedia &nbsp


 NOTE: this code has been superceded by the version at the new site.



&nbsp

Transparent Sprite Library

[vbAccelerator Screen Saver]

Download the Blob Screen Saver Sample (267kb)

This sample requires the SSubTmr.DLL component because it includes an implementation of the COMCTL32.DLL Slider control. Make sure you have loaded and registered this before trying the BlobSaver project.

Download the Simple Transparent Sprites Demo (36kb)

Download the Transparent Sprite Classes Only (9kb)

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. To get quicker or smoother than this, you'll need to use Direct X (article coming soon!)

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. In this article I will describe the principle of the sprite library and how to draw any bitmap transparently.

Drawing Bitmaps Transparently
There are basically two 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. Whilst this is the most flexible method, it is considerably slower under Windows than the method described here.

The other method is to take advantage of the BitBlt method. The grunt of the BitBlt method is implemented in the graphics card driver and is usually extremely quick under Windows 95. To make use of this method, we need to process the bitmap and create a mask and a sprite bitmap as follows:

  1. Choose a colour in the bitmap you want to be transparent.
  2. Create a monochrome bitmap which is black where the bitmap should be transparent and white otherwise (this is called the mask).
  3. Change the bitmap colour to white in the transparent area (this becomes the sprite).
Having done this, the bitmap can be drawn transparently in two BitBlt operations:
  1. Firstly, OR the Mask bitmap with the background. This sets the background pixels to white where the sprite should be drawn (where the mask is white) but leaves them unaffected otherwise. (since 0 or 0 = 0, 1 or 0 = 1, 0 or 1 = 1, 1 or 1= 1).
  2. Secondly, AND the Sprite bitmap over the area you've just ORed the mask into. Where the Sprite is white (the transparent area) there is no effect - it leaves the background pixels unaffected, but where the background has been coloured white by the mask the bitmap itself is drawn. (since 0 and 0 = 0, 1 and 0 = 0, 0 and 1 = 1, 1 and 1 = 1)
Thus the bitmap can be drawn transparently. The following series of pictures shows the process in detail:

Creating Sprite and Mask from the Bitmap:
&nbsp
&nbsp


Original Sprite
Original
&nbsp



Mask
Mask
&nbsp


Sprite
Sprite
&nbsp

&nbsp
&nbsp
ORing the Mask onto the Background:
&nbsp
&nbsp


Sprite Background
Background
&nbsp


Mask
Mask
&nbsp



Mask ORed with Background
OR Mask onto Background
&nbsp

&nbsp
&nbsp
ANDing the Sprite to Get the Transparent Effect:
&nbsp
&nbsp


Mask ORed with Background
Background ORed with Mask
&nbsp


Sprite
Sprite
&nbsp



Transparent Sprite
AND Sprite
&nbsp

&nbsp
&nbsp


That covers how to transparently draw a sprite, but you need to do more to gain flicker-free moving sprites.

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 (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:

  1. Restore the background behind the sprite into the stage.
  2. Move the sprite to its new position, and store the background behind the sprite. The stored background can be used to restore the background next time round the loop.
  3. Draw the sprite in its new position on the stage using the transparent draw method.
  4. Finally, copy the old and the new sprite positions from the stage to the screen. Here if the old sprite position is close to the new sprite position, we can minimise the amount of drawing by drawing both at the same time.
The loop is shown pictorially below:

Initial position:
&nbsp
&nbsp


Screen
Screen
&nbsp


Stage
Stage
&nbsp

&nbsp
&nbsp
Restore the background behind the sprite into the stage (repeating for all other sprites in the scene):
&nbsp
&nbsp


Screen
Screen
&nbsp


Stage
Stage
&nbsp

&nbsp
&nbsp
Move the sprite to its new position in the stage, and store the area behind the sprite so we can restore it next time around the loop (repeating for all sprites in the scene). Note that at this stage we could change the background if we wanted, provided you remember which rectangles have been updated so they can be copied in the last part of the loop:
&nbsp
&nbsp


Screen
Screen
&nbsp


Stage
Stage
&nbsp

&nbsp
&nbsp
Draw the sprite transparently in the new position (repeating for all sprites in the scene):
&nbsp
&nbsp


Screen
Screen
&nbsp


Stage
Stage
&nbsp

&nbsp
&nbsp
Finally, copy the changes from the stage to the screen, minimising the number of drawing steps (here both the background and the sprite are copied as one rectangle):
&nbsp
&nbsp


Screen
Screen
&nbsp


Stage
Stage
&nbsp

&nbsp
&nbsp


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 ultra 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 install BlobSaver as a screen saver, just copy BlobSaver.scr, all the 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 HKEY_CURRENT_USER\Software\vbaccelerator\Blob Saver. The sprite files should split into 7x5 images to display correctly.

&nbsp
&nbsp

Back to top
Back to Source Code Overview


&nbsp
 

About  Contribute  Send Feedback  Privacy

Copyright © 1998-1999, Steve McMahon ( steve@vbaccelerator.com). All Rights Reserved.
Last updated: 24 June 1998