Jump to content

Slow recursion


UEZ
 Share

Recommended Posts

I wrote L-System Fractals using recursion but the drawing is relatively slow when I compare it with e.g. web based implementations.

Is this a limit of AutoIt or better say a limit of an interpreter language?

Of course it depends also on recursions depth...

Regards,

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

  • Replies 71
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Yes, AutoIt will be slower than many other solutions. It was designed for ease, not for speed.

I already thought it... :)

Thanks,

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

I looked at your code and the slowness doesn't seem to be related to recursion. I do see poor usage of GUIGetMsg().

Do you mean the line in each function which will be called recursively?

If GUIGetMsg() = -3 Then _Exit()

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Do you mean the line in each function which will be called recursively?

If GUIGetMsg() = -3 Then _Exit()

UEZ

You do know that GuiGetMsg() will PAUSE the script when nothing happened/returned?? There are also other things that could be changed to improve speed but I don't know by how much so I am not sure if they are worth the work
Link to comment
Share on other sites

Link to comment
Share on other sites

You do know that GuiGetMsg() will PAUSE the script when nothing happened/returned?? There are also other things that could be changed to improve speed but I don't know by how much so I am not sure if they are worth the work

The pause in GUIGetMsg is only something like 10 milliseconds. It doesn't stall your application like the C++ variant of the GUIGetMsg.
Link to comment
Share on other sites

The bottleneck is not the GUIGetMsg() function in each function.

When you comment out the the lines then you will see that it is NOT running faster!

How does AutoIt handle recursion?

E.g. if you implement Quicksort in two versions (1. with recursion and 2. with iteration) and benchmark it against time then the iteration should be faster in this case (not tested!). Or?

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

The slowness here is due to _GDIPlus_GraphicsDrawImageRect, if you use a timer you will see its taking 500 ms to redraw. You either need to use a different method for displaying the buffer or build the buffer up with entire image before redrawing.

Link to comment
Share on other sites

If anyone is feeling brave they can help me figure out the CachedBitmap Functions.

I created the following functions using this example.

_GDIPlus_CreateCachedBitmap($hBitmap,$hGraphics)

_GDIPlus_GdipDrawCachedBitmap($hGraphics,$pCachedBitmap)

_GDIPlus_DeleteCachedBitmap($pCachedBitmap)

This example uses the standard _GDIPlus_GraphicsDrawImage inside my WM_PAINT handler. I have commented out the call to _GDIPlus_GdipDrawCachedBitmap because it doesn't display anything and the return values are showing success.

CODE

#include <GuiConstantsEx.au3>

#include <GDIPlus.au3>

Global Const $GUI_Width = 1000

Global Const $GUI_Height = 1000

Global Const $PI = 3.14159265

Global $hGUI, $hGraphicGUI, $hBMPBuff, $hGraphic

Global $hCachedBitmap

_Main()

Func _Main()

$hGUI = GUICreate("GDI+", $GUI_Width, $GUI_Height)

GUISetBkColor(0xFFFFFF)

GUISetState()

_GDIPlus_Startup ()

$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GUI_Width, $GUI_Height, $hGraphicGUI) ;Create graphics buffer

$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

$hCachedBitmap = _GDIPlus_CreateCachedBitmap($hBMPBuff,$hGraphic)

_AntiAlias($hGraphic)

Hypotrochoid($hGraphic)

GUIRegisterMsg(0xF, "MY_PAINT") ;Register repaint handler

_WinAPI_RedrawWindow($hGUI, 0, 0, 2) ;Trigger repaint

Do

Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Clean up resources

_GDIPlus_GraphicsDispose ($hGraphic)

_GDIPlus_DeleteCachedBitmap($hCachedBitmap)

_GDIPlus_Shutdown ()

EndFunc ;==>_Main

;Func to redraw the BMP on PAINT MSG

Func MY_PAINT($hWnd, $MSG, $wParam, $lParam)

; Check, if the GUI with the Graphic should be repainted

If $hWnd = $hGUI Then

$Timer = TimerInit()

_GDIPlus_GraphicsClear($hGraphicGUI, 0xFFFFFFFF)

_GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ;WORKS OK

