How do I "cut out" text from bitmap, so background would show through after this:
render.ClearBackbuffer( Color(255,0,0) ); render.DrawImage( mask, 0, 0 );
So far, I can't find the right blending mode. I always end up with the WHOLE glyph being transparent, not just where text is. So the end result looks like a set of red rectangles of varying height and width.
I thought that
render.SetBlender( ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ZERO, ALLEGRO_ADD, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ZERO );
should do it with text being drawn with color (0,0,0,255), but it does not work.
I haven't used the blenders before, but I think this will do what you want :
al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO); al_set_target_bitmap(overlay); al_clear_to_color(al_map_rgb(255,0,0,255)); al_draw_text(/*...*/ , al_map_rgb(0,0,0,0)); al_set_target_bitmap(al_get_backbuffer(display)); al_draw_bitmap(overlay , 0 , 0 , 0); al_flip_display();
Short version, the only way I know to do "cut out" text is by drawing the text to a texture and processing each pixel, inverting the alpha. You might be able to do it with 5.1's new blenders.
Otherwise, this is the code I use to mask images:
static ALLEGRO_BITMAP *create_masked_image(ALLEGRO_BITMAP *top_image, ALLEGRO_BITMAP *bottom_image); creates an image by combining the opacity of both images, retaining the pixel colors of the bottom (top?) image. draw_masked_image() does not create a new bitmap, but performs the same operation to a given destination bitmap.
However, this will not enable you to "cut out" text from a solid texture. For that you will need to have 5.1, which includes more ALLEGRO_INVERSE_* operators.
Nevermind, my way doesn't work. I've tried just about every blender I can think of, but the problem is that ALLEGRO_INVERSE_ALPHA writes the zero alpha values of the glyph background onto the destination, so unless you want a black mask, I don't know what you can do.
The only way I can think of doing it is to write your own custom shader that ignores the glyphs background zero alpha values and writes zero alpha values for the text pixels that have non-zero alpha. (Use ALLEGRO_TTF_MONOCHROME when loading the font).
If you're using Open GL, you could use the stencil buffer.
I thought Allegro 5.0 could do subtractive blending, isn't that essentially what needs to be done here?
I thought Allegro 5.0 could do subtractive blending, isn't that essentially what needs to be done here?
I think you're on to something there :
If you make src ALLEGRO_ONE and use ALLEGRO_DEST_MINUS_SRC, then you have
ALLEGRO_DEST_MINUS_SRC : r = dr * dst - sr g = dg * dst - sg b = db * dst - sb a = da * dst - sa
Clear black source pixels (like the glyph background) would have no effect. If you gave them an alpha of 255 and left them black, then they would essentially write zero alpha pixels, which is what you want.
This test program shows how to make a masked overlay using this method :
It creates a pure white bitmap with pixel values of 255,255,255,255 and then writes pixel values of 0,0,0,255 onto it using al_set_blender(ALLEGRO_DEST_MINUS_SRC , ALLEGRO_ONE , ALLEGRO_ONE);. It then clears the backbuffer to 0,0,0,0 and draws the white overlay onto it using non-premultiplied alpha. The black background then shows through where you have drawn the text :
{"name":"605172","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/c\/3cb230666cd77b71b1c0314fdcabbd14.png","w":812,"h":632,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/c\/3cb230666cd77b71b1c0314fdcabbd14"}
Thanks! That works perfectly! It's a pity I still get confused by blending modes. I shouldn't be