winapi — печать C32 win32 на консоль в фиксированные временные шаги

Я пытаюсь создать функцию, которая позволит мне вводить желаемые кадры в секунду и максимальное количество кадров, а затем использовать функцию «cout» для консоли на фиксированных временных шагах. Я использую Sleep (), чтобы избежать занятого ожидания. Кажется, я заставляю программу спать дольше, чем нужно, потому что она продолжает останавливаться на команде сна, я думаю. ты можешь помочь мне с этим? У меня проблемы с пониманием времени, особенно на окнах.

В конечном счете, я, вероятно, буду использовать этот метод хронометража для определения времени и анимации простой игры, например, понга, или даже простой программы с объектами, которые могут ускоряться. Я думаю, что я уже понимаю GDI и васапи достаточно для воспроизведения звука и отображения цвета на экране, так что теперь мне нужно понять время. Я долго искал, прежде чем задавать этот вопрос в интернете, и уверен, что что-то упустил, но не могу понять, как это сделать 🙁
вот код:

#include <windows.h>
#include <iostream>

// in this program i am trying to make a simple function that prints frame:  and the number frame  in between fixed time intervals
// i am trying to make it so that it doesn't do busy waiting

using namespace std;void frame(LARGE_INTEGER& T, LARGE_INTEGER& T3, LARGE_INTEGER& DELT,LARGE_INTEGER& DESI, double& framepersec,unsigned long long& count,unsigned long long& maxcount,bool& on, LARGE_INTEGER& mili)
{
QueryPerformanceCounter(&T3); // seccond measurement

DELT.QuadPart = &T3.QuadPart - &T.QuadPart; // getting the ticks between the time measurements

if(DELT.QuadPart >= DESI.QuadPart) {count++; cout << "frame: " << count << " !" << endl; T.QuadPart = T3.QuadPart; } // adding to the count by just one frame (this may cause problems if more than one passes)

if(count > maxcount) {on = false;} // turning off the loop

else {DESI.QuadPart = T.QuadPart + DESI.QuadPart;//(long long)framepersec; // setting the stop tick
unsigned long long sleep = (( DESI.QuadPart - DELT.QuadPart) / mili.QuadPart);
cout << sleep << endl;
Sleep(sleep);} // sleeping to avoid busy waiting
}int main()
{

LARGE_INTEGER T1, T2, Freq, Delta, desired, mil;
bool loopon = true; // keeps the loop flowing until max frames has been reached

QueryPerformanceFrequency(&Freq); // getting num of updates per second
mil.QuadPart = Freq.QuadPart / 1000; // getting the number clock updates that occur in  a millisecond
double framespersec; // the number of clock updates that occur per target frame
unsigned long long framecount,maxcount; //to stop the program after a certain amount of frames
framecount = 0;cout << "Hello world! enter the amount of frames per second : " << endl;
cin >> framespersec;
cout << "you entered: " << framespersec << " ! how many max frames?" << endl;
cin >> maxcount;
cout << "you entered: " << maxcount << " ! now doing the frames !!!" << endl;
desired.QuadPart = (Freq.QuadPart / framespersec);

while(loopon == true) {
frame(T1, T2, Delta, desired, framespersec, framecount, maxcount,loopon, mil);
}cout << "all frames are done!" << endl;
return 0;
}

0

Решение

Время, в течение которого вы спите, ограничено частотой системных часов. Частота по умолчанию равна 64 Гц, поэтому вы в конечном итоге увидите сны с шагом 16 мс. Любой сон менее 16 мс будет длиться не менее 16 мс — он может быть дольше в зависимости от загрузки процессора. Аналогично, сон в 20 мс, вероятно, будет округлен до 32 мс.

Вы можете изменить этот период, вызвав timeBeginPeriod (…) и timeEndPeriod (…), что может повысить точность сна до 1 мс. Если вы посмотрите на мультимедийные приложения, такие как VLC Player, вы увидите, что они используют эти функции для получения надежной синхронизации кадров. Обратите внимание, что это меняет частоту планирования в масштабе всей системы, что влияет на время автономной работы ноутбуков.

Больше информации:
http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298%28v=vs.85%29.aspx

2

Другие решения

Таймеры ожидания более точны, чем Sleep, а также лучше интегрировать с циклом сообщений GUI (заменить GetMessage с MsgWaitForMultipleObjects). Я успешно использовал их для синхронизации графики раньше.

Они не дадут вам высокой точности, например управление последовательным или сетевым выходом с точностью до миллисекунды, но обновления пользовательского интерфейса в любом случае ограничены VSYNC.

0