|
[A5] Blending |
weapon_S
Member #7,859
October 2006
|
Hi, everybody! I have some 'gradients' I make with al_put_pixel [1]. I use a very straight-forward subtraction, and I assume I could (easily[2]) rewrite it to use a blender. Blenders will (try to) use hardware acceleration, right?
On the wiki is an outdated blending tutorial... Any help, please? References
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Weapon_S said:
al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA) Will have a pixel be influenced more by a destination pixel, when that destination pixel's alpha is lower...???
al_set_blender said: ALLEGRO_INVERSE_ALPHA src = 1 - sa So when dst is ALLEGRO_INVERSE_ALPHA, you can replace all the 'dst's in the formulas below with 1 - sa : Quote: ALLEGRO_ADD r = dr * dst + sr * src ALLEGRO_DEST_MINUS_SRC r = dr * dst - sr * src ALLEGRO_SRC_MINUS_DEST r = sr * src - dr * dst
Weapon_S said: but some use the correct blending mode for pre-multiplied-alpha images. But then the latter two 'ignore' the source alpha, and use 1 With correct results...? Destination alpha is max; so destination pixels shouldn't contribute anywhere the the 'blit' is happening? ALLEGRO_ONE is used because all the pixels in the image have already been scaled by the alpha value, so it should now be ignored. Destination alpha never matters unless you are using one of the special new blenders in A5.1 with al_set_separate_blender. (Edit - Actually, I don't think destination alpha is ever used.) My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
weapon_S
Member #7,859
October 2006
|
Thanks, Edgar. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
weapon_S said: So pre-multiplied means: replacing the use of the alpha channel with a additive operation is facilitated by reducing a pixel's value based on its alpha... I still don't fully understand. I'll look into it. Take the green component for example. Say you have fully bright green (255) and half opaque alpha (127). If you 'pre-multiply' the alpha, then you get (255*127)/255 { (sg*sa)/255 } for the resulting green component, or roughly 127. Now to draw that half opaque, fully bright color of green, you must use additive blending (ALLEGRO_ADD , ALLEGRO_ONE , ALLEGRO_INVERSE_ALPHA) (the default) and add that 127 to (dg*(255-sa)) to get the result. Quote: 'Clearing' without touching alpha channel can't be done... but I'll work around it. It can with shaders... You'll need 5.1 though, or else lock a bitmap region and alter the pixel values directly. Or you can use al_set_separate_blender : void al_set_separate_blender(int op, int src, int dst, int alpha_op, int alpha_src, int alpha_dst) I think it would be al_set_separate_blender(op , src , dst , ALLEGRO_ADD , ALLEGRO_ZERO , ALLEGRO_ONE); That would let you draw anything onto a destination bitmap without affecting its alpha value. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
weapon_S
Member #7,859
October 2006
|
Premultiplied is clear now. The contribution of the source is 'pre-calculated', by subtracting a proportionate amount; then the contribution of the destination is calculated using the alpha of the source (also subtracting a proportionate amount). 1//Very pseudo code
2ALLEGRO_BITMAP* alpha_mask; //Black with alpha pattern
3
4// 1.
5ALLEGRO_BITMAP* buffer2; //No premultiply alpha
6
7set_target_bmp(buffer2);
8clear_to_color(color, zero_alpha);
9set_blender(add, one, one);
10draw_bmp(alpha_mask);
11set_target(final_target);
12set_blender(for final target);
13draw_bmp(buffer2);
14
15// 2.
16set_target(alpha_mask);
17set_separate_blender(add, one, zero, add, zero, one);
18rectfill(completely, color);
19set_target(final_target);
20set_blender(for final target);
21draw_bmp(buffer2)'
22
Clearly option #2 is smaller and doesn't use an extra buffer, but my gut says #1 uses faster operations. I.e. the rectfill with blender would take some more time. It is very much an edge case (in my mind), and I'd like to see how they compare in practice. Edgar Reynaldo said: or else lock a bitmap region and alter the pixel values directly. This looks at least faster than using a blender and drawing a filled rectangle... No wait; HW accel is out of the question then... but then you can resort to fast CPU instructions... and then it gets out of my league BTW could anybody comment on the hardware acceleration part? The manual is silent and the source is confusing. |
Thomas Fjellstrom
Member #476
June 2000
|
Allegro 4 doesn't do a lot of hardware acceleration to begin with. The best you can normally expect is hardware accelerated plain blits. I don't think any of the platforms support anything fancier than that with their 2D apis (and even if they do, the drivers for people's hardware probably won't or will implement it with the 3d hardware...). -- |
weapon_S
Member #7,859
October 2006
|
While the pseudo code was posted, omitting the 'al' prefix, my concerns are about Allegro 5. |
Thomas Fjellstrom
Member #476
June 2000
|
weapon_S said: I will interpret this answer as: "Allegro 5 should do most things via hardware." Thanks for the answer. It will at least try. If you do anything on a locked bitmap, you fall back to software. -- |
weapon_S
Member #7,859
October 2006
|
The function I was looking for was al_draw_tinted_bitmap. 5.1 adds some options that might make me reconsider the precise way I'm doing things now. |
|