2010-09-06 4 views
1

Sur chaque trame de mon application, je peux appeler timeGetTime() pour récupérer les millisecondes actuelles écoulées et soustraire la valeur de timeGetTime() de l'image précédente pour obtenir le temps entre les deux trames. Cependant, pour obtenir la fréquence d'images de l'application, je dois utiliser cette formule: fps = 1000/delay (ms). Ainsi, par exemple, si le délai était de 16 millisecondes, alors 1000/16 = 62,5 (stocké en mémoire sous 62). Alors disons que le retard est devenu 17 millisecondes, puis 1000-1017 = 58, et ainsi de suite:Déterminez le framerate en fonction du délai

1000/10 = 100
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

Comme vous pouvez le voir pour des instances consécutives pour le délai, il y a de gros écarts dans les fréquences d'images. Alors, comment les programmes comme FRAPS déterminent-ils le taux de trame des applications qui se situent entre ces valeurs (par exemple 51,53,54,56,57, etc.)?

Répondre

2

Vous verrez si vous le faites sur tous les dixième trame, puis divisez cette valeur par 10, vous obtiendrez facilement les taux de trame dans les lacunes que vous voyez. Vous trouverez également probablement votre taux de cadre sont plus élevés depuis que vous faites moins de travail admin dans la boucle :-)

En d'autres termes, quelque chose comme (pseudo code):

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 
0

Vous ne savez pas, mais vous avez peut-être besoin d'une meilleure minuterie (haute résolution). Vérifiez QueryPerformanceTimer. Pourquoi voudriez-vous faire cela sur chaque image?

2

En plus de @ Marko suggestion d'utiliser une meilleure minuterie, l'astuce clé pour un variant sans heurts et une meilleure évaluation approximative de la fréquence d'image est d'utiliser une moyenne mobile - ne pas considérer seulement le dernier délai que vous avez observé, Considérez la moyenne de (disons) les cinq derniers. Vous pouvez calculer ce dernier comme un nombre à virgule flottante, pour obtenir plus de valeurs possibles pour la fréquence d'images (que vous pouvez toujours arrondir à l'entier le plus proche bien sûr).

Pour le calcul minimal, envisager une "file d'attente fifo" des 5 derniers retards (...) pseudocode:

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

Au lieu d'une moyenne mobile (comme le suggère @ Alex) Je suggère un passe-bas Filtre. Il est plus facile à calculer et peut être ajusté pour avoir une quantité arbitraire de lissage de valeur sans modification de la performance ou de l'utilisation de la mémoire. En bref (démontré en 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; 
} 

Pour une jolie démonstration de cette fonctionnalité, voir mon exemple en direct ici:
http://phrogz.net/JS/framerate-independent-low-pass-filter.html

Questions connexes