Le brouillard sous OpenGL sous Windows
Ca y est, vous y êtes dans le brouillard !
Après tout ce que vous venez de voir, voici quelque chose de beaucoup plus simple !
A première vue !!!
Principe
Il s'agit d'un brouillard, donc tous les objets qui s'éloignent de vous vont disparaître pour se fondre dans le brouillard.
Il sera possible de régler la densité du brouillard ainsi que sa couleur.
A savoir, le brouillard va s'épaissir uniquement suivant l'axe des z.
Création d'un brouillard
Il suffira d'activer le brouillard via la fonction glEnable en passant GL_FOG. Pour désactiver le brouillard, vous utiliserez glDisable () !
Ensuite, la fonction glFog qui se dérive ainsi:
void glFogf( GLenum pname, GLfloat param )
void glFogi( GLenum pname, GLint param )
void glFogfv( GLenum pname, const GLfloat *params )
void glFogiv( GLenum pname, const GLint *params )
Avec pname pouvant prendre les valeurs suivantes GL_FOG_MODE, GL_FOG_DENSITY, GL_FOG_START, GL_FOG_END, ou GL_FOG_COLOR (voir explications qui suivent)
Pour définir la couleur du brouillard:
glFogfv(GL_FOG_COLOR, fogcolor) ;
avec fogcolor contenant les composantes de la couleur
Avec par exemple GLfloat fogcolor[4] = {0.5, 0.5, 0.5, 1} ;
Pensez à
mettre la couleur de fond de l'écran à la couleur du brouillard
pour faire un effet plus impressionnant !
Voir la fonction GlearColor ();
Pour définir la densité du brouillard:
glFogf(GL_FOG_DENSITY, densite) ;
Avec par exemple GLfloat densite = 0.35) ;
Profondeur de champ:
Il s'agit là de définir le point de départ où le brouillard commence à faire effet sur l'objet et le point final au-delà duquel vous ne pourrez absolument plus voir l'objet dans le brouillard.
Exemple :
glFogf(GL_FOG_START, 0.5) ;
glFogf(GL_FOG_END, 5.0) ;
Formules de calcul utilisées pour générer le brouillard:
Il y a le plus rapide, mais le moins beau, et évidemment le plus lent mais bien plus beau...
· GL_LINEAR : f = (end – z) / (end – start)
· GL_EXP : f = e-density * z
· GL_EXP2 : f = e-(density * z)²
Le plus rapide étant GL_LINEAR, la différence entre GL_EXP et GL_EXP2 n'étant pas forcement flagrante.
glFogi (GL_FOG_MODE, fogmode) ;
où fogmode est de type GLint et prendra les valeurs GL_LINEAR, GL_EXP ou GL_EXP2. Bien entendu vous pourrez passer la valeur directement dans la fonction, mais il peut-être intéressant de la passer dans une variable afin de régler le brouillard suivant la puissance de la machine.
Exemple
Un programme qui affiche une série de cubes:
Le résultat n'est pas mal...
Problème
Et bien oui, c'était trop simple jusque là !
Faisons tourner nos cubes maintenant autour du premier cube (Le centre de rotation de nos cubes est donc le premier cube):
et
Là, on voit un problème sur l'image de droite: Bien que les cubes
soient plus proche de nous, ils semblent être dans le brouillard.
En fait, le brouillard est dessiné par rapport au repère d'origine de la matrice de modèle initialisée à la matrice identité. Hors, nous avons dessiné notre premier cube à l'origine de ce repère. Plus nous nous éloignons de l'origine, plus les pièces sont dans le brouillard. Il est donc normal que les cubes qui semblent proche de nous soient dans le brouillard car ils sont en fait loin de l'origine.
Pour éviter ce problème, une solution consistera à modifier l'origine du repère de notre matrice afin de faire en sorte que les objets les plus éloignés arrive lors de la rotation de nos cubes sur le repère d'origine de notre matrice de modèle qui était initialisée à la matrice identité.
Pour cela, rien de plus simple, il suffit de faire une translation de la longueur de nos objets sur l'axe z, puis de dessiner en effectuant la rotation sur nos cubes.
On pourra ensuite déplacer la caméra pour se rapprocher de nos objets.
D'où le correctif:
On notera en passant que contrairement aux objets, le brouillard ne subit pas les transformations du repère sur la matrice de modèle.
D'ailleurs dans l'exemple qui suit, je vais initialiser la matrice, puis faire une translation. Ensuite, j'active le brouillard. Le brouillard se dessine quand même par rapport aux origines initiales de la matrice.
Porté du brouillard
Les objets affectés
par le brouillard sont les objets dessinés suite à une commande
glEnable(GL_FOG). Les objets dessinés avant cette commande ne seront
absolument pas impactés !
De même, les objets dessinés après un glDisable(GL_FOG) seront les seuls à ne pas être impactés par le brouillard.
Il sera donc possible de faire apparaître dans le brouillard certains objets et de faire apparaître d'autres objets sans qu'ils soient impactés par ce même brouillard !
Qualité du brouillard
Il est possible d'améliorer la qualité du brouillard, mais ceci est expliqué dans ce chapitre...
Voilà pour le brouillard...
Annexes
OpenGL pour Linux, Windows, Android...