Effet de transparence

            Plusieurs fois déjà des couleurs ont été présentée sous forme RGBA : rouge, vert, bleu et alpha. Si les trois premières coordonnées sont évidentes, la quatrième, quant à elle, sert à indiquer la « transparence ».

1.    Activation

            Si pour l’instant rien n’a été dit sur les valeurs de l’alpha, c’est simplement parce que par défaut OpenGL s’en fiche. Pour activer le canal alpha, il faut appeler comme d’habitude glEnable :

glEnable(GL_BLEND) ;
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;   
        // expliqué après

            Ensuite il suffit de changer la valeur de A suivant la transparence.

2.    Exemple

Il s'agit, toujours du même cube, mais dont les côtés sont maintenant transparents.

void CALLBACK Main_part(void)
{
            glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
            drawFloor();
            glPushMatrix();
                                    //initialisation de la transparence
                        glEnable(GL_BLEND);
                                    //la couleur de l'objet va être (1-alpha_de_l_objet) * couleur du fond et (le_reste * couleur originale)
                        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                        glTranslatef(0.0f, -2.0f, 5.0f);
                        glRotatef((80.0f), -0.5f, 0.3f, -0.8f);
                        glRotatef((10.0f), 0.5f, -0.3f, 0.8f);
                        glCallList(cube);
                        //on désactive la transparence
                        glDisable(GL_BLEND);
            glPopMatrix();
            auxSwapBuffers();
}

void init()
{
                        //C'est la partie la plus importante
                        //Les couleurs sont définies avec un alpha de 0.25
                        //qui va servir dans le calcul de la transparence
                        //Rappel : 0 = transparent, 1 = opaque
            GLfloat Rouge[] = {0.8f, 0.0f, 0.0f, 0.25f};
            GLfloat Vert[] = {0.0f, 0.8f, 0.0f, 0.25f};
            GLfloat Bleu[] = {0.0f, 0.0f, 0.8f, 0.25f};
            GLfloat Jaune[] = {0.8f, 0.8f, 0.0f, 0.25f};
            GLfloat Rose[] = {0.8f, 0.0f, 0.8f, 0.25f};
            GLfloat Cyan[] = {0.0f, 0.8f, 0.8f, 0.25f};

                        //on se contente de dessiner le cube,
                        //en utilisant cependant la fonction
                        //glColor4f() au lieu de glColor3f()
                        //car la composante alpha compte cette fois_ci
            cube = glGenLists(1);
            glNewList(cube, GL_COMPILE);
                        glBegin(GL_QUADS);
                                    glColor4fv(Jaune);
                                    glNormal3d(-1.0,0.0,0.0);
                                    glVertex3d( -1, 1, 1);
                                    glVertex3d( -1, 1, -1);
                                    glVertex3d( -1, -1, -1);
                                    glVertex3d( -1, -1, 1);
                                    glColor4fv(Rose);
                                    glNormal3d(0.0,1.0,0.0);
                                    glVertex3d( -1, 1, 1);
                                    glVertex3d( 1, 1, 1);
                                    glVertex3d( 1, 1, -1);
                                    glVertex3d( -1, 1, -1);
                                    glColor4fv(Bleu);
                                    glNormal3d(0.0,-1.0,0.0);
                                    glVertex3d( -1, -1, 1);
                                    glVertex3d( -1, -1, -1);
                                    glVertex3d( 1, -1, -1);
                                    glVertex3d( 1, -1, 1);
                                    glColor4fv(Cyan);
                                    glNormal3d(0.0,0.0,-1.0);
                                    glVertex3d( 1, 1, -1);
                                    glVertex3d( 1, -1, -1);
                                    glVertex3d( -1, -1, -1);
                                    glVertex3d( -1, 1, -1);
                                    glColor4fv(Vert);
                                    glNormal3d(1.0,0.0,0.0);
                                    glVertex3d( 1, 1, 1);
                                    glVertex3d( 1, -1, 1);
                                    glVertex3d( 1, -1, -1);
                                    glVertex3d( 1, 1, -1);
                                    glColor4fv(Rouge);
                                    glNormal3d(0.0,0.0,1.0);
                                    glVertex3d(-1, 1, 1);
                                    glVertex3d(-1, -1, 1);
                                    glVertex3d( 1, -1, 1);
                                    glVertex3d( 1, 1, 1);
                        glEnd();
            glEndList();
}

