-
Notifications
You must be signed in to change notification settings - Fork 162
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AGS 4: support alpha-blending DrawingSurface operations #2661
AGS 4: support alpha-blending DrawingSurface operations #2661
Conversation
6b8ea3f
to
ab95107
Compare
This looks alright, and it appears it works. I also made a fix for the CI that should prevent the unrelated CI failure you had here. I noticed that the blend mode settings is global, and not a set of that particular drawing surface, which is why I understood it requires the start and end brush calls wrapping things. |
That is true, and that's the most annoying thing in Allegro 4. IMO the proper API would have a kind of a "drawing context" object, which holds all the drawing settings. Strangely, they still don't have that in Allegro 5 either, although, judging by the docs, they at least have separate blending settings per thread. In our case we cannot have any drawing operations on separate threads even if they are done on separate bitmaps, or we'd have to lock mutex everywhere any drawing mode is set. I believe that's the biggest reason to replace allegro 4 code with another drawing lib. (Of course there's also an option to adjust it ourselves, but idk how well worth that would be) |
ab95107
to
0565ff8
Compare
Rebased with some minor fixes. I also tried to add BlendMode to drawing operations today, but it turned out that the existing software implementation of blend modes completely ignores destination alpha, and produces zero final alpha; so it sort of works in 24-bit mode. I cannot tell why it was done so, or how does it work with sprites... Perhaps @AlanDrake could shed some light on this? In order to use blendmode when raw drawing, we'd need a proper 32-bit variants of all blenders, that combine both alphas (from src and dst), and add final alpha too. Original AGSBlend plugin was doing that (judging by its code). |
IIRC the alpha blender variants for blend modes did not exists in allegro and were not needed at the time, so I went ahead with the simplest case. |
Hmm, I shall look into this separately then. |
Had to move blender.h/cpp to Common, because it contains our proper alpha blender, and other stuff.
0565ff8
to
bf19431
Compare
Alright, I will merge this, since this appears working. |
@AlanDrake I'm investigating these blenders now, and it looks like they got something wrong. Here where the final color is being combined: Lines 201 to 206 in c9367d9
The color shifts are opposite to the ones that AGS actually uses: ags/Engine/main/engine_setup.cpp Lines 81 to 84 in c9367d9
Did anyone notice any wrong colors in blend results previously? I am not sure if these were properly tested. Hmmm, this might explain why my previous tests gave such weird results. |
Allegro had these defs being assigned to
But they would change through engine_setup_color_conversions() and become the opposite. I suppose I should've paid more attention and used the makecol facilities. |
Resolve #1514
This lets DrawingSurface to make use of a alpha component in DrawingColor.
The implementation utilizes Allegro's
drawing_mode
that lets run a custom blender when drawing graphical primitives. DrawingSurface would check if the surface is 32-bit and assigned drawing color has non-opaque alpha component, in which case it sets "alpha blending mode". In this mode it will enable blending drawing before making a draw and disable after (so to not conflict with anything else drawn afterwards). Added internal StartDrawingWithBrush / EndDrawingWithBrush methods that handle that.DrawPixel has its own way, where it switches between Bitmap::PutPixel and Bitmap::BlendPixel.
Bitmap::BlendPixel is the new Bitmap method I wrote, that basically runs a active blender func over a single pixel, and then writes result into bitmap.
For string drawing, I added alpha handling directly into each of the Font Renderers, because they might have their own ways of drawing (and if we set anything in engine, that won't affect plugin font renderers anyway).
Following is the current state of alpha blending support for DrawingSurface methods:
On a side note, I suppose we may want to add a separate DrawingSurface function for writing pixels, which ignores blending, and always directly sets color value.