;_GDIPlus_GdipDrawCachedBitmap($hGraphic,$hCachedBitmap) ;NO ERRORS, NOTHING DISPLAYED

ConsoleWrite(TimerDiff($Timer) & @CRLF)

EndIf

EndFunc ;==>MY_PAINT

;------------------------------------

;CachedBitmap Functions

;------------------------------------

Func _GDIPlus_CreateCachedBitmap($hBitmap,$hGraphics)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipCreateCachedBitmap", "hwnd", $hBitmap,"hwnd", $hGraphics, "int*",0)

If @error Then Return SetError(@error, @extended, 0)

For $X = 0 to Ubound($aResult)-1

ConsoleWrite("[" & $X & "]: " & $aResult[$X] & @CRLF)

Next

ConsoleWrite(@CRLF)

Return SetError($aResult[0], 0, $aResult[3])

EndFunc

Func _GDIPlus_DeleteCachedBitmap($pCachedBitmap)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipDeleteCachedBitmap", "hwnd", $pCachedBitmap)

If @error Then Return SetError(@error, @extended, 0)

Return SetError($aResult[0], 0, $aResult[0])

EndFunc

Func _GDIPlus_GdipDrawCachedBitmap($hGraphics,$pCachedBitmap)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipDrawCachedBitmap", "hwnd", $hGraphics, "hwnd",$pCachedBitmap,"int",0,"int",0)

If @error Then Return SetError(@error, @extended, 0)

For $X = 0 to Ubound($aResult)-1

ConsoleWrite("[" & $X & "]: " & $aResult[$X] & @CRLF)

Next

ConsoleWrite(@CRLF)

Return SetError($aResult[0], 0, $aResult[0])

EndFunc

Func Hypotrochoid(ByRef $hG, $color = 0x7F000000)

$hPen = _GDIPlus_PenCreate()

_GDIPlus_PenSetColor($hPen, $color)

;_GDIPlus_PenSetWidth($hPen, 4)

#cs

$RR = 50

$r = -.25

$p = 25

$Q = 3

$m = 1

$n = 6

#ce

$RR = 250

$r = -.66

$p = 125

$Q = 15

$m = 1

$n = 6

$offset_x = $GUI_Width/2

$offset_y = $GUI_Height/2

$ox = 0

$oy = 0

$increment = 1 / 180 * $Pi

$increment /= 50

For $t = 0 to 2*$Pi Step $increment

;$x = ($RR - $r) * cos($t) + $p * cos((($RR - $r) / $r)*$t)

;$y = ($RR - $r) * sin($t) - $p * sin((($RR - $r) / $r)*$t)

;$x = ($RR + $r) * cos($t) + ($r + $p) * cos((($RR - $r) / $r)*$t) * 20

;$y = ($RR + $r) * sin($t) - ($r + $p) * sin((($RR - $r) / $r)*$t) * 20

$x = ($RR + $r) * cos($m * $t) + ($r + $p) * cos((($RR + $r) / $r)* $m * $t) + $Q * cos($n * $t)

$y = ($RR + $r) * sin($m * $t) - ($r + $p) * sin((($RR + $r) / $r)* $m * $t) + $Q * sin($n * $t)

;$x = 3 * cos($t)

;$y = sin($t)

;Enlarge

;$x *= 5

;$y *= 5

;Center

$x += $offset_x

$y += $offset_y

;Only set registration point when first coordinates are calculated

If $t <> 0 Then

_GDIPlus_GraphicsDrawLine ($hG, $ox, $oy, $x, $y, $hPen)

EndIf

$OX = $x

$OY = $y

Next

_GDIPlus_PenDispose ($hPen)

EndFunc

;$a = Outer side count

;$b = Inner side count

;$c = Outer relative distance

;$d = Outer rotation

;$e = Inner rotation

;$f = Overall amplitude

;$color = 0xAARRGGBB

Func Guilloche(ByRef $hG, $a, $b, $c, $d, $e, $f, $color = 0xFF000000)

$hPen = _GDIPlus_PenCreate()

_GDIPlus_PenSetColor($hPen, $color)

$offset_x = $GUI_Width/2

