AdmiralAlkex Posted October 12, 2010 Posted October 12, 2010 (edited) Anyone else thinks it would be cool if you could move data between a bitmap and a surface? It would be useful for both SDL and GDI+ users. If you use SDL: Load images from disc with GDI+ instead of big SDL_image. There's one problem with this, per-pixel alpha. I don't know why but it's just solid black. I would be very grateful for any help on this! If you use GDI+: Use SDL to blit to screen. SDL is faster, handles redrawing "automagically", and you doesn't need any "double-buffer template" to combat flickering. Here's an example demonstrating loading images with GDI+ for usage in SDL. The second image uses alpha to show the problem above. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <GDIPlus.au3> #Include "SDL.au3" Local $sFile1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _ & "\Examples\GUI\msoobe.jpg" ;Path to image1 Local $sFile2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _ & "\Examples\GUI\Torus.png" ;Path to image2 ;Initialize libraries _SDL_Init($_SDL_INIT_VIDEO) ;initialize SDL _GDIPlus_Startup() $pScreen = _SDL_GuiCreate(StringTrimRight(@ScriptName, 4), 1024, 768, 32, $_SDL_SWSURFACE) ;You can use zero on bbp and SDL will choose what it thinks is appropriate $hImage1 = _SDL_GDIPlus_ImageLoadFromFile($sFile1) _SDL_BlitSurface($hImage1, 0, $pScreen, 0) _SDL_FreeSurface($hImage1) $hImage2 = _SDL_GDIPlus_ImageLoadFromFile($sFile2) _SDL_BlitSurface($hImage2, 0, $pScreen, 0) _SDL_FreeSurface($hImage2) _SDL_Flip($pScreen) While 1 Sleep(10) WEnd Func _SDL_GDIPlus_ImageLoadFromFile($sFile) $hImage = _GDIPlus_ImageLoadFromFile($sFile) $iWidth = _GDIPlus_ImageGetWidth($hImage) $iHeight = _GDIPlus_ImageGetHeight($hImage) $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB) $Scan0 = DllStructGetData($Reslt, "Scan0") $pOldBitmap = _SDL_CreateRGBSurfaceFrom($Scan0, $iWidth, $iHeight, 32, $iWidth * 4, 0, 0, 0, 0) $pNewSurface = _SDL_CreateRGBSurface($_SDL_SWSURFACE, $iWidth, $iHeight, 32, 0, 0, 0, 0) ;If you set 0 for $iRmask, $iGmask, $iBmask, $iAmask it will be set to a default value _SDL_BlitSurface($pOldBitmap, 0, $pNewSurface, 0) _SDL_FreeSurface($pOldBitmap) _GDIPlus_BitmapUnlockBits($hImage, $Reslt) _GDIPlus_ImageDispose($hImage) Return $pNewSurface EndFuncAnd a quick example to show the extra speed you get with SDL: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <GDIPlus.au3> #Include "SDL.au3" #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) Global $iBlittingMethod = 1, $asBlittingMethod[4] = ["", "SDL", "GDI+", "GDI+wSDL"] HotKeySet("{SPACE}", "_Next") Local $iWidth = 800, $iHeight = 600 $hGui = GUICreate(StringTrimRight(@ScriptName, 4), $iWidth, $iHeight, 0, 0) EnvSet("SDL_WINDOWID", $hGui) _SDL_Init($_SDL_INIT_VIDEO) _GDIPlus_Startup() $hScreenSurface = _SDL_SetVideoMode($iWidth, $iHeight, 32, $_SDL_SWSURFACE) $hScreenGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hScreenGraphics) $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) GUISetState() GUISetOnEvent(-3, "_Exit") Global $iLoopCurrent = 0 AdlibRegister("_FPS", 1000) Do Switch $iBlittingMethod Case 1 _SDL_FillRect($hScreenSurface, 0, Random(0, 0xFFFFFF, 1)) _SDL_Flip($hScreenSurface) Case 2 $hBrush = _GDIPlus_BrushCreateSolid("0xFF" & Random(0, 0xFFFFFF, 1)) _GDIPlus_GraphicsFillRect($hScreenGraphics, 0, 0, $iWidth, $iHeight, $hBrush) _GDIPlus_BrushDispose($hBrush) Case 3 $hBrush = _GDIPlus_BrushCreateSolid("0xFF" & Random(0, 0xFFFFFF, 1)) _GDIPlus_GraphicsFillRect($hGraphics, 0, 0, $iWidth, $iHeight, $hBrush) _GDIPlus_BrushDispose($hBrush) $Reslt = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB) $Scan0 = DllStructGetData($Reslt, "Scan0") $pOldBitmap = _SDL_CreateRGBSurfaceFrom($Scan0, $iWidth, $iHeight, 32, $iWidth * 4, 0, 0, 0, 0) _SDL_BlitSurface($pOldBitmap, 0, $hScreenSurface, 0) _SDL_FreeSurface($pOldBitmap) _GDIPlus_BitmapUnlockBits($hBitmap, $Reslt) _SDL_Flip($hScreenSurface) EndSwitch $iLoopCurrent += 1 Until 0 Func _FPS() WinSetTitle($hGui, "", "Rendering with: " & $asBlittingMethod[$iBlittingMethod] & " (" & $iLoopCurrent & " FPS)") $iLoopCurrent = 0 EndFunc Func _Next() $iBlittingMethod += 1 If $iBlittingMethod = 4 Then $iBlittingMethod = 1 EndFunc Func _Exit() _SDL_Quit() Exit EndFuncIf you don't have the SDL udf already, download it from >HERE (you only need SDL.dll and SDL.au3 for the above code). Edited June 22, 2014 by AdmiralAlkex Xandy 1 .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
Authenticity Posted October 12, 2010 Posted October 12, 2010 You can use SDL_SetColorKey, so you only need 24 bits image. _SDL_SetColorKey($pNewSurface, $_SDL_SRCCOLORKEY, 0) _SDL_BlitSurface($pOldBitmap, 0, $pNewSurface, 0) According to the documentation: [RGBA]mask are the bitmasks used to extract that colour from a pixel. For instance, Rmask being FF000000 means the red data is stored in the most significant byte. Using zeros for the RGB masks sets a default value, based on the depth. (e.g. SDL_CreateRGBSurface(flags,w,h,32,0,0,0,0)However, using zero for the Amask results in an Amask of 0.
AdmiralAlkex Posted October 12, 2010 Author Posted October 12, 2010 (edited) That's a neat trick, as long as you don't need anything between fully opaque and fully transparent It looks like this now: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Include <GDIPlus.au3> #Include "SDL.au3" Local $sFile1 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _ & "\Examples\GUI\msoobe.jpg" ;Path to image1 Local $sFile2 = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\AutoIt", "InstallDir") _ & "\Examples\GUI\Torus.png" ;Path to image2 ;Initialize libraries _SDL_Init($_SDL_INIT_VIDEO) ;initialize SDL _GDIPlus_Startup() ;~ _MemTest() ;Uncomment and look at task manager. "Private Working Set" does increase a few MB, but how often do you load 10K images normally?? :P $pScreen = _SDL_GuiCreate(StringTrimRight(@ScriptName, 4), 1024, 768, 32, $_SDL_SWSURFACE) ;You can use zero on bbp and SDL will choose what it thinks is appropriate (but we want 32) $hImage1 = _SDL_GDIPlus_ImageLoadFromFile($sFile1) _SDL_BlitSurface($hImage1, 0, $pScreen, 0) _SDL_FreeSurface($hImage1) $hImage2 = _SDL_GDIPlus_ImageLoadFromFile($sFile2) _SDL_BlitSurface($hImage2, 0, $pScreen, 0) _SDL_FreeSurface($hImage2) _SDL_Flip($pScreen) While 1 Sleep(10) WEnd Func _SDL_GDIPlus_ImageLoadFromFile($sFile) $hImage = _GDIPlus_ImageLoadFromFile($sFile) $iWidth = _GDIPlus_ImageGetWidth($hImage) $iHeight = _GDIPlus_ImageGetHeight($hImage) $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iWidth, $iHeight, $GDIP_ILMREAD, $GDIP_PXF32ARGB) $Scan0 = DllStructGetData($Reslt, "Scan0") $pOldBitmap = _SDL_CreateRGBSurfaceFrom($Scan0, $iWidth, $iHeight, 32, $iWidth * 4, 0, 0, 0, 0) $pNewSurface = _SDL_CreateRGBSurface($_SDL_SWSURFACE, $iWidth, $iHeight, 32, 0, 0, 0, 0) ;If you set 0 for $iRmask, $iGmask, $iBmask it will be set to a default value _SDL_SetColorKey($pNewSurface, $_SDL_SRCCOLORKEY, 0) _SDL_BlitSurface($pOldBitmap, 0, $pNewSurface, 0) _SDL_FreeSurface($pOldBitmap) _GDIPlus_BitmapUnlockBits($hImage, $Reslt) _GDIPlus_ImageDispose($hImage) Return $pNewSurface EndFunc Func _MemTest() MsgBox(0, "", "Before array") Local $apSurfaces[10000] ;Uses about 1.4 GB memory MsgBox(0, "", "Before loading") For $iX = 0 To UBound($apSurfaces) -1 $apSurfaces[$iX] = _SDL_GDIPlus_ImageLoadFromFile($sFile2) Next MsgBox(0, "", "Before UNloading") For $iX = 0 To UBound($apSurfaces) -1 _SDL_FreeSurface($apSurfaces[$iX]) Next MsgBox(0, "", "After UNloading") EndFunc Thank you Authenticity! Edited October 16, 2010 by AdmiralAlkex .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
JScript Posted June 22, 2014 Posted June 22, 2014 @AdmiralAlkexHello friend, the download link has problems, see:ForbiddenYou don't have permission to access /amax/autoit/SDL.zip on this server.Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.JS http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!
AdmiralAlkex Posted June 22, 2014 Author Posted June 22, 2014 @AdmiralAlkex Hello friend, the download link has problems, see: JS Yes, unfortunately they discontinued their hosting service but I couldn't remember all the places where I linked to files on my site there. Thanks for telling me. If it is okay for you, please download the full SDL UDF from >HERE and you can extract the needed 2 files from there. If you prefer a smaller package (pay per MB internet?) then tell me and I will prepare a new small zip. .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
JScript Posted June 23, 2014 Posted June 23, 2014 Thanks for your attention!I've done the download, now I'm testing to see the possibilities of exchanging some functions. JS http://forum.autoitbrasil.com/ (AutoIt v3 Brazil!!!) Somewhere Out ThereJames Ingram Download Dropbox - Simplify your life!Your virtual HD wherever you go, anywhere!
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