Jak obliczyć czas delta z SDL?

11

Słyszałem, że możesz obliczyć czas delta za pomocą dwóch funkcji o nazwie SDL_GetPerformanceCounter i SDL_GetPerformanceFrequency. Nie jestem pewien, jak działają całkowicie, ale słyszałem, że jest to trochę podobne do używania SDL_GetTicks ()

    Uint64 NOW, LAST;
    double deltaTime = 0;

    while (somebool)
    {
       LAST = SDL_GetPerformanceCounter();
       NOW = SDL_GetPerformanceCounter();
       LAST = NOW;

       deltaTime = (NOW - LAST) / (double)SDL_GetPerformanceFrequency();

       /**Rendering**/
    }

Mam ten kod, ale ilekroć drukuję deltaTime lub próbuję go użyć, zawsze ma on kilka naprawdę losowych i szalonych liczb. Czy to jest poprawne?

surafel911
źródło
2
pokazany kod zawsze ustawiałby czas delty na 0, prawda? (TERAZ = OSTATNI, TERAZ - OSTATNI.)
David van Brink

Odpowiedzi:

13

Czytając przykład kodu dostarczony przez SDL na SDL_GetPerformanceFrequency, mogłem łatwo dowiedzieć się, jak obliczyć deltatime za pomocą tych funkcji.

Zasadniczo powinno sprowadzać się do tego:

Uint64 NOW = SDL_GetPerformanceCounter();
Uint64 LAST = 0;
double deltaTime = 0;

while (somebool)
{
   LAST = NOW;
   NOW = SDL_GetPerformanceCounter();

   deltaTime = (double)((NOW - LAST)*1000 / (double)SDL_GetPerformanceFrequency() );

   /**Rendering**/
}

Uwaga: pierwsza ramka zawsze będzie miała deltatime 0 lub coś bardzo zbliżonego

Powinno to wypełnić wartość deltaTime w milisekundach, można to łatwo przekonwertować na sekundy, mnożąc końcowy wynik przez 0,001.

Odniesienie: https://wiki.libsdl.org/SDL_GetPerformanceFrequency

Patrick le Duc
źródło
6
Byłoby to dokładniejsze: deltaTime = ((NOW - LAST)*1000 / (double)SDL_GetPerformanceFrequency() );ponieważ pozwala to uniknąć zaciśnięcia liczby z powodu podziału na liczby całkowite.
Mortennobel,
2

Sposób, w jaki poszedłem do obliczania czasu delty, był przez SDL_GetTicks():

struct Clock
{
    uint32_t last_tick_time = 0;
    uint32_t delta = 0;

    void tick()
    {
        uint32_t tick_time = SDL_GetTicks();
        delta = tick_time - last_tick_time;
        last_tick_time = tick_time;
    }
};

Następnie po prostu zaznaczam Clockwystąpienie w głównej pętli.

Salajouni
źródło
Chociaż to podejście również działa, druga odpowiedź jest bardziej precyzyjna.
Tyyppi_77