$offset_y = $GUI_Height/2

$ox = 0

$oy = 0

$increment = 1 / 180 * $Pi

For $n = 0 to 19

For $x = 0 to 2*$Pi Step $increment

$r = ($c + Sin($a*$x + $d)) + (($b + Sin($b*$x + $e)) - ($c + Sin($a*$x + $d))) * ($f + Sin($a*$x + $n/ $Pi))/2

;Convert angle and radius into absolute coordinates (from gui center)

$coord = Cartesian($offset_x,$offset_y,$x,$r*10)

;Only set registration point when first coordinates are calculated

If $X <> 0 Then

_GDIPlus_GraphicsDrawLine ($hG, $ox, $oy, $coord[0], $coord[1], $hPen)

EndIf

$OX = $coord[0]

$OY = $coord[1]

Next

Next

_GDIPlus_PenDispose ($hPen)

EndFunc

Func Cartesian($xxx, $yyy, $Theta, $Radius)

Local $Return[2]

$Return[0] = $xxx + ($Radius * Cos($Theta))

$Return[1] = $yyy - ($Radius * Sin($Theta))

Return $Return

EndFunc ;==>Angle

Func _AntiAlias($hGraphics)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)

If @error Then Return SetError(@error, @extended, False)

Return SetError($aResult[0], 0, $aResult[0] = 0)

EndFunc

Link to comment
Share on other sites

Here a compact, reduced to minimum, version of L-System Fractals - Pythagoras Tree only :

#include <GDIPlus.au3>
Opt('MustDeclareVars', 1)

Global Const $Pi = 3.1415926535897932384626
Global Const $width = 800
Global Const $height = 600
Global $hGUI, $hWnd, $hGraphic, $Pen
Global $angle = 0, $x1, $y1, $x2, $y2
Global $length, $depth, $dir, $degree, $dist_rel

$hGUI = GUICreate("GDI+: L-System Fractals by UEZ 2009", $width, $height)
$hWnd = WinGetHandle($hGUI)
GUISetState()

_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
$Pen = _GDIPlus_PenCreate(0, 1) ; create a pen to use later on
_GDIPlus_GraphicsSetSmoothingMode($hGraphic, 4) ; AntiAlias
_GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFFF)


$x1 = $width / 2
$y1 = $height / 1.1
$length = 110
$depth = 10
$dir = 1
$angle = 5
Pythagoras($length, $depth, $dir)
Sleep(1000*10)
_Exit()

Func Pythagoras($length, $split, $dir)
    If $split = 0 Then
        Pythagoras_Square($length)
    Else
        $dist_rel = Sqrt(3) / 2
        $degree = 30
        Pythagoras_Square($length)
        Forward_Only($length)
        Turn(-$dir * 1 * $degree)
        Pythagoras($length * $dist_rel, $split - 1, 1)
        Turn($dir * 3 * $degree)
        Forward_Only($length * $dist_rel)
        Pythagoras($length / 2, $split - 1, 1)
        Forward_Only(-$length * $dist_rel)
        Turn(-$dir * 2 * $degree)
        Forward_Only(-$length)
    EndIf
    Sleep(1)
EndFunc

Func Pythagoras_Square($length)
    Local $i
    For $i = 1 To 4
        Draw_and_Forward($length)
        Turn($dir * 90)
    Next
EndFunc

Func Turn ($degrees)
    $angle = $angle + ($degrees * $Pi / 180)
EndFunc

Func Draw_and_Forward($length)
    $x2 = $x1 + Cos($angle) * $length
    $y2 = $y1 + Sin($angle) * $length
    _GDIPlus_PenSetColor($Pen, "0x7F000000") ;Set the pen color
    _GDIPlus_GraphicsDrawLine($hGraphic, $x1, $y1, $x2, $y2, $Pen)
    $x1 = $x2
    $y1 = $y2
EndFunc

Func Forward_Only($length)
    $x2 = $x1 + Cos($angle) * $length
    $y2 = $y1 + Sin($angle) * $length
    $x1 = $x2
    $y1 = $y2
EndFunc


