al_draw_text with alpha
AMCerasoli

There is a way to draw text with "al_draw_text" with Alpha? I tried:

al_draw_text(font, al_map_rgba(255, 255 ,255 ,120), 635, 645, 0, "aloha");

But didn't work, there is a way? or should I use bitmap fonts?

Conclusion:

Allegro Uses pre-multiplied alpha by default al_map_rgba works great with bitmaps but doesn't seems to work with text.

al_map_rgba_f works fine with text, but instead of use a parameter number from 0-255 for RBG colors uses a ranging from 0.0f-1.0f.

So if you wan to convert a color from 0-255 to 0.0f-1.0f you need to use division.

Ex: normal RGB (180,120,100,127.5)
180/255=0.705
120/255=0.470
100/255=0.392
127/255=0.5

Would be:
Allegro RGB al_map_rgba_f(0.705,0.470,0.392.0.5)

And if you need convert from 0.0f-1.0f to 0-255 you need to use uses multiplication.

Ex: normal RGB (0.705,0.470,0.392,0.5)
0.705*255=180
0.470*255=120
0.392*255=100
0.5*255=127.5

jmasterx

It should work its just pre multiplied alpha is on by default so at the top of your render loop try:

al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

http://docs.liballeg.org/graphics.html#al_set_blender

AMCerasoli

Thanks man, now is working!

But, when it says: "Sets the function to use for blending for the current thread" what is saying?

The current tread is the whole tread right? because I saw something about "threading interface" which allows me to do multi threading? but if I'm not using it there is just one thread, right?

jmasterx

What they mean I think is that it affects all of your displays. If you have many displays, you must set blender for each one.

void render()
{
  //set display
  //set blender
  //draw

  //set display2
  //set blender
  //draw
}

But if you only have 1 display (1 window) you don't have to worry about it.

AMCerasoli

Oh I see.

But have just notice this problem:

I put al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);
before all the drawing calls.

{"name":"603492","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/e\/2e1ea87d9d52d4ffa11dfc586179bb35.jpg","w":505,"h":718,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/2\/e\/2e1ea87d9d52d4ffa11dfc586179bb35"}603492

Should be like the PhotoShop version.
If I remove al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA); it works but again can't draw transparent text. :o

I'm using: al_draw_tinted_bitmap(PNG, al_map_rgba(255, 255, 255, 255), 0, 0, 0 );

it's a PNG which already have transparency.

jmasterx

This is because Photoshop premultiplies Alpha for Bitmaps so try to set it back to premultiplied before drawing bitmaps and before loading bitmaps, but use the other blender to draw text.

Elias

Or premultiply the color you draw the text with then you never need to touch the blender.

AMCerasoli

But by default Allegro is also premultiplaying alpha right?

Because if I don't modify the blending, Allegro draw it the same as Photoshop does.

"premultiply the color you draw the text" sounds better, that doesn't mean that if I premultiply the white color, all the bitmaps that are using the white color are going to be affected?

1) How can I premultiply just one color? (if that is what you're suggesting)
2) Isn't changing the blending, CPU expensive?
3) By default, Allegro premultiply alpha?

Edgar Reynaldo

1) How can I premultiply just one color? (if that is what you're suggesting)
2) Isn't changing the blending, CPU expensive?
3) By default, Allegro premultiply alpha?

1) Use al_map_rgba_f(255.0f*0.5f , 127.0f*0.5f , 64.0f*0.5f , 0.5f). Premultiplying the alpha means multiplying it yourself, which makes no sense to me.
2) Probably not. I'm guessing it just sets some flags.
3) Yes

Dennis

But by default Allegro is also premultiplaying alpha right?

Last time I checked, Allegro had no multiplayer functions at all. :P

Premultiplied alpha means this:
The individual RGB components of any pixel source data are interpreted in the alpha blending step as having already been multiplied by some alpha value, so the alpha blending step does not multiply the source RGB components with the source A component anymore to determine what gets blended with the RGB components of the target pixel data.

Additional reading:
http://en.wikipedia.org/wiki/Alpha_compositing
A5 specific: http://docs.liballeg.org/graphics.html#al_set_blender
Look at those formulas and the description below. Do the math and feel enlightened afterwards (Note how the A component of the source color is still important for calculating the amount of each RGB value from the target color in the alpha blending step.).

AMCerasoli

;D;D;D hahahahaha

That would be good a Multiplayer function!!.

You just have to call al_set_multiplayer(ALLEGRO_PC * pc); and that's it.

I would like to do it the Elias way. But I don't even know what means the 'f' letter after the numbers. Can someone drop a link? I don't know how to search (google:"the "f" letter after a number c++"?), it's something related with Hexadecimals right?

The al_map_rgba_f function that Edgar gave me, seems to instead of get transparent, become black (when I modify it), because if I use it as he gave it to me, the text is drawn blue. This surely is because I don't know how to use it. I never saw anything about that in my C++ Book. :P

Edgar Reynaldo

Sorry, I used al_map_rgba_f wrong. The values go from 0.0 to 1.0, not 0 to 255.

