OpenGL avec Delphi


précédentsommairesuivant

V. Lumière en mouvement

V-A. Spécification de réflectivité de matière (petit truc)

Vous vous rappelez que dans le quatrième tutoriel nous avons abordé la manière de procéder pour spécifier les propriétés réflectives de la matière d'un objet ? Si vous vous en souvenez alors je suis sûr que vous avez remarqué qu'il est long et gourmand en mémoire de déclarer trois variables distinctes pour chaque matière située dans une scène. Ce que je vous propose c'est de spécifier la réflectivité de votre matière non pas en raccourcissant votre code de programmation, mais en réduisant les variables utilisées pour le faire. Par contre cette commande ne s'avèrera intéressante (optimisation) que si vous ne devez spécifier qu'un seul paramètre de matière pour la majorité des sommets de la scène. Dans mon exemple, à télécharger en bas, vous constaterez que j'ai utilisé cette commande pour tous les paramètres, mais ici ce n'est pas important, car ce n'est que pour comprendre le principe. Une fois que vous avez terminé l'utilisation de cette commande, il est conseillé de la désactiver pour augmenter les performances de votre application.

Activation et désactivation de la commande en question :

 
Sélectionnez
glEnable( GL_COLOR_MATERIAL );
   ... 
     Spécification des paramètres de réflectivité des ou de la matière     
   ...
glDisable( GL_COLOR_MATERIAL );

V-B. Créer une lumière éclairant un objet en mouvement

Comme la lumière doit suivre l'objet en question alors la position de celle-ci doit toujours être invoquée juste après la transformation de l'objet à suivre. N'oubliez pas que si vous dessinez d'autres primitives après avoir invoqué la position de la lumière alors la lumière affectera aussi ces primitives. Si vous désirez dessiner plusieurs primitives dans votre scène alors, n'oubliez pas de vous servir gracieusement des deux commandes magiques : glPushMatrix et glPopMatrix. Je parle encore des deux commandes magiques, car il ne faut pas oublier que la lumière affecte autant la matrice de modélisation que la lumière peut affecter la couleur des primitives dans la scène.

Si vous désirez afficher une primitive représentant la lumière elle-même alors elle ne devrait pas être affectée par sa propre source de lumière donc il serait mieux d'éteindre la lumière, d'afficher la primitive représentant la lumière et d'ensuite rallumer. Comment procède-t-on ?
glDisable( GL_LIGHTING ) et de la réactiver avec glEnable( GL_LIGHTING ).

Maintenant je vous propose une partie du code représentant deux projecteurs lumineux qui reflètent sur une plateforme :

 
Sélectionnez
     glPushMatrix();
         glTranslated(-4 * Cos(DegreRot1) *-5 * Cos(DegreRot2),
                       5 * Sin(DegreRot1),
                      -6 * Cos(DegreRot1) * 4 * Sin(DegreRot2));

         glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 30 + (10 * Sin(DegreRot2)) );
         glLightfv( GL_LIGHT0, GL_POSITION, @Lumiere0_Position );


         glDisable( GL_LIGHTING );
            glPointSize( 3.0 );
            glColor3f( 1.0, 1.0, 1.0);
            glBegin( GL_POINTS );
               glVertex3d( Lumiere0_Position[0], Lumiere0_Position[1], Lumiere0_Position[2] );
            glEnd();
         glEnable( GL_LIGHTING );

     glPopMatrix();
  • glTranslated… : en premier lieu, une translation est effectuée dans tous les sens pour faire pivoter la première lumière. Le but est seulement d'en faire un projecteur actif alors il n'y a rien de spécial à comprendre ici, à part le fait d'effectuer plein de rotations dans la matrice de modélisation.
  • glLightf( GL_LIGHT0, GL_SPOT_EXPONENT… : « Lumiere0_Position » est une variable tableau de trois valeurs GLfloat qui représentent la position de la lumière. Quand la scène bouge ou plutôt dire quand la matrice de modélisation est affectée par des déplacements quelconques alors la lumière se déplace en fonction du mouvement de la scène. Donc la position de la lumière n'est plus spécifiée par la variable « Lumiere0_Position », mais plutôt récupérée par celle-ci.
  • glPointSize( 3.0 ) : Ah Ha! Nouvelle commande inédite… Elle n'a vraiment rien de spécial à part de spécifier la grosseur des pixels dessinés sur la scène. Cette commande est surtout utilisée dans le procédé d'Antialiasing, expliqué dans un prochain tutoriel.
  • glVertex3d( Lumiere0_Position[0]… ); : vous connaissez déjà cette commande j'espère Image non disponible. Comme la variable « Lumiere0_Position » a récupéré la nouvelle position de la lumière dans la scène alors nous nous en servons pour placer un gros pixel qui représente le projecteur lui-même.

V-C. Éclairage se déplaçant avec le point de vue

Si l'on veut déplacer la lumière avec le point de vue ou plutôt, déplacer le point de vue et que la lumière suive, il faut lui donner sa position dans la procédure Redimension(), juste avant la transformation de visualisation (PROJECTION), ou si vous aimez mieux juste avant que la matrice de projection soit activée.
Comme ceci :

 
Sélectionnez
     glLightfv( GL_LIGHT0, GL_POSITION, @LumiereX_Position );

     glViewport( 0, 0, ClientWidth, ClientHeight );
     glMatrixMode( GL_PROJECTION );
     glLoadIdentity();

     gluPerspective( 45, Width / Height, 0.1, 200.0 );

     glMatrixMode( GL_MODELVIEW );

Capture d'écran :

Image non disponible

Hum!!! Ma vielle Voodoo Banshee…
Excusez-moi les captures laissent souvent à désirer.
Une chance je suis à quelques jours de changer de système Image non disponible.

V-D. Programme relié

Cet exemple n'est pas des plus originaux, mais il représente des projecteurs situés en haut d'une plateforme qui reflète la lumière de ceux-ci. Ce qui est à surveiller, c'est l'optimisation possible que l'on peut apporter à cette petite application, par exemple les fonctions Cos et Sin qui sont extrêmement utilisées. Pour remédier à ce problème, il faudrait créer deux tableaux précalculés de ces valeurs… De plus, quelques commandes OpenGL sont répétées en double à maintes reprises et cela n'est fait que dans un but pédagogique, donc ils ne servent à rien.

En pratique, vous pourriez :

  • optimiser le programme (si vous comprenez bien le fonctionnement) ;
  • créer des murs à la plateforme et s'organiser pour que les lumières reflètent sur le mur (servez-vous de la direction de la lumière).
  • Amusez-vous…

Source

Pour ceux que cela intéresse, voici l'autre manière. Source (à la C++).


précédentsommairesuivant

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Copyright © 2002 Martin Beaudet. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.