Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [A5] Color a masked bitmap

Credits go to SiegeLord for helping out!
This thread is locked; no one can reply to it. rss feed Print
[A5] Color a masked bitmap
Arevil
Member #12,872
May 2011
avatar

Hello,
when porting my game from A4 to A5, I came to following problem:
I want to draw a bitmap colored in a specific color, e.g. in cyan.

This is my Allegro 4 code:

#SelectExpand
1drawing_mode( DRAW_MODE_TRANS, NULL, 0, 0); 2set_trans_blender( 0, 255, 255, 0); 3draw_lit_sprite( camera, bitmap, x, y, alpha);

How can i achieve this with Allegro 5?
I tried with al_draw_tinted_bitmap, but this only draws color components of the bitmap. And I want to color the bitmap. :-/

My Project (Mi55ion):
www.Mi55ion.de

SiegeLord
Member #7,827
October 2006
avatar

Either use a shader... or I think you probably can get away with some trickery with multiple bitmaps.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Arevil
Member #12,872
May 2011
avatar

Shader:
Do you mean the shader addon? I did not pay attention to it up to now.
I can't understand, why it should be so complicated, to color a bitmap in allegro 5.

Trickery with multiple bitmaps:
That sounds good, but how can I achieve it? I have no beginning to this.
Which functions do I have to use? Blenders and tinted drawing only handle the colors of the bitmap, don't they?

My Project (Mi55ion):
www.Mi55ion.de

SiegeLord
Member #7,827
October 2006
avatar

Arevil said:

I can't understand, why it should be so complicated, to color a bitmap in allegro 5.

It's twofold... firstly, this is just not implemented (yet?) in the shader addon so effectively you have to implement it yourself. Secondly, it needs to be done via a shader because that's the price you pay for hardware acceleration.

Quote:

That sounds good, but how can I achieve it?

I don't know off the top of my head either... so here's a shader implementation that might do what you want:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_image.h> 3#include <allegro5/allegro_shader.h> 4#include <allegro5/allegro_shader_glsl.h> 5 6#include <stdio.h> 7 8const char* pixel_shader = 9"uniform sampler2D tex; \n" 10"uniform float light_intensity; \n" 11"uniform vec4 light_color; \n" 12"varying vec4 varying_color; \n" 13"varying vec2 varying_texcoord; \n" 14"void main() \n" 15"{ \n" 16" vec4 tex_color = varying_color * texture2D(tex, varying_texcoord); \n" 17" vec4 blended_light_color = tex_color.w * light_color; \n" 18" gl_FragColor = vec4(tex_color.xyz + (blended_light_color.xyz - tex_color.xyz) * light_intensity, tex_color.w); \n" 19"} \n"; 20 21int main() 22{ 23 al_init(); 24 al_init_image_addon(); 25 26 al_set_new_display_flags(ALLEGRO_USE_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL); 27 ALLEGRO_DISPLAY* display = al_create_display(800, 600); 28 29 ALLEGRO_BITMAP* bmp = al_load_bitmap("sample.png"); 30 31 /* Shader stuff*/ 32 ALLEGRO_SHADER* shader = al_create_shader(ALLEGRO_SHADER_GLSL); 33 if(!al_attach_shader_source(shader, ALLEGRO_VERTEX_SHADER, al_get_default_glsl_vertex_shader())) 34 printf("%s", al_get_shader_log(shader)); 35 if(!al_attach_shader_source(shader, ALLEGRO_PIXEL_SHADER, pixel_shader)) 36 printf("%s", al_get_shader_log(shader)); 37 if(!al_link_shader(shader)) 38 printf("%s", al_get_shader_log(shader)); 39 al_set_shader(display, shader); 40 41 float light_color[4] = {0.0f, 1.0f, 1.0f, 1.0f}; 42 float light_intensity = 0.0; 43 44 al_clear_to_color(al_map_rgb_f(0, 0, 0)); 45 46 for(int ii = 0; ii < 11; ii++) 47 { 48 al_set_shader_float_vector(shader, "light_color", 4, light_color, 1); 49 al_set_shader_float(shader, "light_intensity", light_intensity); 50 51 light_intensity += 0.1; 52 53 al_use_shader(shader, true); 54 al_draw_bitmap(bmp, 0, 0, 0); 55 al_use_shader(shader, false); 56 al_flip_display(); 57 al_rest(0.5); 58 } 59}