Func _Exit()
    ; Clean up resources
    _GDIPlus_PenDispose($Pen)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    Exit
EndFunc

Here you can measure the speed of recursion...

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

If anyone is feeling brave they can help me figure out the CachedBitmap Functions.

I created the following functions using this example.

_GDIPlus_CreateCachedBitmap($hBitmap,$hGraphics)

_GDIPlus_GdipDrawCachedBitmap($hGraphics,$pCachedBitmap)

_GDIPlus_DeleteCachedBitmap($pCachedBitmap)

This example uses the standard _GDIPlus_GraphicsDrawImage inside my WM_PAINT handler. I have commented out the call to _GDIPlus_GdipDrawCachedBitmap because it doesn't display anything and the return values are showing success.

CODE

#include <GuiConstantsEx.au3>

#include <GDIPlus.au3>

Global Const $GUI_Width = 1000

Global Const $GUI_Height = 1000

Global Const $PI = 3.14159265

Global $hGUI, $hGraphicGUI, $hBMPBuff, $hGraphic

Global $hCachedBitmap

_Main()

Func _Main()

$hGUI = GUICreate("GDI+", $GUI_Width, $GUI_Height)

GUISetBkColor(0xFFFFFF)

GUISetState()

_GDIPlus_Startup ()

$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GUI_Width, $GUI_Height, $hGraphicGUI) ;Create graphics buffer

$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

$hCachedBitmap = _GDIPlus_CreateCachedBitmap($hBMPBuff,$hGraphic)

_AntiAlias($hGraphic)

Hypotrochoid($hGraphic)

GUIRegisterMsg(0xF, "MY_PAINT") ;Register repaint handler

_WinAPI_RedrawWindow($hGUI, 0, 0, 2) ;Trigger repaint

Do

Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Clean up resources

_GDIPlus_GraphicsDispose ($hGraphic)

_GDIPlus_DeleteCachedBitmap($hCachedBitmap)

_GDIPlus_Shutdown ()

EndFunc ;==>_Main

;Func to redraw the BMP on PAINT MSG

Func MY_PAINT($hWnd, $MSG, $wParam, $lParam)

; Check, if the GUI with the Graphic should be repainted

If $hWnd = $hGUI Then

$Timer = TimerInit()

_GDIPlus_GraphicsClear($hGraphicGUI, 0xFFFFFFFF)

_GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ;WORKS OK

;_GDIPlus_GdipDrawCachedBitmap($hGraphic,$hCachedBitmap) ;NO ERRORS, NOTHING DISPLAYED

ConsoleWrite(TimerDiff($Timer) & @CRLF)

EndIf

EndFunc ;==>MY_PAINT

;------------------------------------

;CachedBitmap Functions

;------------------------------------

Func _GDIPlus_CreateCachedBitmap($hBitmap,$hGraphics)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipCreateCachedBitmap", "hwnd", $hBitmap,"hwnd", $hGraphics, "int*",0)

If @error Then Return SetError(@error, @extended, 0)

For $X = 0 to Ubound($aResult)-1

ConsoleWrite("[" & $X & "]: " & $aResult[$X] & @CRLF)

Next

ConsoleWrite(@CRLF)

Return SetError($aResult[0], 0, $aResult[3])

EndFunc

Func _GDIPlus_DeleteCachedBitmap($pCachedBitmap)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipDeleteCachedBitmap", "hwnd", $pCachedBitmap)

If @error Then Return SetError(@error, @extended, 0)

Return SetError($aResult[0], 0, $aResult[0])

EndFunc

Func _GDIPlus_GdipDrawCachedBitmap($hGraphics,$pCachedBitmap)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipDrawCachedBitmap", "hwnd", $hGraphics, "hwnd",$pCachedBitmap,"int",0,"int",0)

If @error Then Return SetError(@error, @extended, 0)

For $X = 0 to Ubound($aResult)-1

ConsoleWrite("[" & $X & "]: " & $aResult[$X] & @CRLF)

Next

ConsoleWrite(@CRLF)

Return SetError($aResult[0], 0, $aResult[0])

EndFunc

Func Hypotrochoid(ByRef $hG, $color = 0x7F000000)

