Определить частоту кадров на основе задержки - PullRequest
1 голос
/ 06 сентября 2010

В каждом кадре моего приложения я могу вызвать timeGetTime (), чтобы получить текущие истекшие миллисекунды, и вычесть значение timeGetTime () из предыдущего кадра, чтобы получить время между двумя кадрами. Однако, чтобы получить частоту кадров приложения, я должен использовать эту формулу: FPS = 1000 / задержка (мс). Так, например, если задержка составляла 16 миллисекунд, то 1000/16 = 62,5 (хранится в памяти как 62). Тогда, скажем, задержка стала 17 миллисекунд, затем 1000/17 = 58 и так далее:

* * Тысяча два 1000/10 = 100 * 1 003 * 1000/11 = 90
1000/12 = 83
1000/13 = 76
1000/14 = 71
1000/15 = 66
1000/16 = 62
1000/17 = 58
1000/18 = 55
1000/19 = 52
1000/20 = 50

Как вы можете видеть для последовательных случаев задержки, в частотах кадров есть довольно большие разрывы. Так как же программы типа FRAPS определяют частоту кадров приложений, которые находятся между этими значениями (например, 51,53,54,56,57 и т. Д.)?

Ответы [ 4 ]

2 голосов
/ 06 сентября 2010

Почему вы делаете это на каждом кадре?Вы обнаружите, что если вы делаете это на каждом десятом кадре, а затем делите это значение на 10, вы легко получите частоту кадров в промежутках, которые видите.Вы также, вероятно, обнаружите, что частота кадров выше, поскольку вы выполняете меньше административной работы в цикле: -)

Другими словами, что-то вроде (псевдокод):

chkpnt = 10
cntr = chkpnt
baseTime = now()
do lots of times:
    display next frame
    cntr--
    if cntr == 0:
        cntr = chkpnt
        newTime = now()
        display "framerate = " (newTime - baseTime) / chkpnt
        baseTime = newTime
2 голосов
/ 06 сентября 2010

В дополнение к предложению @ Marko использовать лучший таймер, ключевой трюк для плавно изменяющегося и лучшей приблизительной оценки частоты кадров заключается в использовании скользящего среднего - не учитывайте только самую последнюю задержку, которую вы наблюдали, рассмотрите среднее (скажем) последних пяти. Вы можете вычислить последнее как число с плавающей запятой, чтобы получить больше возможных значений частоты кадров (которые вы, конечно, можете округлить до ближайшего целого числа).

Для минимальных вычислений рассмотрим «очередь fifo» из последних 5 задержек (псевдокод) ...:

array = [16, 16, 16, 16, 16]   # initial estimate
totdelay = 80
while not Done:
    newest = latestDelay()
    oldest = array.pop(0)
    array.append(newest)
    totdelay += (newest - oldest)
    estimatedFramerate = 200 / totdelay
    ...
0 голосов
/ 23 сентября 2011

Вместо скользящего среднего (как предлагает @Alex) я предлагаю фильтр нижних частот.Его проще вычислить, и его можно настроить для произвольного сглаживания значений без изменения производительности или использования памяти.Вкратце (продемонстрировано в JavaScript):

var smoothing = 10; // The larger this value, the more smoothing
var fps = 30;       // some likely starting value
var lastUpdate = new Date;
function onFrameUpdate(){
  var now = new Date;
  var frameTime = now - lastUpdate;
  var frameFPS  = 1/frameTime;
  // Here's the magic
  fps += (frameFPS - fps) / smoothing;
  lastUpdate = now;
}

Для демонстрации этой функциональности см. Мой живой пример здесь:
http://phrogz.net/JS/framerate-independent-low-pass-filter.html

0 голосов
/ 06 сентября 2010

Не уверен, но, возможно, вам нужен более качественный таймер.Проверьте QueryPerformanceTimer .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...