2016-11-28 1 views
2

verwendet Dies ist, wie ich das Spiel Schleife Griff:SDL/OpenGL-Spiel läuft zu schnell auf 144Hz-Bildschirm; kann nicht Vsync

while (running) { 
    diff = duration_cast<milliseconds>(end - start).count(); 
    start = clock::now(); 

    dt = diff/(16.0); 

    handleInput(); // get input 
    update(dt); // game logic 
    render(); // render game 

    SDL_GL_SwapWindow(window); // swap frame buffer 

    end = clock::now(); 
} 

Es ist beabsichtigt, ein fester Zeitschritt Spiel auf 60FPS gesperrt zu sein (es ist eine Emulation eines SNES Spiels neu gemacht) aber es läuft 144 mal auf meinem 144hz Bildschirm, viel zu schnell. Vsync kann das nicht lösen, also was kann?

+3

Vielleicht nicht 'update (dt);' bei jeder Iteration aufrufen. –

+0

warum sollte ich nicht? – Accumulator

+0

Weil die Aktualisierung jede 1/144 Sekunde zu schnell ist! –

Antwort

2

Hier ist ein kleines Beispiel dafür, wie Spielschleife kann realisiert werden:

int32_t tickInteval = 1000/FPS; // frequency in Hz to period in ms 
uint32_t lastUpdateTime = 0; 
int32_t deltaTime = 0; 
while (running) { // running condition 
    uint32_t currentTime = SDL_GetTicks(); 
    deltaTime = currentTime - lastUpdateTime; 

    int32_t timeToSleep = tickInteval - deltaTime; 
    if(timeToSleep > 0) 
    { 
     SDL_Delay(timeToSleep); // energy saving 
    } 

    update(deltaTime); // game logic 
    lastUpdateTime = currentTime; 
} 

würde ich empfehlen, nah zu diesem Thema zu suchen.


UPD.
Man könnte mit uint32_t Überlauf betroffen sein. Und ja, es wird überlaufen. Nach fast zwei Monaten ununterbrochenem Spiellauf (49,7 Tage um genau zu sein). Was wird dann passieren? currentTime wird eine sehr kleine positive ganze Zahl sein, lastUpdateTime wird eine sehr große positive ganze Zahl sein. Aber die Subtraktion von zwei wird nicht überlaufen, egal was passiert. Außerdem, wenn der Unterschied nicht in int32_t passt, wird es um Modulo von UINT_MAX + 1 gewickelt, was zu einer kleinen positiven ganzen Zahl führt, die die genaue Anzahl der Ticks ist, die diese zwei Werte unterscheiden (in Bezug auf vorzeichenlosen Überlauf von eins).

+0

Ist SDL_Delay nicht unzuverlässig und könnte länger dauern als erwartet? – Accumulator

+0

@Omega gleich mit 'std :: this_thread :: sleep_for' -" Blockiert die Ausführung des aktuellen Threads für mindestens die angegebene sleep_duration ". Dies ist eine Eigenschaft von Nicht-Echtzeit-Betriebssystemen. – teivaz

+0

Also kann ich nicht sicherstellen, dass es nicht plötzlich unter 59/60 FPS fällt? – Accumulator