Aktuelle Zeit: 25.06.2019 14:37

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]




Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite Vorherige  1, 2
Autor Nachricht
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 06.05.2018 18:55 
Offline
Benutzeravatar

Registriert: 25.09.2016 01:42
mk-soft hat geschrieben:
Es ist besser mit Frames zu arbeiten um nicht die CPU Last zu hoch zu schrauben...

...


Danke, verwendet aber leider AddWindowTimer() was ich (später) nicht nutzen kann.
Der Code soll auch bei Fenstern funktionieren die nicht mit PureBasic erstellt wurden.

Hier mal mein Ansatz, leider ist noch was falsch es wird auf ~100 FPS :? gedrosselt anstatt auf 60!

Code:
Code:
DeclareModule FPS
  Declare.i Init()
  Declare.i Count()
  Declare.f Delta()
  Declare.i Update()
EndDeclareModule

Module FPS
 
  #FPS_60 = 16
  #FPS_30 = 33
  #FPS_25 = 40
  #FPS_80 = 12
  #FPS_75 = 13
  #FPS_24 = 41
  #FPS_20 = 50
  #FPS_10 = 100
   
  Structure PERFORMANCE_STRUCT
    FrameTarget.q
    FrameStart.q
    FrameEnd.q
    FrameTime.f   
    Timing.f
    FrameCount.i
    FPS.i
    DeltaTime.f
  EndStructure
 
  Global Performance.PERFORMANCE_STRUCT
 
  Procedure.i Init()
    With Performance
      \FrameTarget = #FPS_60;GEWÜNSCHTE FPS!
      \FrameStart = ElapsedMilliseconds()
    EndWith
  EndProcedure
 
  Procedure.i Count()
    ProcedureReturn Performance\FPS
  EndProcedure
 
  Procedure.f Delta()
    ProcedureReturn Performance\DeltaTime
  EndProcedure
 
  Procedure.i Update()
    With Performance
      If \FrameTime < \FrameTarget
        Delay(\FrameTarget - \FrameTime);NICHT KORREKT !?
      EndIf
      \FrameEnd = ElapsedMilliseconds()
      \FrameTime = \FrameEnd - \FrameStart
      \DeltaTime = \FrameTime / \FrameTarget
      \FrameStart = \FrameEnd
      If \Timing > 999
        \FPS = \FrameCount
        \Timing = 0
        \FrameCount = 1
      Else
        \Timing + \FrameTime
        \FrameCount + 1
      EndIf
    EndWith
  EndProcedure

EndModule