al_map_rgba_f(1.0f*0.5f , 0.5f*0.5f , 0.25f*0.5f , 0.5f);

Would give you a slightly desaturated orange at 50% opacity.

The _f at the end of al_map_rgba_f just means it takes floating point values. The f at the end of the number values means they are floating point values.

AMCerasoli

But why are you multiplying all that? isn't the same: al_map_rgba_f(0.5f , 0.25f , 0.125 , 0.5f) well actually it is, I tried it.

I like this way since I don't have to use blending. But if I do al_map_rgba_f(0.5f , 0.25f , 0.125 , 0.0f) It gets white instead of transparent. I have been reading and that is one of the difference between premultiply and the other way.

But then what I have to do?, changing the whole blending mode it seems unnecessary I don't know.

I want to make an "appearing effect". from completely invisible to visible.

PS: Oh boy, jmasterx already have told me that premultiplied is on by default, and I asked again, I didn't see it :o:o. I didn't process correctly the info :-X.

Evert

But why are you multiplying all that? isn't the same: al_map_rgba_f(0.5f , 0.25f , 0.125 , 0.5f) well actually it is, I tried it.

Of course it's the same.
But first, it's an example, and second, doing the multiplication explicitly can be clearer. It's evaluated at compile-time anyway.

AMCerasoli

I did change the values with al_set_blender and then set it back, but I'm getting this effect, and I really don't like it.

