views:

124

answers:

4

I have one window that is drawn to by various objects to create a layered effect (think of a heads up display where one object draws a compass, the other draws the grid lines, another the altimeter reading etc). So, each object has a black memory bitmap that it draws to. When I call that objects Draw function, the memory bitmap is blitted to the application window. The memory bitmaps are all black to begin with and the object draws on it. Black is the transparent color so it is masked off. The result is an overlay effect.

So, I've been using OR as my logical function in the blt() function and it has worked. But, I've noticed that if the previous layer has painted white, then the layer that draws on top of it comes out looking as if it is beneath the previous layer. The white(ish) colors are the only ones where this effect occurs. All other colors are painted correct (that is, the layer looks like it is painted on top of the previous one and so forth). Has anyone seen this phenomenon?

+1  A: 

It's been awhile since I've used the GDI, but I'm assuming you're talking about the BitBlt function, right? What exactly are you ORing together? As I recall BitBlt just takes a source and destination HDC, rectangles and some flags.

Are you ORing the bits of the bitmaps to achieve the overlay effect? That won't work, as the OR operator is both associative and commutative. In other words,

a | b == b | a

and

(a | b) | c == a | (b | c)

which means that the order in which you OR things has no effect on the outcome. You just need to blit each bitmap one at a time in order to get an overlay effect.

If this doesn't help I apologize, I may have completely misinterpreted your question as it has been a few years since I've even looked at the GDI.

Niki Yoshiuchi
+2  A: 

You're using the wrong function for this. Using a BitBlt with a logical OR will work if the pixel you're trying to overwrite happens to be black, but if you combine two non-zero colours with OR, then you'll get strange results. Try using TransparentBlt instead. That function lets you explicitly specify which colour is supposed to be transparent.

Peter Ruderman
A: 

Why bother with BitBlt and OR? Just use AlphaBlend(), which gives you a whole byte of transparency.

Roel
In general, GDI isn't very good about dealing with (or preserving) the alpha channel. If Max wants to use GDI to draw the grid lines, compass, and other overlays, he's going to have to do a lot of work to generate the alpha channel manually.
Adrian McCarthy
A: 

What you want to do requires two blits: one to mask out the portions of the destination bitmap (using pixelwise AND), and then a second one to pixelwise OR the colors from the overlay onto the destination.

Do do this manually, you need to make a monochrome mask from your overlay bitmap, with white in the transparent parts and black in the opaque parts. AND the mask with the destination, then OR the color data from your original overlay.

screen AND mask OR overlay

And if this is for full-screen stuff, you may want to do the composition in an off-screen bitmap to avoid flicker.

Peter Ruderman's suggestion to use TransparentBlt is probably a good one, though I've never tried it myself.

Adrian McCarthy