You'll need a bitmap ("sample.png" in the code above) to run this. Link with image and shader addons.

EDIT: The shader had an error in it...

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Arthur Kalliokoski
Second in Command
February 2005
avatar

If you used OpenGL, you could specify the material colors for the bitmap.

[EDIT]

I just noticed Tobing mentioning al_draw_tinted_bitmap(), I forgot I used it for something else only a week ago!

{"name":"607234","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/7\/27978a6d80f566b3f3c98e2146d305b9.png","w":937,"h":314,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/7\/27978a6d80f566b3f3c98e2146d305b9"}607234

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Arevil
Member #12,872
May 2011
avatar

Thanks for the suggestions!

But I don't want to use Allegro 5.1 (concerning unstable), so the shader addon is no solution. And the direct use of OpenGL is no alternative for me so far.

My quick solution is to draw the bitmap and then draw over a primitive (in this case a circle) with alpha channel. In the example image you can see the result (right), but in fact I wanted to color the full bitmap (with the red crown).

{"name":"607235","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/2\/72cf75fb7f71edd3fb1673985e2ea086.png","w":640,"h":400,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/7\/2\/72cf75fb7f71edd3fb1673985e2ea086"}607235

My Project (Mi55ion):
www.Mi55ion.de

J-Gamer
Member #12,491
January 2011
avatar

Arevil said:

But I don't want to use Allegro 5.1 (concerning unstable), so the shader addon is no solution.

The only thing that's unstable in 5.1 is the API. Some functions in the API can still change/get removed. In terms of bugs, 5.1 is way more stable than the "stable" branch.

" There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo
"If your body was a business, thought would be like micro-management and emotions would be like macro-management. If you primarily live your life with emotions, then you are prone to error on the details. If you over-think things all the time you tend to lose scope of priorities." - Mark Oates

Arevil
Member #12,872
May 2011
avatar

Well, that is new to me!
If that's true, I want to try it with Allegro 5.1. ;)

My Project (Mi55ion):
www.Mi55ion.de

SiegeLord
Member #7,827
October 2006
avatar

Arevil said:

My quick solution is to draw the bitmap and then draw over a primitive (in this case a circle) with alpha channel. In the example image you can see the result (right), but in fact I wanted to color the full bitmap (with the red crown).

It's easy to extend this solution to the entire bitmap by creating a mask and using that instead of the primitive:

ALLEGRO_BITMAP* mask = al_create_bitmap(al_get_bitmap_width(bmp), al_get_bitmap_height(bmp));

/* Only need to run this code once per bitmap */
al_set_target_bitmap(mask);
al_clear_to_color(al_map_rgb_f(1, 1, 1));
al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ZERO, ALLEGRO_ALPHA, ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ZERO);
al_draw_bitmap(bmp, 0, 0, 0);
al_set_target_bitmap(al_get_backbuffer(display));
al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);

al_draw_bitmap(bmp, 0, 0, 0);
al_draw_tinted_bitmap(mask, al_map_rgba_f(light_intensity * r, light_intensity * g, light_intensity * b, light_intensity), 0, 0, 0);

This isn't quite the same thing as the draw_lit_sprite or the shader does, but it might look close enough for your needs.

"For in much wisdom is much grief: and he that increases knowledge increases sorrow."-Ecclesiastes 1:18
[SiegeLord's Abode][Codes]:[DAllegro5]:[RustAllegro]

Arevil
Member #12,872
May 2011
avatar

Yeah - thanks!

This code is an acceptable solution for my needs. ;)

My Project (Mi55ion):
www.Mi55ion.de

kazzmir
Member #1,786
December 2001
avatar

Just wanted to say that I tested SiegeLord's lit sprite shader, and it works.

Go to: