Transparent bitmap
CodeStepper

How to create transparent bitmap in Allegro5?
I have try something like this:

#SelectExpand
1int main( void ) 2#include <iostream> 3#include <vector> 4 5#include <allegro5/allegro.h> 6#include <allegro5/allegro_primitives.h> 7#include <allegro5/allegro_font.h> 8#include <allegro5/allegro_ttf.h> 9 10int main( void ) 11{ 12 al_init( ); 13 al_init_primitives_addon( ); 14 15 al_install_mouse( ); 16 al_install_keyboard( ); 17 18 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 ); 19 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue( ); 20 ALLEGRO_TIMER *timer = al_create_timer( 1.0 / 60 ); 21 22 bool run = true; 23 bool redraw = true; 24 bool response = true; 25 26 al_register_event_source( queue, al_get_keyboard_event_source( ) ); 27 al_register_event_source( queue, al_get_mouse_event_source( ) ); 28 al_register_event_source( queue, al_get_timer_event_source( timer ) ); 29 al_register_event_source( queue, al_get_display_event_source( display ) ); 30 31 // Creating bitmap 32 ALLEGRO_BITMAP *bitmap[5]; 33 34 for( int A = 0; A < 5; ++A ) 35 { 36 bitmap[A] = al_create_bitmap( 200, 35 ); 37 al_set_target_bitmap( bitmap[A] ); 38 39 al_clear_to_color( al_map_rgba( 0, 0, 0, 0 ) ); 40 al_draw_filled_rectangle( 0, 0, 200, 35, al_map_rgba( 60, 80, 100, 0 ) ); 41 42 al_set_target_bitmap( al_get_backbuffer( display ) ); 43 } 44 45 al_start_timer( timer ); 46 while( run ) 47 { 48 49 ALLEGRO_EVENT event; 50 al_wait_for_event( queue, &event ); 51 52 switch( event.type ) 53 { 54 case ALLEGRO_EVENT_TIMER: redraw = true; break; 55 case ALLEGRO_EVENT_DISPLAY_CLOSE: run = false; break; 56 case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: response = false; break; 57 case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: response = true; break; 58 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 59 60 break; 61 case ALLEGRO_EVENT_MOUSE_BUTTON_UP: 62 63 break; 64 65 case ALLEGRO_EVENT_MOUSE_AXES: 66 67 break; 68 } 69 70 71 if( redraw && al_is_event_queue_empty( queue ) ) 72 { 73 redraw = false; 74 al_clear_to_color( al_map_rgb( 100, 100, 100 ) ); 75 76 // Drawing bitmap 77 al_draw_filled_rectangle( 20, 0, 90, 600, al_map_rgb( 25, 25, 25 ) ); 78 for( int A = 0; A < 5; ++A ) 79 { 80 al_draw_bitmap( bitmap[A], 50, A * 50 + 50, 0 ); 81 } 82 83 al_flip_display( ); 84 } 85 } 86 87 al_destroy_display( display ); 88 al_destroy_event_queue( queue ); 89 al_destroy_timer( timer ); 90 91 for( int A = 0; A < 5; ++A ) al_destroy_bitmap( bitmap[A] ); 92 return 0; 93}

And it doesn't work correct :/

Elias

You can just draw any bitmap transparently like this:

al_draw_tinted_bitmap(bitmap, al_map_rgba_f(a, a, a, a), x, y, 0);

Where a is a value from 0 (transparent) to 1 (solid).

CodeStepper

Thank you for your reply.

In fact, this works, but this is not what i mean...
I want to get this effect ( in comment, in real this not working :/ )

