Idle et timer
Idle
Vous savez maintenant que glutMainLoop va lire les messages concernant les fenêtres GLUT. Lorsqu'un évènement arrive dans cette liste de message, soit
- Cette fonction prend en charge automatiquement ce message/évènement.
- Soit vous avez demandé à en être informé. Dans ce cas (en tout cas pour certains messages), une fonction que vous aurez codifié sera lancée. A vous donc de prendre en charge l'évènement.
Mais parfois, il n'y a rien dans la liste de message. Dans ce cas, pourquoi ne pas en profiter pour faire autre chose ???
C'est le rôle de la fonction idle. Lorsque glutMainLoop n'a plus rien à faire, elle va lancer votre fonction "idle" pour effectuer des tâches comme par exemple calculer votre prochaine animation.
La fonction permettant d'indiquer votre fonction idle est:glutIdleFunc()
void glutIdleFunc ( void (*func) ( void ));
Comme vous pouvez le voir, votre fonction idle ne recevra aucun paramètre et n'en transmettra aucun en retour.
Bon, vous aurez compris
que les traitements a ce niveau ne doivent pas prendre trop de temps, car les
messages arrivant pour la gestion de ou des fenêtres ne sont plus lus
durant ce temps. Et dans ce cas, cela peut provoquer des temps de réponses/réactions
de votre fenêtre qui peuvent être assez désagréable
à l'utilisateur.
De plus, les appels dans le temps seront irréguliers, pour une animation, cela peut être génant...
Voir à utiliser
glutVisibilityFunc(), fonction qui pourra indiquer
pour votre fonction idle s'il y a lieu ou non d'effectuer un traitement dans
votre fonction idle alors que la fenêtre n'est pas visible...
Cette fonction utilisera
(peut-être) la fonction glutPostRedisplay() qui indique à GLUT
que la fenêtre courante doit être rafraîchie. Ce qui lancera
votre fonction de rendu/affichage
Si vous utilisez
plusieurs fenêtres ou menus, il vous faudra bien penser à définir
la fenêtre courante via glutSetWindow() ou le menu via glutSetMenu() dès
le début de l'appel à votre fonction idle...
Avant de détruire
votre fenêtre, il peut être nécessaire de terminer la fonction
idle, sinon elle risque d'être de nouveau relancée alors que la
fenêtre n'existe plus. Pour arrêter l'appel à votre fonction
idle, il suffira de taper glutIdleFunc(NULL);
Timer
Mais vous pouvez aussi lancer des traitements par interval de temps régulier. Il suffit de programmer un timer pour cela.
glutTimerFunc
void glutTimerFunc ( unsigned int msecs, void (*func) ( int value), value);
En entrée:
msecs Le nombre de millisecondes avant de faire appel à votre fonction.
func Votre fonction.
value Une valeur pour indiquer le timer qui a lancé la fonction. Il est
en effet possible de lancer plusieurs timer sur la même fonction. Vous
pouvez passer n'importe quelle valeur, c'est à vous de la gérer.
En sortie:
Rien !
La fonction déclenchée par le timer recevra la valeur value du timer. Vous pourrez donc identifer le timer qui a déclenché votre fonction.
Le timer ne marche
qu'une fois, il vous faudra donc le réamorcer dans votre fonction timer
pour le redéclencher à interval régulier.
Si un timer est
déclenché, vous ne pourrez plus l'arrêter ! Donc à
vous de faire en sorte que cette fonction ne se plante pas parceque la fenêtre
traitée n'existe plus (voir glutDrestroyWindow).
Voir à utiliser
glutVisibilityFunc(), fonction qui pourra indiquer
pour votre fonction idle s'il y a lieu ou non d'effectuer un traitement dans
votre fonction idle alors que la fenêtre n'est pas visible...
Cette fonction utilisera
(peut-être) la fonction glutPostRedisplay() qui indique à GLUT
que la fenêtre courante doit être rafraîchie. Ce qui lancera
votre fonction de rendu/affichage
Si vous utilisez
plusieurs fenêtres ou menus, il vous faudra bien penser à définir
la fenêtre courante via glutSetWindow() ou le menu via glutSetMenu() dès
le début de l'appel à votre fonction idle...
Exemple
Une fonction idle qui va déclencher un réaffichage du fond de l'écran (utilisation d'un tampon logique/physique dans la fonction d'affichage pour éviter le clignotement)
Une fonction timer qui affiche le n° du timer qui la déclenchée. Cette fonction étant déclenchée par deux timers:
Timer1 au bout de 500 ms
Timer2 au bout de 200 ms
Qui sera déclenché en premier ???