$hPen = _GDIPlus_PenCreate()

_GDIPlus_PenSetColor($hPen, $color)

;_GDIPlus_PenSetWidth($hPen, 4)

#cs

$RR = 50

$r = -.25

$p = 25

$Q = 3

$m = 1

$n = 6

#ce

$RR = 250

$r = -.66

$p = 125

$Q = 15

$m = 1

$n = 6

$offset_x = $GUI_Width/2

$offset_y = $GUI_Height/2

$ox = 0

$oy = 0

$increment = 1 / 180 * $Pi

$increment /= 50

For $t = 0 to 2*$Pi Step $increment

;$x = ($RR - $r) * cos($t) + $p * cos((($RR - $r) / $r)*$t)

;$y = ($RR - $r) * sin($t) - $p * sin((($RR - $r) / $r)*$t)

;$x = ($RR + $r) * cos($t) + ($r + $p) * cos((($RR - $r) / $r)*$t) * 20

;$y = ($RR + $r) * sin($t) - ($r + $p) * sin((($RR - $r) / $r)*$t) * 20

$x = ($RR + $r) * cos($m * $t) + ($r + $p) * cos((($RR + $r) / $r)* $m * $t) + $Q * cos($n * $t)

$y = ($RR + $r) * sin($m * $t) - ($r + $p) * sin((($RR + $r) / $r)* $m * $t) + $Q * sin($n * $t)

;$x = 3 * cos($t)

;$y = sin($t)

;Enlarge

;$x *= 5

;$y *= 5

;Center

$x += $offset_x

$y += $offset_y

;Only set registration point when first coordinates are calculated

If $t <> 0 Then

_GDIPlus_GraphicsDrawLine ($hG, $ox, $oy, $x, $y, $hPen)

EndIf

$OX = $x

$OY = $y

Next

_GDIPlus_PenDispose ($hPen)

EndFunc

;$a = Outer side count

;$b = Inner side count

;$c = Outer relative distance

;$d = Outer rotation

;$e = Inner rotation

;$f = Overall amplitude

;$color = 0xAARRGGBB

Func Guilloche(ByRef $hG, $a, $b, $c, $d, $e, $f, $color = 0xFF000000)

$hPen = _GDIPlus_PenCreate()

_GDIPlus_PenSetColor($hPen, $color)

$offset_x = $GUI_Width/2

$offset_y = $GUI_Height/2

$ox = 0

$oy = 0

$increment = 1 / 180 * $Pi

For $n = 0 to 19

For $x = 0 to 2*$Pi Step $increment

$r = ($c + Sin($a*$x + $d)) + (($b + Sin($b*$x + $e)) - ($c + Sin($a*$x + $d))) * ($f + Sin($a*$x + $n/ $Pi))/2

;Convert angle and radius into absolute coordinates (from gui center)

$coord = Cartesian($offset_x,$offset_y,$x,$r*10)

;Only set registration point when first coordinates are calculated

If $X <> 0 Then

_GDIPlus_GraphicsDrawLine ($hG, $ox, $oy, $coord[0], $coord[1], $hPen)

EndIf

$OX = $coord[0]

$OY = $coord[1]

Next

Next

_GDIPlus_PenDispose ($hPen)

EndFunc

Func Cartesian($xxx, $yyy, $Theta, $Radius)

Local $Return[2]

$Return[0] = $xxx + ($Radius * Cos($Theta))

$Return[1] = $yyy - ($Radius * Sin($Theta))

Return $Return

EndFunc ;==>Angle

Func _AntiAlias($hGraphics)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)

If @error Then Return SetError(@error, @extended, False)

Return SetError($aResult[0], 0, $aResult[0] = 0)

EndFunc

Nice example but what is the benefit of cached bitmap?

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Creates a CachedBitmap object based on a Bitmap object and a Graphics

object. The cached bitmap takes the pixel data from the Bitmap object and

stores it in a format that is optimized for the display device associated

with the Graphics object.

Here is a short example in C++:

http://www.ayrware.com/articles/gdidoublebuffer.html

Edited by weaponx
Link to comment
Share on other sites

Aha, thanks for the information. Currently C/C++ is for me like reading Chinese :)

