adventuregamestudio / ags

AGS editor and engine source code
Other
697 stars 159 forks source link

AGS4: Attribute `DrawingSurface::DrawingTransparency` #1514

Open fernewelten opened 2 years ago

fernewelten commented 2 years ago

Describe the problem True-colour space provides a full-fledged alpha channel (RGBA). This alpha channel isn't easily accessible in AGS games.

In AGS, when you want to draw onto a DrawingSurface in true-colour games, you can set the pen colour with DrawingSurface::DrawingColor. However, there's no way to set the pen transparency. So convoluted workarounds are needed in order to draw semi-transparent shapes onto a surface.

Suggested change Introduce int DrawingSurface::DrawingTransparency to set the alpha channel value of the drawing pen.

The range of this attribute would need to be discussed: AFAIK, the real range of the alpha channel in true-colour space is [0 .. 255]. However, traditionally in AGS, alpha values are given in percent. This must by needs be inexact from the get-go, and 255 isn't an exact multiple of 100, so some percentages must by needs be “more inexact” than others.

We also need to discuss how this parameter should be handled in non-true-colour games, i.e., games where pixels can only be completely transparent or completely opaque.

ivan-mogilko commented 2 years ago

I mentioned this elsewhere, so will restate here. Besides finding a good script API for this feature there seem to be a couple of major problems blocking it:

  1. Currently the draw colours in AGS are represented in 16-bit range (at least ones settable by script API). Even though they are stored in 32-bit integer, they are remapped on assignment to match the range available for 16-bit graphics. Having DrawingTransparency as a separate field may potentially mitigate this issue (completely or to some extent), but otoh if you like DrawingColor to have alpha channel component instead, then solving it becomes a higher priority. Moving to full 32-bit color representation in all "color" fields is a must.

  2. IIRC all the primitive drawing operations (line, rectangle, and so on) in the graphics library are ignoring alpha channel: this has to be double checked, but they probably simply copy value over to dest. Properly using alpha channel would assume alpha-blending operations for primitive draws. Either this has to be implemented as a separate set of operations, or internally drawn on an intermediate bitmap and then result blended to the dest.

Perhaps it's worth to have at least p1 as a separate ticket.


In regards to the script API, this is of course an open topic and will be discussed further, but my IMHO currently is:

  1. If we keep color fields as integers, then 0-255 is a better range, and it should be a properly handled range, without any special edge values (e.g. currently internally there's a backward compatible treatment of 0 and 255 transparency which are given reverse meaning).
  2. Having transparency in floats in script API would only make sense if we also move colors to floats too. Personally, I don't think that's a good idea, as many people seemed to handle 0-255 ranges better than the 0-1 (and it's easier to paste values from the graphic software); but maybe times are changing, idk.
  3. I think that Alpha (or Opaqueness) property is better than Transparency, although old users may beg to differ.
  4. I think that it may be worth to (instead) include alpha component into DrawingColor and any other color field. This will let to have any color setting transparent without having to add extra fields each time. That would require to solve problem 1 from the first list.

EDIT: regarding p4 of imho, I may have a false memory, but I think @AlanDrake once suggested to have a argb Color property for every object in game, which would determine its blending operation (optionally replacing Tint and Transparency properties altogether, or used by these properties under the hood). Such property would also include alpha value.

fernewelten commented 2 years ago

I like the idea of having something like dsu.DrawingColor = Game.GetColorFromRGBA(250, 100, 100, 255); available (where the fourth “A” parameter would be optional and default to fully opaque), and all the primitives that the current libraries can provide.

But I can see that this is going to be a lot of work if the internal coding doesn't fully provide for the alpha channel yet.

AlanDrake commented 2 years ago

I remember we discussed about the use cases and limitations of Tint, that it could cover more uses if it were possible to also apply a pure color ove the sprite, but that had more to do with shaders. We had also discussed the possiblity of having a Color property inside Tint instead of separate R G B A integers, although in the case of Tint it would make more sense to have HSV, or HSL, or both, I don't know. Currently Tint works as a "HSV colorize filter" where RGB are the Hue/Saturation, "TintSaturation" is alpha opacity, and TintLuminance is Value (because real luminance would allow us to brighten it to white). A single RGBA Color should be capable of describing HSV and A, so yes, it could become a sub property of Tint, but I wouldn't replace player's transparency with it, unless we change the meaning of Tint. Because the alpha in that case is how much of the tinted filter to apply over the original sprite.

Then there's LightLevel that reused some of those values. This represents a Brigthness adjustment in HW, while SW rendering applies a flat white/black color (which would be directly translatable to HSL adjustment).

Both namings and implementations are misleading. Tint and Brightness should be made separate properties. Ideally Tint would embrace the full HSL adjustment range, so it's less limited. That would still come short for cases where tinting with flat colors other than white/black would be preferable, though.

Sorry for having derailed the topic with these separate topics.

Anyway, I agree with all points, @ivan-mogilko . DrawingColor should be handled natively as 32bit 0-255 values. "Alpha/Opacity" would be a good choice for a new parameter to phase out the deprecated awkward Transparency..

ivan-mogilko commented 1 year ago

Opened a ticket regarding 32-bit color values: #1980

But this ticket, I think, may be repurposed into proposal to support alpha channel during primitive drawing operations, as it's not clear whether it will work automatically with the allegro sources we're currently using. So, an extra work may be required for that purpose (also see my comment above).