#SelectExpand
1#include <iostream> 2#include <vector> 3 4#include <allegro5/allegro.h> 5#include <allegro5/allegro_primitives.h> 6#include <allegro5/allegro_font.h> 7#include <allegro5/allegro_ttf.h> 8 9int main( void ) 10{ 11 12 al_init( ); 13 al_init_primitives_addon( ); 14 15 al_install_mouse( ); 16 al_install_keyboard( ); 17 18 19 ALLEGRO_DISPLAY *display = al_create_display( 800, 600 ); 20 ALLEGRO_EVENT_QUEUE *queue = al_create_event_queue( ); 21 ALLEGRO_TIMER *timer = al_create_timer( 1.0 / 60 ); 22 23 24 bool run = true; 25 bool redraw = true; 26 bool response = true; 27 28 29 al_register_event_source( queue, al_get_keyboard_event_source( ) ); 30 al_register_event_source( queue, al_get_mouse_event_source( ) ); 31 al_register_event_source( queue, al_get_timer_event_source( timer ) ); 32 al_register_event_source( queue, al_get_display_event_source( display ) ); 33 34 ALLEGRO_BITMAP *bitmap[5]; 35 36 for( int A = 0; A < 5; ++A ) 37 { 38 bitmap[A] = al_create_bitmap( 200, 35 ); 39 al_set_target_bitmap( bitmap[A] ); 40 41 al_clear_to_color( al_map_rgba( 0, 0, 0, 0 ) ); 42 43 // This must have solid color 44 al_draw_rectangle( 1, 1, 198, 33, al_map_rgb( 100, 80, 60 ), 2 ); 45 46 // And this must be almost transparent 47 al_draw_filled_rectangle( 2, 2, 150, 20, al_map_rgba( 255, 255, 255, 20 ) ); 48 49 al_set_target_bitmap( al_get_backbuffer( display ) ); 50 } 51 52 53 al_start_timer( timer ); 54 while( run ) 55 { 56 57 ALLEGRO_EVENT event; 58 al_wait_for_event( queue, &event ); 59 60 61 switch( event.type ) 62 { 63 64 case ALLEGRO_EVENT_TIMER: redraw = true; break; 65 66 case ALLEGRO_EVENT_DISPLAY_CLOSE: run = false; break; 67 case ALLEGRO_EVENT_DISPLAY_SWITCH_OUT: response = false; break; 68 case ALLEGRO_EVENT_DISPLAY_SWITCH_IN: response = true; break; 69 case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN: 70 71 break; 72 case ALLEGRO_EVENT_MOUSE_BUTTON_UP: 73 74 break; 75 76 case ALLEGRO_EVENT_MOUSE_AXES: 77 78 break; 79 } 80 81 82 if( redraw && al_is_event_queue_empty( queue ) ) 83 { 84 redraw = false; 85 al_clear_to_color( al_map_rgb( 100, 100, 100 ) ); 86 87 al_draw_filled_rectangle( 20, 0, 90, 600, al_map_rgb( 25, 25, 25 ) ); 88 for( int A = 0; A < 5; ++A ) 89 { 90 // And drawing partly transparent bitmapt 91 al_draw_bitmap( bitmap[A], 50, A * 50 + 50, 0 ); 92 } 93 94 al_flip_display( ); 95 } 96 } 97 98 99 al_destroy_display( display ); 100 al_destroy_event_queue( queue ); 101 al_destroy_timer( timer ); 102 for( int A = 0; A < 5; ++A ) al_destroy_bitmap( bitmap[A] ); 103 104 return 0; 105}

weapon_S

That should work. Are you sure it isn't working? (Grey slightly tinted white doesn't really stand out :P) You could try higher alpha values to be sure.
Else you could explicitly set the blending mode. Or you could change the pre-multiplied option of your bitmaps. Neither of that should be necessary; I can see no mistakes, and what you have there should work.

CodeStepper

No, it is not working, but i found solution:

// And this must be almost transparent
float alpha = 0.1f;
al_draw_filled_rectangle( 2, 2, 150, 20, al_map_rgba( 255*alpha, 255*alpha, 255*alpha, alpha ) );

http://www.allegro.cc/forums/thread/606149

It's strange...

Neil Walker

Why do you have to alter your RGB to get the alpha/transparency channel working? seems daft to me. I'd have thought white with a alpha of 0.5 would be semi-transparent white?

weapon_S

Ah. I take my words back.
I expected the primitive drawing operations to actually respect the pre-multiplied-alpha flag. Have you read the linked topic in your link?
Pre-multiplied color blending is enabled by default. This mode expects the colors to be "multiplied" by the alpha value of the pixel. (Which you are doing now.)
You can get a "normal" mode by doing al_set_new_bitmap_flags(ALLEGRO_NO_PREMULTIPLIED_ALPHA) before creating bitmaps, and setting the blending mode like this: al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA).
(The main difference is the blending mode, which is al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA) when using "pre-multiplied-alpha", which is default.)
BTW I personally would set the blending mode to "replace", when creating/preparing semi-transparent bitmaps with al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO). That's because (obviously >_>') I have no idea of how the primitives treat the alpha value exactly, unless using this blending mode.

CodeStepper

Thanks, its working now normal when I add this before creating bitmaps:

al_set_new_bitmap_flags( ALLEGRO_NO_PREMULTIPLIED_ALPHA );
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

:)

Elias

You should look at ex_premul_alpha before doing that though, in many cases it's a bad idea.

CodeStepper

By keyword ex_premul_alpha ( because i don't know what is this :P ) i found only this post:
http://www.allegro.cc/forums/thread/608171
And i see, why this option is bad...

So, this method is better in your opinion?:

float alpha = 0.1f;
al_draw_filled_rectangle( 2, 2, 150, 20, al_map_rgba( 255*alpha, 255*alpha, 255*alpha, alpha ) );

Thread #610925. Printed from Allegro.cc