BitBlt doesn't support transparency as you probably know from color keys in DirectX (note that I don't mean alpha blending!). But it does support different combining modes like logical AND (vbSrcPaint) and OR (vbSrcAnd). We can use these modes to do a little trick but we'll need a mask for each picture to get it working. The mask is some kind of black/white copy of the original picture where white pixels are supposed to be transparent. Don't be scared of this, we will make functions to generate these masks when the program loads later. Since this is a work-around for transparency it's quite slower than solid drawing, in fact it's just half as fast because we need to draw both, the mask and the picture, seperately.
So how can you provide transparency with a simple mask and some drawing modes? Before you continue reading make sure you know about the special cases black and white when using vbSrcPaint and vbSrcAnd, this will help you understanding the technique. If you're not familiar with this you can read about it here:
In this tutorial I'll show you one of 2 ways that solve this problem. Anyways, once you understood the technique it won't be such a problem to implement the one you like better. But first we go on to the theory:
Here you can see the original picture where the white background pixels are supposed to be transparent. The mask is exactly swapped, so every pixel that was white in the original picture became black here and any other pixel became white. Now that was the whole logic behind masks, you see it's quite easy to create them. We'll get back to this later, now let's see what we can use this for:
First of all we draw the mask using vbSrcPaint. As you should know white (255, 255, 255) OR (color) always stays white and black (0, 0, 0) OR (color) always stays (color). We can use this to create a white shape of the original picture as shown in the following illustration:
So that was the half way of work. Now remember the vbSrcPaint (logical AND) mode, where white pixels won't affect the picture at all (because (255, 255, 255) AND (color) always becomes (color) again). The original picture has a white background so we can draw it without affecting this part of the target. On the other hand the target now has a white shape where the picture is going to be so when drawing there this won't affect the original picture. And that's just it! What we get is the transparent picture as we need it:
As I told you before there's another way to reach the same goal with the same performance, just swap the colors (black and white) and also swap the drawing modes (vbSrcPaint and vbSrcAnd). This will do the same job but instead we get a black spare-out where the picture is going to be and the original pictures background won't affect the target picture because black is a special case when using vbSrcPaint.
So the most important difference is the color key which was white in this tutorial. If you prefer black to be transparent try swapping colors and modes as mentioned. Note that I will use white as the transparent color in any tutorial you can find here.
Drawing transparent pictures is tricky when using BitBlt and you need a mask to do the job. Because you need to draw everything twice you should try to use as less transparent objects as possible. In tile engines there are many ways to get around this problem when using a second layer that is transparent however.
The following demo project shows you in 2 steps how the masks are drawn, feel free to play around with it.