Archaic Posted Thursday at 09:51 PM Posted Thursday at 09:51 PM Good day, I'm a bit in a pickle. I'm trying to repaint a Graphics object area with 100% alpha color over an already painted area. Basically, the intent is to "clear" the area. I can do it with the _GDIPlus_GraphicsClear function, I know. But, there are a few things to consider. My goal is to use animations. The working area is large, my dimensions are 1920x1080, full screen so to speak. With such a large area to clear with _GDIPlus_GraphicsClear in each frame, there are screen flickerings and it takes more time, than just to repaint the neccesary small area. Already tried that. Repainting the previous area with background color and then painting the next area is also not quite an option as the background will be dynamic (moving image). This would require reading all the pixel colors of the previous area of the background at that instance, adding extra delay per frame. I have been experimenting with "layers", bitmaps created with _GDIPlus_BitmapCreateFromScan0, using 32bpp plus alpha and filling each with specific content and drawing them to a final bitmap as the final frame and then to the window Graphics object. This removed any flickering from doing one thing at a time and the speed is also reasonable. But, repainting with full alpha also does not work. And clearing the Graphics object, basically adds a delay as with the main window Graphics object. Repainting with alpha just "paints over" the previous color instead completely changing the pixel. So, my question is: Is there a way to change a solid color pixel with just alpha, and so to turn it to the original Graphics object pixel? Just so it looks like default, before doing any painting. Here's a sample code of the issue. #include <GUIConstantsEx.au3> #include <GDIPlus.au3> Local $Gui = GUICreate("",200,200) GUISetState() Local $WindowGraphics = _GDIPlus_GraphicsCreateFromHWND($Gui) Local $Brush = _GDIPlus_BrushCreateSolid(0xFF00FF00) ; Green _GDIPlus_GraphicsFillRect($WindowGraphics,0,0,200,200,$Brush) _GDIPlus_BrushSetSolidColor($Brush,0x800000FF) ; Blue, 50% alpha, mixes with green _GDIPlus_GraphicsFillRect($WindowGraphics,0,0,200,200,$Brush) _GDIPlus_BrushSetSolidColor($Brush,0x00000000) ; Total alpha, no effect _GDIPlus_GraphicsFillRect($WindowGraphics,0,0,200,200,$Brush) Local $Msg While 1 $Msg = GUIGetMsg() If $Msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd GUIDelete() Can it be done using other UDF's, like WinAPI? GDIPlus encoders? DLL's? Some kind of GUI style? Or maybe some kind of hack into the Graphics object?
ahmet Posted Friday at 07:28 PM Posted Friday at 07:28 PM What about painting the rectangular region in white opaque color and the drawing that same region with the background color? If you paint with the white brush and then paint with original transparent brush you will get the original color.
Solution genius257 Posted Friday at 10:31 PM Solution Posted Friday at 10:31 PM Hi @Archaic. So I'm not 100% sure i get what you need. First of all, your sample code does not work, you are missing _GDIPlus_Startup at the very least. To clear the window graphics between frames with alpha content, you need to have a opaque color as the background. You can match the parent background-color, if possible. To mostly avoid the flickering, you need double buffering, like you mention with a in memory bitmap from _GDIPlus_BitmapCreateFromScan0 and paint the result to the window graphics. If i understand correctly you need to clear the in memory bitmap between frames, but _GDIPlus_GraphicsClear is too slow? If so you could always try changing CompositingMode with _GDIPlus_GraphicsSetCompositingMode with $GDIP_COMPOSITINGMODESOURCECOPY, draw your alpha color and flip back, but I think that is slower than using clear. GDI+ is not great for big images updating quick, so depending on your need for speed, you might need openGL, Direct2D/3D or something else that is GPU accelerated. To show your appreciation My highlighted topics: AutoIt Package Manager, AutoItObject Pure AutoIt, AutoIt extension for Visual Studio Code Github: AutoIt HTTP Server, AutoIt HTML Parser
Archaic Posted Friday at 11:45 PM Author Posted Friday at 11:45 PM @genius257 Thanks for the tip on OpenGL. Just found a a good example on this forum, worth checking out. Might actually suit my needs much better.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now