[Total noob]Vitesse d'execution

So far, toute tentative de faire des trucs un poil interactifs se sont revelé foireuses… Bon, je me suis bien amusé avec SDL, j’avais quelque peu contourné le probleme en utilisant la fonction SDL_Wait() avant chaque drawning, mais là maintenant que je fais mumuse avec des moteurs 3D j’aimerais bien faire des trucs un peu plus propre…

Donc voilà, mes applis ont toujours ce même syndrome “jeu PC du début des 80’s”, plus le proc est rapide, plus ça va aller vite (au lieu de se fluidifier), et inversement, si il est trop lent, le jeu n’est pas moins fluide, juste plus lent… C’est un peu con, tous les jeux actuels pourtant ne font incider la vitesse du proc sur la fluidité…

La seule solution que je vois est de faire un timer qui n’autorisera le dessin de la prochaine frame que si un certain temps s’est ecoulé depuis la derniere, seulement si ça reglera le probleme de frames trop rapide, le jeu ralentira quand même si il n’atteind pas le nombre de fps hardcodé…

Donc bref, question super basique que tout l’monde a du se poser un jour : Comment faire garder a cette foutu appli une vitesse stable ?

Réponse courte : tu utilises l’horloge, celle qui a une trotteuse.
 
En gros, tu calcules puis affiches le monde tel qu’il doit être à un instant t (position et direction de la caméra, du monde…). Disons que tu as mis t1 (= 0.02s par exemple) pour le faire sur ton P4 3GHz. Si l’ordi est lent, ça mettra plus de temps pour tout faire : t2>>t1 (= 0.10s par exemple). Ben ensuite, tu calcules puis affiches le monde tel qu’il est censé être à l’instant d’après, i.e t+t1 pour le P4 (ex: la balle a bougé de 10cm), et t+t2 pour le lent (ex: la balle a bougé de 50cm). Deux images successives n’ont donc aucune raison d’être identiques sur 2 PC différents. Dans ce cas, tu vois bien que ton image sera beaucoup plus souvent rafraîchie sur le P4 (50 FPS) que sur le PII (10 FPS).

(Ou alors j’ai pas compris ce que tu demandais)
Ce message a été édité par xentyr le 18/05/2004

Bah oui pareil que le monsieur du dessus: tu dois pas calculer tes frames en fonction d’un indice ‘i’ qui s’incrément à pas fixe mais en fonction du temps !
D’ailleurs merci pour l’astuce Xentyr. Perso j’aurais juste fait ça: calcul d’une position attendue en fonction du temps mais dans ce cas là tu as un lag entre le calculé (basé sur l’instant de début de calcul) et le moment d’affichage (tps début+durée calcul) alors que ta méthode donne l’image qu’il faudrait avoir au moment souhaitée en utilisant un temps estimée pour le qui est le temps du précédent calcul.

Moi je connaissais la technique (sous windows) d’utiliser le GetTicks, qui donne le temps écoulé.

Puis tu lancais une mise à jour de l’affichage tous les n-ticks… Ca simule la vitesse par seconde…

Bon, j’ai essayé mais ça m’a pas l’air tres fiable… j’ai l’impression que ça rame pas mal malgré les 300+ FPS que ça dit afficher…

Vous pouvez jetter un oeil sur ce truc là et me dire si le temps de rotation indiqué est bien egal a 2.29s ? Et comme ça, à l’oeil, vous pensez vraiment qu’un truc aussi saccadé puisse atteindre autant de FPS ?

Mmmmh dans ta fonction idle, si le temps de calcul et d’affichage est trop petit tu peux aussi t’imposer un nombre max de FPS, genre 150. En gros tu ne recalcules pas avant que :
currentTime-t > 1/150.
Sinon, vérifie bien que tu attends que tout soit affiché avant de réafficher par dessus. Et si ça clignote/scintille, double-buffering power.

Je donne ces “tips” en aveugle car je ne peux pas tester sur mon ordi du taf.

Testé chez moi, ça affiche 250 FPS et ça les fait, à l’oeil. Surtout que y’a pas grand chose donc ça me semble cohérent

Si tu as des problèmes de “micro saccades”, ça peut venir de plusieurs raisons :

