1. Introduction

Connaître le nombre d'images par seconde est un bon moyen d'estimer le travail demandé à votre machine, ou d'évaluer les performances de votre matériel... Vous pouvez ainsi ensuite repérer ce qui demande le plus de ressources ou le code mal optimisé.

Mais voyons ce qu'est cet indicateur. L'indicateur d'Images Par Seconde (en anglais, Frame Per Second — FPS) correspond tout simplement au rapport nombre d'images rendues par le temps écoulé pour les afficher, soit n / dtn est le nombre d'images et dt = t(n) - t(0) le temps écoulé.

Calculer le nombre d'images par seconde est donc très facile. Je vais proposer ici deux méthodes.

Dans tous les cas, il vous faudra une fonction capable de vous retourner un temps. Cet article n'est pas spécifique à une certaine API donc je vais prendre GetTime() comme nom générique pour une fonction qui retourne le temps en secondes. Par exemple, sous GLUT vous pouvez utiliser glutGet( GLUT_ELAPSED_TIME ), sous SDL, SDL_GetTicks(), ou bien encore timeGetTime() sous Windows. Attention, ces fonctions retournent un temps en millisecondes !

Si votre fonction retourne le temps en milisecondes, pensez à diviser par 1000.

2. Première méthode

Cette première méthode consiste à calculer le temps écoulé entre deux cycles dans votre boucle de rendu puis avec la formule précédente, de calculer le rapport avec pour nombre d'images n = 1 :

 
Sélectionnez
void GameCycle( void )
{
    static double current_time = 0;
    static double last_time = 0;
 
    last_time = current_time;
    current_time = GetTime();
 
    double fps = 1.0 / (current_time - last_time);
 
    // ...
}

Tout d'abord, on déclare deux variables pour le temps actuel du programme et le temps du précédent cycle. Les variables sont déclarées en mode statique pour qu'elles ne soient pas détruites puis reconstruites à chaque cycle. On les initialise à 0 lors du premier appel de GameCycle().

Ensuite ces deux variables sont mises à jour. Ainsi, last_time contiendra le temps courant au moment du précédent cycle, donc le temps du précédent cycle, et current_time récupère le temps actuel.

Enfin, on applique la formule : le temps écoulé entre les deux frames est égal à la différence du temps actuel t(1) par le temps précédent t(0).

L'avantage de cette méthode est que l'on obtient le nombre de FPS en temps réel. En revanche, ce nombre peut osciller entre deux valeurs très proches comme 84.9 et 85.0 et dans ce cas un affichage de ce nombre à chaque rendu peut être un peu difficile à lire (effet de clignotement).

3. Seconde méthode

La seconde méthode consiste à incrémenter le nombre n d'images à chaque cycle et de le réinitialiser à zéro toutes les secondes :

 
Sélectionnez
void GameCycle( void )
{
    static double current_time = 0;
    static double last_time = 0;
    static int n = 0;
    static int fps = n;
 
    n++;
    current_time = GetTime();
 
    if( (current_time - last_time) >= 1.0 )
    {
        // nombre de frames par seconde
        fps = n;
        n = 0;
        last_time = current_time;
    }
 
    // ...
}

Ici le nombre de FPS est moins précis que dans la première méthode car il y a peu de chance que vous arriviez à le calculer le nombre d'images en exactement une seconde, vous aurez certainement 1.03 secondes par exemple (c'est pour cela qu'on fait une comparaison avec >=, pour les « débordements »).

À chaque cycle on incrémente un compteur (n), la variable fps se verra attribuer la valeur de n toutes les secondes.

Toutes les secondes, last_time obtient la valeur de current_time et n est remis à zéro pour recommencer un compte de frames sur une seconde...

Vous pouvez obtenir une plus grande précision en remplaçant fps = n; par fps = n / (current_time - last_time); (et en changeant cette variable en double).

Avec cette méthode, le nombre de FPS est mis à jour toutes les secondes (à quelques millisecondes près).

4. Images par seconde et cycles par seconde

Ce que vous obtenez avec les deux méthodes exposées précédemment est le nombre moyen de fois que GameCycle() a été appelé en une seconde. Ceci ne signifie pas que votre démo ou votre jeu affiche ce nombre d'images à chaque seconde. En effet, par défaut sous OpenGL, le cycle de rendu est réglé pour au maximum atteindre la vitesse de rafraîchissement de votre écran. Dans ce cas, vous obtenez réellement le nombre d'images par seconde, cependant si vous avez une machine très puissante, vous plafonnerez toujours au maximum et vous aurez du mal à évaluer les instructions qui demandent plus de travail.

Pour avoir un nombre de cycles indépendant de votre rafraîchissement vidéo, vous devez désactiver la synchronisation verticale (vsync) par le biais d'un programme comme NVMax ou dans vos propriétés d'affichage si le driver de votre carte graphique le permet. Là, vous aurez par exemple 325 FPS, ce qui n'est certainement pas le nombre d'images sorties à l'écran.

Version PDF : télécharger (16.2 Ko)