Sources et éxécutables

3.      Paramètres

            La paramétrage principal est effectué par la fonction :

void glBlendFunc( GLenum sfactor, GLenum dfactor )

            Si la fonction s’appelle « blend » (« mélanger » en anglais, ici en parlant des couleurs) et pas « transparency », c’est que la transparence n’est qu’une application de l’alpha-blending. C’est de loin la principale. Néanmoins, ce que fait réellement l’alpha-blending, c’est mélanger la couleur déjà affichée avec une nouvelle.

            Le mélange est précisé par un appel à glBlendFunc, avec le premier paramètre indiquant par quelle valeur multiplier (canal par canal) la nouvelle couleur, le second la couleur déjà affichée. La nouvelle couleur affichée est la somme de ces deux multiplications. L’indice « s » indique que la nouvelle couleur est concernée, « d » qu’il s’agit de la couleur déjà affichée. La couleur affichée est : C = CsS + CdD. S et D étant paramétrés respectivement par sfactor et dfactor.

            Principales valeurs de S en fonction de sfactor :

Valeur de sfactor

Valeur de S

ZERO

(0,0,0,0)

ONE

(1,1,1,1)

DST_COLOR

(Rd,Gd,Bd,Ad)

ONE_MINUS_DST_COLOR

(1,1,1,1) - (Rd,Gd,Bd,Ad)

SRC_ALPHA

(As, As, As, As)

ONE_MINUS_SRC_ALPHA

(1,1,1,1) - (As,As,As,As)

DST_ALPHA

(Ad,Ad,Ad,Ad)

ONE_MINUS_DST_ALPHA

(1,1,1,1) - (Ad,Ad,Ad,Ad)

SRC_ALPHA_SATURATE

(f,f,f,1) avec f = min (As, 1 - Ad)


            Principales valeurs de D en fonction de dfactor :

Valeur de sfactor

Valeur de D

ZERO

(0,0,0,0)

ONE

(1,1,1,1)

SRC_COLOR

(Rs,Gs,Bs,As)

ONE_MINUS_SRC_COLOR

(1,1,1,1) - (Rs,Gs,Bs,As)

SRC_ALPHA

(As, As, As, As)

ONE_MINUS_SRC_ALPHA

(1,1,1,1) - (As,As,As,As)

DST_ALPHA

(Ad, Ad, Ad, Ad)

ONE_MINUS_DST_ALPHA

(1,1,1,1) - (Ad,Ad,Ad,Ad)

SRC_ALPHA_SATURATE

(f,f,f,1) avec f = min (As, 1 - Ad)


            Les paramètres les plus courants sont (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).
            Cela représente bien la transparence codée dans le canal Alpha : la couleur affichée est multipliée par la valeur de transparence (si 0, complètement transparent, si 1 opaque), et la couleur en dessous est multipliée par le complément.

4.    Ordre des primitives

Le problème avec cette manière de rendre les objets transparents, c’est qu’il faut dessiner les surfaces dans l’ordre d’apparition pour avoir un meilleur rendu. en fait, ce qu'il faut faire, c'est dessiner la surface transparente juste après les surfaces que l'on doit voir au travers, et dessiner après les surfaces qui ne doivent pas apparaître. Par exemple, dans le programme final, j'ai placé une fenètre teintée en bleu. Comme je voulais que toute ma scène soit visible au travers, je la dessine presque en dernier (ce qu'il y a après est seulement ce qui n'apparaîtra jamais dedans).

Page précédente    Page suivante