1/ tu calcules ton delta time (temps séparant une frame de la suivante) en entier, donc problème de précision : par exemple tu affiches “4 ms pour afficher une image” dans la barre de titre, sauf que voila… si ta précision est de 1 ms, alors tu as jusqu’a 25% d’erreur dans un sens comme dans l’autre, ce qui fait 50% d’erreur maxi ce qui est énorme.
2/ tu ne calcules pas ton delta time à chaque image. Si c’est le cas, alors il faut que tu le calcule à chaque image. Pour la simple (et bonne) raison que le temps d’affichage d’une image n’est pas forcément constant en fonction de la vitesse de la machine
3/ tu vas tellement vite que tu atteint la précision de ton timer… a ce moment la il faut adopter un timer plus précis (de type “QueryPerformanceCounter roulaize” sur PC)
4/ tu as des variations de vitesse d’affichage liées à une appli externe chez toi (par exemple un player MP3 avec un module de visualisation qui prends un temps CPU non constant), à ce moment la le mieux que tu puisses faire est de “smoother” ton delta time sur quelques images, ou d’appliquer une autre technique de filtre, afin de réduire l’impact visuel…

Il existe encore pleins d’autres explications possibles en fait. Mais tu devrais déjà regarder de ce coté la.

A cette vitesse là : une autre raison pour laquelle ca peux parraitre saccadé : L’écran suit pas !
Si le double buffer est activé, active aussi la VSync, pasque a ton écran ne peux afficher que 1 frames sur 2.5. Bien sur, ca tombe pas juste, et sans VSync, si mes souvenirs sont bons, les frames changent pendant leur affichage par le RAMDAC. En activant la VSync, Dx verrouille le framerate à la fréquence de rafraischissement de ton écran.

[quote]Bon, j’ai essayé mais ça m’a pas l’air tres fiable… j’ai l’impression que ça rame pas mal malgré les 300+ FPS que ça dit afficher…

Vous pouvez jetter un oeil sur ce truc là et me dire si le temps de rotation indiqué est bien egal a 2.29s ? Et comme ça, à l’oeil, vous pensez vraiment qu’un truc aussi saccadé puisse atteindre autant de FPS ?[/quote]Bon, 195 fps  et 2.291504s.

Est-ce-que tu utilises le Timer de Irrlicht pour déterminer le DetaTime entre chaque frame.

Bon donc grosso modo ce qui ressort des réponses c’est que les saccades disparaitront quand il y aura plus de choses à afficher.

Pour le vsync j’y avais déjà pensé, j’ai tenté via les drivers mais ça semblait toujours aussi hashé.

Et j’utilisais en fait 2 timers, celui d’irrlicht pour l’incrementation de l’angle, et le timer systeme pour le temps effectué par une rotation, je suspectais le timer irrlicht au depart, mais apparament, puisque vous avez tous une vitesse de rotation de 2.29s, le probleme ne vient pas de là.

Enfin bref, à la base c’est surtout l’astuce d’incrementer what’s happen en fonction du temps et pas de la frame qui m’a bien aidé, moi qui était resté sur mon idée de “on incremente par frame mais on limite le nombre de fps”.

'faut bien commencer un jour, et merci les libs de (tres) haut niveau qui permettent de s’y mettre en douceur sans pour autant avoir des perfs à la ramasse, je suis franchement impressioné par les 300 fps de ma merde chez moi malgré 4000 faces reflechissants une source de lumiere mobile…

… truc bizzare quand même, bien que ce soit censé s’incrementer en fonction du temps, si je fais lire un mp3 en fond par audiere, la rotation ne se fait qu’en 2.01s, en comentant toutes les references a la lecture de sons et sans rien changer au reste, ça monte à 2.29…

edit : Oh, et est il normal que malgré mon refresh rate de 85hz, ça affiche toujours 300fps une fois la vsync activée ?

Ce message a été édité par Clad le 21/05/2004

Ah, encore un détail, il faut faire attention à ce que tu time.

par exemple il faut éviter de faire :

DebutBoucleDeRendu:

  TempDebut = GetTemp();

… calcule du truc à afficher …

  TempFin = GetTemp();
  TempAffichage = TempFin - TempDebut;

  BalanceImageToEcran();

FinBoucleDeRendu

Il vaut mieux faire :

TempPrécédent = GetTemp();

DebutBoucleDeRendu:

  TempCourant = GetTemp();
  TempAffichagePrécédent = TempCourant - TempPrécédent;
  TempPrécédent = TempCourant;

  … calcule du truc à afficher …

  BalanceImageToEcran();

FinBoucleDeRendu

Comme ça tu es sûr de bien mesurer le temps pour l’intégralité de l’image précédemment calculée. Ca permet d’éviter d’oublier de mesurer le temps de certaines parties du code

Et donc il n’est pas normal si tu fais bien comme ça que ça t’affiche 300 FPS alors que le rendu est bloqué à 85. Puisque DX par exemple fait le blocage dans “BalanceImageToEcran”.
 
Ce message a été édité par tuo le 21/05/2004

C’est pourtant exactement ce que j’ai fait, voilà mon bout de code texto :

int CurrentTime = AffPrinc->getTimer()->getTime();
int MillisParFrame = CurrentTime - AgesAgo;
AgesAgo = CurrentTime;