Uriziel01 Posted November 24, 2009 Posted November 24, 2009 Can someone give me a Autoit implementation of GDI+ double buffer i have some code and I want to avoid flickering. I now that it can be done by creating second DC, compatible bitmap and _WinAPI_BitBlt or (second way) by _GDIPlus_BitmapLockBits My script is only a example and I can make the entire script in entire diffrent way, I just need a key to solution of this problem: Code: expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <GDIPlus.au3> #include <WinAPI.au3> #include <Misc.au3> #include <Array.au3> _GDIPlus_Startup() Opt("MouseCoordMode", 2) $dll = DllOpen("user32.dll") $Gui=GUICreate("GameName",800,600,-1,-1) GUISetBkColor(0x303030, $Gui) $pic3=GUICtrlCreatePic("",0,0,800,600) $pic2=GUICtrlCreatePic("",10,10,500,500) $pic1=GUICtrlCreatePic("",3,110,100,100) GUISetState(@SW_SHOW) PicSetGraphics($pic3, 800, 600, @ScriptDir&"\gfx\grass.jpg",1,0) PicSetGraphics($pic2, 100, 100, @ScriptDir&"\gfx\explosion.png",4,0) PicSetGraphics($pic1, 100, 100, @ScriptDir&"\gfx\sprite.png",1,20) Local $ii=3 While 1 $ii+=1 if $ii=300 then $ii=0 ControlMove("GameName","",$pic1,110,$ii) _WinAPI_RedrawWindow($Gui,"", "", $RDW_INVALIDATE) sleep(15) $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then ExitLoop WEnd GUIDelete() Func PicSetGraphics($cID, $img_W, $img_H, $image_file,$scale,$rotate) Local $STM_SETIMAGE = 0x0172 Local $IMAGE_BITMAP = 0 Local $hWnd, $hBitmap, $hImage, $hGraphic, $hBrush, $hBrush1, $hbmp, $aBmp $hWnd = GUICtrlGetHandle($cID) ; $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hWnd) $hImage = _GDIPlus_BitmapCreateFromGraphics(($img_W*$scale)*3, ($img_H*$scale)*3, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage) if $rotate<>0 then $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixRotate($hMatrix, $rotate, "False") _GDIPlus_GraphicsSetTransform($hGraphic, $hMatrix) endif _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2) ;-----> All Graphics Here if $rotate<>0 then $hBitmap = _GDIPlus_ImageLoadFromFile($image_file) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, $img_w, $img_H, $img_W*$scale, $img_H*$scale) Else $hBitmap = _GDIPlus_ImageLoadFromFile($image_file) _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 0, 0, $img_W*$scale, $img_H*$scale) endif ; -----> End of all Graphics $hbmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $iX = _GDIPlus_ImageGetWidth ($hImage) $iY = _GDIPlus_ImageGetHeight ($hImage) $aBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hbmp) _WinAPI_RedrawWindow($Gui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) If $aBmp[0] <> 0 Then _WinAPI_DeleteObject($aBmp[0]) _WinAPI_DeleteObject($hbmp) _WinAPI_DeleteObject($hImage) _GDIPlus_BrushDispose($hBrush1) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBitmap) EndFunc ;==>PicSetGraphics Func _Quit() Exit EndFunc ;==>_Quit ; Func ntmem($i_PID = -1) If $i_PID <> -1 Then Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID) Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0]) DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0]) Else Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1) EndIf EndFunc ;==>ntmem
dantay9 Posted November 24, 2009 Posted November 24, 2009 Here is a double buffer template (i think made by monoceres) that I use all time. #include <GUIConstants.au3> #include <GDIplus.au3> Global Const $width = 600 Global Const $height = 400 Global $title = "GDI+" ; Build your GUI here Opt("GUIOnEventMode", 1) $hwnd = GUICreate($title, $width, $height) GUISetOnEvent($GUI_EVENT_CLOSE, "close") GUISetState() ; Load your GDI+ resources here: _GDIPlus_Startup() $graphics = _GDIPlus_GraphicsCreateFromHWND($hwnd) $bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $graphics) $backbuffer = _GDIPlus_ImageGetGraphicsContext($bitmap) While 1 _GDIPlus_GraphicsClear($backbuffer) ; Draw your GDI+ scene onto $backbuffer here _GDIPlus_GraphicsDrawImageRect($graphics, $bitmap, 0, 0, $width, $height) Sleep(10) WEnd Func close() _GDIPlus_GraphicsDispose($backbuffer) _GDIPlus_BitmapDispose($bitmap) _GDIPlus_GraphicsDispose($graphics) _GDIPlus_Shutdown() Exit EndFunc ;==>close
Uriziel01 Posted November 24, 2009 Author Posted November 24, 2009 (edited) With all the respect, where is the double buffering in you example? I can only see a normal GraphicsDrawImageRect function with only one DC? Or im wrong, meaby you can make a example with some example moving picture, I would really appreciate that. Thank you Edited November 24, 2009 by Uriziel01
UEZ Posted November 24, 2009 Posted November 24, 2009 (edited) Look here: http://www.autoitscript.com/forum/index.php?showtopic=87200A lot of GDI+ examples or seach in the forum!UEZ Edited November 24, 2009 by UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
dantay9 Posted November 24, 2009 Posted November 24, 2009 It isn't a working example. It was just a template to build on. I thought it would be easier if you had a clean example of how double buffering should work.
monoceres Posted November 24, 2009 Posted November 24, 2009 On 11/24/2009 at 8:40 PM, 'Uriziel01 said: With all the respect, where is the double buffering in you example? I can only see a normal GraphicsDrawImageRect function with only one DC? Or im wrong, meaby you can make a example with some example moving picture, I would really appreciate that. Thank you There are two handles. One to the screen and one to an offscreen buffer that will be drawn to the screen when all drawing is complete. Broken link? PM me and I'll send you the file!
Uriziel01 Posted November 24, 2009 Author Posted November 24, 2009 (edited) Ohhh, sorry everyone I did'nt looked it the script correctly, after seeing UEZ link (Enterprise Warp by youknowwho4eva) I have understood double-buffering trick in it Now I have second question, how can I make a one image from (for example) 32 images (tile based game map) ? Because it will need less % of CPU and BM's of RAM when I will render only one big image instead of 32 (or more) small ones, I think? And it will be faster to save this to a file and then read and display? Or meaby leave it in memory ? p.s-Im HORRIBLE sorry for my bad english, if you dont know what im talking about, please say, I will try to do it again more correctly. Thank you for the help! Edited November 24, 2009 by Uriziel01
UEZ Posted November 25, 2009 Posted November 25, 2009 Have a look also to monoceres' excellent example -> http://www.autoitscript.com/forum/index.php?showtopic=81580This might answer your question partly.UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ
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