Blitting Images onto Backgrounds

The logical meaning of the various operations probably doesn’t give you much idea of their practical use. Here are some step-by-step examples of how to put one image onto another. I can’t illustrate the color steps on a black-and-white page, so you’ll have to start Bit Blast and follow along. Begin by following the steps listed below.

  1. Left-click picture 1 (the face) to make it the source, and right-click picture 4 (the circle) to make it the destination. Now click the Mask button to create a mask of the face in picture 4. The mask consists entirely of black pixels (0 bits) and white pixels (1 bits). Later I’ll explain how to create a mask with code.

  2. Left-click picture 4, and right-click picture 3 (the marble background). Select MergePaint and click the Blit button (or double-click Merge-Paint in the list box) to transfer the mask to the marble. The result is a white face on the marble background. MergePaint first changed all the black (masked) bits to white, thus reversing the mask. Then it used an OR operation to combine the source bits with the destination bits. The marble bits that were on, combined with the black outside bits, stay on; and the marble bits that were off, combined with masked black bits, stay off. But all the masked white bits stay on, regardless of their status in the marble. MergePaint is a one-step way of doing a DstInvert operation on the mask and then doing a SrcPaint operation from the mask to the marble.

  3. Left-click picture 1, and do a SrcAnd from the face to the marble. This puts the face on the marble. That’s essentially how we’re going to create transparent pictures and animate them.

You might expect that an ROP could do all this in one operation. No such luck. The closest you can get is to SrcAnd the face directly onto the marble. This creates a mixture of the face and the marble, which is an interesting effect but isn’t how you write video games.

Click Clear Destination to restore the marble, and then try this exercise:

  1. Mask the face over the circle (the picture I usually use as a work area).

  2. SrcInvert the face onto the marble.

  3. SrcAnd the mask onto the marble.

  4. SrcInvert the face onto the marble.

    A Short Digression on Patterns

    Some ROPs—vbMergeCopy, vbPatCopy, vbPatInvert, and vbPatPaint—work on what SDK documentation calls the pattern when it discusses ROPs. When discussing everything else, the document refers to this as the brush. Every device context has a brush, and you can change the brush by selecting a new brush into the device context.

    In Visual Basic, you change the brush by setting the FillPattern and FillColor properties. Few Visual Basic programmers bother to do this. The default transparent black brush is suitable for most purposes. If you use the default brush, you can ignore all the ROPs that deal with patterns (as I will for the rest of this book).

    But first try blitting to and from various boxes with MergeCopy, PatPaint, Pat­Invert, and PatCopy. You’ll see that the leftmost three boxes in Bit Blast have invisible background patterns (set with the FillStyle property) that merge with or overwrite the pictures.

Different process, same result—with some bizarre color combinations along the way. Before you try to figure out why, imagine what your screen would look like if you used this technique to move a transparent picture around the screen: you’d see an ugly color change for every update. We’ll follow this path no further because it temporarily changes the whole background.

One more example:

  1. Mask the face onto the circle.

  2. DstInvert the face. It doesn’t matter what the source is because it will be ignored.

  3. NotSrcErase the mask onto the face. (You can also do this in two steps: SrcPaint the mask onto the face, and then DstInvert the face.) The face now has an inverted background.

  4. SrcAnd the mask onto the marble, which masks out the shape of the image on the background.

  5. SrcInvert the face onto the marble. Alternatively, you can SrcPaint the face onto the marble.

This might seem strange, but actually it is the same technique used in the CALL­DLLS sample program provided with Visual Basic—except that the developers cheated. They created the same inverted image you get from steps 1, 2, and 3 in a bitmap editor. They also created a mask like the one you’ll create in the next section with a bitmap editor. Then with steps 4 and 5, they combined these two images on the background. The key difference between this third example and the first example you tried is that the first technique uses the original picture (white background) and a reversed (white) mask, whereas this one uses a reversed picture (black background) and a normal (black) mask.

Windows also uses this technique to display icons. In fact, if you dump the data in an icon (using the memory techniques discussed in Chapter 8), you’ll see that the icon image displayed on the screen doesn’t even exist internally. An icon consists of a monochrome mask (called the XOR mask) with all the opaque bits black and an image with an inverted background (called the AND mask). If you study the source code of the old IconWorks sample, you can see how it’s done. (IconWorks isn’t provided with Visual Basic, but this book’s companion CD provides it.) We’ll do this in the rest of the chapter, defining a class that creates the XOR and AND masks only once, when initialized, and then uses them to put a transparent image on the screen as often as you want. In other words, we’ll define icons of any size.

But before you can use any of these techniques, you must create masks.