[Port] Lava-Fraktal

  • Hi!

    James und ich haben mal das Lava-Fraktal mit überliegendem Noisefilter aus BASIC nach AutoIt geportet.
    Compiliert läuft das original etwa mit 200FPS und hat ne schöne Grafik. Das Autoit-Äquivalent läuft auf der gleichen Größe mit etwa .5FPS und Noise ist nicht mehr wirklich zu erkennen ^^ .

    Es handelt sich dabei wirklich um ein Äquivalent, alle BASIC Funktionen, wie die Pointer die im Speicher direkt auf die Pixel zeigen und die Farbpalette die mit RGB Werten überschrieben wird, werden fast 1:1 simuliert. Es ist nicht auf au3 optimiert.

    Naja, jedenfalls kann man mit den $FracHeight und $FracWidth kann man die Werte für das Skript festlegen.

    Viel Spaß damit.

  • Moin,

    (Wieder wurden keine Ressourcen freigegeben)

    Habe es bei 640x480 auf ca. 30 FPS gebracht. (Vorher um die 4-5)
    Es wird aber nur jeder 25te Pixel wirklich gezeichnet.

    Daher hab ich überlegt einfach ein kleines Bild zu zeichnen und das dann zu vergrößern.
    Die Effektive Auflösung ist damit um einen gewissen Faktor höher.
    Damit das ganze dann nicht mit 1-2 FPS gammelt wird jedes Bild gepuffert.

    Spoiler anzeigen
    [autoit]

    ; Dies ist eine geportete und emulierte Version des Lavafraktals.

    [/autoit] [autoit][/autoit] [autoit]

    ; Autor: minx, Jame1337
    ; Editiert: Mars

    [/autoit] [autoit][/autoit] [autoit]

    #include <WinAPI.au3>
    Opt('GUIOnEventMode', 1)

    [/autoit] [autoit][/autoit] [autoit]

    ; Größe der Anzeige. Bitte eine urch 2^n Teilbare Zahl, oder 1 nutzen.
    Global $iFaktor = 2

    [/autoit] [autoit][/autoit] [autoit]

    ; Größe der "Pixel". Je höher, desto niedriger ist die Qualität. Bitte eine durch 2^n Teilbare Zahl, oder 1 nutzen.
    Global $iDiv = 4

    [/autoit] [autoit][/autoit] [autoit]

    Global $iBreite = 320 * $iFaktor
    Global $iHoehe = 240 * $iFaktor

    [/autoit] [autoit][/autoit] [autoit]

    Global $iDivW = $iBreite/$iDiv
    Global $iDivH = $iHoehe/$iDiv

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGUI = GUICreate('Lava-Fraktal: 00 FPS', $iBreite, $iHoehe)

    [/autoit] [autoit][/autoit] [autoit]

    Global $user32 = DllOpen("user32.dll")
    Global $gdi32 = DllOpen("gdi32.dll")

    [/autoit] [autoit][/autoit] [autoit]

    Global $vImg = _Image_Create($iDivW, $iDivH)
    Global $hDC_Buf = DllStructGetData($vImg, 1, 1)
    Global $vBitmap = DllStructCreate('int[' & DllStructGetData($vImg, 1, 2) * DllStructGetData($vImg, 1, 3) * 4 & ']', DllStructGetData($vImg, 1, 4))

    [/autoit] [autoit][/autoit] [autoit]

    Global $aImg[90]

    [/autoit] [autoit][/autoit] [autoit]

    Global $1 = 21856 * $iFaktor, $2 = 18001 * $iFaktor, $3 = 18000 * $iFaktor, $4 = 21601 * $iFaktor

    [/autoit] [autoit][/autoit] [autoit]

    Global $sins[3601 * $iFaktor]
    Global $rands[18001 * $iFaktor]
    Global $n
    Global $aCol[$iBreite / $iDiv+1][$iHoehe / $iDiv+1], $f, $f2

    [/autoit] [autoit][/autoit] [autoit]

    ProgressOn('Bitte Warten', 'Die Bilder werden gepuffert','Sinus und Random Werte erzeugen...')

    [/autoit] [autoit][/autoit] [autoit]

    For $n = 0 To $1
    If ($n < $2) Then
    $rands[$n] = Random() * 32
    ElseIf ($n < $4) Then
    $sins[$n - $3] = 256 * Sin(($n - $3) * .0349)
    EndIf
    Next

    [/autoit] [autoit][/autoit] [autoit]

    For $p = 0 To 89 Step 1
    ProgressSet(10+$p, 'Bild Puffern: ' & $p+1 & '/90')
    $f = Mod(($f + 2), 180)
    $f2 = Mod(($f2 + 2), 50)
    For $r = 0 To $iHoehe Step $iDiv
    For $c = 0 To $iBreite Step $iDiv
    $aCol[$c / $iDiv][$r / $iDiv] = $sins[$r + $f] + $sins[$c + $f] + $sins[$r + $c] + $rands[$f2 * $r + $c]
    If $aCol[$c / $iDiv][$r / $iDiv] < 0 Then
    $aCol[$c / $iDiv][$r / $iDiv] = 0
    Else
    $aCol[$c / $iDiv][$r / $iDiv] = BitShift($aCol[$c / $iDiv][$r / $iDiv], -16)
    EndIf
    Next
    Next
    $aImg[$p] = _Image_Create($iDivW, $iDivH)
    $vBitmap = DllStructCreate('int[' & DllStructGetData($aImg[$p], 1, 2) * DllStructGetData($aImg[$p], 1, 3) * 4 & ']', DllStructGetData($aImg[$p], 1, 4))
    For $r = 0 To $iDivH-1 Step 1
    For $c = 0 To $iDivW-1 Step 1
    If $aCol[$c][$r] Then DllStructSetData($vBitmap, 1, $aCol[$c][$r], $c + $r*$iDivW + 1)
    Next
    Next
    Next

    [/autoit] [autoit][/autoit] [autoit]

    ProgressOff()

    [/autoit] [autoit][/autoit] [autoit]

    ; Den Kram löschen...
    $sins = 0
    $rands = 0
    $aCol = 0

    [/autoit] [autoit][/autoit] [autoit]

    Global $hDC_GUI = _WinAPI_GetDC($hGUI)
    GUISetOnEvent(-3, '_Exit', $hGUI)
    OnAutoItExitRegister('_Freigeben')

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState()
    GUISetBkColor(0)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    For $p = 0 To 89 Step 1
    _FPS(25)
    _WinAPI_BitBlt($hDC_Buf, 0, 0, $iDivW, $iDivH, DllStructGetData($aImg[$p],1,1),0,0,0xCC0020)
    WM_PAINT()
    Next
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _Freigeben()
    _WinAPI_ReleaseDC($hGUI, $hDC_GUI)
    _Image_Delete($vImg)
    For $i = 0 To 89 Step 1
    _Image_Delete($aImg[$i])
    Next
    DllClose($gdi32)
    DllClose($user32)
    EndFunc ;==>_Freigeben

    [/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

    [/autoit] [autoit][/autoit] [autoit]

    Func _FPS($s)
    Static $z = TimerInit(), $y
    Local $x = TimerDiff($z), $w = (1000 / $s - $x)
    $y += $w
    If $y < 0 Then $y = 0
    If $w < 0 Then $w = 0
    Sleep(Int($y / 10) * 10)
    $y -= Int($y / 10) * 10
    $z = TimerInit()
    Return $x / ($x + $w)
    EndFunc ;==>_FPS

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_PAINT()
    Local Static $iFPS, $iFPS_Timer = TimerInit()
    If TimerDiff($iFPS_Timer) > 1000 Then
    WinSetTitle($hGUI, '', 'Lava-Fraktal: ' & $iFPS & ' FPS')
    $iFPS = 0
    $iFPS_Timer = TimerInit()
    EndIf
    DllCall($gdi32, 'bool', 'StretchBlt', 'handle', $hDC_GUI, 'int', 0, 'int', 0, 'int', $iBreite, 'int', $iHoehe, 'handle', $hDC_Buf, 'int', 0, 'int', 0, 'int', $iDivW, 'int', $iDivH , 'dword', 0xCC0020)
    $iFPS += 1
    EndFunc ;==>WM_PAINT

    [/autoit] [autoit][/autoit] [autoit]

    Func _Image_Create($iW, $iH)
    Local $Ptr, $hDC, $hBmp, $tBMI, $aDIB, $vStruct
    $hDC = _WinAPI_CreateCompatibleDC(0)
    $tBMI = DllStructCreate($tagBITMAPINFO)
    DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI) - 4)
    DllStructSetData($tBMI, "Width", $iW)
    DllStructSetData($tBMI, "Height", -$iH)
    DllStructSetData($tBMI, "Planes", 1)
    DllStructSetData($tBMI, "BitCount", 32)
    $aDIB = DllCall($gdi32, 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBMI), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'uint', 0)
    $hBmp = $aDIB[0]
    $Ptr = $aDIB[4]
    _WinAPI_SelectObject($hDC, $hBmp)
    $vStruct = DllStructCreate('int[5]')
    DllStructSetData($vStruct, 1, $hDC, 1)
    DllStructSetData($vStruct, 1, $iW, 2)
    DllStructSetData($vStruct, 1, $iH, 3)
    DllStructSetData($vStruct, 1, $Ptr, 4)
    DllStructSetData($vStruct, 1, $hBmp, 5)
    Return $vStruct
    EndFunc ;==>_Image_Create

    [/autoit] [autoit][/autoit] [autoit]

    Func _Image_Delete(ByRef $vStruct)
    _WinAPI_DeleteObject(DllStructGetData($vStruct, 1, 5))
    _WinAPI_DeleteDC(DllStructGetData($vStruct, 1, 1))
    $vStruct = 0
    EndFunc ;==>_Image_Delete

    [/autoit]


    .
    .

  • Mit 1024x768 stürzt es ab...

    Code
    lalal.au3 (30) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.:
    pix($dc,$c,$r, ($sins[$r + $f] + $sins[$c + $f] + $sins[$r + $c] + $rands[$f2*$r + $c]))
    pix($dc,$c,$r, ($sins[$r + $f] + $sins[$c + $f] + $sins[$r + $c] + ^ ERROR
    ->22:20:45 AutoIT3.exe ended.rc:1
    >Exit code: 1	Time: 12.359
  • Es geht ja um das größte Feld der Zelle, minx ;)
    Also ich find die Mandelbrot sowie Juliamengr immrernoch am spannendsten ;)

    Es gibt sehr viele Leute, die glauben. Aber aus Aberglauben.
    - Blaise Pascal