これはプログラマーの間では大きな秘密のように思えます。誰もこのコードを共有したくありません。なんで?
v-sync を使用せずに FPS を少なくとも 60 に制限できる有効な FPS リミッターが見つかりません。
もちろん、私はそれを正しい方法で行いたいと思っています。だから私はまだ自分のものを作っていません.彼らは皆、fpsリミッターのすべてのトリックを学ぶのに1年かかったと言っています...
編集:これは完璧ではない私のfpsリミッターコードですが、私ができる最善のことですが、それでも涙が出ます:
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 :提案されたように待機可能なタイマーを使用して、2回目の試行を行います:
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つのチェックが失敗する可能性があるのではないかと心配しています...これまでのところ、失敗していません。これは、そのサポートを確認する正しいアプローチですか?