Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Techie

Alter Hase

  • »Techie« ist der Autor dieses Themas

Beiträge: 717

Wohnort: Bayreuth

Beruf: Student | Hilfswissenschaftler in der Robotik

  • Private Nachricht senden

1

02.03.2013, 18:03

FPS berechnen???

Hi,
ich arbeite mit C# und SharpDX und möchte die FPS berechnen, leider kommt bei mir immer 0.
Folgendes Code

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// The main-file for the Game

using System;
//using System.Drawing;
using SharpDX;
using SharpDX.Direct3D9;
using SharpDX.Windows;
using Color = SharpDX.Color;

namespace Mindfigs
{
    static class Game
    {
        [STAThread]
        static void Main()
        {
            var form = new RenderForm(" Mind Figures ");
            var device = new Device( new Direct3D(), 0, DeviceType.Hardware, form.Handle, CreateFlags.HardwareVertexProcessing, new PresentParameters( form.ClientSize.Width, form.ClientSize.Height ));

            FontDescription FontText = new FontDescription()
            {
                Height = 24,
                Italic = false,
                CharacterSet = FontCharacterSet.Ansi,
                FaceName = "Arial",
                MipLevels = 0,
                OutputPrecision = FontPrecision.TrueType,
                PitchAndFamily = FontPitchAndFamily.Default,
                Quality = FontQuality.ClearType,
                Weight = FontWeight.Bold
            };

            var MyFont = new Font(device, FontText);
            var MyText = ("0");
            // var MyDimenson = MyFont.MeasureText(null, MyText, FontDrawFlags.Center);

            int Frames = 0;
            float fFPS = 0;
            float FirstTime = 0;
            float LastTime = 0;

            RenderLoop.Run(form, () =>
            {
                FirstTime = DateTime.Now.Ticks;
                Frames = Frames + 1;
                
                device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);

                device.BeginScene();

                // MyFont.DrawText(null, MyText, MyDimenson, FontDrawFlags.Center | FontDrawFlags.VerticalCenter, Color.White);
                MyFont.DrawText(null, MyText, 200, 200, Color.White);

                device.EndScene();
                device.Present();
                fFPS = FPS(FirstTime, Frames);
                MyText = fFPS.ToString();
                Frames = 0;
                LastTime = FirstTime;
               // LastTime = DateTime.Now.Ticks - FirstTime;
               // Frames = FPS(LastTime);
            });
        }



        static public float FPS(float Time, int Frame )
        {
            float NewTime = DateTime.Now.Ticks;
            float FPS = 0;
            if (NewTime > Time + 1000.0f)
            {
                FPS = (NewTime - Time) / 1000.0f + Frame;
                return FPS;
            }
           return FPS;
        }
        
    }

}


Ich habe irgendwo 'nen Denkfehler aber wo? :\

Gruß Techie
I write my own game engines because if I'm going to live in buggy crappy filth, I want it to me my own - Ron Gilbert

daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

2

02.03.2013, 18:14

Guck dir mal deine Funktion FPS genauer an, du gibst die Variable FPS zurück welche du vorher auf 0 gesetzt hast. Deine Bedingung trifft ja nur einmal pro Sekunde zu ;)

FSA

Community-Fossil

  • Private Nachricht senden

3

02.03.2013, 18:29

Trotzdem hat er den falschen Ansatz.
Am besten am Ende von Run():
LastTime = DateTime.Now.Ticks - FirstTime
Deine FPS sind dann 1.0f/LastTime
Ob es wirklich Frames per Second sind weiß ich nicht. Ich weiß nicht was Ticks zurückgibt.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

4

02.03.2013, 19:50

Zitat

Ich weiß nicht was Ticks zurückgibt.

Ich bin mir nicht ganz sicher, aber ich glaube es war ein Int64 mit 100ns Auflösung.
Hier bräuchte man eher das "TotalSeconds"-Property.

Ganz nebenbei ist die Berechnung von Zeitabständen über die Uhrzeit eine ganz schlechte Idee:
Und zwar weil die Genauigkeit unter dem 10ms Bereich liegt, was hier ganz schlecht ist.
Ich würde dir die "System.Diagnostics.Stopwatch"-Klasse nahe legen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

02.03.2013, 20:14

Datetime.Now.Ticks liefert Werte auf 1/10.000 Millisekunde. D.h. um auf Sekunden zu kommen, muss man durch 10.000.000 teilen!

Die Auflösung dieser Zeit liegt nicht bei 10ms. Nicht nach meiner Erfahrung. Selbst wenn sie da läge, wäre das 1/100 einer Sekunde, für FPS-Berechnung wohl absolut ausreichend genau. Eine Stopwatch wäre da totaler Overkill und übrigens auch nicht anders von der Genauigkeit her. Ich weiß, dass bei Google überall was von 10ms steht und dass Stopwatch besser sei. Wenn ich das hier ausprobiere ist aber genau das Gegenteil der Fall.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

6

03.03.2013, 00:17

Zitat

Datetime.Now.Ticks liefert Werte auf 1/10.000 Millisekunde

Was genau 100 Nanosekunden entspricht, wie ich geschrieben habe. ;-)

Zitat

Die Auflösung dieser Zeit liegt nicht bei 10ms.

