Jump to content
Sign in to follow this  
Luigi

Optimize GDI movement

Recommended Posts

Luigi

Greetings AutoIt scripters!

I wrote this little code, and it seems to me that sometimes the graph moves faster and sometimes slower.

It seems that the graph is less complex moves faster. And the graph is more complex moves slower.

Is there any way to speed up the performance?

Does anyone have can see it (slower) is or just on my PC?

Thanks

; first download image from...
; 'http://upload.wikimedia.org/wikipedia/commons/b/b2/Esperanza_de_vida.PNG'
; use arrow keys [up, down, left, right] to move map



#include <Array.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <GUIConstantsEx.au3>
Global $hGui, $hMsg, $active = True
Global $hGraphic, $hPen, $hBitmap, $hBackbuffer, $width = 800, $height = 600, $hImage, $old = 1

Global $iWidth = 820, $iHeight = 620, $aMove[4] = [0, 0, 0, 0]
Global $hDLL = DllOpen('user32.dll'), $iStep = 4, $xxx, $yyy, $iXX, $iYY, $movX = 0, $movY = 0

$hGui = GUICreate('Map move', $iWidth, $iHeight)
GUISetState(@SW_SHOWNORMAL)

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphic)
$hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
$hPenRed = _GDIPlus_PenCreate(0xFFFF0000)
$hPenGreen = _GDIPlus_PenCreate(0xFF00FF00)
$hPenArrow = _GDIPlus_PenCreate(0xFF00FF00)

Global $hEndCap = _GDIPlus_ArrowCapCreate(3, 6)
_GDIPlus_PenSetCustomEndCap($hPenArrow, $hEndCap)
_GDIPlus_PenSetWidth($hPenArrow, 3)

; download (a large) image from...
; 'http://upload.wikimedia.org/wikipedia/commons/b/b2/Esperanza_de_vida.PNG'
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '/img/Esperanza_de_vida.PNG')

$iXX = _GDIPlus_ImageGetWidth($hImage)
$iYY = _GDIPlus_ImageGetHeight($hImage)
$xxx = $iXX / 2
$yyy = $iYY / 2

; 25 LEFT ARROW key esquerda
; 26 UP ARROW key cima
; 27 RIGHT ARROW key direita
; 28 DOWN ARROW key baixo

;~ baixo e esquerda 28 25
;~ baixo e direita 28 27
;~ cima e esquerda 26 25
;~ cima e direita 26 27
;~ esquerda 25 0
;~ cima 26 1
;~ direita 27 2
;~ baixo 28 3

$hPen = _GDIPlus_PenCreate()
_GDIPlus_GraphicsClear($hBackbuffer)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
_update(1)
While 1
$hMsg = GUIGetMsg()
Switch $hMsg
Case $GUI_EVENT_CLOSE
_exit()
EndSwitch

For $xx = 0 To 3
If _IsPressed(25 + $xx, $hDLL) And Not $aMove Then
$aMove[$xx] = 2 ^ $xx
ElseIf Not _IsPressed(25 + $xx, $hDLL) And $aMove[$xx] Then
$aMove[$xx] = 0
EndIf
Next

If WinActive($hGui) Then
_update(_arrow($aMove[0] + $aMove[1] + $aMove[2] + $aMove[3]))
If Not $active Then
_update(1)
$active = True
EndIf
ElseIf Not WinActive($hGui) And $active Then
$active = False
EndIf
WEnd

Func _update($input = 0)
If Not $input And Not $old Then Return
;ConsoleWrite('|' & $aMove[0] & '|' & $aMove[1] & '|' & $aMove[2] & '|' & $aMove[3] & '| max<' & $input & '>' & @LF)
_GDIPlus_GraphicsClear($hBackbuffer, 0xF0FFFFFF)
_GDIPlus_GraphicsDrawImageRectRect($hBackbuffer, $hImage, $xxx, $yyy, 780, 580, 10, 10, 780, 580)
_box($hBackbuffer, 10, 10, 780, 580)
_GDIPlus_GraphicsDrawLine($hBackbuffer, 10, 300, 790, 300, $hPen)
_GDIPlus_GraphicsDrawLine($hBackbuffer, 400, 10, 400, 590, $hPen)
_curve($input)
_GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 10, 10, $width, $height)
If $input Then
$old = $input
Else
$old = 0
EndIf
EndFunc ;==>_update

Func _exit($input = '')
_GDIPlus_GraphicsDispose($hBackbuffer)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_PenDispose($hPen)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_PenDispose($hPenRed)
_GDIPlus_PenDispose($hPenGreen)
_GDIPlus_PenDispose($hPenArrow)

_GDIPlus_ArrowCapDispose($hEndCap)
_GDIPlus_Shutdown()
DllClose($hDLL)
Exit
EndFunc ;==>_exit

