Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » custom bitmap with alpha channel

This thread is locked; no one can reply to it. rss feed Print
custom bitmap with alpha channel
wracker
Member #15,173
June 2013
avatar

Afternoon everyone,

I was wondering if there's any way I could create a custom bitmap with alpha channel

#SelectExpand
1bitmap = al_create_bitmap(30, 30); 2al_set_target_bitmap(bitmap); 3al_clear_to_color(al_map_rgb(255,255,255)); 4.... 5al_draw_tinted_bitmap(bitmap, al_map_rgba(0, 0, 0, 0.5), X, Y, 0);

I'm sure that I'm either not creating or drawing the bitmap correctly, so I could really use some advice.

Thanks in advance,
Alex

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

wracker
Member #15,173
June 2013
avatar

tried that , it's not working :/

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

wracker
Member #15,173
June 2013
avatar

I'm actually not loading any image. I can make a image transparent but in this case I'm trying to make a premade bitmap with transparecy.

Below you can see the whole code ..

tried setting the alpha value to 150 but I couldn't see any change..

#SelectExpand
1#include <stdio.h> 2#include <allegro5/allegro.h> 3 4const float FPS = 60; 5const int SCREEN_W = 640; 6const int SCREEN_H = 480; 7const int BOUNCER_SIZE = 32; 8 9int main(int argc, char **argv){ 10 ALLEGRO_DISPLAY *display = NULL; 11 ALLEGRO_EVENT_QUEUE *event_queue = NULL; 12 ALLEGRO_TIMER *timer = NULL; 13 ALLEGRO_BITMAP *bouncer = NULL; 14 float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0; 15 float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0; 16 float bouncer_dx = -4.0, bouncer_dy = 4.0; 17 bool redraw = true; 18 19 if(!al_init()) { 20 fprintf(stderr, "failed to initialize allegro!\n"); 21 return -1; 22 } 23 24 timer = al_create_timer(1.0 / FPS); 25 if(!timer) { 26 fprintf(stderr, "failed to create timer!\n"); 27 return -1; 28 } 29 30 display = al_create_display(SCREEN_W, SCREEN_H); 31 if(!display) { 32 fprintf(stderr, "failed to create display!\n"); 33 al_destroy_timer(timer); 34 return -1; 35 } 36 37 bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE); 38 if(!bouncer) { 39 fprintf(stderr, "failed to create bouncer bitmap!\n"); 40 al_destroy_display(display); 41 al_destroy_timer(timer); 42 return -1; 43 } 44 45 al_set_target_bitmap(bouncer); 46 al_set_blender(ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_ZERO); 47 al_clear_to_color(al_map_rgba(255, 0, 255,150)); 48 49 al_set_target_bitmap(al_get_backbuffer(display)); 50 51 event_queue = al_create_event_queue(); 52 if(!event_queue) { 53 fprintf(stderr, "failed to create event_queue!\n"); 54 al_destroy_bitmap(bouncer); 55 al_destroy_display(display); 56 al_destroy_timer(timer); 57 return -1; 58 } 59 60 al_register_event_source(event_queue, al_get_display_event_source(display)); 61 62 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 63 64 al_clear_to_color(al_map_rgb(0,0,0)); 65 66 al_flip_display(); 67 68 al_start_timer(timer); 69 70 while(1) 71 { 72 ALLEGRO_EVENT ev; 73 al_wait_for_event(event_queue, &ev); 74 75 if(ev.type == ALLEGRO_EVENT_TIMER) { 76 if(bouncer_x < 0 || bouncer_x > SCREEN_W - BOUNCER_SIZE) { 77 bouncer_dx = -bouncer_dx; 78 } 79 80 if(bouncer_y < 0 || bouncer_y > SCREEN_H - BOUNCER_SIZE) { 81 bouncer_dy = -bouncer_dy; 82 } 83 84 bouncer_x += bouncer_dx; 85 bouncer_y += bouncer_dy; 86 87 redraw = true; 88 } 89 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 90 break; 91 } 92 93 if(redraw && al_is_event_queue_empty(event_queue)) { 94 redraw = false; 95 96 al_clear_to_color(al_map_rgb(0,0,0)); 97 98 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); 99 100 al_flip_display(); 101 } 102 } 103 104 al_destroy_bitmap(bouncer); 105 al_destroy_timer(timer); 106 al_destroy_display(display); 107 al_destroy_event_queue(event_queue); 108 109 return 0; 110}

Matthew Leverton
Supreme Loser
January 1999
avatar

First off, as far as I know, al_clear_to_color() doesn't use the blenders.

The default Allegro blender when drawing a bitmap is:

al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);

So if you want something like rgba(1.0, 0.0, 1.0, 0.5) to mean draw purple at 50%, you need to pre-multiply the alpha: (r=r*a, g=g*a, b=b*a). In your case:

al_clear_to_color(al_map_rgba(150, 0, 150, 150));

Now when you draw the bitmap using the default blender, you'll get what you expect.

Alternatively, you can change the default blender:

al_clear_to_color(al_map_rgba(255, 0, 255, 150));
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

wracker
Member #15,173
June 2013
avatar

thanks mate, it's now working like a charm..

Let's say I want to periodically decrease/increase the alpha channel value..

Can I change the alpha channel like this?

#SelectExpand
1int alpha=0; 2while (x!=1) 3{ 4 ... 5 if (alpha < 250){alpha++;;}else {alpha=0;} 6 7 al_set_target_bitmap(bouncer); 8 al_clear_to_color(al_map_rgba(255, 0, 255, alpha)); 9 al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); 10 11 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); 12... 13}

Matthew Leverton
Supreme Loser
January 1999
avatar

Yes, with that blender it will work as you expect. (Although you only have to call al_set_blender one time in your example.)

wracker
Member #15,173
June 2013
avatar

It's not working. I can only set the initial alpha channel.
If I try to change the alpha channel inside the while
cycle the bitmap is not being displayed at all.

Not sure what I'm doing wrong :/ ..

#SelectExpand
1 2 int alpha=0; 3int main(int argc, char **argv){ 4... 5 al_set_target_bitmap(bouncer); 6 al_clear_to_color(al_map_rgba(255, 0, 255, 10)); 7 al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); 8... 9 while (x!=1) 10 { 11 ... 12 al_clear_to_color(al_map_rgb(0,0,0)); 13 if (alpha < 250){alpha++;;}else {alpha=0;} 14 15 al_set_target_bitmap(bouncer); 16 al_clear_to_color(al_map_rgba(255, 0, 255, alpha)); 17 al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); 18 19 al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); 20 al_flip_display(); 21 ... 22 } 23}

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

You never changed your drawing target to draw to the backbuffer. You are only drawing to your 'bouncer' bitmap. That is why it is not visible.

al_set_target_backbuffer(display);
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(bouncer , bouncerx , bouncery , 0);
al_flip_display();

Edit
-and, you're drawing a bitmap onto intself. I don't believe this is allowed or wise. You need to keep an original somewhere to draw into your alpha varied buffer.

wracker
Member #15,173
June 2013
avatar

after I set the

#SelectExpand
1al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

it allowed me to draw my "bouncer" bitmap and change its alpha channel using the below function:

#SelectExpand
1al_draw_tinted_bitmap(bouncer, al_map_rgba_f(1, 1, 1, alpha), 40, 0, 0);

This previously did not work , so I guess adding the al_set_blender solved the "mistery".

Thanks for all your help guys, it's greatly appreciated.

Go to: