C ++: Where can I get a frame rate limiter that doesn't use v-sync?

This seems like a huge secret among programmers, no one wants to share their codes for this. Why?

I cannot find a working FPS limiter that could limit FPS to at least 60 without using v-sync.

And I want, of course, to do it right. So I haven’t done my own yet, because everyone says it took them a year to learn all the tricks in the fps limiters ...

Edit: here is my fps limiting code, which is not perfect, but its best I could do, it breaks down anyway:

timeBeginPeriod(1);

frame_start_time = TimerGetTime();

while(!done){
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
        if(msg.message == WM_QUIT){
            done = 1;
        }else{
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }else if(active){ 
        draw_everything();
        SwapBuffers(hDC);

        // fps limiter:
        one_frame_limit = 1000.0f/(float)framerate_limit; // 16.666 ms
        while((time_left = one_frame_limit-(TimerGetTime()-frame_start_time)) > 0){
            if(time_left >= 6.0f){
                Sleep((int)(time_left/6.0f));
            }else{
                Sleep(0); // sleep less than 1ms
            }
        }
        frame_start_time = TimerGetTime();
    }
}

EDIT2: retries my second attempt using the expected timers as suggested:

float one_frame_limit = 1000.0f/(float)framerate_limit;
float time_left = one_frame_limit-(TimerGetTime()-frame_start_time); // 4.7432ms
liDueTime.QuadPart = -(LONGLONG)(time_left*10000.0f);
if(SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0)){
    WaitForSingleObject(hTimer, INFINITE);
}
while((time_left = one_frame_limit-(TimerGetTime()-frame_start_time)) > 0.003f){
    Sleep(0);
}
frame_start_time = TimerGetTime();

, . ... , while , , .

-

: ?:

HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
liDueTime.QuadPart = -100000LL; // testing timer: wait for 10ms

hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
if(hTimer == NULL){
    waitable_timer_supported = 0;
}else if(!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0)){
    waitable_timer_supported = 0;
}else if(WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0){
    waitable_timer_supported = 0;
}

, 2 , ... . ?

+3
3

, 16.6666 , . . , , .

, v-sync - .

+2

DirectX Present(), , , FPS . , 1% , . , Sleep , -, , .

QueryPerformanceCounter Sleep().

LARGE_INTEGER freq, begin, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&begin);
QueryPerformanceCounter(&end);
const unsigned __int64 waitinticks = static_cast<unsigned __int64>(static_cast<double>(1000)/60));
while(end.QuadPart - begin.QuadPart < waitinticks) {
    Sleep(0); // If someone else wants to run, let them.
    QueryPerformanceCounter(&end);
}

- - http://msdn.microsoft.com/en-us/library/ms682492(v=VS.85).aspx. , .

+1

, - , , , , VSync . , , , . VSync .

Regarding the frame restriction code, here are some methods for the producer / consumer configuration step:

http://gafferongames.com/game-physics/fix-your-timestep/

His reasons, apparently, are focused on physics, but they are perfectly applicable to the limitation of personnel.

+1
source

Source: https://habr.com/ru/post/1772641/


All Articles