{"name":"603498","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/e\/0e0e895fbf9444353e9b5164277536a4.jpg","w":243,"h":159,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/e\/0e0e895fbf9444353e9b5164277536a4"}603498

That black border.

How does work al_map_rgb_f?

Can someone show me an example drawing text completely transparent with al_map_rgb_f? no matter what color it's.

Isn't as simple as used to... the unique way I can make it complytly transparent is doing this: al_map_rgba_f(0.0f , 0.0f , 0.0f , 0.0f), the thing is now I don't know how to control those variables... RGB are in most applications, but know what can I use as reference?

Dennis

..but know what can I use as reference?

Yes, the manual: http://docs.liballeg.org/graphics.html#al_set_blender
and http://docs.liballeg.org/graphics.html#al_map_rgb_f
It explains what's happening in detail. Also, read my previous post (and the links I provided).

Be patient. Read those sections of the manual slowly and make sure you understand each sentence before reading the next one. If there are any words you don't understand, look them up.

Elias

It's very simple:

al_map_rgba_f(0, 0, 0, 0) // 0% opaque (fully transparent)
al_map_rgba_f(0.25, 0.25, 0.25, 0.25) // 25% opaque
al_map_rgba_f(0.50, 0.50, 0.50, 0.50) // 50% opaque (half transparent)
al_map_rgba_f(1, 1, 1, 1) // 100% opaque (default, no transparency)

This is when using the default blending mode only of course.

[edit: The black border will appear if you change to non-pre-multiplied alpha, so don't do that. Leave everything at the defaults unless you know what you are doing.]

Edgar Reynaldo
Elias said:

The black border will appear if you change to non-pre-multiplied alpha, so don't do that.

Why would there be a black border if you're not using pre multiplied alpha? Shouldn't the outcome be the same as if you were using premultiplied alpha?

Dennis
Elias said:

Leave everything at the defaults unless you know what you are doing.

..and to reach a point where you know what you're doing, it helps to read and understand manuals, to look up unknown words and to seek more details about a topic and not just copy & pasting examples.

Elias

Why would there be a black border if you're not using pre multiplied alpha? Shouldn't the outcome be the same as if you were using premultiplied alpha?

Not if you use any kind of filtering (which I assume he's doing, don't see how there could be dark borders otherwise) - and that's precisely the reason why we switched to using pre-multipled alpha. Linear-interpolation-alpha just doesn't work with the way OpenGL/DirectX do interpolation.

AMCerasoli

Black borders appear when I'm not using pre-multiplied alpha. But anyway thack a lot Elias that examples help me a lot, I know that I gonna have to read, what Dennis gave me, but I already solve my problem.

The thing is now I have no reference, if I see for example a text in HTML/PhotoShop/etc, which use simple RGB, with the maximum amount of color been always 255.

What I have to do to transform that to this type of RGB, when the maximum amount of color is 1.0?. I haven't read the links above, so if I'm saying something that I can find there, just don't even bother...

J-Gamer

Just multiply the value between 0.0 and 1.0 with 255 and there you go ;D
The other way around: just divide by 255.

jmasterx

N/A

J-Gamer

Err... jmaster, it's what I said... With that part of the phrase, I meant when going from photoshop/inkscape/... values to allegro values. So here is something clearer.

When converting from the allegro values to the photoshop/inkscape/... values, multiply with 255.
When going from the photoshop/inkscape/... to allegro values divide by 255.

AMCerasoli

Thanks to all problem solved! :D

Mark Oates

For some reason the concept hasn't quite sunk in with all the allegroids, yet. When this thread comes up again, nobody should mention the al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) and/or the ALLEGRO_NO_PREMULTIPLIED_ALPHA flag as a solution. It does not "return things to how they were before." Specifically, half-opacity is gray, you get text outlines, etc.

Those two are not a working solution. (In fact, I think ALLEGRO_NO_PREMULTIPLIED_ALPHA should be removed. :-X)

The correct solution is "you'll need to multiply all your color components by the alpha value. For example:

float alpha = 0.3f;
ALLEGRO_COLOR color = al_map_rgba_f(0.7*alpha, 0.3*alpha, 0.6*alpha, alpha);

" or, the similar answer using 0-255 values.

Thank you.
:P

Edgar Reynaldo

For some reason the concept hasn't quite sunk in with all the allegroids, yet.

I haven't used A5 yet, but well personally I just don't get it either.

Mark Oates said:

The correct solution is "you'll need to multiply all your color components by the alpha value. For example:

The problem is, it should work the same way whether you multiply the alpha yourself or whether Allegro multiplies it for you.

Using 'filtering' on a bitmap with alpha makes no sense to me, because then the color values in the pixels with zero alpha are used to blend the edges. So you better pick the right color values for your zero alpha pixels, or you're screwed and you get funky outlines.

So the real problem is that you can't pick sensible values for zero alpha pixels with filtering because it should be mixed with the background color instead.

I'm reading Shawn Hargreaves blogs linked from Elias's response to anomalous blending, and maybe it makes sense and maybe it doesn't. I'm not sure yet.

jmasterx

I really think a nice flag which would state weather allegro's color mapping functions will be multiplying the colors for you would be very useful.

By this I mean, if the flag is set, a call to al_map_rgba would do:

al_map_rgba(r * a, g * a, b * a, a);

and would return a pre multiplied ALLEGRO_COLOR.

Mark Oates
jmasterx said:

By this I mean, if the flag is set, a call to al_map_rgba would do:

al_map_rgba(r * a, g * a, b * a, a);

I think that's a good idea.

Right now, I use these two functions quite a bit:

#SelectExpand
1static inline ALLEGRO_COLOR color_hex(const char *hex, float a=1.0f) 2{ 3 ALLEGRO_COLOR color = al_color_html(hex); 4 color.a = a; 5 color.r *= a; 6 color.g *= a; 7 color.b *= a; 8 return color; 9} 10 11static inline ALLEGRO_COLOR color_name(const char *name, float a=1.0f) 12{ 13 ALLEGRO_COLOR color = al_color_name(name); 14 color.a = a; 15 color.r *= a; 16 color.g *= a; 17 color.b *= a; 18 return color; 19}

Some time ago, I had a convenience function:
static inline ALLEGRO_COLOR color(const char *identifier, float alpha=1.0);
that would identify identifier as a hex or name string, and would handle them accordingly. I should bring that bad boy back. 8-)

Peter Wang

There would be no problem adding convenience versions of al_map_rgb* which multiply in the alpha component, if only someone could suggest decent names.

For now, I create my own makecol.

jmasterx

al_map_premultiplied_rgba ? or a flag and use the same functions

Mark Oates

if only someone could suggest decent names.

I think the al_map_rgb* functions should, by default, multiply the components by the alpha.

But, if you ALLEGRO_NO_PREMULTIPLIED_ALPHA then they will not.

jmasterx

I think the al_map_rgb* functions should, by default, multiply the components by the alpha.

But, if you ALLEGRO_NO_PREMULTIPLIED_ALPHA then they will not.

I was hoping Allegro 5.0.0 was going to work like that.

Mark Oates

I haven't completely thought through what else it could affect, but it seems to make sense. Since it's essentially what's happening to a bitmap's colors when you're loading them, it should also happen with the mapped colors.

[edit]however, I seem to recall that xma makes you multiply the components explicitly... hmm...

Matthew Leverton

The flag used for bitmap loading is a necessary evil. For colors, it would be another annoying thing I'd have to check for and disable in library code.

Peter Wang

ALLEGRO_NO_PREMULTIPLIED_ALPHA is only a bitmap flag that affects how allegro_image loads images. It has no other bearing. The rest of Allegro really doesn't care if you use the convention or not, which is all it is.

Mark Oates

ALLEGRO_NO_PREMULTIPLIED_ALPHA is only a bitmap flag that affects how allegro_image loads images. It has no other bearing. The rest of Allegro really doesn't care if you use the convention or not, which is all it is.

Hmm... I see...

Evert
jmasterx said:

I really think a nice flag which would state weather allegro's color mapping functions will be multiplying the colors for you would be very useful.

It could potentially slow you down quite a bit as well, if you're doing an extra comparison in a tight loop.

There would be no problem adding convenience versions of al_map_rgb* which multiply in the alpha component, if only someone could suggest decent names.

Agreed.
How about al_map_alpha_rgba()?
By the way, having functions that converts from non-pre-multiplied alpha to pre-multiplied alpha and back would be useful too.

Elias
Evert said:

How about al_map_alpha_rgba()?

Or maybe al_map_premultipled_rgba(). In both cases you likely want to keep your custom color functions/macros though so not sure it's necessary.

Thread #606537. Printed from Allegro.cc