IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

Limitation des fps


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 12
    Par défaut Limitation des fps
    Bonjour,

    D'ores et déjà, je m'excuse si je ne poste pas au bon endroit, mais je considère que ce problème pas forcément d'attrait direct aux interfaces graphiques !

    Dans le cadre d'un jeu, je souhaiterais fixer une limitation des FPS. En effet, sans limitation, le jeu tourne à environ 1600 fps, et le processeur prend cher :]

    Mon rafraichissement graphique se fait dans un thread séparé, dans une boucle infinie que je temporise.

    Cependant, même si dans ma tête tout marche très bien, mais limitation n'est jamais parfaite.

    Si je demande 50 FPS, j'en obtiens environ 55.
    Si je demande 120 FPS, j'en obtiens environ 130.
    Si je demande 200 FPS, j'en obtiens environ 230.
    Si je demande 500 FPS, j'en obtiens environ 1000.

    Et ainsi de-suite. Les valeurs sont de moins en moins précises.

    Voici le code que j'utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    public void run(){
    	long time;
    	long nanoTime;
    	long retard = 0;
    	/*
    	long fps = 0;
    	long lastFPSTime = 0;
    	*/
    	for (;;) {
    		try {
    			/*
    			 * Un des codes que j'utilise pour calculer les FPS
    			 *
    			if (++fps > 20) {
    				System.out.println((1000 * fps) / (System.currentTimeMillis() - lastFPSTime));
    				lastFPSTime = System.currentTimeMillis();
    				fps = 0;
    			}*/
     
    			nanoTime = System.nanoTime();
     
    			// Fonction d'affichage
    			graphicalRender();
     
    			/*
    			 * J'utilisais ici seulement les millisecondes avant, mais le résultat était identique
    			 * J'ai voulu testé avec les micros, et j'ai laissé comme ça..
    			 *
    			 * FPS est une variable tq : int FPS = 120;
    			 */
    			nanoTime = 1000000000 / FPS - (System.nanoTime() - nanoTime);
    			time = nanoTime / 1000000;
    			nanoTime -= time * 1000000;
     
    			/* Avec ou sans retard, les fps varient toujours autant */
    			time += retard;
    			retard = 0;
     
    			if (time > 0 || time == 0 && nanoTime > 0) {
    				sleep(time, (int) nanoTime);
    			}
    			else {
    				retard = time;
    			}
    		} catch (Exception e) {} 
    	}
    }

    Je n'arrive pas à voir en quoi ma temporisation est imparfaite.
    Si je souhaite <FPS> fps, il faut que j'ai un rafraichissement tous les 1 / <FPS> secondes, donc chaque "boucle" doit prendre 1/<FPS> secondes.

    Si je fais <T> secondes de traitement, je dois attendre 1/<FPS> - <T> secondes avant de recommencer..

    Si vous avez la solution miracle, je suis preneur :]

  2. #2
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Salut,

    Premiere chose, il faut savoir que la fonction Thread.sleep(X) garantit uniquement que le Thread va dormir pendant au moins X ms. Mais cette fonction est connue pour etre plutot imprécise et une erreur de 10% ne semble pas du tout anormale.

    Citation Envoyé par Tiller Voir le message
    Si je demande 50 FPS, j'en obtiens environ 55.
    Si je demande 120 FPS, j'en obtiens environ 130.
    Si je demande 200 FPS, j'en obtiens environ 230.
    Si je demande 500 FPS, j'en obtiens environ 1000.
    Je ne vois pas trop comment tu peux avoir un FPS réel plus élevé que le théorique. J'imagine que tu veux dire le contraire. En particulier pour 500 FPS. Ca fait un temps d'attente de 2 ms. D'apres la précision du sleep, c'est clairement pas envisageable. Pour s'en convaincre, il suffit d'essayer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    long start;
             start = System.currentTimeMillis();
             try
             {
                for (int i = 0; i < 200; i++)
                {
                   Thread.sleep(10);
                }
             }
             catch (Exception ex)
             {
                ex.printStackTrace();
             }
             System.out.println("diff=" + (System.currentTimeMillis() - start));
    Au passage j'ajouterais que contrairement à ce que sa signature peut laisser penser, la fonction void sleep(long millis, int nanos) n'est pas plus précise. Il suffit de regarder le code source pour voir qu'en fait, la valeur en ms est arrondie d'apres le nombre de nanos mais que ca aboutit à un simple appel de Thread.sleep(long millis).

  3. #3
    Membre éprouvé
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2010
    Messages
    119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2010
    Messages : 119
    Par défaut
    J'ajouterai une chose qui ne va pas résoudre ton problème : ta variable "retard" ne sert à rien selon moi. Si t'as été en retard sur un coup parce que le traitement a été trop long, ça ne me semble pas judicieux de lancer la frame suivante plus tôt... ton lag tu l'as eu, c'est trop tard .

    Pour ton problème, je pense aussi que c'est un manque de précision de cette fonction, associé aussi au fait que tu fais quelques calculs (ça mange des nanosec aussi ^^). Mais effectivement ça m'étonne que tu obtiennes un FPS plus élevé que celui souhaité.

  4. #4
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2004
    Messages
    1 184
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 184
    Par défaut
    Pourquoi t'embêter à fixer le nombre de FPS ?
    Si ton jeu est programmé sur la base du temps (dt) qui s'est écoulé entre 2 frames, que ton jeu tourne à 30 ou à 1000 FPS ça ne changera rien.

    Si c'est juste pour baisser la charge du CPU, tu peux mettre une faible pause à chaque frame, mais plus la complexité de ton jeu va augmenter (Notamment pour l'affichage) , moins t'en aura besoin.
    Pas besoin de faire des calculs en plus, ta pause sera prise en compte dans ton dt.

  5. #5
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 12
    Par défaut
    Bonjour,

    Déjà merci pour vos réponses qui sont déjà plus intéressantes que sur d'autres forums.

    @hwoarang: C'est justement ça qui me gène à vrai dire. Je ne me suis pas trompé dans mon énoncé de départ, si je veux limiter à 500 fps, j'obtiens 1000 fps réelle.
    J'étais parti sur le principe aussi que sleep dormait au moins le temps qu'on lui donnait, et donc que j'aurais moins de fps.

    @Mopmop: Effectivement, mais c'était plus du bricolage pour essayer d'améliorer les choses. Mais au final ça ne sert à rien effectivement.

    @Mathieu.J: Quelque soit les FPS mon jeu tourne toujours à la même vitesse, ton en soit, je me moque d'obtenir 130 fps au lieu de 120.

    C'est surtout que je fais ce "jeu" dans un but pédagogique et que par conséquent je "n'aime pas" avoir des problèmes et me dire "C'est pas grave". Je préfère essayer de les comprendre.

    Si jamais vous souhaitez voir par vous même :
    http://stooit.com/pub/Unnamed.jar (le jeu)

    http://stooit.com/pub/unnamed.zip (le zip fait par Eclipse)

  6. #6
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Bah moi, quand je mets 500 dans FPS, j'obtiens ~260 ce qui semble cohérent avec ce que j'ai dit...
    Apres, j'ai pas été fouiller dans le code mais ca semble pas mal...

  7. #7
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 12
    Par défaut
    Après c'est peut-être que ton PC ne te permet que 260 fps en terme de performance.

    Je pense que si tu mets 2000 fps, tu seras toujours à 260.

Discussions similaires

  1. Réponses: 4
    Dernier message: 27/01/2006, 16h38
  2. [MFC] Limitation des CString
    Par Aradesh dans le forum MFC
    Réponses: 2
    Dernier message: 15/04/2005, 10h40
  3. Limite des smtp
    Par silef dans le forum Serveurs (Apache, IIS,...)
    Réponses: 3
    Dernier message: 27/03/2005, 23h49
  4. Réponses: 8
    Dernier message: 17/02/2005, 09h05
  5. Limite des GENERATORS
    Par Débéa dans le forum Débuter
    Réponses: 5
    Dernier message: 24/07/2003, 13h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo