2015-01-14 2 views
0

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

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

#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

Убедитесь, что вы передаете миллисекунды спать. Если ваша математика дает другие единицы (я не проверял логику подробно), то вы не получите то, что хотите. Кроме того, обратите внимание, что сон традиционно не настолько точен. Например, Sleep (1) может очень хорошо спать в течение более 1 миллисекунды. – TheUndeadFish

+0

Я буду изучать использование времени начала периода, чтобы увеличить разрешение Sleep(), но как я могу убедиться, что использую миллисекунды? Я думал, что я ... – user3023723

+0

Познакомившись с вашим кодом, ваши параметры функции являются указателями, но вы не разыскиваете их. Вы также не можете инициализировать некоторые значения (например, вы никогда не инициализируете framecount). Когда вы передаете framecount в качестве указателя, а затем выполняете count ++, вы увеличиваете указатель, а не значение count. – awr

ответ

0

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

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

+0

Или вызовите [SetTimer] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644906 (v = vs.85) .aspx). –

+0

@ DanKorn: Это не будет работать в его консольном приложении вообще, а также накапливает ошибку с течением времени, в отличие от ожидаемого таймера. –

+0

Что заставляет вас думать, что SetTimer не будет работать в консольном приложении? Мы используем его в службе Windows, без какого-либо интерфейса, и он отлично работает. Кроме того, [нет скопирования ошибок в Vista и позже] (http://www.virtualdub.org/blog/pivot/entry.php?id=272). –

2

Время, в которое вы спите, ограничено частотой системных часов. Частота по умолчанию равна 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

+0

Спасибо за ваше быстрое время отклика! : D Я думаю, что я обязательно посмотрю, что за время игры на Win 32. Но я не получаю 60 кадров в секунду, это просто швы, чтобы висеть во сне, как я заставил его слишком долго спать или что-то в этом роде. Я продолжаю спотыкаться о времени, когда я пытаюсь создать игру или программу с учетом сроков. – user3023723

+0

@ user3023723: Сделайте некоторые отладки. Распечатайте значение, которое вы передаете для сна, и убедитесь, что оно кажется разумным. Помните, что Sleep принимает значение в миллисекундах. –

+0

Это не позволяет мне печатать в коде. Я думаю, что он либо застрял на консоли, либо программа останавливается в первом операторе if в frame(). – user3023723

Смежные вопросы