SDL_GetTicks() accuracy below the millisecond level

10,358

Solution 1

You cannot use SDL_GetTicks() if you want higher precision but there are many other alternatives. If you want to be platform independant you need to be careful though, but here is a portable C++11 example that will get you started:

#include <iostream>
#include <chrono>
typedef std::chrono::high_resolution_clock Clock;

int main()
{
    auto t1 = Clock::now();
    auto t2 = Clock::now();
    std::cout << "Delta t2-t1: " 
              << std::chrono::duration_cast<std::chrono::nanoseconds>(t2 - t1).count()
              << " nanoseconds" << std::endl;
}

Running this on ideone.com gave me:

Delta t2-t1: 282 nanoseconds

Solution 2

Well, of course, you need to actually wait until >=1ms has passed before updating your last tick count

void Application::Update()
{
    Uint32  current_time = SDL_GetTicks();
    Uint32  delta_time = current_time - last_update_time;

    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
        switch(event.type)
        {
            case SDL_QUIT:
            {
                should_close = true;
            }
            break;

            default:
                break;
        }
    }

    if (delta_time >= 1)
    {
        // Update game objects with delta_time

        last_update_time = current_time;
    }   
}
Share:
10,358
user3325226
Author by

user3325226

Updated on June 12, 2022

Comments

  • user3325226
    user3325226 almost 2 years

    I program currently something with SDL2. All works fine, but I have a problem with the SDL_GetTicks() method. Normally it should return the total application time in milliseconds, but it always returns most of the time the value 0 and sometimes the value 1.

    I initialized SDL with SDL_INIT_EVERYTHING flag.

    The problem with the following code is the loop is too fast, so the delta time is smaller than 1 ms. Is there a method to achieve a higher precision?

    #include "Application.hpp"
    
    void Application::Initialize()
    {
        int sdl_initialize_result = SDL_Init(SDL_INIT_EVERYTHING);
        if(sdl_initialize_result < 0)
        {
            std::cerr << "Failed to initialize SDL !" << std::endl << SDL_GetError() << std::endl;
        }
    
        window = SDL_CreateWindow("Project Unknown", 100, 100, 800, 600, SDL_WINDOW_SHOWN);
        if(window == nullptr)
        {
            std::cerr << "Failed to create  SDL window !" << std::endl << SDL_GetError() << std::endl;
        }
    
        last_update_time = SDL_GetTicks();
    }
    
    void Application::Dispose()
    {
        SDL_DestroyWindow(window);
        SDL_Quit();
    }
    
    void Application::Render()
    {
    }
    
    void Application::Update()
    {
        Uint32  current_time = SDL_GetTicks();
        Uint32  delta_time = current_time - last_update_time;
    
    
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                {
                    should_close = true;
                }
                break;
    
                default:
                {
    
                }
                break;
            }
        }
    
        // Update game objects with delta_time
    
        last_update_time = current_time;
    }
    
    
    void Application::Run()
    {
        Initialize();
    
        should_close = false;
        do
        {
            Render();
            Update();
        }
        while(should_close == false);
    
        Dispose();
    }