Jump to content

Some Graphical Examples using GDI+ Vol. I


UEZ
 Share

Recommended Posts

Added two more examples (rotating squares and plasma) - see my 1st post.

Plasma is very CPU intensive and thus very slow :)

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

The calculations are what slows it down. I tried making it so it made all the calculations first, but I'm doing something wrong. I believe I'm in the right directions though. See if this helps you.

;coded by UEZ 2009-01-11
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
Opt('MustDeclareVars', 1)

Global $hGUI, $hWnd, $hGraphic, $Bitmap, $Buffer, $Brush, $bluep, $v
Global $starting_point, $i, $j, $k, $red[1000][1000], $green[1000][1000], $blue[1000][1000], $color[1000][1000], $r

Global Const $Pi = 3.1415926535897932384626
Global Const $width = 180 
Global Const $height = 180 


$hGUI = GUICreate("GDI+: Plasma by UEZ 2009", $width, $height)
$hWnd = WinGetHandle($hGUI)
GUISetState()

_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd);create graphic
$Bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphic);create bitmap
$Buffer = _GDIPlus_ImageGetGraphicsContext($Bitmap);create buffer
;~ AntiAlias($Buffer, 4)
_GDIPlus_GraphicsClear($Buffer);clear buffer
$bluep = 0
$r = 0
$v = 0
Global $square_x = 6
Global $square_y = 6
Do
    $r += ATan(-0.007)
    $v += 1
    For $i = 0 To $height Step $square_y
        For $j = 0 To $width Step $square_x
            $red[$i][$j] = ((-Sin(3 * ($j-$square_y) / 2^9) - $r + 1) / 2) * 256
            $green[$i][$j] = $red[$i][$j] * ((-Cos(2 * ($i-$square_y) / 2^9) - $r + 1) / 2) * 256
            $blue[$i][$j] = $bluep * ((Sin(2 * ($j-$square_y) / 2^9) + $r + 1) / 2) * 256
            $bluep = $blue[$i][$j]
$color[$i][$j] = _GDIPlus_BrushCreateSolid("0x07" & Hex($red[$i][$j], 2) & Hex($green[$i][$j], 2) & Hex($blue[$i][$j], 2))
        Next
    Next
Until $v = 3
Do
    $v += 1
For $a = 0 To $height Step $square_y
    For $b = 0 to $width Step $square_x
            _GDIPlus_GraphicsFillRect($Buffer, $a, $b, $square_x, $square_y, $color[$a][$b])
Next
    _GDIPlus_BrushDispose($Brush)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $Bitmap, 0, 0, $width, $height);copy to bitmap
    Sleep(1)
Next
Until $v = 6

    MsgBox(0,"","here")

; Clean up resources
_GDIPlus_GraphicsDispose ($hGraphic)
_GDIPlus_BitmapDispose($Bitmap)
_GDIPlus_GraphicsDispose($Buffer)
_GDIPlus_BrushDispose($Brush)
_GDIPlus_Shutdown ()


Func AntiAlias($hGraphics, $iMode)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", $iMode)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc  ;==>_AntiAlias

Giggity

Link to comment
Share on other sites

The calculations are what slows it down. I tried making it so it made all the calculations first, but I'm doing something wrong. I believe I'm in the right directions though. See if this helps you.

...

I don't agree because the effect is real time calculated. Of course you can pre-calculate it and save it to the memory and then give the effect the calculated numbers but I tried real time calculation.

The problem are the two For loops which takes O(n^2) time and this is too much. You can increase the $square values but it is not beautifull.

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

Hi UEZ,

Plasma is a memory hog..

Your only releasing one brush after creating 1400+ brushes.

Memory goes up by a couple of MB every couple of seconds..

Move the _GDIPlus_BrushDispose($Brush) into the same loop that your creating the $Brush in.

Cheers

Edit: Same thing goes for Rotating Squares example, move the _GDIPlus_PenDispose($Pen) into the same loop your creating the pen in.

Or Instead of creating a new pen every step, move the pen creation to before the loop and use _GDIPlus_PenSetColor() in the loop and dispose of then pen on exiting the example.

Edited by smashly
Link to comment
Share on other sites

Hi UEZ,

Plasma is a memory hog..

Your only releasing one brush after creating 1400+ brushes.

Memory goes up by a couple of MB every couple of seconds..

Move the _GDIPlus_BrushDispose($Brush) into the same loop that your creating the $Brush in.

Cheers

Edit: Same thing goes for Rotating Squares example, move the _GDIPlus_PenDispose($Pen) into the same loop your creating the pen in.

