My attempt at a fixed framerate using SDL2 without using VSync. Just using SDL_Delay left the fps a bit slower or faster due to the fact SDL_Delay only works with milliseconds. So the solution I came up with is after using SDL_Delay the remainder of the "extra" time is elapsed through a loop. The solution seems a little bit cluttered to me and my experience with programming in general is very limited so any pointers would be much appreciated.

float frame_cap{ 60 };
float ms_per_frame{ 1000.0f / frame_cap };
float fps{ 0 };
uint64_t start_counter;
uint64_t end_counter;

bool quit{ false };
while( quit != true )
    start_counter = SDL_GetPerformanceCounter();


    end_counter = SDL_GetPerformanceCounter();
    //multiplying by 1000.0f to convert to ms
    float elapsed_ms = ((end_counter - start_counter) / (float)SDL_GetPerformanceFrequency()) * 1000.0f;
    if( elapsed_ms < ms_per_frame )
        float ms_left = ms_per_frame - elapsed_ms;
        SDL_Delay( floor(ms_left) );

        //loop for the amount of time that could not be delayed with SDL_Delay
        float missed_ms = ms_left - floor(ms_left);
        start_counter = SDL_GetPerformanceCounter();
        float delayed_ms { 0 };
        while(delayed_ms < missed_ms)
            end_counter = SDL_GetPerformanceCounter();
            delayed_ms = ((end_counter - start_counter) / (float)SDL_GetPerformanceFrequency()) * 1000.0f;
        //adding time delayed to elapsed time of frame for fps calculation
        elapsed_ms += floor(ms_left) + delayed_ms;
        /*floor(ms_left) is time delayed using SDL_Delay
        this has a chance to be inaccurate if SDL_Delay 
        delays more then floor(ms_left) due to OS scheduling*/
    //dividing by 1000.0f to convert to seconds
    fps = 1.0f / (elapsed_ms / 1000.0f);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.