GDI+ Spielerei: Rolle aus Rechtecken

  • Moin,

    Hier mal ein kleines Skript welches Rollen aus Rechtecken in GDI+ zeichnen kann.

    Vllt kann man sowas ja zur Unterstützung eines Ladebalkens oder Ähnlichem mal einsetzen.
    (Dann sollte man die wenigen Frames aber puffern. Das sollte schnell gehen)

    "Skript"
    [autoit]

    #include <GDIPlus.au3>

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

    Opt('GUIOnEventMode', 1)
    Opt('MustDeclareVars', 1)

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

    Global Const $iFrameRate = 45

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

    Global Const $iHoehe = 480, $iBreite = Int($iHoehe * 4 / 3)
    Global $hGUI, $hBUF, $hBMP, $hGFX, $hBRU, $fLast, $iFPS = 0, $iTimer

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

    $hGUI = GUICreate('Beispiel:', $iBreite, $iHoehe)
    GUISetBkColor(0x000000, $hGUI)

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

    _GDIPlus_Startup()

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

    $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBMP = _GDIPlus_BitmapCreateFromGraphics($iBreite, $iHoehe, $hGFX)
    $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
    $hBRU = _GDIPlus_BrushCreateSolid()

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

    _GDIPlus_GraphicsClear($hBUF, 0xFF000000)
    WM_PAINT()

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

    OnAutoItExitRegister('_Freigeben')
    GUIRegisterMsg(0xF, 'WM_PAINT')
    GUISetOnEvent(-3, '_Exit', $hGUI)
    GUISetState(@SW_SHOW, $hGUI)

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

    $iTimer = TimerInit()

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

    While True
    _GDIPlus_GraphicsClear($hBUF, 0xFF000000)
    _Main()
    WM_PAINT()
    WEnd

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

    Func _Main()
    Local Static $iCounter = 0, $aARGB1[4] = [255, 255, 0, 0], $aARGB2[4] = [100, 0, 255, 0], $aARGB3[4] = [255, 0, 0, 255], $aARGB4[4] = [150, 0, 255, 255]
    _Rolle($hBUF, 5, 25, 25, $iBreite / 2 - 50, $iHoehe / 2 - 50, 20, $aARGB1, $iCounter, False)
    _Rolle($hBUF, 35, 25 + $iBreite / 2, 25, $iBreite / 2 - 50, $iHoehe / 2 - 50, 10, $aARGB2, $iCounter, False)
    _Rolle($hBUF, 25, 25, 25 + $iHoehe / 2, $iBreite / 2 - 50, $iHoehe / 2 - 50, 10, $aARGB3, $iCounter, True)
    _Rolle($hBUF, 25, 25 + $iBreite / 2, 25 + $iHoehe / 2, $iBreite / 2 - 50, $iHoehe / 2 - 50, 5, $aARGB4, $iCounter, True)
    $iCounter += 1
    If $iCounter = 360 Then $iCounter = 0
    EndFunc ;==>_Main

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

    Func _Rolle($hGFX, $iAnz, $iX, $iY, $iB, $iH, $iElementH, $aARGB, $iCounter, $iAlpha = False)
    Local $iT = $iH, $_Y[$iAnz], $_T[$iAnz], $_C[$iAnz], $iTMP_1, $iTMP_2
    For $i = 0 To $iAnz - 1 Step 1
    $_Y[$i] = $iH / 2 + _Sin($iCounter + (360 / $iAnz) * $i) * ($iH / 2 - $iElementH / 2) + $iY
    $_T[$i] = (2.5 + (-_Sin($iCounter + (360 / $iAnz) * $i + 90)) / 2) / 3
    Next
    For $x = 0 To $iAnz - 1 Step 1
    $iTMP_1 = 0
    $iTMP_2 = $_T[0]
    For $i = 1 To $iAnz - 1 Step 1
    If $iTMP_2 > $_T[$i] Then
    $iTMP_2 = $_T[$i]
    $iTMP_1 = $i
    EndIf
    Next
    _Balken($hGFX, $iX, $_Y[$iTMP_1], $iB, $iElementH, $_T[$iTMP_1], $aARGB, $iAlpha)
    $_T[$iTMP_1] = 10
    Next
    EndFunc ;==>_Rolle

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

    Func _Balken($hGFX, $iX, $iY, $iB, $iH, $iT, $aARGB, $iAlpha)
    Local $iTMP_1 = $iT ^ 3
    If $iAlpha Then
    _GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int($aARGB[0] * $iTMP_1), 2) & Hex(Int($aARGB[1] * $iTMP_1), 2) & Hex(Int($aARGB[2] * $iTMP_1), 2) & Hex(Int($aARGB[3] * $iTMP_1), 2))
    Else
    _GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int($aARGB[0]), 2) & Hex(Int($aARGB[1] * $iTMP_1), 2) & Hex(Int($aARGB[2] * $iTMP_1), 2) & Hex(Int($aARGB[3] * $iTMP_1), 2))
    EndIf
    _GDIPlus_GraphicsFillRect($hGFX, $iX + $iB / 2 - ($iB * $iT) / 2, $iY - ($iH * $iT) / 2, $iB * $iT, $iH * $iT, $hBRU)
    $iY += $iH
    EndFunc ;==>_Balken

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

    Func _Sin($a)
    Return Sin($a * 0.0174532925199433)
    EndFunc ;==>_Sin

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    Func _Freigeben()
    _GDIPlus_BrushDispose($hBRU)
    _GDIPlus_GraphicsDispose($hBUF)
    _GDIPlus_BitmapDispose($hBMP)
    _GDIPlus_GraphicsDispose($hGFX)
    _GDIPlus_Shutdown()
    EndFunc ;==>_Freigeben

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

    Func WM_PAINT()
    _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    $fLast += _FPS($iFrameRate)
    $iFPS += 1
    If TimerDiff($iTimer) > 1000 Then
    WinSetTitle($hGUI, '', 'FPS: ' & $iFPS & ' | Auslastung: ' & Round($fLast / $iFPS, 2) * 100 & '%')
    $iFPS = 0
    $fLast = 0
    $iTimer = TimerInit()
    EndIf
    EndFunc ;==>WM_PAINT

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

    Func _FPS($i)
    Local Static $_T = TimerInit(), $f
    Local $s = TimerDiff($_T), $l = (1000 / $i - $s)
    $f += $l
    If $f < 0 Then $f = 0
    If $l < 0 Then $l = 0
    Sleep(Int($f / 10) * 10)
    $f -= Int($f / 10) * 10
    $_T = TimerInit()
    Return $s / ($s + $l)
    EndFunc ;==>_FPS

    [/autoit]

    .

  • Gefällt mir super :D
    Da sieht man mal wieder, wie leicht das menschliche Auge zu täuschen ist, durch Farb und Größenspielerei :D

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

  • Sehr cooles Script! :thumbup:

    Allerdings ein kleiner Kritikpunkt: Du erstellst zwar einen Backbuffer, verwendest diesen aber nicht ;)

    Wenn du dann noch _GDIPlus_GraphicsSetSmoothingMode und GdipFillRectangle verwendest, dann ist die Bewegung smoother...

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>

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

    Opt('GUIOnEventMode', 1)
    Opt('MustDeclareVars', 1)

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

    Global Const $iFrameRate = 45

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

    Global Const $iHoehe = 480, $iBreite = Int($iHoehe * 4 / 3)
    Global $hGUI, $hBUF, $hBMP, $hGFX, $hBRU, $fLast, $iFPS = 0, $iTimer

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

    $hGUI = GUICreate('Beispiel:', $iBreite, $iHoehe)
    GUISetBkColor(0x000000, $hGUI)

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

    _GDIPlus_Startup()

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

    $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hBMP = _GDIPlus_BitmapCreateFromGraphics($iBreite, $iHoehe, $hGFX)
    $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
    $hBRU = _GDIPlus_BrushCreateSolid()
    _GDIPlus_GraphicsSetSmoothingMode($hBUF, 2)

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

    _GDIPlus_GraphicsClear($hBUF, 0xFF000000)
    WM_PAINT()

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

    OnAutoItExitRegister('_Freigeben')
    GUIRegisterMsg(0xF, 'WM_PAINT')
    GUISetOnEvent(-3, '_Exit', $hGUI)
    GUISetState(@SW_SHOW, $hGUI)

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

    $iTimer = TimerInit()

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

    While True
    _GDIPlus_GraphicsClear($hBUF, 0xFF000000)
    _Main()
    _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    WM_PAINT()
    WEnd

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

    Func _Main()
    Local Static $iCounter = 0, $aARGB1[4] = [255, 255, 0, 0], $aARGB2[4] = [100, 0, 255, 0], $aARGB3[4] = [255, 0, 0, 255], $aARGB4[4] = [150, 0, 255, 255]
    _Rolle($hBUF, 5, 25, 25, $iBreite / 2 - 50, $iHoehe / 2 - 50, 20, $aARGB1, $iCounter, False)
    _Rolle($hBUF, 35, 25 + $iBreite / 2, 25, $iBreite / 2 - 50, $iHoehe / 2 - 50, 10, $aARGB2, $iCounter, False)
    _Rolle($hBUF, 25, 25, 25 + $iHoehe / 2, $iBreite / 2 - 50, $iHoehe / 2 - 50, 10, $aARGB3, $iCounter, True)
    _Rolle($hBUF, 25, 25 + $iBreite / 2, 25 + $iHoehe / 2, $iBreite / 2 - 50, $iHoehe / 2 - 50, 5, $aARGB4, $iCounter, True)
    $iCounter += 1
    If $iCounter = 360 Then $iCounter = 0
    EndFunc ;==>_Main

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

    Func _Rolle($hGFX, $iAnz, $iX, $iY, $iB, $iH, $iElementH, $aARGB, $iCounter, $iAlpha = False)
    Local $iT = $iH, $_Y[$iAnz], $_T[$iAnz], $_C[$iAnz], $iTMP_1, $iTMP_2
    For $i = 0 To $iAnz - 1 Step 1
    $_Y[$i] = $iH / 2 + _Sin($iCounter + (360 / $iAnz) * $i) * ($iH / 2 - $iElementH / 2) + $iY
    $_T[$i] = (2.5 + (-_Sin($iCounter + (360 / $iAnz) * $i + 90)) / 2) / 3
    Next
    For $x = 0 To $iAnz - 1 Step 1
    $iTMP_1 = 0
    $iTMP_2 = $_T[0]
    For $i = 1 To $iAnz - 1 Step 1
    If $iTMP_2 > $_T[$i] Then
    $iTMP_2 = $_T[$i]
    $iTMP_1 = $i
    EndIf
    Next
    _Balken($hGFX, $iX, $_Y[$iTMP_1], $iB, $iElementH, $_T[$iTMP_1], $aARGB, $iAlpha)
    $_T[$iTMP_1] = 10
    Next
    EndFunc ;==>_Rolle

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

    Func _Balken($hGFX, $iX, $iY, $iB, $iH, $iT, $aARGB, $iAlpha)
    Local $iTMP_1 = $iT ^ 3
    If $iAlpha Then
    _GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int($aARGB[0] * $iTMP_1), 2) & Hex(Int($aARGB[1] * $iTMP_1), 2) & Hex(Int($aARGB[2] * $iTMP_1), 2) & Hex(Int($aARGB[3] * $iTMP_1), 2))
    Else
    _GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int($aARGB[0]), 2) & Hex(Int($aARGB[1] * $iTMP_1), 2) & Hex(Int($aARGB[2] * $iTMP_1), 2) & Hex(Int($aARGB[3] * $iTMP_1), 2))
    EndIf
    ;_GDIPlus_GraphicsFillRect($hGFX, $iX + $iB / 2 - ($iB * $iT) / 2, $iY - ($iH * $iT) / 2, $iB * $iT, $iH * $iT, $hBRU)
    DllCall($ghGDIPDll, "int", "GdipFillRectangle", "handle", $hBUF, "handle", $hBRU, "float", $iX + $iB / 2 - ($iB * $iT) / 2, "float", $iY - ($iH * $iT) / 2, "float", $iB * $iT, "float", $iH * $iT)
    $iY += $iH
    EndFunc ;==>_Balken

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

    Func _Sin($a)
    Return Sin($a * 0.0174532925199433)
    EndFunc ;==>_Sin

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    Func _Freigeben()
    _GDIPlus_BrushDispose($hBRU)
    _GDIPlus_GraphicsDispose($hBUF)
    _GDIPlus_BitmapDispose($hBMP)
    _GDIPlus_GraphicsDispose($hGFX)
    _GDIPlus_Shutdown()
    EndFunc ;==>_Freigeben

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

    Func WM_PAINT()
    _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    $fLast += _FPS($iFrameRate)
    $iFPS += 1
    If TimerDiff($iTimer) > 1000 Then
    WinSetTitle($hGUI, '', 'FPS: ' & $iFPS & ' | Auslastung: ' & Round($fLast / $iFPS, 2) * 100 & '%')
    $iFPS = 0
    $fLast = 0
    $iTimer = TimerInit()
    EndIf
    EndFunc ;==>WM_PAINT

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

    Func _FPS($i)
    Local Static $_T = TimerInit(), $f
    Local $s = TimerDiff($_T), $l = (1000 / $i - $s)
    $f += $l
    If $f < 0 Then $f = 0
    If $l < 0 Then $l = 0
    Sleep(Int($f / 10) * 10)
    $f -= Int($f / 10) * 10
    $_T = TimerInit()
    Return $s / ($s + $l)
    EndFunc ;==>_FPS

    [/autoit]

    E

  • Läuft flüssiger jetzt.

    Der Puffer wird in WM_PAINT genutzt. (bestimmt übersehen)
    Das GraphicsDrawImage kann aus der Hauptschleife also wieder raus.

    Die Funktionen für GDI+ die Float Angaben vertragen hielt ich immer für eine Legende^^
    Habe die auch irgendwann schonmal ausprobiert, aber ohne Erfolg.
    Edit: Aaaaah es liegt am Smoothing Mode ! Ohne Smoothing, keine Float Angaben.

    Das was hier Zeit schluckt ist das Zeichnen per GDI+ auf das GUI.
    Habe es jetzt mal auf BitBlt umgestellt.

    Bei mir ist jetzt ein kleines Ruckeln zu spüren...
    Ist das bei anderen auch der Fall ?

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WindowsConstants.au3>

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

    Opt('GUIOnEventMode', 1)
    Opt('MustDeclareVars', 1)

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

    Global Const $iFrameRate = 60

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

    Global Const $iHoehe = 600, $iBreite = Round($iHoehe * 4 / 3,0)
    Global $hGUI, $hBUF, $hBMP, $hGFX, $hBRU, $fLast, $iFPS = 0, $iTimer, $hDC, $hIMG

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

    $hGUI = GUICreate('Beispiel:', $iBreite, $iHoehe)
    GUISetBkColor(0x000000, $hGUI)
    WinSetTrans($hGUI, '', 255)

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

    _GDIPlus_Startup()

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

    ;~ $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    ;~ $hBMP = _GDIPlus_BitmapCreateFromGraphics($iBreite, $iHoehe, $hGFX)
    ;~ $hBUF = _GDIPlus_ImageGetGraphicsContext($hBMP)
    $hBRU = _GDIPlus_BrushCreateSolid()

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

    $hDC = _WinAPI_GetDC($hGUI)
    $hIMG = _Image_Create($iBreite, $iHoehe)
    $hBUF = _GDIPlus_GraphicsCreateFromHDC(DllStructGetData($hIMG, 1, 1))
    _GDIPlus_GraphicsSetSmoothingMode($hBUF, 2)

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

    _GDIPlus_GraphicsClear($hBuf, 0xFF000000)
    WM_PAINT()

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

    OnAutoItExitRegister('_Freigeben')
    GUIRegisterMsg(0xF, 'WM_PAINT')
    GUISetOnEvent(-3, '_Exit', $hGUI)
    GUISetState(@SW_SHOW, $hGUI)

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

    $iTimer = TimerInit()

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

    While True
    _GDIPlus_GraphicsClear($hBuf, 0xFF000000)
    _Main()
    WM_PAINT()
    WEnd

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

    Func _Main()
    Local Static $iCounter = 0, $aARGB1[4] = [255, 255, 0, 0], $aARGB2[4] = [100, 0, 255, 0], $aARGB3[4] = [255, 0, 0, 255], $aARGB4[4] = [150, 0, 255, 255]

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

    _Rolle($hBUF, 5, 25, 25, $iBreite / 2 - 50, $iHoehe / 2 - 50, 20, $aARGB1, $iCounter, False)
    _Rolle($hBUF, 35, 25 + $iBreite / 2, 25, $iBreite / 2 - 50, $iHoehe / 2 - 50, 10, $aARGB2, $iCounter, False)
    _Rolle($hBUF, 25, 25, 25 + $iHoehe / 2, $iBreite / 2 - 50, $iHoehe / 2 - 50, 10, $aARGB3, $iCounter, True)
    _Rolle($hBUF, 25, 25 + $iBreite / 2, 25 + $iHoehe / 2, $iBreite / 2 - 50, $iHoehe / 2 - 50, 5, $aARGB4, $iCounter, True)

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

    ;~ _Rolle($hBUF, 5, 25, 25, $iBreite - 50, $iHoehe - 50, 20, $aARGB1, $iCounter, False)

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

    $iCounter += 0.75
    If $iCounter >= 360 Then $iCounter -= 360
    EndFunc ;==>_Main

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

    Func _Rolle($hGFX, $iAnz, $iX, $iY, $iB, $iH, $iElementH, $aARGB, $iCounter, $iAlpha = False)
    Local $iT = $iH, $_Y[$iAnz], $_T[$iAnz], $_C[$iAnz], $iTMP_1, $iTMP_2
    For $i = 0 To $iAnz - 1 Step 1
    $_Y[$i] = $iH / 2 + _Sin($iCounter + (360 / $iAnz) * $i) * ($iH / 2 - $iElementH / 2) + $iY
    $_T[$i] = (2.5 + (-_Sin($iCounter + (360 / $iAnz) * $i + 90)) / 2) / 3
    Next
    For $x = 0 To $iAnz - 1 Step 1
    $iTMP_1 = 0
    $iTMP_2 = $_T[0]
    For $i = 1 To $iAnz - 1 Step 1
    If $iTMP_2 > $_T[$i] Then
    $iTMP_2 = $_T[$i]
    $iTMP_1 = $i
    EndIf
    Next
    _Balken($hGFX, $iX, $_Y[$iTMP_1], $iB, $iElementH, $_T[$iTMP_1], $aARGB, $iAlpha)
    $_T[$iTMP_1] = 10
    Next
    EndFunc ;==>_Rolle

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

    Func _Balken($hGFX, $iX, $iY, $iB, $iH, $iT, $aARGB, $iAlpha)
    Local $iTMP_1 = $iT ^ 3
    If $iAlpha Then
    _GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int($aARGB[0] * $iTMP_1), 2) & Hex(Int($aARGB[1] * $iTMP_1), 2) & Hex(Int($aARGB[2] * $iTMP_1), 2) & Hex(Int($aARGB[3] * $iTMP_1), 2))
    Else
    _GDIPlus_BrushSetSolidColor($hBRU, '0x' & Hex(Int($aARGB[0]), 2) & Hex(Int($aARGB[1] * $iTMP_1), 2) & Hex(Int($aARGB[2] * $iTMP_1), 2) & Hex(Int($aARGB[3] * $iTMP_1), 2))
    EndIf
    ;~ _GDIPlus_GraphicsFillRect($hGFX, $iX + $iB / 2 - ($iB * $iT) / 2, $iY - ($iH * $iT) / 2, $iB * $iT, $iH * $iT, $hBRU)
    DllCall($ghGDIPDll, "int", "GdipFillRectangle", "handle", $hGFX, "handle", $hBRU, "float", $iX + $iB / 2 - ($iB * $iT) / 2, "float", $iY - ($iH * $iT) / 2, "float", $iB * $iT, "float", $iH * $iT)
    $iY += $iH
    EndFunc ;==>_Balken

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

    Func _Sin($a)
    Return Sin($a * 0.0174532925199433)
    EndFunc ;==>_Sin

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

    Func _Exit()
    Exit
    EndFunc ;==>_Exit

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

    Func _Freigeben()
    _GDIPlus_BrushDispose($hBRU)
    _GDIPlus_GraphicsDispose($hBUF)
    _Image_Delete($hIMG)
    _WinAPI_ReleaseDC($hGUI, $hDC)
    ;~ _GDIPlus_BitmapDispose($hBMP)
    ;~ _GDIPlus_GraphicsDispose($hGFX)
    _GDIPlus_Shutdown()
    EndFunc ;==>_Freigeben

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

    Func WM_PAINT()
    _WinAPI_BitBlt($hDC, 0, 0, $iBreite, $iHoehe, DllStructGetData($hIMG,1,1), 0, 0, 0xCC0020)
    ;~ _GDIPlus_GraphicsDrawImage($hGFX, $hBMP, 0, 0)
    $fLast += _FPS($iFrameRate)
    $iFPS += 1
    If TimerDiff($iTimer) > 1000 Then
    WinSetTitle($hGUI, '', 'FPS: ' & $iFPS & ' | Auslastung: ' & Round($fLast / $iFPS, 2) * 100 & '%')
    $iFPS = 0
    $fLast = 0
    $iTimer = TimerInit()
    EndIf
    EndFunc ;==>WM_PAINT

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

    Func _FPS($i)
    Local Static $_T = TimerInit(), $f
    Local $s = TimerDiff($_T), $l = (1000 / $i - $s)
    $f += $l
    If $f < 0 Then $f = 0
    If $l < 0 Then $l = 0
    Sleep(Int($f / 10) * 10)
    $f -= Int($f / 10) * 10
    $_T = TimerInit()
    Return $s / ($s + $l)
    EndFunc ;==>_FPS

    [/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.dll', '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]
  • Bei mir ist jetzt ein kleines Ruckeln zu spüren...
    Ist das bei anderen auch der Fall ?


    Also bei mir gibt es ungefähr alle 2 Sekunden einen Ruckler, eine Art Erschütterung. Aber nur beim zweiten Script, das Script im Startpost läuft ruckelfrei und sieht toll aus :thumbup:

  • Sehr schöne Spielerei, gefällt mir wirklich sehr.

    Erstes Skript: 40 FPS, keine Ruckler
    Zweites Skript: 60 FPS, keine Ruckler

    Win 7 Profesional 64 Bit

    MfG,
    Nestos.

    Zitat

    [Heute, 11:39] Raupi: Soll ich es dir machen?
    [Heute, 11:47] BugFix: "Soll ich es dir machen? " - also Raupi !! bitte nicht so öffentlich :rofl:

    Zitat

    [Heute, 11:51] BugFix: und ich werde es mir jetzt machen - das Mittagessen :P

    AMsg UDF v1.00.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%
    OwnStyle UDF Version 1.10.00 IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 100%

  • Also ich hab wie Cheater ca. alle 2sek ein ruckeln.
    Ich kann die FPS auch auf 90 stellen, dann entfällt das (oder ist für mich nicht mehr sichtbar).

    Woran das liegt kann ich nicht herausfinden.
    Alle Funktionen arbeiten wie sie sollen, die Framerate ist auch stabil (und die Zeit zwischen den Frames ist mehr oder weniger Konstant)

    Ich habe eine Vermutungen womit das zusammenhängen kann.
    Das Update des Fensters ist Zeitverzögert: Evtl wird das Bild was auf dem Bildschirm ist nicht in der gleichen Geschwindigkeit aktualisiert wie das Bild was im Fenster ist. GDI+ müsste dann im Draw Befehl etwas haben, was die Anzeige mit aktualisiert.

    Vllt kann man das mit UpdateWindow beheben. (das teste ich gleich. Mass Effect geht vor !^^)


    Die Idee habe ich von einer alten Demo (sowas wie die 64k Demos usw).
    Hier ein Beispiel dazu: http://www.stpe.se/javascript/rasterbar.php

    Edit:
    FPS ist frei wählbar. Die Auslastung zeigt an wie viel das Skript arbeitet. Das ist NICHT die Prosessorauslastung. Bei Einkernern kann sie aber ähnlich sein.

  • Der Puffer wird in WM_PAINT genutzt. (bestimmt übersehen)


    Jo, entschuldigung! War natürlich mein Fehler :whistling:

    Die Funktionen für GDI+ die Float Angaben vertragen hielt ich immer für eine Legende^^
    Habe die auch irgendwann schonmal ausprobiert, aber ohne Erfolg.
    Edit: Aaaaah es liegt am Smoothing Mode ! Ohne Smoothing, keine Float Angaben.

    Fast alle GDI+ Graphics-Funktionen gibt es in der Int und Float Version.
    Die Int-Versionen haben ein großes i am Ende: GdipFillRectangleI
    Bei Smoothingmode 0 verhalten sich die Float-Funktionen fast so, wie die Int´s; allerdings mit einem feinen Unterschied:
    Float: Nachkommastellen werden abgeschnitten (3.7 = 3)
    Int: Wird normal gerundet (3.7 = 4)

    E


  • ...
    Die Idee habe ich von einer alten Demo (sowas wie die 64k Demos usw).
    Hier ein Beispiel dazu: http://www.stpe.se/javascript/rasterbar.php
    ...

    Ich hatte ein bissl Zeit und habe mal das JavaScript portiert:

    Spoiler anzeigen
    [autoit]


    ;coded by UEZ 2012 build 2012-08-03
    #AutoIt3Wrapper_Run_Obfuscator=y
    #Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
    #AutoIt3Wrapper_Tidy_Stop_OnError=n
    #AutoIt3Wrapper_UseUpx=y
    #AutoIt3Wrapper_UPX_Parameters=--best --lzma
    #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_Obfuscated.au3"
    #include <Array.au3>
    #include <WindowsConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <GDIPlus.au3>
    Opt('GUIOnEventMode', 1)
    Opt("MustDeclareVars", 1)

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

    _GDIPlus_Startup()
    Global Const $iW = 640, $iH = 480
    Global $sGUIText = "Rotating Raster Bars (C64 Style) by UEZ 2012 / FPS: "
    Global Const $hGUI = GUICreate($sGUIText, 640, 480)
    GUISetState()

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

    #region init GDI+
    Global Const $hBitmap = _WinAPI_CreateDIB($iW, $iH)
    Global Const $hDC = _WinAPI_GetDC($hGUI)
    Global Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC)
    Global Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hBitmap)
    Global Const $hGraphic = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer)
    Global Const $hBrush = _GDIPlus_BrushCreateSolid(0x40000000)
    _GDIPlus_GraphicsSetSmoothingMode($hGraphic, 2)
    #endregion
    Global Const $fPI = ACos(-1)
    Global Const $f2PI = 2 * ACos(-1)
    Global Const $fRad = ACos(-1) / 180
    Global Const $fYPos = $iH / 2
    Global Const $fSpeed = 0.3
    Global Const $fRadius = 150
    Global Const $fZSize = 20
    Global Const $iSize = 100, $iS2 = $iSize / 2
    Global $aBitmaps[3][4], $e, $r, $j, $k, $l , $z = 0, $iFPS = 0
    Global $iUb = UBound($aBitmaps) - 1

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

    For $e = 0 To $iUb
    $r = Random(3, 12, 1)
    $aBitmaps[$e][0] = CreateBar($r, $iW, $iSize, "0xFF" & Hex(Random(0x0, 0xFFFFFF, 1), 6))
    $aBitmaps[$e][1] = $fYPos
    $aBitmaps[$e][2] = Sin($e * $fRad) * 360 / ($iUb + 1)
    Next

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

    GUISetOnEvent($GUI_EVENT_CLOSE , "_Exit")
    AdlibRegister("FPS", 1000)

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

    While Sleep(10)
    DllCall($ghGDIPDll, "int", "GdipFillRectangleI", "handle", $hGraphic, "handle", $hBrush, "int", 0, "int", 0, "int", $iW, "int", $iH) ;_GDIPlus_GraphicsFillRect()
    For $j = 0 To $iUb
    $k = Sin($fRad * $z + $aBitmaps[$j][2]) * $fRadius
    $aBitmaps[$j][3] = Cos(-270 + $fRad * $z + $aBitmaps[$j][2])
    $aBitmaps[$j][1] = $fYPos + $k - $iS2
    DllCall($ghGDIPDll, "int", "GdipDrawImageRect", "handle", $hGraphic, "handle", $aBitmaps[$j][0], "float", 0, "float", $aBitmaps[$j][1], "float", $iW, "float", $iSize + $aBitmaps[$j][3] * $fZSize)
    $z += $fSpeed
    Next
    _ArraySort($aBitmaps, 0, 0, 0, 3)
    DllCall("gdi32.dll", "bool", "BitBlt", "handle", $hDC, "int", 0, "int", 0, "int", $iW, "int", $iH, "handle", $hDC_backbuffer, "int", 0, "int", 0, "dword", $SRCCOPY) ;_WinAPI_BitBlt()
    $iFPS += 1
    WEnd

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

    Func CreateBar($iStep, $iW, $iH, $iColor, $iBoost = 3)
    Local Const $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    Local Const $hBitmap = $aResult[6]
    Local Const $hCtx = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local Const $hBrush = _GDIPlus_BrushCreateSolid(0x00000000)
    Local $i, $y = 0
    For $x = 0 To $iH / 2 Step $iStep
    _GDIPlus_BrushSetSolidColor($hBrush, CalcColor($iColor, $iBoost * $x))
    _GDIPlus_GraphicsFillRect($hCtx, 0, $y, $iW, $iStep, $hBrush)
    $y += $iStep
    Next
    For $x = $iH / 2 - $iStep To 0 Step -$iStep
    _GDIPlus_BrushSetSolidColor($hBrush, CalcColor($iColor, $iBoost * $x))
    _GDIPlus_GraphicsFillRect($hCtx, 0, $y, $iW, $iStep, $hBrush)
    $y += $iStep
    Next
    _GDIPlus_GraphicsDispose($hCtx)
    _GDIPlus_BrushDispose($hBrush)
    Return $hBitmap
    EndFunc

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

    Func CalcColor($iColor, $iStep)
    Local Const $iA = Hex(BitAND(0xFF, BitShift($iColor, 24)), 2)
    Local Const $iR = Hex(Min(BitAND(0xFF, BitShift($iColor, 16)) + Int($iStep), 0xFF), 2)
    Local Const $iG = Hex(Min(BitAND(0xFF, BitShift($iColor, 8)) + Int($iStep), 0xFF), 2)
    Local Const $iB = Hex(Min(BitAND(0xFF, $iColor) + Int($iStep), 0xFF), 2)
    Return "0x" & $iA & $iR & $iG & $iB
    EndFunc

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

    Func FPS()
    WinSetTitle("", "", $sGUIText & $iFPS)
    $iFPS = 0
    EndFunc

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

    Func Min($a, $b)
    If $a < $b Then Return $a
    Return $b
    EndFunc

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

    Func _Exit()
    AdlibUnRegister("FPS")
    Local $c
    For $c = 0 To UBound($aBitmaps) - 1
    _GDIPlus_BitmapDispose($aBitmaps[$c][0])
    Next
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hGraphic)
    _WinAPI_SelectObject($hDC, $DC_obj)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_ReleaseDC($hGUI, $hDC)

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

    _GDIPlus_Shutdown()
    GUIDelete($hGUI)
    Exit
    EndFunc

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

    Func _WinAPI_CreateDIB($iWidth, $iHeight, $iBitsPerPel = 32) ;taken from WinAPIEx.au3 by Yashied
    Local $tBIHDR, $hBitmap, $pBits
    Local Const $BI_RGB = 0, $DIB_RGB_COLORS = 0
    Local Const $tagBITMAPINFOHEADER = 'dword biSize;long biWidth;long biHeight;ushort biPlanes;ushort biBitCount;dword biCompression;dword biSizeImage;long biXPelsPerMeter;long biYPelsPerMeter;dword biClrUsed;dword biClrImportant'
    $tBIHDR = DllStructCreate($tagBITMAPINFOHEADER)
    DllStructSetData($tBIHDR, 'biSize', DllStructGetSize($tBIHDR))
    DllStructSetData($tBIHDR, 'biWidth', $iWidth)
    DllStructSetData($tBIHDR, 'biHeight', $iHeight)
    DllStructSetData($tBIHDR, 'biPlanes', 1)
    DllStructSetData($tBIHDR, 'biBitCount', $iBitsPerPel)
    DllStructSetData($tBIHDR, 'biCompression', $BI_RGB)
    $hBitmap = _WinAPI_CreateDIBSection(0, $tBIHDR, $DIB_RGB_COLORS, $pBits)
    If @error Then Return SetError(1, 0, 0)
    Return $hBitmap
    EndFunc ;==>_WinAPI_CreateDIB

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

    Func _WinAPI_CreateDIBSection($hDC, ByRef $tBITMAPINFO, $iUsage, ByRef $pBits, $hSection = 0, $iOffset = 0) ;taken from WinAPIEx.au3 by Yashied
    $pBits = 0
    Local $Ret = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', $hDC, 'ptr', DllStructGetPtr($tBITMAPINFO), 'uint', $iUsage, 'ptr*', 0, 'ptr', $hSection, 'dword', $iOffset)
    If @error Or (Not $Ret[0]) Then Return SetError(1, 0, 0)
    $pBits = $Ret[4]
    Return $Ret[0]
    EndFunc ;==>_WinAPI_CreateDIBSection

    [/autoit]

    Warum hast du dein GDI+ Beispiel in Off-Topic gepostet?

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    3 Mal editiert, zuletzt von UEZ (3. August 2012 um 11:51)


  • Warum hast du dein GDI+ Beispiel in Off-Topic gepostet?

    Das liegt daran, weil es eher was "kleines" ist.
    Der Skripte Bereich ist eher für die "größeren" Kleinigkeiten. Etwas was auch praktische Anwendung hat.
    Daher lieber in OffTopic^^
    Es gibt iwie keinen Bereich für "Schaut mal was ich gebastelt habe, nehmt es aber nicht zu ernst."

  • Na ja, Off-Topic ist eher für Themen, die sonst nichts mit Coding zu tun haben. Egal wie "klein" dein Beispiel Skript ist, sollte aber in Skripte liegen. ;)

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

  • Hi,

    Zitat

    Egal wie "klein" dein Beispiel Skript ist, sollte aber in Skripte liegen.

    So klein kann ein Script garnicht sein, dass nicht ein anderer noch etwas daraus lernen könnte....daher ab damit ins SCRIPTE

    Zitat

    Ich hatte ein bissl Zeit und habe mal das JavaScript portiert:

    coole Sache, wie immer :thumbup: