Klasse für das Messen von Frameraten(FPS) oder sonstigen periodischen Events

    • VB.NET

      Klasse für das Messen von Frameraten(FPS) oder sonstigen periodischen Events

      Hallo VB-Paradise Community :)

      Hab wegen einem Spiel kürzlich einen FPS-Messer gebraucht. Da für mich auch die Berechnung der durschnittlichen Frame Rate interessant war, hab ich diese Funktion auch eingebaut. Ich weiß ein sehr simpler Zweck, da ich aber im Inet nur FPS-Meter in VB für die aktuelle bzw. max. und min. Framerate gefunden haben, dachte ich es wäre interessant den Code hier für die Nachwelt zu teilen.

      Natürlich kann man damit alle möglichen Aktualisierungsintervalle messen!

      Hier die Klasse:

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Option Strict On
      2. Public Class FPS_Measure
      3. ' api declare
      4. Public Declare Function GetTickCount Lib "kernel32" () As Long
      5. ' is one sec. ?
      6. Private FPS_LastCheck As Long
      7. ' FPS were counted
      8. Private FPS_Count As Long
      9. ' here is the actual FPS number
      10. Public FPS_Current As Integer
      11. ' AVG FPS
      12. Public FPS_AVG As Double
      13. ' highest FPS
      14. Public FPS_Highest As Integer
      15. ' lowest FPS
      16. Public FPS_Lowest As Integer
      17. Public Sub Measure_FPS(ByVal calcHighest As Boolean, ByVal calcLowest As Boolean, ByVal calcAVG As Boolean)
      18. If GetTickCount() - FPS_LastCheck >= 1000 Then
      19. FPS_Current = CInt(FPS_Count)
      20. FPS_Count = 0 ' set the counter
      21. FPS_LastCheck = GetTickCount()
      22. End If
      23. If calcHighest Then
      24. measure_FPS_Highest()
      25. End If
      26. If calcLowest Then
      27. measure_FPS_Lowest()
      28. End If
      29. If calcAVG Then
      30. measure_FPS_AVG()
      31. End If
      32. FPS_Count = FPS_Count + 1
      33. End Sub
      34. Private Sub measure_FPS_Highest()
      35. ' highest FPS
      36. If FPS_Current > FPS_Highest Then
      37. FPS_Highest = FPS_Current
      38. End If
      39. End Sub
      40. Private Sub measure_FPS_Lowest()
      41. ' lowest FPS
      42. If FPS_Current < FPS_Lowest Then
      43. FPS_Lowest = FPS_Current
      44. End If
      45. End Sub
      46. ' the last n FPSs
      47. Private FPS_HISTORY_NR As Integer = 10
      48. ' is one sec. ?
      49. Private FPS_AVG_LastCheck As Long
      50. ' values of the last fps
      51. Private FPS_AVG_last_readings(FPS_HISTORY_NR) As Double
      52. 'we'll be reading the stats every second
      53. Private STAT_INTERVAL As Integer = 1000 ' ms
      54. ' Index of last status stored
      55. Private idx_lastStatusStored As Integer = 0
      56. '10 Messwerte --> FPS_HISTORY_NR und das erfassen eines neuen alle 1000 ms --> STAT_INTERVAL sind die besten Konfigurationseinstellungen.
      57. Private Sub measure_FPS_AVG()
      58. 'Works with ring buffer principle
      59. If GetTickCount() - FPS_AVG_LastCheck >= STAT_INTERVAL Then
      60. FPS_AVG_last_readings(idx_lastStatusStored) = FPS_Current
      61. If idx_lastStatusStored >= FPS_HISTORY_NR Then
      62. idx_lastStatusStored = 0
      63. Else
      64. idx_lastStatusStored += 1
      65. End If
      66. Dim sum As Double = 0
      67. For i As Integer = 0 To FPS_HISTORY_NR - 1
      68. sum += FPS_AVG_last_readings(i)
      69. Next
      70. FPS_AVG = sum / FPS_HISTORY_NR
      71. FPS_AVG_LastCheck = GetTickCount()
      72. End If
      73. End Sub
      74. End Class


      Verwendungsbeispiel, kleine DirectX Anwendung:

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Private Sub draw()
      2. drawfont = New Direct3D.Font(d3ddev, New System.Drawing.Font("IMPACT", 32, FontStyle.Regular, GraphicsUnit.Pixel))
      3. Dim fps_measure As New FPS_Measure 'Unsere in einer eigenen vb-Datei definierte Klasse
      4. Do While gamerun 'Game Loop also zyklisch aufgerufener Code Abschnitt, dessen Aktualisierungsintervall wir messen wollen!
      5. Dim cursorposx As Integer = Cursor.Position.X
      6. Dim cursorposy As Integer = Cursor.Position.Y
      7. d3ddev.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, bkgcolor, 1, 0)
      8. d3ddev.BeginScene()
      9. 'Bei diesem Beispiel zeichnen wir einen Namen auf den Screen. Die spezifischen Werte werden auch auf den Bildschirm gezeichnet.
      10. 'hier werden die Variablen die die jeweiligen Werte enthalten gleich direkt als String verwendet. Eben abhängig vom Anwendungdzweck
      11. drawfont.DrawText(Nothing, "ALEX", cursorposx, cursorposy, Color.DarkCyan)
      12. drawfont.DrawText(Nothing, "FPS Current: " & fps_measure.FPS_Current, 0, 0, Color.DarkCyan)
      13. drawfont.DrawText(Nothing, "FPS Average: " & fps_measure.FPS_AVG.ToString("0.00"), 0, 36, Color.DarkCyan)
      14. drawfont.DrawText(Nothing, "FPS Highest: " & fps_measure.FPS_Highest, 0, 72, Color.DarkCyan)
      15. drawfont.DrawText(Nothing, "FPS Lowest: " & fps_measure.FPS_Lowest, 0, 108, Color.DarkCyan)
      16. d3ddev.EndScene()
      17. d3ddev.Present()
      18. Windows.Forms.Application.DoEvents()
      19. fps_measure.Measure_FPS(True, True, True) 'Aufruf unserer Messfunktion mittels 3 Parametern: Ob er die Höchste, Niedrigste und Durchschnittsanzahl berechnen soll --> bei False minimalste Performence Unterschiede
      20. Loop
      21. End Sub


      Hoffe vll kann ich irgendjemanden mal damit helfen.

      LG Kryo4lex