Tipps für mein Projekt...

  • Hi,

    ich schreibe im Moment ein Skript in autoit, welches ca. 40 Rechtecke zeichnet und deren Farbe ändert. Leider reicht mir die Performance mit GDI+ nicht.
    Ich hätte gerne ca. 30 FPS aber da komme ich bei weitem nicht hin.

    Deshalb und weil ich gerne OOProgrammieren möchte, überlege ich ob ich für das Projekt auf C++ umsteige.

    Meine Frage, ist jetzt mit welcher Grafik Engine sollte ich das machen? Direct2D fällt leider raus, weil das auch auf älteren Rechnern mit XP laufen soll.
    Von mir aus kann es auch gerne in 3D sein. Ich habe mich dazu mal etwas mit Irrlicht beschäftigt. Aber leider sehe ich im moment die Schnittstelle mein Programm <-> Irrlicht nicht. Also wie kann ich z.b. Lichter dynamisch ändern?

    Was ich von euch genau möchte?
    Ich möchte das ihr mir ein Paar Stichwörter/Wegweiser gebt. Ich brauche erstmal nur eine Richtung in die ich weiterarbeiten kann.
    Manchmal fehlen einem ja nur die Begriffe nach denen man suchen muss.

    Danke
    Gruß Daniel

  • Naja, wenn man BitBlt verwendet komtm man schon auf eine ganz nette FPS:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinApi.au3>
    Enum $Green, $Red, $Blue
    Global $hBrush[3], $iFPS
    $hWnd=GUICreate("")
    GUISetState()
    $hDC = _WinAPI_GetDC($hWnd)
    $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, 400, 400)
    $hBitmapDC = _WinAPI_CreateCompatibleDC($hDC)
    _WinAPI_SelectObject($hBitmapDC, $hBitmap)
    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hBitmapDC)
    $hBrush[$Green]=_GDIPlus_BrushCreateSolid(0xFF00FF00)
    $hBrush[$Red]=_GDIPlus_BrushCreateSolid(0xFFFF0000)
    $hBrush[$Blue]=_GDIPlus_BrushCreateSolid(0xFF0000FF)
    AdlibRegister("SetWinTitle", 1000)
    While True
    Switch GUIGetMsg()
    Case -3
    For $i=0 to 2
    _GDIPlus_BrushDispose($hBrush[$i])
    Next
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_DeleteDC($hBitmapDC)
    _WinAPI_DeleteObject($hBitmap)
    Exit
    EndSwitch
    _GDIPlus_GraphicsClear($hGraphics)
    For $i=0 to 39
    _GDIPlus_GraphicsFillRect($hGraphics, Random(0, 400, 1), Random(0, 400, 1), Random(5, 20,1), Random(5, 20, 1), $hBrush[Random(0, 2, 1)])
    Next
    _WinAPI_BitBlt($hDC, 0, 0, 400, 400, $hBitmapDC, 0, 0, 0x00CC0020)
    $iFPS+=1
    WEnd
    Func SetWinTitle()
    WinSetTitle($hWnd, "", "FPS: "&$iFPS)
    $iFPS=0
    EndFunc

    [/autoit]
  • Ok habs mal auf BitBlt umgebaut. Ich kriege 7-8 FPS.
    Mit deinem Beispiel komme ich auf ca. 80FPS.

    Meine "Lampen" setze ich so:

    [autoit]

    Func _Set_Lamp($i,$Color)
    $lamp[$i] = $Color

    if $i < 11 Then
    $hBrush = _GDIPlus_BrushCreateSolid($Color)
    _GDIPlus_GraphicsFillRect($hGraphics, $position[$i][2] , $position[$i][3], $position[$i][1], $position[$i][1]*1.5,$hBrush) ;Rechteck auf den Buffer zeichnen
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $image_becher, $position[$i][2] , $position[$i][3],$position[$i][1],$position[$i][1]*1.5)
    EndIf
    if $i > 10 Then
    $i = $i-10
    $hBrush = _GDIPlus_BrushCreateSolid($Color)
    _GDIPlus_GraphicsFillRect($hGraphics, $position[$i][4] , $position[$i][3], $position[$i][1], $position[$i][1]*1.5,$hBrush) ;Rechteck auf den Buffer zeichnen
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $image_becher, $position[$i][4] , $position[$i][3],$position[$i][1],$position[$i][1]*1.5)
    EndIf
    EndFunc

    [/autoit]

    Das Image welches ich da lade ist 15kbyte groß.

    Was ich noch komisch finde, ist wenn ich

    [autoit]

    _GDIPlus_GraphicsClear($hGraphics)

    [/autoit]


    einbaue, bleibt mein Bild schwarz.

    Danke
    Gruß Daniel

  • Den Brush andauernd neu zu erstellen ist sinnlos, damit überlädst du höchstens deinen Arbeitsspeicher. Einmal am Anfang erstellen und dann am Ende wieder Disposen, das reicht. Wenn du bei GraphicsClear den 2. Parameter nicht angibst, wird die Grafik mit schwarz übermalt, nicht mit weiß.

  • Wenn du umbedingt hohe Perfomence möchtest und auch bereit bist auf C# umzusteigen, würde ich dir empfehlen das du dir mal XNA anzuschaust.

    Damit hast du (ziemlich) hohe Frameraten, Licht, Wasser, und viele andere Effekte. Obendrein kannst du auch Programme für Xbox, WP7 und Zune entwickeln.

  • Das BitBlt Beispiel von Ineluki ist schon höllisch schnell, zeigt aber durch den Messageloop nicht sein volles Potenzial.
    Ich kriege ca. 75 FPS, wenn ich nichts tue und ca. 270, wenn ich die Maus bewege.

    Wer andern eine Bratwurst brät
    der hat ein Bratwurstbratgerät.

  • Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <WinApi.au3>

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

    Opt("GUIOnEventMode",1)

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

    Enum $Green, $Red, $Blue
    Global $hBrush[3], $iFPS , $hGraphics , $hWnd , $hDC , $hBitmapDC , $hBitmap

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

    $hWnd=GUICreate("")
    GUISetOnEvent(-3,"_Exit")
    GUISetState()
    $hDC = _WinAPI_GetDC($hWnd)
    $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, 400, 400)
    $hBitmapDC = _WinAPI_CreateCompatibleDC($hDC)
    _WinAPI_SelectObject($hBitmapDC, $hBitmap)
    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hBitmapDC)
    $hBrush[$Green]=_GDIPlus_BrushCreateSolid(0xFF00FF00)
    $hBrush[$Red]=_GDIPlus_BrushCreateSolid(0xFFFF0000)
    $hBrush[$Blue]=_GDIPlus_BrushCreateSolid(0xFF0000FF)
    AdlibRegister("SetWinTitle", 1000)

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

    While True
    _GDIPlus_GraphicsClear($hGraphics)
    For $i=0 to 39
    _GDIPlus_GraphicsFillRect($hGraphics, Random(0, 400, 1), Random(0, 400, 1), Random(5, 20,1), Random(5, 20, 1), $hBrush[Random(0, 2, 1)])
    Next
    _WinAPI_BitBlt($hDC, 0, 0, 400, 400, $hBitmapDC, 0, 0, 0x00CC0020)
    $iFPS+=1
    WEnd

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

    Func SetWinTitle()
    WinSetTitle($hWnd, "", "FPS: "&$iFPS)
    $iFPS=0
    EndFunc

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

    Func _Exit()
    For $i=0 to 2
    _GDIPlus_BrushDispose($hBrush[$i])
    Next
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    _WinAPI_ReleaseDC($hWnd, $hDC)
    _WinAPI_DeleteDC($hBitmapDC)
    _WinAPI_DeleteObject($hBitmap)
    Exit
    EndFunc

    [/autoit]


    375 FPS :thumbup:

    MfG hellboy

    [autoit]

    Do
    _help($user)
    Until $questions = 0

    [/autoit]

    Meine Werke:
    Ste`s Web-Radio

  • Hi,
    solange die zu blittenden Objekte klein sind, gibts keine grossartigen Probleme. Wenn allerdings komplette Hintergründe in einen Backbuffer geblittet werden müssen, und sich auch noch viele relativ grosse Objekte auf dem bild bewegen, DANN wirds schon bitter. Allerdings hängt das primär nicht an GDI, sondern an der Menge der Daten, die über den Systembus zur Grafikkarte transportiert werden müssen. Da es auch keine Beschleunigungsfunktionen für 2D gibt (idR), bleibt einem nur der mühsame bzw. langsame Weg "zu Fuss"!
    GDI ist also je nach Anforderung schnell oder langsam!