Meines Wissens ist das prinzipbedingt so bei all den Uhrzeitfunktionen.
10ms und sogar noch positiv geschätzt. Ich habe im Internet schon oft von viel schlechteren Ergebnissen von 20 bis 50ms gelesen.
http://stackoverflow.com/questions/21431…e-now-precision

Zitat

Selbst wenn sie da läge, wäre das 1/100 einer Sekunde, für FPS-Berechnung wohl absolut ausreichend genau.

Nein ist es sicher nicht.
Bei 60FPS was ich als minimale Anforderung sehen würde liegt die vergangene Zeit zwischen den Frames bei 1s/60 (~16ms).
Und zum Performancetest etc. sind durchaus auch locker weit über hundert FPS möglich die korrekt bestimmt werden sollten.

Zitat

Eine Stopwatch wäre da totaler Overkill und übrigens auch nicht anders von der Genauigkeit her.

Nix Overkill, sondern das Mittel der Wahl.
Anstatt die Different zweier Zeitpunkte zu bilden, wieso nicht gleich den Zeitabstand messen?

Zitat

übrigens auch nicht anders von der Genauigkeit her

Auch hier liegst du leider falsch.
Diese Klasse nutzt unter Windows den QueryPerformanceCounter und der bestimmt die Zeitdifferenz mit maximal möglicher Genauigkeit.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

03.03.2013, 08:55

Dude, bevor Du einfach nur nacherzählst, was bei Stackoverflow steht, lies was ich geschrieben habe und teste es selbst aus. Ich erzähle das Zeug nicht, weil ich es glaube, sondern weil ich wegen einer hochpräzisen Timer-Lösung viele Wege durchprobiert habe. Und das hat sehr deutlich gezeigt, dass die DateTime.Now.Ticks viel mehr auflösen als die Leute meinen. Vielleicht ist das unter XP mit den ~10-20ms noch der Fall, weil es den BIOS-Timer ausliest, unter Win7 jedenfalls nicht mehr, da sind Auflösungen von 1ms absolut kein Problem. Probier es selbst aus, wenn Du es nicht glaubst. Die Aussagen von Stackoverflow sind mir alle hinreichend bekannt, denn genau auf die bin ich bei meiner Suche ebenfalls gestoßen.

Und dennoch reicht es für eine FPS Anzeige locker aus. Eine FPS-Anzeige ist nämlich kein Zeit-kritisches System. Ein FPS-Counter muss nur eins können: Sagen, wenn eine Sekunde vergangen ist. Dazu braucht man eine Auflösung von einer einzigen Sekunde, nicht mehr und nicht weniger. Also ob 1/60 oder 1/100 oder 1/10 ist dabei total egal, denn weder ist das für einen FPS-Counter irgendwie relevant, noch ist es kritisch, wenn dieser mal +-1 anzeigen sollte. Vielleicht hast Du ja jetzt verstanden, was gemeint war.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

8

03.03.2013, 09:36

Nur um das mal erwähnt zu haben, eine FPS Anzeige ist ja ganz nett. Aber sie ist nicht sehr gut geeignet um eine Aussage darüber zu geben wie performant etwas läuft. Dazu sollte man lieber eine Anzeige der „Schleifen“zeit zu Rate ziehen.

Nur als Beispiel um das einmal auf zu zeigen was ich meine, bei einer Zeiterhöhung von 1ms;
Von 0,2ms auf 1,2ms entspricht 5000F/s auf 834F/s sprich 1ms bewirkt einen FPS Einbruch von fast 4200F/s.
Von 14ms auf 15ms entspricht 71F/s auf 67F/s hier wieder 1ms aber nur noch 4F/s Einbrucht.
:love: := Go;

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

03.03.2013, 09:41

Das Argument ist zwar richtig, aber eine FPS-Anzeige dient meist nur einem Zweck: Schafft es das Spiel oberhalb der Bildschirmfrequenz (oder der magischen Grenze von 24) zu bleiben oder nicht. Außerdem interessiert es einen Gamer nicht, welche Frametime da steht, mit der kann er nichts anfangen. Mit FPS hingegen durchaus.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

10

03.03.2013, 11:43

Zitat

Dude, bevor Du einfach nur nacherzählst, was bei Stackoverflow steht, lies was ich geschrieben habe und teste es selbst aus.

Ich habe das Problem schon selber oft gehabt.
Außerdem habe ich selber den Stackoverflow-Link nur überflogen und absolut nicht nacherzählt, sondern als Beleg benutzt.

Zitat

unter Win7 jedenfalls nicht mehr, da sind Auflösungen von 1ms absolut kein Problem.

Weshalb eine unsaubere Lösung nehmen, die nur mit etwas Glück auf einen neuen Betriebssystem läuft?

Zitat

Sagen, wenn eine Sekunde vergangen ist. Dazu braucht man eine Auflösung von einer einzigen Sekunde, nicht mehr und nicht weniger.

So würde ich das nicht machen.
So kann man es machen, aber das ist nicht der Königsweg.
1 geteilt durch die Zeit die ein Frame braucht.
Genau so wie FSA beschrieben hat.
So können die FPS viel präziser bestimmt werden was zu Performancetests und Optimierungen nützlich ist und außerdem kann bestimmt werden wieviel die Framerate variiert. Jedes Frame sollte nach Möglichkeit genau gleich lange zu rendern brauchen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (30.10.2013, 23:50)


Werbeanzeige