Or Instead of creating a new pen every step, move the pen creation to before the loop and use _GDIPlus_PenSetColor() in the loop and dispose of then pen on exiting the example.

Thanks you're right. It is a greedy memory eater... I will change the examples now.

Anyway, the calculation will not be faster...

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

Added another simple GDI+ example: Dragon Curve (see my 1st post as usual) :)

Currently exit function is buggy... sorry. Fixed -> thanks to smashly

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

Hi and thank you once again for the entertainment :)

Sorry to keep beating the same drum but...

Argggg, Once again your example is great, but memory gets used each loop and climbs over time.

GDI+ is a memory hog if you don't keep an eye on your code..

This is why we have functions like _GDIPlus_PenSetxxxxx() ...

As it is your creating a Pen every loop and only disposing of 1 pen on exit.

In your nice dragon example instead of creating a new pen every loop:

Create the pen outside loop..

Then in the loop set the color of the pen..

This way your code can run for hours or days or months without chewing any further memory then what was initially used to launch your code.

eg:

;coded by UEZ 2009-01-15
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
Opt('MustDeclareVars', 1)
HotKeySet("{ESC}", "_Exit")
Global Const $Pi = 3.1415926535897932384626
Global Const $width = 640
Global Const $height = 480
Global $hGUI, $hWnd, $hGraphic, $Bitmap, $GDI_Buffer, $Pen

; Create GUI
$hGUI = GUICreate("GDI+: Dragon Curve by UEZ 2009", $width, $height)
$hWnd = WinGetHandle($hGUI)
GUISetState()

_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
$Bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphic)
$GDI_Buffer = _GDIPlus_ImageGetGraphicsContext($Bitmap)

$Pen = _GDIPlus_PenCreate(0, 1) ; create a pen to use later on

_GDIPlus_GraphicsSetSmoothingMode($GDI_Buffer, 2) ; AntiAlias
;~ AntiAlias($GDI_Buffer, 2)

_GDIPlus_GraphicsClear($GDI_Buffer)

Global $angle = 0
Global $x1 = $width / 4, $y1 = $height / 3, $x2, $y2
Global Const $size = 384
Global $depth = 8

While 1
    Dragon($size, $depth, 1)
    $depth = Random(7, 16, 1)
    Sleep(3000)
    _GDIPlus_GraphicsClear($GDI_Buffer) ;clear buffer
    $x1 = $width / 4
    $y1 = $height / 3
WEnd
_Exit()

Func _Exit()
    ; Clean up resources
    _GDIPlus_PenDispose($Pen)
    _GDIPlus_GraphicsDispose($GDI_Buffer)
    _GDIPlus_BitmapDispose($Bitmap)
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
EndFunc

Func AntiAlias($hGraphics, $iiMode)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", $iiMode)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_AntiAlias

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

Func Forward($length)
    $x2 = $x1 + Cos($angle) * $length
    $y2 = $y1 + Sin($angle) * $length
    Local $red = ((Sin(1 * $x1 / 2^5) + 1) / 2) * 256
    Local $green = ((Sin(1 * $y1 / 2^6) + 1) / 2) * 256
    Local $blue = ((Sin(1 * ($x2 + $y2) / 2^7) + 1) / 2) * 256
    _GDIPlus_PenSetColor($Pen, "0xEF" & Hex($red, 2) & Hex($green, 2) & Hex($blue, 2)) ;Set the pen color
    _GDIPlus_GraphicsDrawLine($GDI_Buffer, $x1, $y1, $x2, $y2, $Pen)   
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $Bitmap, 0, 0, $width, $height)
    $x1 = $x2
    $y1 = $y2
EndFunc

Func Dragon($length, $split, $d)
    If $split = 0 Then
        Forward($length)
    Else
        Turn($d * 45) ;+
        Dragon($length / Sqrt(2), $split - 1, 1) ;R
        Turn(-$d * 90) ;--
        Dragon($length / Sqrt(2), $split - 1, -1) ;L
        Turn($d * 45) ;+
    EndIf
    Sleep(1)
