Seite 3 von 3

Verfasst: 21.08.2009 19:23
von Rebon
cxAlex hat geschrieben:Bei mir sind die FPS erst auf ~550, beim drücken von Tab auf 1900-2000.

Bei einer echt miesen GraKa:

GeForce 7300 SE

Gruß, Alex
Ob diese Graka auch für DirectDraw-Beschleunigung mies ist? Habe es gerade getestet, es geht erst auf 725MHz wenn ich die TAB drücke.

Verfasst: 21.08.2009 19:25
von cxAlex
PS: Ich hab mir den FPS - Source mal angesehen:

Static ist sehr schlecht in Zeiten von Mehrkernprozessoren, eine threated - Anwendung kann damit schnell Probleme kriegen. Drum hier mal meine Version einer FPS - Anzeige, angelehtn an RSBasics - Code inkl. HighRes - Zeitabfrage und Thread Local Storage (wollte ich mal probieren, nutze ich normal nie wegen der Cross Plattform Kompatibilität):

Code: Alles auswählen

; ------------------------------------------------------------------------------------
;  Thread-Safe FPS - Counter
;  PB 4.x +, Windows, x86/x64
; ------------------------------------------------------------------------------------

; EnableExplicit

; ------------------------------------------------------------------------------------
; Internal
; ------------------------------------------------------------------------------------

; HR Timer
Prototype HR_Time()

Structure _HR_Internal
  StartTime.q
  Res.d
EndStructure

Define _HR._HR_Internal
Global GetTimeMS.HR_Time

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Procedure _HR_InitTime()
    Shared _HR._HR_Internal
    Protected Frequency.q
    With _HR
      If Not QueryPerformanceFrequency_(@Frequency)
        ProcedureReturn 0
      Else
        QueryPerformanceCounter_(@\StartTime)
        \Res = 1000/Frequency
        ProcedureReturn 1
      EndIf
    EndWith
  EndProcedure
  
  Procedure _HR_Get()
    Shared _HR._HR_Internal
    Protected currentTime.q
    With _HR
      QueryPerformanceCounter_(@currentTime)
      ProcedureReturn (currentTime-\StartTime)*\Res;*\TicksPerSecond/\Frequency
    EndWith
  EndProcedure
CompilerEndIf

Procedure _HR_oldPC_or_Linux()
  ProcedureReturn ElapsedMilliseconds()
EndProcedure

CompilerIf #PB_Compiler_OS<>#PB_OS_Windows
  GetTimeMS = @_HR_oldPC_or_Linux()
CompilerElse
  If _HR_InitTime()
    GetTimeMS = @_HR_Get()
  Else
    GetTimeMS = @_HR_oldPC_or_Linux()
  EndIf
CompilerEndIf

;FPS Data
Structure FPS_Data
  *OldTime
  *Frames
  *FPS
EndStructure

; ------------------------------------------------------------------------------------
; Procedures
; ------------------------------------------------------------------------------------

; FPS Initialisieren
Procedure FPS_Init()
  Protected FPS_TS, *FPS.FPS_Data
  ; FPS - Struktur anlegen
  *FPS = AllocateMemory(SizeOf(FPS_Data))
  With *FPS
    ; Thread Local Storage anlegen
    \OldTime = TlsAlloc_()
    \Frames = TlsAlloc_()
    \FPS = TlsAlloc_()
  EndWith
  ProcedureReturn *FPS
EndProcedure

; FPS deinitialisieren
Procedure FPS_Deinit(*FPS.FPS_Data)
  With *FPS
    ; Thread Local Storage freigeben
    TlsFree_(\OldTime)
    TlsFree_(\Frames)
    TlsFree_(\FPS)
    ; Speicher freigeben
    FreeMemory(*FPS)
  EndWith
EndProcedure

; FPS deinitialisieren
Procedure FPS_Get(*FPS.FPS_Data)
  Protected NewTime, OldTime, Frames, FPS
  
  ; Neue Zeit
  NewTime = GetTimeMS()
  
  With *FPS
    ; Lokale Kopien der Variablen machen
    OldTime = TlsGetValue_(\OldTime)
    Frames = TlsGetValue_(\Frames)
    FPS = TlsGetValue_(\FPS)
    
    If Not Frames
      ; Startzeit setzen
      OldTime = NewTime
      TlsSetValue_(\OldTime, NewTime)
    EndIf
    Frames + 1
    
    If NewTime-OldTime>1000
      FPS = Frames*1000/(NewTime-OldTime)
      Frames = 0
    EndIf
    
    ; Werte rückspeichern
    TlsSetValue_(\Frames, Frames)
    TlsSetValue_(\FPS, FPS)
    
    ProcedureReturn FPS
    
  EndWith
