Limiter nombre fps [opengl & queryperformance & devcpp]

Soyez le premier à donner votre avis sur cette source.

Vue 10 649 fois - Téléchargée 611 fois

Description

Dans la plupart des jeux, il est possible de limiter le nombre d'images par seconde (FPS, frames per second) que peut afficher un jeu.

Il est souvent inutile de gaspiller du temps machine pour afficher jusqu'à 3000 FPS avec des cartes graphiques dernier cri (aaaaaahhh !). L'oeil n'en percoit qu'une centaine au maximum.

Ce programme :
  • calcule le nombre de FPS.
  • limite le nombre de FPS selon votre choix.
  • déplace les objets selon la méthode du TimeStep (déplacement en fonction du temps).
  • toutes les valeurs des variables sont affichées en temps réel (toutes les 1s).


Comment faire ?
  • Le principal soucis pour calculer le nombre d'images par seconde est de réussir à trouver des fonctions de timing très précises. Les fonctions classiques sont trop imprécises (de l'ordre de 1 à 10 ms). C'est une précision insuffisante lorsqu'on désire afficher plus de 100 FPS (ca nous fait une image toutes les 10ms ou moins). Les seules fonctions intéressantes sont QueryPerformanceFrequency et QueryPerformanceCounter (qui existent bien sur tous les processeurs, quoi qu'en dise la MSDN, qui doit dater un peu). Leur seul inconvénient est de ne pas donner directement le temps, il faut au préalable diviser le nombre de cycle par la fréquence du nombre de cycles par seconde. Il y a donc un coût en temps supplémentaire pour les divisions et également un coût en mémoire pour stocker les résultats en seconde dans des variables de type double.
  • Le nombre de cycles est un résultat beaucoup plus précis que le millième de seconde. Un cycle correspond environ (sur mon PC, Barton 3200+) à 270 nano secondes.
  • Pour calculer le nombre de frames par seconde (FPS), nous allons comptabiliser toutes les frames affichées (temps.nbFrames). Ensuite, toutes les secondes, on affiche le résultat et on remet le compteur à 0. Le résultat est assez précis.
  • Pour limiter le nombre de FPS, il faut 2 variables. Il faut comptabiliser le nombre de cycles maintenant (temps.cSuiv) et le nombre de cycles pour la prochaine frame (temps.cSuiv). Dès que temps.cNow > temps.cSuiv, on dessine une nouvelle image et on augmente temps.cSuiv. Si on veut beaucoup de FPS, on ajoutera un peu de cycles à temps.cSuiv, ou inversement.
  • Pour animer un objet, on n'incrémentera pas son déplacement de manière statique à chaque image (pos++). On utilisera le temps qu'il s'est écoulé entre deux frames (pos += temps.cSuiv - temps.cPrec) pour savoir où l'objet sera placé.
  • Concernant l'affichage OpenGL, la fonction glutSwapBuffers() permet un affichage en double buffering. Il faut uniquement l'utiliser lorsqu'on est sur le point d'afficher une nouvelle image (temps.cNow > temps.cSuiv). La fonction glutPostRedisplay() permet de redemander l'affichage d'une nouvelle image, il faut toujours utiliser cette fonction à la fin de l'affichage, que la frame précédente soit affichée ou non.

Source / Exemple :


[code]
//------------------------------------------------------------------------------
// Structures
//------------------------------------------------------------------------------

    // Gestion du temps : toutes les variables ne sont pas indispensables
    struct TEMPS
    {
        // Par rapport au démarrage de Windows
        LONGLONG cBase;             // Nombre de cycles depuis le démarrage de Windows, trouvé au démarrage de l'application
        LONGLONG cPrec;             // Nombre de cycles depuis le démarrage de Windows, trouvé lors du dernier rendu
        LONGLONG cNow;              // Nombre de cycles depuis le démarrage de Windows, trouvé actuellement
        LONGLONG cSuiv;             // Nombre de cycles depuis le démarrage de Windows, qu'on doit atteindre pour le prochain rendu
        
        // Par rapport au démarrage de l'application
        LONGLONG cBegin;            // Nombre de cycles écoulés uniquement depuis le démarrage de l'application
        LONGLONG allFrames;         // Nombre de frames depuis le démarrage de l'application
        LONGLONG allFramesPrec;     // Nombre de frames depuis le démarrage de l'application
        LONGLONG cUneSeconde;       // On attend une seconde pour comptabiliser le nombre de frames
        long int ns;                // Nombre de nano secondes depuis le démarrage de l'application

        // Par rapport aux conversions temps <=> cycle
        LONGLONG frequence;         // Nombre de cycles par seconde (de l'ordre de 3 millions avec un Barton 3200+)
        double   tpsPerC;           // Temps en seconde entre deux cycles
        
        // Par rapport aux frames
        LONGLONG cPerFrame;         // Nombre de cycles qui doivent s'écouler entre deux frames (pour la limitation)
        LONGLONG cEcoule;           // Nombre de cycles écoulés entre deux frames (pour le TimeStep)
        double   ecoule;            // Temps en secondes entre deux frames (pour le TimeStep)
        LONGLONG nbFrames;          // Nombre de frames affichées (remis à 0 toutes les secondes)
        double   fps;               // Nombre de frames par seconde (mis à jour toutes les secondes via nbFrames)
    };
    struct TEMPS temps;
/code

Conclusion :


Utiliser les touches '-' et '+' pour changer le framerate.
Si vous avez une autre méthode : laissez moi un message.

Vous pouvez comparer les résultats inscrits dans la barre du titre de la fenêtre OpenGL avec des programmes tels que FRAPS (qui affichent le nombre de FPS). Ils sont identiques normalement.

Enjoy,
BeLZeL

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

Tiens donc, celui qui nous a tous convertis à GLFW est encore vivant :)
Messages postés
1267
Date d'inscription
mercredi 1 janvier 2003
Statut
Membre
Dernière intervention
28 février 2007
3
Juste un bémol, chez moi en tous cas, GLFW n'a pas voulu reconnaître mon joystick, alors que SDL si...(NB : je parle sous Linux, la version Win32 fonctionnait).

Mais sinon c'est mon framework préféré :)
Messages postés
3006
Date d'inscription
dimanche 14 avril 2002
Statut
Membre
Dernière intervention
31 décembre 2008

Je confirme, GLFW a été la réponse à la majorité de mes soucis en matière de fenêtre OpenGL. Elle est même équipée d'un support de thread portables, d'un loader de TGA et de toute la gestion clavier / souris / joystick. A découvrir absolument ;)
Messages postés
67
Date d'inscription
vendredi 28 décembre 2001
Statut
Membre
Dernière intervention
23 juin 2015

De rien ^^

Le seul défaut de cette librairie c'est de ne pas être très connue, mais elle le mériterait...
Messages postés
110
Date d'inscription
mardi 10 octobre 2000
Statut
Membre
Dernière intervention
20 décembre 2005

J'achète ;)

Comme quoi, on en apprend tous les jours.
Je ne connaissais pas, merci :)
J'espère que j'arriverai à faire marcher la souris sous Linux avec ce framework ...
Afficher les 31 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.