Draw a semitransparent rectangle onto a drawing surface

Started by fernewelten, Sun 23/01/2022 01:46:04

Previous topic - Next topic

fernewelten

Hi folks,

I'm in a true-colour game. I've got a drawing surface. I'd like to draw a semitransparent black rectangle onto it, transparency 70 %. How do I do it?
Code: ags

DynamicSprite *ds = DynamicSprite.Create(500, 500, true);
DrawingSurface *dsu = ds.GetDrawingSurface();
// […]
dsu.DrawingColor = Game.GetColorFromRGB(0, 0, 0);
// And at this point, I lack a possibility to set the pen transparency.
dsu.DrawRectangle(10, 10, 20, 20);
dsu.Release();
object[6].Graphic = ds.Graphic;

eri0o

I think the only one in the API with a Transparency setting is the DrawingSurface.DrawImage command. So you need to do in two steps, first build a Dynamic Sprite that is the desired rectangle, and then use DrawingSurface.DrawImage to place it in the other dynamic sprite where you want with the desired transparency.

Crimson Wizard

#2
There are two major (years old) issues here:
1) there's a issue of AGS not having alpha in color API. The DrawingColor is even packed for 16-bit format, so you cannot set any 32-bit color but only certain range of these.
2) this may be clarfied, but I 99% believe that the raw drawing operations cannot account for the alpha channel, and would never blend the source pixels with the destination, but only plain copy over, thus replacing the alpha value.

So, yes, intermediate images seem to be the only way now, unless the raw drawing is overhauled in the engine.

fernewelten

#3
As I've just found out, at least DrawingSurface::DrawSurface does not work in 3.5.1 Patch 7 (bug report) even if we take into account that alpha values don't blend:The transparency parameter of that function seems to trigger the same calculation results not matter if 1 % is passed or 20 % or 70 %.

However, first tests seem to show that works properly in AGS 4, probably because AGS4 is SDL based.

I'll experiment with DrawingSurface.DrawImage next and see whether this'll help me for AGS 3.5.

Edit: DrawingSurface.DrawImage seems to work as expected.
Code: ags

DynamicSprite *ds;

function test(int transp)
{
    DynamicSprite *ds_work = DynamicSprite.CreateFromExistingSprite(ds.Graphic, true);
    DrawingSurface *dsuw = ds_work.GetDrawingSurface();
    dsuw.DrawingColor = Game.GetColorFromRGB(250, 255, 255);
    dsuw.DrawRectangle(10, 10, 50, 50);
    dsuw.Release();
    
    DrawingSurface *dsu = ds.GetDrawingSurface();
    dsu.DrawingColor = Game.GetColorFromRGB(250, 100, 100);
    dsu.DrawCircle(20, 20, 20);
    dsu.DrawImage(0, 0, ds_work.Graphic, transp);
    dsu.Release();
    player.Say("This is DrawImage with %d %% transparency", transp);
    ds_work.Delete();
}

function room_AfterFadeIn()
{
    ds = DynamicSprite.Create(50, 50, true);
    oTestTest.Graphic = ds.Graphic;
    
    test(99);
    test(70);
    test(20);
    test(1);
    test(0);
}

Crimson Wizard

Quote from: fernewelten on Sun 23/01/2022 16:53:59
However, first tests seem to show that works properly in AGS 4, probably because AGS4 is SDL based.

For the raw drawing we're still using allegro 4 library (we kept parts of it in 3.6.0/ags4). It could be a problem with the engine logic. I recall changing something in DrawImage/DrawSurface in 3.6.0, maybe that fixed this problem by occasion.

fernewelten

So, it seems that DrawingSurface::DrawSurface() specifically is broken in 3.5.1; DrawingSurface::DrawImage() is not.

SMF spam blocked by CleanTalk