I hope I can start learning C/C++ soon so that I can understand source codes written C/C++ ....

All my GDI+ example using double buffering regardless whether it is really needed (L-System Fractals)!

Thanks,

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Well i've got my example working with the the BitmapCache functions, unfortunately the speed gain is miniscule.

_GDIPlus_GraphicsDrawImage ~386ms

_GDIPlus_GdipDrawCachedBitmap ~366ms

CODE

#include <GuiConstantsEx.au3>

#include <GDIPlus.au3>

Global Const $GUI_Width = 1000

Global Const $GUI_Height = 1000

Global Const $PI = 3.14159265

Global $hGUI, $hGraphicGUI, $hBMPBuff, $hGraphic

Global $hCachedBitmap

_Main()

Func _Main()

$hGUI = GUICreate("GDI+", $GUI_Width, $GUI_Height)

GUISetBkColor(0xFFFFFF)

GUISetState()

_GDIPlus_Startup ()

$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND ($hGUI)

$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GUI_Width, $GUI_Height, $hGraphicGUI) ;Create graphics buffer

$hGraphicDC = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

_AntiAlias($hGraphicDC)

Hypotrochoid($hGraphicDC)

$hCachedBitmap = _GDIPlus_CreateCachedBitmap($hBMPBuff,$hGraphicGUI)

GUIRegisterMsg(0xF, "MY_PAINT") ;Register repaint handler

_WinAPI_RedrawWindow($hGUI, 0, 0, 2) ;Trigger repaint

Do

Until GUIGetMsg() = $GUI_EVENT_CLOSE

; Clean up resources

_GDIPlus_GraphicsDispose ($hGraphic)

_GDIPlus_DeleteCachedBitmap($hCachedBitmap)

_GDIPlus_Shutdown ()

EndFunc ;==>_Main

;Func to redraw the BMP on PAINT MSG

Func MY_PAINT($hWnd, $MSG, $wParam, $lParam)

; Check, if the GUI with the Graphic should be repainted

If $hWnd = $hGUI Then

$Timer = TimerInit()

_GDIPlus_GraphicsClear($hGraphicGUI, 0xFFFFFFFF)

;_GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ;WORKS OK

_GDIPlus_GdipDrawCachedBitmap($hGraphicGUI,$hCachedBitmap) ;WORKS OK

ConsoleWrite(TimerDiff($Timer) & @CRLF)

EndIf

EndFunc ;==>MY_PAINT

;------------------------------------

;CachedBitmap Functions

;------------------------------------

Func _GDIPlus_CreateCachedBitmap($hBitmap,$hGraphics)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipCreateCachedBitmap", "hwnd", $hBitmap,"hwnd", $hGraphics, "int*",0)

If @error Then Return SetError(@error, @extended, 0)

;For $X = 0 to Ubound($aResult)-1

; ConsoleWrite("[" & $X & "]: " & $aResult[$X] & @CRLF)

;Next

ConsoleWrite(@CRLF)

Return SetError($aResult[0], 0, $aResult[3])

EndFunc

Func _GDIPlus_DeleteCachedBitmap($pCachedBitmap)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipDeleteCachedBitmap", "hwnd", $pCachedBitmap)

If @error Then Return SetError(@error, @extended, 0)

Return SetError($aResult[0], 0, $aResult[0])

EndFunc

Func _GDIPlus_GdipDrawCachedBitmap($hGraphics,$pCachedBitmap)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipDrawCachedBitmap", "hwnd", $hGraphics, "hwnd",$pCachedBitmap,"int",0,"int",0)

If @error Then Return SetError(@error, @extended, 0)

;For $X = 0 to Ubound($aResult)-1

; ConsoleWrite("[" & $X & "]: " & $aResult[$X] & @CRLF)

;Next

ConsoleWrite(@CRLF)

Return SetError($aResult[0], 0, $aResult[0])

EndFunc

Func Hypotrochoid(ByRef $hG, $color = 0x7F000000)

$hPen = _GDIPlus_PenCreate()

_GDIPlus_PenSetColor($hPen, $color)

;_GDIPlus_PenSetWidth($hPen, 4)

#cs

$RR = 50

$r = -.25

$p = 25

$Q = 3

$m = 1

$n = 6

#ce

$RR = 250

$r = -.66

$p = 125

$Q = 15

$m = 1

$n = 6

$offset_x = $GUI_Width/2

$offset_y = $GUI_Height/2

$ox = 0

$oy = 0

$increment = 1 / 180 * $Pi

$increment /= 50

For $t = 0 to 2*$Pi Step $increment

;$x = ($RR - $r) * cos($t) + $p * cos((($RR - $r) / $r)*$t)

;$y = ($RR - $r) * sin($t) - $p * sin((($RR - $r) / $r)*$t)

;$x = ($RR + $r) * cos($t) + ($r + $p) * cos((($RR - $r) / $r)*$t) * 20

;$y = ($RR + $r) * sin($t) - ($r + $p) * sin((($RR - $r) / $r)*$t) * 20

$x = ($RR + $r) * cos($m * $t) + ($r + $p) * cos((($RR + $r) / $r)* $m * $t) + $Q * cos($n * $t)

$y = ($RR + $r) * sin($m * $t) - ($r + $p) * sin((($RR + $r) / $r)* $m * $t) + $Q * sin($n * $t)

;$x = 3 * cos($t)

;$y = sin($t)

;Enlarge

;$x *= 5

;$y *= 5

;Center

$x += $offset_x

$y += $offset_y

;Only set registration point when first coordinates are calculated

If $t <> 0 Then

_GDIPlus_GraphicsDrawLine ($hG, $ox, $oy, $x, $y, $hPen)

EndIf

$OX = $x

$OY = $y

Next

_GDIPlus_PenDispose ($hPen)

EndFunc

;$a = Outer side count

;$b = Inner side count

;$c = Outer relative distance

;$d = Outer rotation

;$e = Inner rotation

;$f = Overall amplitude

;$color = 0xAARRGGBB

Func Guilloche(ByRef $hG, $a, $b, $c, $d, $e, $f, $color = 0xFF000000)

$hPen = _GDIPlus_PenCreate()

_GDIPlus_PenSetColor($hPen, $color)

$offset_x = $GUI_Width/2

$offset_y = $GUI_Height/2

$ox = 0

$oy = 0

$increment = 1 / 180 * $Pi

For $n = 0 to 19

For $x = 0 to 2*$Pi Step $increment

$r = ($c + Sin($a*$x + $d)) + (($b + Sin($b*$x + $e)) - ($c + Sin($a*$x + $d))) * ($f + Sin($a*$x + $n/ $Pi))/2

;Convert angle and radius into absolute coordinates (from gui center)

$coord = Cartesian($offset_x,$offset_y,$x,$r*10)

;Only set registration point when first coordinates are calculated

If $X <> 0 Then

_GDIPlus_GraphicsDrawLine ($hG, $ox, $oy, $coord[0], $coord[1], $hPen)

EndIf

$OX = $coord[0]

$OY = $coord[1]

Next

Next

_GDIPlus_PenDispose ($hPen)

EndFunc

Func Cartesian($xxx, $yyy, $Theta, $Radius)

Local $Return[2]

$Return[0] = $xxx + ($Radius * Cos($Theta))

$Return[1] = $yyy - ($Radius * Sin($Theta))

Return $Return

EndFunc ;==>Angle

Func _AntiAlias($hGraphics)

Local $aResult

$aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", 2)

If @error Then Return SetError(@error, @extended, False)

Return SetError($aResult[0], 0, $aResult[0] = 0)

EndFunc

Link to comment
Share on other sites

You do know that GuiGetMsg() will PAUSE the script when nothing happened/returned?? There are also other things that could be changed to improve speed but I don't know by how much so I am not sure if they are worth the work

Can you give some examples what could be coded better to improve speed?

Thanks,

UEZ

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Err....

$hGUI = GUICreate("GDI+: L-System Fractals by UEZ 2009", $width, $height)
 $hWnd = WinGetHandle($hGUI)

Read the documentation for GUICreate(), please. What is the return value of GUICreate()?

Thanks Valik.

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...