If InitSprite()
  If OpenWindow(0,0,0,400,400,"TestWindow",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(0),0,0,400,400,#False,0,0,#PB_Screen_NoSynchronization);<- KEIN SYNCH!
      FPS::Init()
      Repeat
        ClearScreen($EB8724)
        If StartDrawing(ScreenOutput())
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawText(10,10,"FPS: " + Str(FPS::Count()))
          DrawText(10,30,"DLT: " + StrF(FPS::Delta(),2))
          StopDrawing()
        Else
          PostEvent(#PB_Event_CloseWindow)
        EndIf
        FlipBuffers()
        FPS::Update()
      Until WindowEvent() = #PB_Event_CloseWindow
    EndIf
  EndIf
EndIf

_________________

Links:
PureBasic Discord
[INCLUDE] GLFW 3.3 Library
[MODULE] Desktop/Window Capture (Win)
[MODULE] Bass Library 2.4 (Win)
[LIBRARY] Hexi Binary2Hex (Win)



Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 06.05.2018 19:00 
Offline
Admin
Benutzeravatar

Registriert: 05.10.2006 18:55
Wohnort: Deutschland::Berlin()
Achso, du verwendest OpenWindowedScreen. Dann ist ein Delay schon sinnvoll, um den Prozessor zu entlasten.
In der PB-Hilfe unter OpenWindowedScreen gibt es ein Beispielcode mit einem Delay(1) und die Screen-Anwendung verbraucht nur 1 %-Prozessorauslastung.

_________________
BildBildBildBildBildBild


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 06.05.2018 19:52 
Offline

Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge
Huhu!!!!

Es ist eigentlich recht simpel.

Wichtig ist eine konstante Framerate festzulegen und die Zeit zwischen dem Aktualisieren zu messen (DeltaT).

Das sind eigentlich die Standards und alles ist locker flockig handelbar.

Man sollte aber beachten das trotz NOSync meist Treibertechnisch trotzdem bei 60 FPS abgeriegelt wird.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 06.05.2018 21:38 
Offline

Registriert: 23.06.2013 06:26
Hm, keine Ahnung ob das weiterhelfen könnte, aber mal 'ne kleine Entkoppelung via Threads.
Vermutlich müssen sich die erfahreneren Coder hier gleich übergeben. ;P
Code:
Procedure.l GetTime()
  Static TimeLast.l
  Protected TimeNow.l
  Protected TimeReturn.l
  If TimeLast = 0
    TimeLast = ElapsedMilliseconds()
    ProcedureReturn 0
  EndIf
  TimeNow = ElapsedMilliseconds()
  TimeReturn = TimeNow-TimeLast
  TimeLast = TimeNow
  ProcedureReturn TimeReturn
EndProcedure
Procedure.l ThreadDelay(Delay)
  Delay(Delay)
  ProcedureReturn 0
EndProcedure

Structure ObjectStructure
 
EndStructure


Global Mutex.l
Global NewList svObjectList.ObjectStructure()
Global NewList clObjectList.ObjectStructure()



Procedure GameInit()
  UsePNGImageDecoder()
 
  InitSprite()
  InitSound()
  InitKeyboard()
 
  PrintN("Opening window.")
  OpenWindow(1, #PB_Ignore, #PB_Ignore, 800, 600, "asCL")
  PrintN("Opening screen.")
  OpenWindowedScreen(WindowID(1), 0, 0, 400, 300, 1, 0, 0, #PB_Screen_NoSynchronization)
  TransparentSpriteColor(#PB_Default, $ff00ff)
 
 
  For i = 0 To 0
  AddElement(svObjectList())
Next
EndProcedure

Procedure GameClient()
  Protected Event.l
  ;SetFrameRate(1000)
  UnlockMutex(Mutex)
 
  Repeat
    Repeat
      Event = WindowEvent()
      Select Event
        Case #PB_Event_CloseWindow
          Quit = 1
      EndSelect
    Until Event = 0
    ClearScreen($606060)
   
   
   
   
   
    LockMutex(Mutex)
    CopyList(svObjectList(), clObjectList())
    UnlockMutex(Mutex)
   
   
   
   
    ForEach clObjectList()
      ;;Display Objects
    Next
   
   
   
   
   
   
   
    FlipBuffers()
   
  Until Quit = 1
 
  ProcedureReturn 0
EndProcedure
Procedure GameServer(Rate_TickRate = 100) ;low overhead asynch rate server
  Protected ThreadDelayID.l
  Protected Correction.l
  Protected Time.l
  Protected ThreadCreationCorrection.l
  For i = 1 To 10
    Time = ElapsedMilliseconds()
    ServerDelay = CreateThread(@ThreadDelay(), 1)
    WaitThread(ServerDelay)
    ThreadCreationCorrection+(Time-ElapsedMilliseconds())
  Next
  ThreadCreationCorrection/10
  PrintN("Thread creation delay: "+Str(ThreadCreationCorrection))
  Time = ElapsedMilliseconds()
  Rate_Elapsed = Rate_TickRate
  PrintN("Resuming server loop.")
  Repeat
    Correction = Correction+(Rate_TickRate-Rate_Elapsed)
    If Rate_TickRate+Correction+ThreadCreationCorrection > 0
      ServerDelay = CreateThread(@ThreadDelay(), Rate_TickRate+Correction+ThreadCreationCorrection)
    EndIf
   
    ;;Debugger has to be disabled when calling Keyboard functions in a thread.
    ;;Else it will raise an exception
    DisableDebugger
    ExamineKeyboard()
    LockMutex(Mutex)
    FirstElement(svObjectList())
    ;;Keyboard Queries
   
    EnableDebugger
   
    ForEach svObjectList()
      ;;Object Actions
    Next
    UnlockMutex(Mutex)
   
    WaitThread(ServerDelay)
    Rate_Elapsed = ElapsedMilliseconds()-Time
    Time+Rate_Elapsed
    PrintN(Str(Rate_Elapsed))
    Debug Correction
   
  ForEver
 
  ProcedureReturn 0
EndProcedure



If OpenLibrary(0, "Kernel32.dll")
  Prototype GetConsoleWindow()
  Define GetConsoleWindow.GetConsoleWindow = GetFunction(0, "GetConsoleWindow")
  CloseLibrary(0)
EndIf



OpenConsole()
ConsoleHandle = GetConsoleWindow()
EnableMenuItem_(GetSystemMenu_(ConsoleHandle, #False), #SC_CLOSE, #MF_DISABLED)






Mutex = CreateMutex()

GameInit()
LockMutex(Mutex)
Server = CreateThread(@GameServer(), 20)
GameClient()
PrintN("Locking server thread.")
LockMutex(Mutex)
KillThread(Server)
PrintN("Killed server thread.")
UnlockMutex(Mutex)
PrintN("Shutting down.")
End


Müsstest eben was in die Struktur einfügen und auch Aktionen dafür festlegen...

_________________
Wer braucht schon Unicode? PB5.24LTS


Zuletzt geändert von Jan125 am 07.05.2018 21:42, insgesamt 3-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 06.05.2018 21:49 
Offline

Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge
Ah!

"ThreadCreationCorrection" :mrgreen:

Zitat:
Vermutlich müssen sich die erfahreneren Coder hier gleich übergeben. ;P

:mrgreen:

Keine Ahnung!


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 06.05.2018 22:46 
Offline
Benutzeravatar

Registriert: 25.09.2016 01:42
Jan125 hat geschrieben:
Hm, keine Ahnung ob das weiterhelfen könnte, aber mal 'ne kleine Entkoppelung via Threads.
Vermutlich müssen sich die erfahreneren Coder hier gleich übergeben. ;P
Code:
...


Müsstest eben was in die Struktur einfügen und auch Aktionen dafür festlegen...


:shock:
Was passiert hier ?
Ist zu komplex/durcheinander für mich.

_________________

Links:
PureBasic Discord
[INCLUDE] GLFW 3.3 Library
[MODULE] Desktop/Window Capture (Win)
[MODULE] Bass Library 2.4 (Win)
[LIBRARY] Hexi Binary2Hex (Win)



Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 07.05.2018 06:33 
Offline

Registriert: 23.06.2013 06:26
Ups, stimmt ja... :D

Ich entkoppele die Logik von der Anzeige via Threads.
Der Großteil des Codes besteht aus Zeitstabilisierung und Korrektur (dazu eben noch das Thread-Erzeugungs-Delay, denn der Delay wird asynchron über einen weiteren Thread bewerkstelligt).
Im Endeffekt kümmert sich der "Server" um Eingaben und alles andere, packt darzustellende Objekte in eine Liste, der "Client" kopiert diese Liste und stellt sie dann dar.

Somit muss man sich um Frameratediskrepanzen keine Sorgen mehr machen. ^w^


(Das Ganze könnte dennoch nicht ganz Save sein, siehe Anmerkung zu Tastaturevents im Server.)

_________________
Wer braucht schon Unicode? PB5.24LTS


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 08.05.2018 22:05 
Offline
Benutzeravatar

Registriert: 25.09.2016 01:42
Jan125 hat geschrieben:
Code:
...



Würde den Code gerne besser verstehen :)

- Wo ist die Procedure -> ThreadDelay() ?
Code:
CreateThread(@ThreadDelay(), 1)
;...
CreateThread(@ThreadDelay(), Rate_TickRate+Correction+ThreadCreationCorrection)
;...

- Wird WindowEvent() nicht geblockt solange bis es ein Signal gibt ?

- Der Code scheint den Prozessor nicht zu entlasten hängt bei mir bei 5 - 8% !

_________________

Links:
PureBasic Discord
[INCLUDE] GLFW 3.3 Library
[MODULE] Desktop/Window Capture (Win)
[MODULE] Bass Library 2.4 (Win)
[LIBRARY] Hexi Binary2Hex (Win)



Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 09.05.2018 05:17 
Offline

Registriert: 23.06.2013 06:26
ThreadDelay ist ganz oben, zweite Prozedur.
Soll einfach nur als Zeitgeber fungieren.

Nö, das wäre WaitWindowEvent, und wenn man das benutzen würde, dann würde die Darstellung blockieren. :D (Oder man macht einen weiteren Thread...)

Entlastung ist hier nicht das Ziel, die Performance wird sogar eher stark abnehmen. Hier soll nur die Tickrate korrigiert werden (wenn in einem Tick zu viel bearbeitet werden muss kann das durch den nächsten Tick u. U. ausgeglichen werden), sowie eine generelle Unabhängigkeit von der britischen Kron-... Äh, von der Bildwiederholfrequenz des Monitors (ältere CRTs haben z. B. meist 75Hz statt 60Hz, manche neueren Monitore 144Hz).

Da ich morgen frei habe setz' ich mich heute Abend mal hin und schreib 'n kleines Beispiel. :>

_________________
Wer braucht schon Unicode? PB5.24LTS


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: [GameLoop] DeltaTime & FPS ? (kein V-Sync/Framelimit)
BeitragVerfasst: 09.05.2018 23:30 
Offline
Benutzeravatar

Registriert: 25.09.2016 01:42
Jan125 hat geschrieben:
ThreadDelay ist ganz oben, zweite Prozedur.
Soll einfach nur als Zeitgeber fungieren.


Ah, das habe ich tatsächlich nicht gesehen, sah wie eine Funktion aus.

Jan125 hat geschrieben:
Nö, das wäre WaitWindowEvent, und wenn man das benutzen würde, dann würde die Darstellung blockieren. :D (Oder man macht einen weiteren Thread...)


Ok das ist gut, ich steig bei Threads noch nicht wirklich durch.

_________________________________________________________________________________________


Ich hab bei meinem Code jetzt eine 'Clock' hinzugefügt um ein Render-Event auszulösen.
Code:
If \Clock >= \FrameTarget
;...

Damit funktioniert es jetzt.
Momentan wird der Prozessor mit Delay(1) entlasted, besser
wäre ein Nano-Sleep (möglich aber nur mit OS-API).

Bild

_________________

Links:
PureBasic Discord
[INCLUDE] GLFW 3.3 Library
[MODULE] Desktop/Window Capture (Win)
[MODULE] Bass Library 2.4 (Win)
[LIBRARY] Hexi Binary2Hex (Win)



Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 20 Beiträge ]  Gehe zu Seite Vorherige  1, 2

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast


Sie dürfen keine neuen Themen in diesem Forum erstellen.
Sie dürfen keine Antworten zu Themen in diesem Forum erstellen.
Sie dürfen Ihre Beiträge in diesem Forum nicht ändern.
Sie dürfen Ihre Beiträge in diesem Forum nicht löschen.

Suche nach:
Gehe zu:  

 


Powered by phpBB © 2008 phpBB Group | Deutsche Übersetzung durch phpBB.de
subSilver+ theme by Canver Software, sponsor Sanal Modifiye