[A5] how to draw with transparency
axilmar

Hi, I am sure this question has been asked before, but my search skills are lousy at best.

Is there a way to setup Allegro 5 so all successive drawing operations are drawn with an alpha (transparency) or do I have to pass the alpha value to every drawing operation?

Kris Asick

Allegro 5 is hardware accelerated and as such, ALL drawing operations use some form of blending, even when just drawing opaque pixels. It's just the nature of the beast and all hardware accelerated graphical things work this way. :P

Allegro 5's got numerous drawing functions that pretty much boil down to how much information you want to pass yourself and how much you just want to assume is default. al_draw_bitmap() doesn't take a colour value, but everything else that does will require you to call one of the Allegro colour creating commands first, which there are several of, some of which presume full alpha, some of which ask you to supply your own alpha value.

It's all listed in the manual. ;)

axilmar

So there isn't a simple way to say "all this drawing from now on will use this alpha", for example?

Elias

No. The alpha component is just like the red, green, blue components.

(Of course if you used a shader to do your drawing, it would be trivial to do it.)

axilmar

Ok, thanks a lot. I'll just create a bitmap to draw onto and then blit this bitmap with alpha then.

Kris Asick

Why... couldn't you just pass the same alpha value to multiple bitmap drawing calls? Like, if you have 5 bitmaps you all want to draw with an alpha of 107, just do:

ALLEGRO_COLOR c = al_map_rgba(255,255,255,107);
for (z = 0; z < 5; z++)
    al_draw_tinted_bitmap(myBitmapArray[z],c,xpos[z],ypos[z],0);

Or if every object has its own colour, but the alpha is global to everything for whatever reason, just code it so that your objects only store their colour as independent RGB colour values, then when you go to draw your bitmaps:

for (z = 0; z < 5; z++)
    al_draw_tinted_bitmap(myBitmapArray[z],al_map_rgba(r[z],g[z],b[z],globalAlpha),xpos[z],ypos[z],0);

Also, if you're trying to achieve a fading effect of some kind then you're doing it wrong. The best way to do this would be to render the screen you want to fade to (or just a pitch-black bitmap) and then fade the alpha of that bitmap in, drawing it overtop of everything else. This will essentially make the elements you don't want to render anymore disappear. (That's right, fades to black are not done by fading everything out, but rather by fading black in overtop of everything!)

axilmar

Why... couldn't you just pass the same alpha value to multiple bitmap drawing calls?

It's for a gui library I am creating. I'd like to make widgets have an alpha value for whatever they draw.

Thomas Fjellstrom

Shouldn't they handle the alpha themselves then?

Though one way to handle this, and get a slight performance boost on partial rendering updates is to cache widgets to an atlas. then you can draw that cached bitmap with an alpha value.

axilmar

Shouldn't they handle the alpha themselves then?

Yes, they should. But the final opacity should not be affected by the overlapping of graphics within the same widget.

For example, if I want to draw a translucent button that has a bitmap background and text over the background, I do not want the text to be transparent relative to the button's background, I want the text to be transparent relative to the the widgets behind the button.

Thomas Fjellstrom

Yeah at that point you have to do some kind of composition then. everything in the widget draws, then that is drawn at some translucency level. You can either do it with some super clever scissor clipping and drawing things multiple times, or just pre-render the widget to a bitmap, and draw that.

Kris Asick

What Thomas said.

If you want certain things to overlap against themselves opaquely, but all those things as a whole to overlap translucently across something else, there's no magic way to handle that with shaders or blending settings. You need to first render your stuff opaquely to a blank bitmap, then render that bitmap translucently overtop of the stuff that's going to appear behind it all.

axilmar

Thank you all, I have just implemented the bitmap trick into my gui lib.

Thomas Fjellstrom

If you also use that as a draw cache, you can probably get some handy optimizations out of it. Not all widgets will have to redraw every update.

axilmar

If you also use that as a draw cache, you can probably get some handy optimizations out of it. Not all widgets will have to redraw every update.

Could be done. Thanks for the tip.

Thread #613571. Printed from Allegro.cc