[A5] Color a masked bitmap
Arevil

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. :-/

SiegeLord

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

Arevil

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?

SiegeLord
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...

Arthur Kalliokoski

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

Arevil

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

J-Gamer
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.

Arevil

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

SiegeLord
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.

Arevil

Yeah - thanks!

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

kazzmir

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

Thread #612092. Printed from Allegro.cc