Func _box($hToGraphic, $xx, $yy, $ll, $aa)
Local $aBox[5][2]
$aBox[0][0] = 4
$aBox[1][0] = $xx
$aBox[1][1] = $yy
$aBox[2][0] = $xx + $ll
$aBox[2][1] = $yy
$aBox[3][0] = $xx + $ll
$aBox[3][1] = $yy + $aa
$aBox[4][0] = $xx
$aBox[4][1] = $yy + $aa
_GDIPlus_GraphicsDrawPolygon($hToGraphic, $aBox)
EndFunc ;==>_box

Func _arrow($input = 0)
Switch $input
Case 1
$xxx -= $iStep
Case 2
$yyy -= $iStep
Case 4
$xxx += $iStep
Case 8
$yyy += $iStep
Case 6
$xxx += $iStep
$yyy -= $iStep
Case 3
$xxx -= $iStep
$yyy -= $iStep
Case 12
$xxx += $iStep
$yyy += $iStep
Case 9
$xxx -= $iStep
$yyy += $iStep
EndSwitch
Return $input
EndFunc ;==>_arrow

Func _curve($input)
Local $pen
If $input Then
$pen = $hPenGreen
Else
$pen = $hPenRed
EndIf
Switch $input
Case 1
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 687, 513, $hPenArrow)
Case 2
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 713, 487, $hPenArrow)
Case 4
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 739, 513, $hPenArrow)
Case 8
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 713, 539, $hPenArrow)
Case 6
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 731, 494, $hPenArrow)
Case 3
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 694, 494, $hPenArrow)
Case 12
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 731, 531, $hPenArrow)
Case 9
_GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 694, 531, $hPenArrow)
EndSwitch
_GDIPlus_GraphicsDrawEllipse($hBackbuffer, 700, 500, 26, 26, $pen)
EndFunc ;==>_curve

Obs:

Hum... _GDIPlus_GraphicsSetSmoothingMode is applied in $hBitmap! Not in $hBackbuffer, maybe this is a reason for slowing?

Edited by detefon

Visit my repository

Share this post


Link to post
Share on other sites
UEZ

Avoid GDI+ operations in a GUIGetMsg() loop and use _WinAPI_BitBlt() instead:

; first download image from...
; 'http://upload.wikimedia.org/wikipedia/commons/b/b2/Esperanza_de_vida.PNG'
; use arrow keys [up, down, left, right] to move map



#include <Array.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#include <GUIConstantsEx.au3>

Opt("GUIOnEventMode", 1)

Global $hGui, $hMsg, $active = True
Global $hDC, $hDC_Backbuffer, $DC_Obj, $aResult, $hHBITMAP, $hPen, $hBackbuffer, $width = 800, $height = 600, $hImage, $old = 1

Global $iWidth = 820, $iHeight = 620, $aMove[4] = [0, 0, 0, 0]
Global $hDLL = DllOpen('user32.dll'), $iStep = 4, $xxx, $yyy, $iXX, $iYY, $movX = 0, $movY = 0

$hGui = GUICreate('Map move', $iWidth, $iHeight)
GUISetState(@SW_SHOWNORMAL)

_GDIPlus_Startup()
Global Const $ghGDI32Dll = DllOpen("gdi32.dll")

$aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", 0, "int", $GDIP_PXF32ARGB, "ptr", 0, "int*", 0)
$hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($aResult[6])
_GDIPlus_BitmapDispose($aResult[6])

$hDC  = _WinAPI_GetDC($hGUI)
$hDC_Backbuffer  = _WinAPI_CreateCompatibleDC($hDC)
$DC_Obj = _WinAPI_SelectObject($hDC_Backbuffer, $hHBITMAP)
$hBackbuffer = _GDIPlus_GraphicsCreateFromHDC($hDC_Backbuffer)

_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)



$hPenRed = _GDIPlus_PenCreate(0xFFFF0000)
$hPenGreen = _GDIPlus_PenCreate(0xFF00FF00)
$hPenArrow = _GDIPlus_PenCreate(0xFF00FF00)

Global $hEndCap = _GDIPlus_ArrowCapCreate(3, 6)
_GDIPlus_PenSetCustomEndCap($hPenArrow, $hEndCap)
_GDIPlus_PenSetWidth($hPenArrow, 3)

; download (a large) image from...
; 'http://upload.wikimedia.org/wikipedia/commons/b/b2/Esperanza_de_vida.PNG'
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '/img/Esperanza_de_vida.PNG')

$iXX = _GDIPlus_ImageGetWidth($hImage)
$iYY = _GDIPlus_ImageGetHeight($hImage)
$xxx = $iXX / 2
$yyy = $iYY / 2

; 25 LEFT ARROW key esquerda
; 26 UP ARROW key cima
; 27 RIGHT ARROW key direita
; 28 DOWN ARROW key baixo

;~ baixo e esquerda 28 25
;~ baixo e direita 28 27
;~ cima e esquerda 26 25
;~ cima e direita 26 27
;~ esquerda 25 0
;~ cima 26 1
;~ direita 27 2
;~ baixo 28 3