EndFuncoÝ÷ Ù8^±©¬~ðéî²)àn»¬ë½éí «­¢+wöÁ ùn±@Åv¬m«Þ¶¬zÛ('[®ë!rh­«('­
·µæ®ë!¢ël×)jwpéò¢éÞyÖ§{(Þuºî²§jZ(§*.q©ãºËlzÛayÊ%¢´áÌÊåËVëºÈb²wuçZØ­ßÛjÌ­¡Ø¬¦¡ðkºÈlz×(ߺw-ãºËbƬ{*.®)í­ë-yÖ®¶­sc²4eTä5Dôâ2ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓУ²æÖRââââââââââã¢ôtDÇW5ô''W66WE6öÆD6öÆ÷ £²FW67&Föâââã¢6WBFR6öÆ÷"öb6öÆB''W6ö&¦V7@£²7çFââââââââã¢ôtDÇW5ô''W66WE6öÆD6öÆ÷"b33c¶''W6²b33c¶$t"ÒdcÒ£²&ÖWFW'2âââã¢b33c¶''W6ÒæFÆRFò''W6ö&¦V7@£²b33c¶$t"ÒÇÂ&VBÂw&VVâæB&ÇVR6ö×öæVçG2öb''W6£²&WGW&âfÇVW2ã¢7V66W72ÒG'VP£²fÇW&RÒfÇ6P£²WF÷"âââââââã £²ÖöFfVBââââââã¢6Ö6Ç£²&VÖ&·2ââââââã £²&VÆFVBââââââ㢣²Ææ²âââââââââã²×6FäÆæ´vF6WE6öÆDfÆÄ6öÆ÷ £²W×ÆRââââââã²W0£²ÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓÓФgVæ2ôtDÇW5ô''W66WE6öÆD6öÆ÷"b33c¶''W6Âb33c¶$t"Òdc Æö6Âb33c¶&W7VÇ@  b33c¶&W7VÇBÒFÆÄ6ÆÂb33c¶vtDFÆÂÂgV÷C¶çBgV÷C²ÂgV÷C´vF6WE6öÆDfÆÄ6öÆ÷"gV÷C²ÂgV÷C¶væBgV÷C²Âb33c¶''W6ÂgV÷C¶çBgV÷C²Âb33c¶$t" bW'&÷"FVâ&WGW&â6WDW'&÷"W'&÷"ÂWFVæFVB &WGW&â6WDW'&÷"b33c¶&W7VÇE³ÒÂÂb33c¶&W7VÇE³ÒÒ¤VæDgVæ2³ÓÒfwCµôtDÇW5ô''W66WE6öÆD6öÆ÷

Cheers

Link to comment
Share on other sites

Very cool example!

@smashly, is it okay if I write a small example and submit it to Gary? I would leave you as the author of course :)

Hi monoceres,

I've already posted it to gary, along with _GDIPlus_BrushGetSolidColor()

Hopefully he'll get some time eventually to look at and add it.

Cheers

Link to comment
Share on other sites

verry nice indeed. mind if i try to make a screen saver?

@UEZ how is the number of boxex calculated on the flying boxex example?

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

Hi and thank you once again for the entertainment :)

Sorry to keep beating the same drum but...

Argggg, Once again your example is great, but memory gets used each loop and climbs over time.

GDI+ is a memory hog if you don't keep an eye on your code..

This is why we have functions like _GDIPlus_PenSetxxxxx() ...

As it is your creating a Pen every loop and only disposing of 1 pen on exit.

In your nice dragon example instead of creating a new pen every loop:

Create the pen outside loop..

Then in the loop set the color of the pen..

This way your code can run for hours or days or months without chewing any further memory then what was initially used to launch your code.

eg: ...

Cheers

smashly, it was too late yesterday and I got square eyes sitting in front of the screen. Anyway, I hope I can act on your advice soon and make it better on next examples. THANKS again!

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

verry nice indeed. mind if i try to make a screen saver?

@UEZ how is the number of boxex calculated on the flying boxex example?

The source codes are free for all - thus use it as you like!

You can influence the distance between squares by changing the Step count: more means the distances is higher between squares:

For $j = 1 To $k Step 16

The amount of squares is save in variable $k -> $k = 2^9 means create 512 squares.

I hope this helps to understand.

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

Any suggestion how to quit example smoothly? Because when pressing "ESC" scripts ends with an error:

C:\Program Files\AutoIt3\Include\GDIPlus.au3 (1520) : ==> Subscript used with non-Array variable.:

E.g. during recursion phase (drawing the dragon curve) check escape keystroke

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

Any suggestion how to quit example smoothly? Because when pressing "ESC" scripts ends with an error:

C:\Program Files\AutoIt3\Include\GDIPlus.au3 (1520) : ==> Subscript used with non-Array variable.:

E.g. during recursion phase (drawing the dragon curve) check escape keystroke

UEZ

Hi,

Yep that error is due to a bad error return/handling in the function _GDIPlus_GraphicsDrawImageRect().

The reason the error happens is _GDIPlus_GraphicsDrawImageRect() is being called after GDIPlus has been shutdown.

As you can guess I was the one that submitted that function for GDIPlus.au3 UDF...lol

The function needs the error return corrected in the GDIPlus UDF to match the way all the other current GDIPlus functions handle an error return when GDIPlus has been shutdown or not running and a GDIPlus function is being called.

To make your dragon exit smoothly call the exit from within the dragon function when notified by the Gui msg:

;coded by UEZ 2009-01-15
#include <GDIPlus.au3>

Opt('MustDeclareVars', 1)

Global Const $Pi = 3.1415926535897932384626
Global Const $width = 640
Global Const $height = 480
Global $hGUI, $hWnd, $hGraphic, $Bitmap, $GDI_Buffer, $Pen

Global $angle = 0
Global $x1 = $width / 4, $y1 = $height / 3, $x2, $y2
Global Const $size = 384
Global $depth = 8

; Create GUI
$hGUI = GUICreate("GDI+: Dragon Curve by UEZ 2009", $width, $height)
$hWnd = WinGetHandle($hGUI)
GUISetState()

_GDIPlus_Startup ()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hWnd)
$Bitmap = _GDIPlus_BitmapCreateFromGraphics($width, $height, $hGraphic)
$GDI_Buffer = _GDIPlus_ImageGetGraphicsContext($Bitmap)
$Pen = _GDIPlus_PenCreate(0, 1) ; create a pen to use later on
_GDIPlus_GraphicsSetSmoothingMode($GDI_Buffer, 2) ; AntiAlias
_GDIPlus_GraphicsClear($GDI_Buffer)

While 1
    Dragon($size, $depth, 1)
    $depth = Random(7, 16, 1)
    Sleep(1000)
    _GDIPlus_GraphicsClear($GDI_Buffer)
    $x1 = $width / 4
    $y1 = $height / 3
Wend

Func Dragon($length, $split, $d)
    ;Since the dragon function is recursing itself, add the exit here
    If GUIGetMsg() = -3 Then _Exit() 
    If $split = 0 Then
        Forward($length)
    Else
        Turn($d * 45) ;+
        Dragon($length / Sqrt(2), $split - 1, 1) ;R
        Turn(-$d * 90) ;--
        Dragon($length / Sqrt(2), $split - 1, -1) ;L
        Turn($d * 45) ;+
    EndIf
    Sleep(10)
EndFunc

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

Func Forward($length)
    $x2 = $x1 + Cos($angle) * $length
    $y2 = $y1 + Sin($angle) * $length
    Local $red = ((Sin(1 * $x1 / 2^5) + 1) / 2) * 256
    Local $green = ((Sin(1 * $y1 / 2^6) + 1) / 2) * 256
    Local $blue = ((Sin(1 * ($x2 + $y2) / 2^7) + 1) / 2) * 256
    _GDIPlus_PenSetColor($Pen, "0xEF" & Hex($red, 2) & Hex($green, 2) & Hex($blue, 2)) ;Set the pen color
    _GDIPlus_GraphicsDrawLine($GDI_Buffer, $x1, $y1, $x2, $y2, $Pen)   
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $Bitmap, 0, 0, $width, $height)
    $x1 = $x2
    $y1 = $y2