EndProcedure

Verfasst: 21.08.2009 19:49
von Rebon
cxAlex und jetzt bitte noch ein Tutorial wie man diesen Code einbindet. :mrgreen:
Ich habe es mit FPS_Init() versucht... :oops:

Verfasst: 21.08.2009 19:54
von cxAlex
So geht es:

Code: Alles auswählen

; ------------------------------------------------------------------------------------
;  Thread-Safe FPS - Counter
;  PB 4.x +, Windows, x86/x64
; ------------------------------------------------------------------------------------

; EnableExplicit

; ------------------------------------------------------------------------------------
; Internal
; ------------------------------------------------------------------------------------

; HR Timer
Prototype HR_Time()

Structure _HR_Internal
  StartTime.q
  Res.d
EndStructure

Define _HR._HR_Internal
Global GetTimeMS.HR_Time

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Procedure _HR_InitTime()
    Shared _HR._HR_Internal
    Protected Frequency.q
    With _HR
      If Not QueryPerformanceFrequency_(@Frequency)
        ProcedureReturn 0
      Else
        QueryPerformanceCounter_(@\StartTime)
        \Res = 1000/Frequency
        ProcedureReturn 1
      EndIf
    EndWith
  EndProcedure
  
  Procedure _HR_Get()
    Shared _HR._HR_Internal
    Protected currentTime.q
    With _HR
      QueryPerformanceCounter_(@currentTime)
      ProcedureReturn (currentTime-\StartTime)*\Res;*\TicksPerSecond/\Frequency
    EndWith
  EndProcedure
CompilerEndIf

Procedure _HR_oldPC_or_Linux()
  ProcedureReturn ElapsedMilliseconds()
EndProcedure

CompilerIf #PB_Compiler_OS<>#PB_OS_Windows
  GetTimeMS = @_HR_oldPC_or_Linux()
CompilerElse
  If _HR_InitTime()
    GetTimeMS = @_HR_Get()
  Else
    GetTimeMS = @_HR_oldPC_or_Linux()
  EndIf
CompilerEndIf

;FPS Data
Structure FPS_Data
  *OldTime
  *Frames
  *FPS
EndStructure

; ------------------------------------------------------------------------------------
; Procedures
; ------------------------------------------------------------------------------------

; FPS Initialisieren
Procedure FPS_Init()
  Protected FPS_TS, *FPS.FPS_Data
  ; FPS - Struktur anlegen
  *FPS = AllocateMemory(SizeOf(FPS_Data))
  With *FPS
    ; Thread Local Storage anlegen
    \OldTime = TlsAlloc_()
    \Frames = TlsAlloc_()
    \FPS = TlsAlloc_()
  EndWith
  ProcedureReturn *FPS
EndProcedure

; FPS deinitialisieren
Procedure FPS_Deinit(*FPS.FPS_Data)
  With *FPS
    ; Thread Local Storage freigeben
    TlsFree_(\OldTime)
    TlsFree_(\Frames)
    TlsFree_(\FPS)
    ; Speicher freigeben
    FreeMemory(*FPS)
  EndWith
EndProcedure

; FPS deinitialisieren
Procedure FPS_Get(*FPS.FPS_Data)
  Protected NewTime, OldTime, Frames, FPS
  
  ; Neue Zeit
  NewTime = GetTimeMS()
  
  With *FPS
    ; Lokale Kopien der Variablen machen
    OldTime = TlsGetValue_(\OldTime)
    Frames = TlsGetValue_(\Frames)
    FPS = TlsGetValue_(\FPS)
    
    If Not Frames
      ; Startzeit setzen
      OldTime = NewTime
      TlsSetValue_(\OldTime, NewTime)
    EndIf
    Frames + 1
    
    If NewTime-OldTime>1000
      FPS = Frames*1000/(NewTime-OldTime)
      Frames = 0
    EndIf
    
    ; Werte rückspeichern
    TlsSetValue_(\Frames, Frames)
    TlsSetValue_(\FPS, FPS)
    
    ProcedureReturn FPS
    
  EndWith
EndProcedure




;{**********************************************
;**    xFPS                                    *
;**    (C)2009 by Wolfram 'aVoX' Weingartner   *
;}**********************************************


;-Procedures:
;
Procedure MyClearScreen()
  
  RndColorR = Random(255)
  RndColorG = Random(255)
  RndColorB = Random(255)
  ClearScreen(RGB(RndColorR, RndColorG, RndColorB))
  
EndProcedure

Procedure SetNew()
  
  rnd = Random(4)
  If StartDrawing(ScreenOutput())
      For Objects = 20 To (Random(100) + 20)
        new = #False
        If (Random(200)%2 = 0)
          DrawingMode(#PB_2DDrawing_Outlined)
        EndIf
        Select rnd
          Case 0 : 
            Box(Random(1000), Random(800), Random(30), Random(40), RGB(Random(255), Random(255), Random(255)))
          Case 1 : 
            Line(Random(1000), Random(800), Random(50), Random(60), RGB(Random(255), Random(255), Random(255)))
          Case 2 : 
            Circle(Random(1000), Random(800), Random(42), RGB(Random(255), Random(255), Random(255)))
          Case 3 : 
            Plot((Objects + 3), (Objects + 5), RGB(Random(255), Random(255), Random(255)))
          Case 4 : 
            Ellipse(Random(1000), Random(800), Random(50), Random(60), RGB(Random(255), Random(255), Random(255)))
        EndSelect
      Next
    StopDrawing()
  Else
    CloseScreen()
    MessageBox_(#Null, "Could Not draw To Screen", "xFPS Error!", #MB_OK | #MB_ICONERROR)
    End
  EndIf
  
EndProcedure


;-Initializings:
;
If Not InitSprite() Or Not InitKeyboard()
  MessageBox_(#Null, "Fehler beim Initialisieren", "Fehler!", #MB_OK | #MB_ICONERROR)
  End
EndIf

If Not OpenScreen(1440, 900, 32, "xFPS v1.00")
  MessageBox_(#Null, "Fehler beim Öffnen eines Screens", "Fehler!", #MB_OK | #MB_ICONERROR)
  End
EndIf


;-Loads:
;
LoadFont(0, "Arial Black", 14)


;-MAIN CODE
;

Define FPSCounter = FPS_Init()

#R = 255
#G = 255
#B = 255
ClearScreen(RGB(#R, #G, #B))


;-* * * M A I N   L O O P   S T A R T * * *
;

Repeat
  
  
  If StartDrawing(ScreenOutput())
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawingFont(FontID(0))
      CurPos = DrawText(0, 0, "Current FPS: ")
      DrawingMode(#PB_2DDrawing_Default)
      DrawText(CurPos, 0, Str(FPS_Get(FPSCounter)))
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawingFont(#PB_Default)
      DrawText(0, 30, "Press ESC to exit, press TAB to set new. Press SPACE to ClearScreen permanently.")
    Else
      CloseScreen()
      MessageBox_(#Null, "Could Not draw To Screen", "xFPS Error!", #MB_OK | #MB_ICONERROR)
      End
    EndIf
  StopDrawing()
  
  ExamineKeyboard()
  
  FlipBuffers(0)
  
  If KeyboardPushed(#PB_Key_Tab)
    SetNew()
  ElseIf KeyboardPushed(#PB_Key_Space)
    MyClearScreen()
  Else
    ClearScreen(RGB(#R, #G, #B))
  EndIf
  
Until KeyboardPushed(#PB_Key_Escape)

FPS_Deinit(FPSCounter)

;-* * * M A I N   L O O P   E N D * * *
;
End


Verfasst: 21.08.2009 20:06
von Rebon
Danke cxAlex! :allright:
Also einen Unterschied hab ich eigentlich nicht Festellen können, bei euch?

Verfasst: 21.08.2009 20:09
von cxAlex
Rebon hat geschrieben:Danke cxAlex! :allright:
Also einen Unterschied hab ich eigentlich nicht Festellen können, bei euch?
Der Unterschied ist das keine Fehler entstehen können wenn mehrer Threads die Funktion verwenden, bzw. der HR - Timer sollte etwas genauer sein als die Windows - Timeslices.

Gruß, Alex

Verfasst: 21.08.2009 20:16
von Rebon
cxAlex hat geschrieben: Der Unterschied ist das keine Fehler entstehen können wenn mehrer Threads die Funktion verwenden, bzw. der HR - Timer sollte etwas genauer sein als die Windows - Timeslices.

Gruß, Alex
Danke für die Info. :allright: