GUI with alpha channel

Started by Crimson Wizard, Sat 23/02/2013 15:56:29

Previous topic - Next topic

Crimson Wizard

A game developer had issues with the Inventory items having alpha channel recently:
http://www.adventuregamestudio.co.uk/forums/index.php?topic=47666.0

While testing that out, it was found that not only Inventory items, but Buttons with alpha channel do not seem to draw properly on solid GUI surface too.
These are two distinct problems (inventory items perhaps were simply not updated with the latest changes in GUI drawing). I am more interested in discussing a Button one.

Here are examples of how Buttons with alpha are drawn on GUI in AGS 3.2.1.1115:

Buttons with alpha on solid GUI with transparent (magic pink) areas:
[imgzoom]http://imageshack.us/a/img254/4863/agsguialphatestalphabtn.png[/imgzoom]
Buttons with alpha on GUI with alpha with translucent areas:
[imgzoom]http://imageshack.us/a/img7/4863/agsguialphatestalphabtn.png[/imgzoom]

The belnding algorythm used there is following:
1. Summ alpha amounts
2. Keep button color
3. Discard background color
Code:
Spoiler
Code: cpp
unsigned long _additive_alpha_blender(unsigned long x, unsigned long y, unsigned long n)
{
    unsigned long newAlpha = ((x & 0xff000000) >> 24) + ((y & 0xff000000) >> 24);

    if (newAlpha > 0xff) newAlpha = 0xff;

    return (newAlpha << 24) | (x & 0x00ffffff);
}
[close]


Here's a fix I was able to come with so far:

Buttons with alpha on solid GUI with transparent (magic pink) areas:
[imgzoom]http://imageshack.us/a/img17/4863/agsguialphatestalphabtn.png[/imgzoom]
Buttons with alpha on GUI with alpha with translucent areas:
[imgzoom]http://imageshack.us/a/img534/4863/agsguialphatestalphabtn.png[/imgzoom]

The blending algorythm:
1. Summ alpha amounts.
2. Get a color between button color and surface color; the button alpha defines a relative distance between those two limits.
Spoiler
Code: cpp

union
{
    struct
    {
        unsigned char r;
        unsigned char g;
        unsigned char b;
        unsigned char a;
    } rgba;
    unsigned long color;
} col_x, col_y, col_r;

unsigned long _test_translucent_blender(unsigned long x, unsigned long y, unsigned long n)
{
    if ((y & 0xff000000) == 0)
        return x;
    unsigned long x_alpha = (x & 0xff000000) >> 24;
    if (x_alpha == 0xff)
        return x;
    if (x_alpha == 0)
        return y;

    unsigned long newAlpha = (x_alpha) | ((y & 0xff000000) >> 24);
    col_r.rgba.a = newAlpha;
    col_x.color = x;
    col_y.color = y;
    col_r.rgba.r = col_x.rgba.r > col_y.rgba.r ?
                   col_y.rgba.r + (col_x.rgba.r - col_y.rgba.r) * x_alpha / 0xff :
                   col_y.rgba.r - (col_y.rgba.r - col_x.rgba.r) * x_alpha / 0xff;
    col_r.rgba.g = col_x.rgba.r > col_y.rgba.g ?
                   col_y.rgba.g + (col_x.rgba.r - col_y.rgba.g) * x_alpha / 0xff :
                   col_y.rgba.g - (col_y.rgba.g - col_x.rgba.g) * x_alpha / 0xff;
    col_r.rgba.b = col_x.rgba.r > col_y.rgba.b ?
                   col_y.rgba.b + (col_x.rgba.b - col_y.rgba.b) * x_alpha / 0xff :
                   col_y.rgba.b - (col_y.rgba.b - col_x.rgba.b) * x_alpha / 0xff;
    return col_r.color;
}
[close]


My questions:
1. What is the expected behavior in this case? Do I at least go in right direction?
2. Is my code okay, or could be simplified?
3. What to do with alpha-blending over magic pink areas? Should the really look like that?

SMF spam blocked by CleanTalk