Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Help with blender and alpha masking

Credits go to Edgar Reynaldo for helping out!
This thread is locked; no one can reply to it. rss feed Print
Help with blender and alpha masking
Michael Weiss
Member #223
April 2000

I am new to the whole blender thing and have spent many hours trying
to figure out what I though would be a simple task.

I am trying to draw a bitmap onto the backbuffer and blend it with the
backbuffer.

This code from the examples works great:

al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5));
al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR);

But my source bitmap has an alpha channel, and I can't figure out how
to get that respected...no matter how many different combination I try
I always get the zero pixels blended also.

I have tried al_set_separate_blender with many different combinations
and gotten nowhere.

I have read the docuemntation many times, and looked at other explanations
of blending of the web. But I can't seem to make it work.

Here is a simple test program:

#SelectExpand
1// this draws a background of colored squares 2 ALLEGRO_COLOR c[5]; 3 c[0] = al_map_rgb(255, 0, 0); 4 c[1] = al_map_rgb(0, 255, 0); 5 c[2] = al_map_rgb(0, 0, 255); 6 c[3] = al_map_rgb(255, 255, 255); 7 c[4] = al_map_rgb(0, 0, 0); 8 9 al_set_target_backbuffer(display); 10 al_flip_display(); 11 al_clear_to_color(al_map_rgb(0,0,0)); 12 13 int ci = 0; 14 for (int y=0; y<10; y++) 15 for (int x=0; x<10; x++) 16 { 17 al_draw_filled_rectangle(x*20, y*20, x*20+20, y*20+20, c[ci]); 18 if (++ci>2) ci = 0; 19 } 20 21 22 23// this is the bitmap I am drawing 24 sprintf(msg, "Test") ; 25 int sw = strlen(msg) * 8; 26 ALLEGRO_BITMAP *temp = al_create_bitmap(sw, 8); 27 al_set_target_bitmap(temp); 28 al_clear_to_color(al_map_rgb(0,0,0)); 29 al_draw_text(font, ci[3], sw/2, 0, ALLEGRO_ALIGN_CENTRE, msg); 30 al_convert_mask_to_alpha(temp, al_map_rgb(0, 0, 0)); 31 32 33// here is where I have tried just about every blender combination I can think of 34 35 al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5)); 36 al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR); 37 38 39 40// this is where i actually draw it 41 al_set_target_backbuffer(display); 42 al_draw_scaled_rotated_bitmap(temp, sw/2, 4, 88, 48, 4, 4, 0, 0); 43 al_flip_display(); 44 al_destroy_bitmap(temp);

When I don't specify any blender I get a nice masked text over background.

When I try this:
al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0.5));
al_set_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR);

I get a nice blended source and dest, just like what I wanted,
except the alpha is not respected and I get a rectangle around the text.

I tried:
al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 0));
al_set_blend_color(al_map_rgba_f(0.5, 0.5, 0.5, 1));
al_set_blend_color(al_map_rgb_f(0.5, 0.5, 0.5));
but they all made no difference.

I tried:
al_set_blend_color(al_map_rgb_f(0.5, 0.5, 0.5));
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);

al_set_blend_color(al_map_rgb_f(0.5, 0.5, 0.5));
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR, ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_ZERO);

plus many more combinations, but I can never get the alpha mask to work...

Can anyone with more experience with blenders help me?

Do I somehow have to do this with 2 steps?

My overall goal is simply to have a partially transparent bitmap superimposed over
another bitmap (the backbuffer), (kind like a water mark), but I want it masked so the
zero pixels are not blended with the background.

Thanks

Dizzy Egg
Member #10,824
March 2009
avatar

Try:

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);

OR

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);

----------------------------------------------------
Please check out my songs:
https://soundcloud.com/dont-rob-the-machina

Michael Weiss
Member #223
April 2000

Hi Dizzy Egg,

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
- no blending and no alpha mask

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
- no blending, but alpha mask works (same as no blender at all)

I also tried:

al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
- no blending and no alpha mask

al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
- no blending, but alpha mask works

al_set_blend_color(al_map_rgb_f(0.5, 0.5, 0.5));
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
- blending, but no alpha mask

al_set_blend_color(al_map_rgb_f(0.5, 0.5, 0.5));
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
- blending, but no alpha mask

al_set_blend_color(al_map_rgb_f(0.5, 0.5, 0.5));
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_CONST_COLOR, ALLEGRO_CONST_COLOR, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
- blending, but no alpha mask

I want something that has blending and alpha mask...

Does the pixel format have anything to do with it?

temp pixel format:
ALLEGRO_PIXEL_FORMAT_ARGB_8888
backbuffer pixel format:
ALLEGRO_PIXEL_FORMAT_RGB_565

Thanks

Edgar Reynaldo
Member #8,592
May 2007
avatar

NiteHackr
Member #2,229
April 2002
avatar

You need to use al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA); BEFORE you create your display, not afterwards.

Note: the options are just ones I use in my Deluxe Pacman 2 game, yours may differ.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Poppycock. You can change the blender anytime you want, except when drawing is held.

What you just quoted is the pre-multiplied alpha blender, which is the default.

NiteHackr
Member #2,229
April 2002
avatar

I just tested that, you're right, no longer needed. But I needed to add it at one point so I will assume something changed. Good to know anyhow, even with Edgar's usual charming, kind replies.

My only guess would be that it has to do with al_convert_mask_to_alpha(temp, al_map_rgb(0, 0, 0));. It's not a function I have ever used but what mask is it converting? And what alpha is it making it? Is it expecting the bitmap to already have a mask? (awaits another rude response from Edgar)

Edgar Reynaldo
Member #8,592
May 2007
avatar

If I'm being fresh it's because I dislike bad advice. :/

al_convert_mask_to_alpha takes a mask color, compares it to every pixel, and writes zero alpha if it matches.

Michael Weiss
Member #223
April 2000

Thanks Edgar!

your suggestion:

Try al_draw_tinted_bitmap with al_map_rgba_f(0.5,0.5,0.5,0.5).

Did exactly what I was looking for.

I didn't even look at the tinted drawing functions.
If I would have I would have found your exact suggestion as an example.

Thanks again.

Go to: