I. Contributions

Nous recherchons toujours des traducteurs pour finir ce projet de traduction des articles de NeHe. Votre aide serait appréciée ! Vous êtes intéressé ? Alors contactez-nous à l'adresse suivante : nehe@redaction-developpez.com .

II. Tutoriel

La plupart des effets spéciaux en OpenGL utilisent une sorte de mélange de couleurs. Ce mélange est effectué en combinant la couleur d'un pixel donné avec ce qui se trouve déjà à l'écran. La façon dont les couleurs sont mélangées se base sur la valeur alpha des deux pixels, et/ou la fonction de mélange utilisée. L'alpha est généralement la quatrième et dernière composante d'une couleur. Dans le passé, vous utilisiez GL_RGB pour spécifier une couleur avec trois composantes. GL_RGBA peut être utilisé pour aussi spécifier le canal alpha. De plus, nous utiliserons glColor4f au lieu de glColor3f.

La plupart des personnes considèrent le canal Alpha comme étant le degré d'opacité d'un matériel. Une valeur de 0.0 veut dire que l'objet est entièrement transparent et 1.0 que l'objet est entièrement opaque.

II-A. Equation de mélange

Si vous êtes inconfortable avec les maths et voulez simplement voir comment utiliser la transparence, passez à la section suivante. Si vous voulez comprendre comment sont gérés les calculs de mélange de couleurs, cette section est pour vous.

Formule pour les couleurs
Sélectionnez
(Rs * Sr + Rd * Dr, Gs * Sg + Gd * Dg, Bs * Sb + Bd * Db, As * Sa + Ad * Da)

OpenGL va calculer le résultat du mélange de deux pixels en se basant sur l'équation précédente. Les variables s et d spécifient les pixels source et destination (donc Rs est la composante rouge du pixel source et Gd est la composante verte du pixel destination...). Les variables S et D représentent les facteurs de mélange. Ces valeurs indiquent comment vous voulez mélanger les deux pixels. Les valeurs les plus courantes pour S et D sont (As, As, As As) (donc la valeur Alpha du pixel source) pour S et (1 - As, 1 - As, 1 - As, 1 - As) (donc 1 moins la valeur Alpha du pixel source) pour D. Ceci va donner une équation de mélange qui ressemblera à :

Formule pour la transparence
Sélectionnez
(Rs * As + Rd * (1 - As), Gs * As + Gd * (1 - As), Bs * As + Bd * (1 - As), As * As + Ad * (1 - As)) 

Cette équation va permettre d'avoir un effet de transparence.

II-B. Faire des mélanges de couleurs avec OpenGL

On active le mélange comme tout le reste (avec la fonction glEnable). Ensuite, on définit l'équation, on désactive l'écriture dans le tampon de profondeur (puisque nous voulons que les objets qui sont derrière les formes transparentes soient encore dessinés). Ceci n'est pas vraiment la bonne façon de faire des mélanges de couleurs mais dans des projets simples, cela suffit. Rui Martins ajoute : Pour le faire correctement, il faut d'abord dessiner toute la scène et ensuite dessiner tous les polygones transparents (avec le canal alpha < 1.0). L'ordre du rendu doit se faire dans l'ordre inverse de la profondeur (donc le polygone le plus lointain doit être dessiné d'abord). Ceci est dû à la différence de résultats dépendant de l'ordre de rendu de deux polygones transparents (1 et 2). Par exemple, en supposant que 1 est plus proche de la caméra, pour être correct, il faudrait dessiner le polygone 2 et seulement ensuite le polygone 1. Si on regarde le rendu, comme dans la réalité, la lumière venant de derrière ces deux polygones (qui sont transparents) doit passer par 2 avant de passer par 1. Vous devez donc trier les polygones transparents par profondeur et les dessiner après tout le reste de la scène avec le test de profondeur mis en place. C'est une technique plus lourde, mais la meilleure si vous souhaitez un résultat correct.

On utilise le code du dernier tutoriel. Nous allons commencer par ajouter deux nouvelles variables au début de ce code. Je vais remettre toute cette partie du code pour être plus clair.

Inclusion, variables globales et déclaration de prototype
Sélectionnez
#include <windows.h>                 // Fichier d'en-tete pour Windows
#include <stdio.h>                   // Fichier d'en-tete pour l'entree/sortie standard
#include <gl\gl.h>                   // Fichier d'en-tete pour la bibliotheque OpenGL
#include <gl\glu.h>                  // Fichier d'en-tete pour la bibliotheque GLu
#include <gl\glaux.h>                // Fichier d'en-tete pour la bibliotheque GLaux

HDC       hDC=NULL;                  // Contexte de fenetre 
HGLRC     hRC=NULL;                  // Contexte de rendu permanent
HWND      hWnd=NULL;                 // Contient un identifiant de fenêtre
HINSTANCE hInstance;                 // Contient une instance de l'application

bool    keys[256];                   // Tableau utilisé pour la gestion du clavier
bool    active=TRUE;                 // Window Active Flag Set To TRUE By Default
bool    fullscreen=TRUE;             // Variable pour le plein écran mis a TRUE par defaut
bool    light;                       // Lumiere ON/OFF
bool    blend;                       // Melange de couleurs (Nouveau) 
bool    lp;                          // L appuye ?
bool    fp;                          // F appuye ?
bool    bp;                          // B appuye ? (Nouveau)
GLfloat xrot;                        // X Rotation
GLfloat yrot;                        // Y Rotation
GLfloat xspeed;                      // X Rotation Vitesse
GLfloat yspeed;                      // Y Rotation Vitesse
GLfloat z=-5.0f;                     // Profondeur dans l'ecran
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };    // Valeurs de la lumiere ambiente
GLfloat LightDiffuse[]=  { 1.0f, 1.0f, 1.0f, 1.0f };   // Valeurs de la lumiere diffuse
GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };   // Position de la lumiere
GLuint  filter;                      // Utiliser quel filtre ?
GLuint  texture[3];                  // Stockage pour 3 textures
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  // Declaration de WndProc

Allez dans la fonction LoadGLTextures. Trouvez la ligne où se trouve if (TextureImage[0]=LoadBMP("Data/Crate.bmp")). Utilisez la ligne ci-dessous à la place. Nous allons utiliser une texture représentant un vitrail pour ce tutoriel.

Chargement d'une image
Sélectionnez
if (TextureImage[0]=LoadBMP("Data/glass.bmp"))  // Charger la texture ( MODIFIE )

Ajoutez les deux lignes suivantes quelque part dans la fonction InitGL. La première ligne met en place une brillance de l'objet au maximum avec 50% d'alpha (opacité). Ceci veut dire que lorsque le mélange de couleur sera mis en place, l'objet sera à 50% transparent. La deuxième ligne met en place le type de mélange que nous allons utiliser.

Rui Martins ajoute : Une valeur de 0.0 veut dire que le matériel serait entièrement transparent. Une valeur de 1.0 veut dire qu'il serait entièrement opaque.

Mise en place du canal alpha et de la fonction de mélange
Sélectionnez
    // Brillance au maximum, 50% Alpha ( NOUVEAU )
    glColor4f(1.0f,1.0f,1.0f,0.5f);    
    // Fonction de melange pour transparence dependant de la valeur source alpha(Nouveau)
    glBlendFunc(GL_SRC_ALPHA,GL_ONE);   

Si vous regardez le code qui suit, il peut être retrouvé à la fin de la septième leçon.

Gestion de la fléche gauche
Sélectionnez
if (keys[VK_LEFT])   // Est-ce qu'on appuie sur la fleche gauche
 {
  yspeed-=0.01f;     // Si oui, décrémenter la vitesse Y
 }

En dessous de ce code, nous voulons ajouter les lignes suivantes. Les lignes à ajouter regardent si la touche 'B' a été appuyée. Si c'est le cas, le programme vérifie s'il est en train de mélanger les couleurs ou non. Si cette option est active, il la désactive, sinon il l'active.

Gestion de la touche 'B'
Sélectionnez
if (keys['B'] && !bp)     // Est-ce que B est appuyee et bp est a FALSE ?
 {
  bp=TRUE;                // Si oui, bp devient TRUE
  blend = !blend;         // Changer la valeur de blend (entre TRUE et FALSE) 
  if(blend)               // Est-ce qu'on melange les couleurs ?
  {
   glEnable(GL_BLEND);    // Activation du melange des couleurs
   glDisable(GL_DEPTH_TEST); // Desactivation du test de profondeur
  }
  else                    // Sinon
  {
   glDisable(GL_BLEND);   // Desactivation du melange des couleurs
   glEnable(GL_DEPTH_TEST); // Activation du test de profondeur
  }
 }
 if (!keys['B'])          // Est-ce que B a ete appuye ?
 {
  bp=FALSE;               // bp devient faux si c'est le cas
 }

Mais comment spécifier la couleur que nous utilisons avec une texture ? C'est simple, en modulant la texture avec la couleur courante, chaque pixel de la texture sera multiplié par la couleur. Donc, si la couleur à utiliser est (0.5, 0.6, 0.4) nous allons mutliplié la couleur de chaque pixel de la texture par (0.5, 0.6, 0.4) (alpha est supposé à 1.0 si ce n'est pas spécifié).

C'est tout ! Le mélange de couleurs est assez simple à faire en OpenGL.

Remarque (13/11/99) :

J'ai (Nehe) modifié le code du mélange pour que le résultat ressemble plus au résultat attendu. En utilisant des valeurs Alpha pour la source et la destination, cela provoque des effets d'irréalisme. Les faces du cube qui se retrouvent derrière et sur les côtés sont plus sombres que ce qu'ells devraient être. Ce que je fais ici n'est probablement pas la meilleure solution mais elle fonctionne et le résultat semble correct lorsque la lumière est active. Merci à Tom pour le code initial, sa technique pour le mélange était correct mais les gens s'attendaient à quelque chose de plus attractif.

II-C. Canal alpha d'une texture

La valeur alpha utilisée pour la transparence peut être récupérée par un fichier image avec les couleurs. Pour le faire, il suffit de rajouter un canal alpha à l'image que vous voulez utiliser et mettre GL_RGBA pour le format à passer aux appels glTexImage2D.

Tom Stanis

Enfin, voici une petite image de ce que vous devez voir :

Image de l'application
Image de l'application

Jeff Molofee (NeHe)

III. Téléchargements

Compte tenu du nombre de versions de codes sources pour les tutoriels nehe, nous les laissons en anglais. En principe, si vous avez compris le code présenté dans ce tutoriel (et les tutoriels antérieurs), vous n'aurez pas de mal à le comprendre :

IV. Remerciements

Merci à Fiquet et à jc_cornic pour leur relecture.

V. Liens