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

1

14.07.2014, 10:20

Fixed TimeStep Problem

Guten Morgen,

ich arbeite mich gerade in SFML.NET ein und da habe ich leider nicht den Luxus einer schönen fertigen GameLoop wie bei XNA.

Deswegen versuche ich gerade selbst eine vernünftige zu Implementieren, leider stoße ich momentan auf einige Hürden hoffe hier kann mir jemand helfen und mir erklären warum das so ist.

Erstmal mein 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
using System;
using SFML.Window;
using SFML.Graphics;
using SFML.Audio;
using System.Diagnostics;
 
namespace SFML_Project_64_Bit
{
    class Program
    {
        static void Main(string[] args)
        {
            MySFMLProgram app = new MySFMLProgram();
            app.StartSFMLProgram();
        }
    }
    class MySFMLProgram
    {
 
        //Window and Cam
 
        public  RenderWindow _window;
        public  View camera;
 
 
        //Asset
 
        protected Texture playTexture;
        protected Sprite playSprite;
 
        //Time Vars
 
        const double frame = 60;
        const double timeStep = 1 / frame;
        double timeBank;
        TimeSpan dT;
       
 
        public void StartSFMLProgram()
        {
            LoadContent();
 
            //Render Window
 
            _window = new RenderWindow(new VideoMode(1280, 760), "SFML window");
            _window.SetVisible(true);
            //_window.SetFramerateLimit(60);
            _window.SetVerticalSyncEnabled(true);
            _window.Closed += new EventHandler(OnClosed);
 
            //Camera
 
            camera = new View(new Vector2f(0, 0), new Vector2f(1280, 760));
 
 
            //DeltaTime
 
            dT = new TimeSpan();
            Stopwatch timer = new Stopwatch();
            timer.Start();
           
            while (_window.IsOpen())
            {
                timeBank += dT.TotalSeconds;
                Console.WriteLine(timeBank);
 
                if (timeBank >= timeStep)
                {
                    camera.Rotation += 1f;
                    _window.SetView(camera);
                    timeBank -= timeStep;
                }
 
                _window.DispatchEvents();
                this.Draw();
 
                dT = timer.Elapsed;
                timer.Restart();
            }
        }
 
        public void Draw()
        {
            _window.Clear(Color.Red);
            _window.Draw(playSprite);
            _window.Display();
        }
 
        void OnClosed(object sender, EventArgs e)
        {
            _window.Close();
        }
 
        public void LoadContent()
        {
            playTexture = new Texture("GraphicAsset/playButton.png");
            playSprite = new Sprite(playTexture);
            playTexture.Smooth = true;
        }
    }
}


Das kuriose ist es funktioniert so mit 60 und 9999 FPS aber es gibt extreme unterschiede bei SetMaxFrame und Vsync.

Wenn SetMaxFrame(60) benutze, habe ich so gut wie keine CPU auslastung wie man hier schön sehen kann --- > http://snag.gy/byQlA.jpg

Allerdings wenn ich VSYNC benutze verbrauche ich einen ganzen Core --> http://snag.gy/kADOW.jpg

Könnte mir bitte jemand erklären warum das auftritt und wie ich es beheben kann?

Grüße

WhySoSad

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

14.07.2014, 11:24

Ich gehe mal davon aus, dass du nur das eine oder nur das andere verwendest.
VSync sorgt dafür, dass, einfach ausgedrückt, auf den Bildschirm und dessen Bildwiederholung gewartet wird, bis ein Swap der Buffer durchgeführt wird. Das allerdings sorgt nicht dafür, dass das gesamte Spiel dich daran anpasst. Auch wird dir Fraps nur die Bilder pro Sekunde anzeigen können, nicht aber die Anzahl der FPS, die für die Spiellogik verwendet werden.
Entweder gehts du davon aus, dass eine Bildwiederholrate von 60 das Optimum ist und verwendest diese, du versuchst die Widerholrate des Bildschirms zu ermitteln, du lässt es wie bisher oder du gibst dem Spieler die Auswahl, was er davon haben will.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

3

14.07.2014, 11:35

Danke Sacaldur für die Erklärung von VSYNC. Leider löst es trotzdem nicht mein Problem mit der hohen CPU last wenn ich VSYNC benutze.

Grüße

WhySoSad

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

4

14.07.2014, 11:47

Entweder gehts du davon aus, dass eine Bildwiederholrate von 60 das Optimum ist und verwendest diese, du versuchst die Widerholrate des Bildschirms zu ermitteln, du lässt es wie bisher oder du gibst dem Spieler die Auswahl, was er davon haben will.

Falls es nicht deutlich genug war: verwende nicht nur VSync, wenn du keine 100 % Auslastung haben willst.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

5

14.07.2014, 11:58

Nein es war nicht deutlich genug, sonst würde ich nicht nachfragen.

Ich habe mich natürlich informiert und überall wird empfohlen VSYNC zu nutzen anstatt MaxFrameRate da dieses noch Tearing unterbindet(ausserdem wird davon abgeraten VSync und MaxFrameRate zu verwenden), so also gibt es für mich nur 2 Optionen (Die es später auch im Menü geben soll) VSync on oder VSync off.

Mein Ziel ist es nun mit Vsync on nicht meinen ganzen Core ausgelastet zu haben. Was aber bei meinem obigen Code passiert.

Also würde ich mich über Tipps freuen wie ich das Problem besser lösen könnte bzw. diese Auslastung unterbinde.

Grüße

WhySoSad

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »WhySoSad« (14.07.2014, 12:09)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

14.07.2014, 11:58

VSync allein sollte aber reichen. Im Normalfall jedenfalls reicht es. Bei RR nutzen wir auch SFML und machen es letztlich nicht anders und da ist die Auslastung prima allein durch Verwendung von VSync (die Game-Logik wird natürlich trotzdem unabhängig von den FPS berechnet). Bei meinen anderen Games ebenfalls (bei denen liegt die Auslastung EINES Prozessors bei ~4% mit VSync).
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]

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

7

14.07.2014, 16:07

Du brauchst in etwa sowas in deiner Hauptschleife:

C-/C++-Quelltext

1
2
3
4
5
while(currentTime > fixedFrameTime*logicFrameCounter)
{
// hier die Logik berechnen.
++logicFrameCounter;
}


Das sorgt dafür, dass die Logik genau 60 mal pro Sekunde berechnet wird. Egal ob du 120 oder 30 Grafik-FPS hast.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »NachoMan« (14.07.2014, 16:13)


H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

8

14.07.2014, 16:30

Bei mir blockiert V-Sync ebenfalls (CFSML). Bin aber auf das hier gestoßen Link.

Ansonsten kannst du auch die Kontrolle über den Thread an das OS abgeben solange dafür noch ausreichend Zeit im Loop ist. Oder mit einem Ticker/Watchdog Timer Thread (aber keine Ahnung wie das mit C# geht).
:love: := Go;

9

14.07.2014, 18:05

Bei mir funktioniert es nun auch mit VSync on. Es hat irgendwie am Taskmanager gelegen. Da ich ihn zwischen den Test's mit 9999 Frames und 60 Frames nicht neugestartet habe, hat er sich anscheinend nicht resettet. Jedenfalls hat Taskmanager restarten das Problem behoben bzw. es hat erst ein falsches Problem angezeigt.

http://snag.gy/wIggg.jpg

Grüße

Sad

Werbeanzeige