EndFunc

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

Cheers

Edited by smashly
Link to comment
Share on other sites

Hi,

Yep that error is due to a bad error return/handling in the function _GDIPlus_GraphicsDrawImageRect().

The reason the error happens is _GDIPlus_GraphicsDrawImageRect() is being called after GDIPlus has been shutdown.

As you can guess I was the one that submitted that function for GDIPlus.au3 UDF...lol

The function needs the error return corrected in the GDIPlus UDF to match the way all the other current GDIPlus functions handle an error return when GDIPlus has been shutdown or not running and a GDIPlus function is being called.

To make your dragon exit smoothly call the exit from within the dragon function when notified by the Gui msg:

...

Cheers

THANKS again smashly. I did something like that yesterday midnight but it didn't work. Maybe it was too late for me :)

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

Changed Dragon Curve code by adding 3 more L-System Fractals (Levy_C, Koch and Peano)!

See as usual my 1st post.

I will make a break creating GDI+ examples...

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

The source codes are free for all - thus use it as you like!

You can influence the distance between squares by changing the Step count: more means the distances is higher between squares:

For $j = 1 To $k Step 16

The amount of squares is save in variable $k -> $k = 2^9 means create 512 squares.

I hope this helps to understand.

UEZ

how do i make the time between squares not effect the number of squares?

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Link to comment
Share on other sites

how do i make the time between squares not effect the number of squares?

Do you mean the distance between the squares independent of number of squares?

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

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

×
×
  • Create New...