$hPen = _GDIPlus_PenCreate()
_GDIPlus_GraphicsClear($hBackbuffer)
_GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2)
_update(1)

GUISetOnEvent(-3, "_Exit")

While Sleep(10)
    For $xx = 0 To 3
        If _IsPressed(25 + $xx, $hDLL) And Not $aMove Then
            $aMove[$xx] = 2 ^ $xx
        ElseIf Not _IsPressed(25 + $xx, $hDLL) And $aMove[$xx] Then
            $aMove[$xx] = 0
        EndIf
    Next

    If WinActive($hGui) Then
        _update(_arrow($aMove[0] + $aMove[1] + $aMove[2] + $aMove[3]))
        If Not $active Then
            _update(1)
            $active = True
        EndIf
    ElseIf Not WinActive($hGui) And $active Then
        $active = False
    EndIf
WEnd

Func _update($input = 0)
    If Not $input And Not $old Then Return
    ;ConsoleWrite('|' & $aMove[0] & '|' & $aMove[1] & '|' & $aMove[2] & '|' & $aMove[3] & '| max<' & $input & '>' & @LF)
    _GDIPlus_GraphicsClear($hBackbuffer, 0xF0FFFFFF)
    _GDIPlus_GraphicsDrawImageRectRect($hBackbuffer, $hImage, $xxx, $yyy, 780, 580, 10, 10, 780, 580)
    _box($hBackbuffer, 10, 10, 780, 580)
    _GDIPlus_GraphicsDrawLine($hBackbuffer, 10, 300, 790, 300, $hPen)
    _GDIPlus_GraphicsDrawLine($hBackbuffer, 400, 10, 400, 590, $hPen)
    _curve($input)
    _WinAPI_BitBlt($hDC, 0, 0, $width, $height, $hDC_Backbuffer, 0, 0, 0x00CC0020) ;$SRCCOPY = 0x00CC0020
    If $input Then
        $old = $input
    Else
        $old = 0
    EndIf
EndFunc   ;==>_update

Func _exit($input = '')
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _WinAPI_SelectObject($hDC_Backbuffer, $DC_Obj)
    _WinAPI_DeleteObject($hHBITMAP)
    _WinAPI_ReleaseDC($hGUI, $hDC)

    _GDIPlus_PenDispose($hPen)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_PenDispose($hPenRed)
    _GDIPlus_PenDispose($hPenGreen)
    _GDIPlus_PenDispose($hPenArrow)

    _GDIPlus_ArrowCapDispose($hEndCap)
    _GDIPlus_Shutdown()
    DllClose($hDLL)
    DllClose($ghGDI32Dll)
    Exit
EndFunc   ;==>_exit

Func _box($hToGraphic, $xx, $yy, $ll, $aa)
    Local $aBox[5][2]
    $aBox[0][0] = 4
    $aBox[1][0] = $xx
    $aBox[1][1] = $yy
    $aBox[2][0] = $xx + $ll
    $aBox[2][1] = $yy
    $aBox[3][0] = $xx + $ll
    $aBox[3][1] = $yy + $aa
    $aBox[4][0] = $xx
    $aBox[4][1] = $yy + $aa
    _GDIPlus_GraphicsDrawPolygon($hToGraphic, $aBox)
EndFunc   ;==>_box

Func _arrow($input = 0)
    Switch $input
        Case 1
            $xxx -= $iStep
        Case 2
            $yyy -= $iStep
        Case 4
            $xxx += $iStep
        Case 8
            $yyy += $iStep
        Case 6
            $xxx += $iStep
            $yyy -= $iStep
        Case 3
            $xxx -= $iStep
            $yyy -= $iStep
        Case 12
            $xxx += $iStep
            $yyy += $iStep
        Case 9
            $xxx -= $iStep
            $yyy += $iStep
    EndSwitch
    Return $input
EndFunc   ;==>_arrow

Func _curve($input)
    Local $pen
    If $input Then
        $pen = $hPenGreen
    Else
        $pen = $hPenRed
    EndIf
    Switch $input
        Case 1
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 687, 513, $hPenArrow)
        Case 2
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 713, 487, $hPenArrow)
        Case 4
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 739, 513, $hPenArrow)
        Case 8
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 713, 539, $hPenArrow)
        Case 6
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 731, 494, $hPenArrow)
        Case 3
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 694, 494, $hPenArrow)
        Case 12
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 731, 531, $hPenArrow)
        Case 9
            _GDIPlus_GraphicsDrawLine($hBackbuffer, 713, 513, 694, 531, $hPenArrow)
    EndSwitch
    _GDIPlus_GraphicsDrawEllipse($hBackbuffer, 700, 500, 26, 26, $pen)
EndFunc   ;==>_curve
Edited 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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
Luigi

Thank you for you reply @UEZ, I will study your code, it have new things for me!


Visit my repository

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×