Limitation de la fréquence d'images

9

Le plus grand succès des moteurs de jeu concurrentiel comme id Tech, GoldSrc, Sourceet permettent par exemple des limitations framerate.

Vous pouvez jouer avec 30, avec 60, avec 99, avec 72, avec 68 etc. En bref, vous pouvez le plafonner et contrôler le plafond.

Je me demandais, comment puis-je limiter le framerate?

Pas intéressé par le code, mais la théorie.

joltmode
la source
Par simple curiosité, quel est l'intérêt de cela autre que de libérer des cycles pour d'autres processus?
3Dave
1
@DavidLively, pensez aux ordinateurs portables, ceux qui surchauffent très facilement à une fréquence d'images très élevée, tandis qu'avec un plafond de 60 images par seconde (plus est inutile de toute façon, même 60 est un peu trop, 40 devraient le faire), ils peuvent contrôler la température beaucoup mieux.
Pour les jeux compétitifs, il est préférable d'avoir une fréquence d'images uniforme au lieu de pics entre 60 et 100 images par seconde, car parfois certaines actions dépendent de la fréquence d'images et non du temps, une fréquence d'images égale vous permet d'avoir une idée de ces actions. Notez que si vous activez VSync, votre jeu a toujours un fps max égal à votre taux de rafraîchissement car (le pilote s'en charge).
Roy T.
gafferongames.com/game-physics/fix-your-timestep
contrat du professeur Falken a été

Réponses:

7

La théorie est la suivante: vérifiez la dernière fois que vous avez rendu une image, et s'il n'est pas encore temps de dessiner une autre image, alors ne le faites pas et attendez qu'elle soit.

Kylotan
la source
8

Supposons que vous souhaitiez limiter votre fréquence d'images à 60 images par seconde, cela signifie que chaque image a un temps de rendu de 1 / 60s = 16,67 ms (arrondi)

Pour limiter votre fréquence d'images, il vous suffit de vérifier l'heure au début de votre boucle de jeu, vous pouvez ensuite la comparer avec l'heure à la fin de la boucle de jeu: si la différence est inférieure à 16,67 ms, vous devez caler pendant ce temps.

Pour ce faire, vous pouvez utiliser:

sleep(waittime)

Cependant, puisque sleep(x)donne le fil pour un minimum de xmillisecondes, vous ne savez pas avec certitude si vous reprendrez le contrôle dans le temps.

Une meilleure façon serait d'utiliser:

while(timediff < 16.67ms){ sleep(0); }

Cela renvoie le fil et demande le contrôle dès que possible.

Une autre solution consiste à avoir juste une boucle d'attente occupée, cela vous donne le meilleur contrôle mais utilise le processeur inutilement.

N'oubliez pas que le planificateur du système d'exploitation peut toujours prendre le contrôle de votre thread, alors préparez-vous à certaines fluctuations.

Roy T.
la source
"1 / 60s" pour être clair. :)
Richard Marskell - Drackir
Cette solution est vraiment mauvaise. Si vous avez activé vsync ou que le système d'exploitation décide de faire des choses, votre fréquence d'images fluctuera beaucoup.
Tara
@Dudeson Pourquoi est-ce mauvais? (c'est la technique utilisée dans Quake3 btw). Si votre FPS est inférieur à 60, la boucle est simplement sautée. Ainsi, il maintient votre FPS aussi haut que possible mais jamais au-dessus de 60.
Roy T.
@RoyT. Intéressant ... D'où avez-vous obtenu cette information? Du code source? De plus, je dis que l'attente en boucle est mauvaise parce que c'est exactement comme ça que je l'ai fait dans mon moteur et cela me fait beaucoup de peine. Le problème est que lorsque vous activez vsync (dans le pilote GPU), vous obtenez beaucoup de pertes d'images si vous essayez également de limiter la fréquence d'images dans votre code, car votre timinig ne sera pas parfait à chaque image. Je parle juste des problèmes vsync. Sans vsync, ce n'est pas un problème. Et je ne sais pas si vsync était le même type d'accord dans les 3 jours de Quake qu'aujourd'hui.
Tara
@Dudeson quelqu'un d'autre m'a fait remarquer cela il y a quelque temps parce que je m'inquiétais de l'attente et du sommeil occupés. Je vois maintenant que vous pouvez osciller entre 30fps et 60fps lorsque la v-sync est activée si vous la manquez légèrement. Mais je suppose que cela se produit avec n'importe quelle technique (n'est-ce pas ce que FreeSync essaie d'atténuer). Un framerate limité par code, ou parce que votre ordinateur ne peut pas rendre à 60 images par seconde aura toujours ce problème je pense :)
Roy T.