OpenGL avec Delphi


précédentsommairesuivant

VI. Transparence

VI-A. Survol du tutoriel

Le « Blending » est en quelque sorte des mélanges de couleurs qui mènent à des effets de transparence sur des primitives. Quand nous dessinons une scène, vous vous rappelez qu'il faut vider le tampon de valeurs chromatiques de cette manière : glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT);, mais maintenant nous allons voir qu'il est possible de garder ces valeurs et de les mélanger aux nouvelles qui seront dessinées par-dessus. Nous pouvons les mélanger de plusieurs manières dont : ne garder qu'une partie de la couleur résidente, les mélanger également, etc. Bref il existe plusieurs façons de réaliser le Blending…

P.-S. Petit rappel de ce qu'est la zone de valeurs chromatiques : pensez à une grille qui contient plusieurs pixels dont ceux-ci possèdent chacun quatre propriétés, la couleur Rouge, Vert, Bleu et sa valeur ALPHA. La valeur Alpha est introduite dans ce chapitre et vous comprendrez son utilité.

VI-B. Fusionnement des couleurs

Vous vous êtes sûrement demandé à quoi sert le quatrième paramètre de la commande servant à spécifier la couleur d'un objet :

 
Sélectionnez
glColor4f( 1.0, 0.5, 0.5, 1.0 );
glColor4d( 0.5, 0.5, 0.5, 0.5 );
glColor4ub( 128, 0, 255, 90 );
glColor4b( 128, 0, 30, 50 );

Cette valeur nommée « ALPHA » est utilisée entre autres pour spécifier le taux de transparence de l'objet. Prenons par exemple la première donnée 1.0 donnée sous type GLfloat, ici elle spécifie que l'objet est complètement opaque et dans ce cas sa surface ne laisse rien passer. En revanche, la deuxième commande attestera que l'objet sera d'un ton gris, mais laissant passer 50 %, donc « ½ » de transparence.

  • Valeur Alpha élevée : la couleur sera de plus en plus opaque. La valeur 1.0 ne laisse passer aucune transparence.
  • Valeur Alpha basse : la couleur sera de plus en plus transparente. La valeur 0.0 est complètement transparente.

Prenez par exemple un cube ayant la valeur Alpha = 1 et une sphère dessinée juste devant avec une valeur Alpha de 0.15. Le cube quant à lui ne laisse rien passer, mais ce n'est pas grave, car il est situé à l'arrière de la sphère. Mais la sphère laisse passé 15 % de transparence, ce qui donnerait donc la possibilité d'apercevoir le cube à travers elle.

Le principe est simple, si nous ne spécifions pas de fonctions de blending, alors quand nous dessinerons deux objets un par-dessus l'autre, OpenGL les dessinera tous deux comme étant deux objets opaques, car le premier objet est dessiné et quand l'autre vient pour l'être alors OpenGL écrase chaque valeur chromatique du cube pour les remplacer par celles de la Sphere. Par conséquent, si le blending est activé alors il est possible de conserver les valeurs chromatiques du cube et de les accoupler à celles de la sphère. D'où vient le nom Blending (Transparence). Un peu plus bas vous verrez un tableau donnant liberté aux diverses fonctions du blending, ses fonctions agissent toujours sur une Source et une Destination. Voici les rôles de l'exemple que je viens de citer avec cube et la sphère :

  • Sphère : elle joue le rôle de la SOURCE, car ses valeurs chromatiques seront affectées à celles du cube ;
  • Cube : il joue le rôle de la DESTINATION, car il est le résultat de l'accouplement de ses valeurs chromatiques et celles de la sphère.

Maintenant voyons comment activer le Blending sous OpenGL : glEnable( GL_BLENDING ) ou pour désactiver : glEnable( GL_BLENDING ).

Voici les différents types d'accouplements entre la source et la destination en utilisant la commande suivante : glBlendFunc( GLenum sfactor, GLenum dfactor );

Facteur de blenging (Source et Destination )

Constante

Facteur concerné

Facteur de blending calculé

GL_ZERO

Source ou Destination

(0, 0, 0, 0)

GL_ONE

Source ou Destination

(1, 1, 1, 1)

GL_DST_COLOR

Source

(Rd, Gd, Bd, Ad)

GL_SRC_COLOR

Destination

(Rs, Gs, Bs, As)

GL_ONE_MINUS_DST_COLOR

Source

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

GL_ONE_MINUS_SRC_COLOR

Destination

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

GL_SRC_ALPHA

Source ou Destination

(As, As, As, As)

GL_ONE_MINUS_SRC_ALPHA

Source ou Destination

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

GL_DST_ALPHA

Source ou Destination

(Ad, Ad, Ad, Ad)

GL_ONE_MINUS_DST_ALPHA

Source ou Destination

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

GL_SRC_ALPHA_SATURATE

Source

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

GL_CONSTANT_COLOR

Source ou Destination

(Rc, Gc, Bc, Ac)

GL_ONE_MINUS_CONSTANT_COLOR

Source ou Destination

(1, 1, 1, 1) - (Rc, Gc, Bc, Ac)

GL_CONST_ALPHA

Source ou Destination

(Ac, Ac, Ac, Ac)

GL_ONE_MINUS_CONSTANT_ALPHA

Source ou Destination

(1, 1, 1, 1) - (Ac, Ac, Ac, Ac)

Comme dirait HOMER : Maudit Verra ! Oui ça l'air compliqué, mais ne vous en faites pas, ce n'est que du charabia qui en fait se résume à quelques explications simplistes pour comprendre

 
Sélectionnez
glBlendFunc( GL_ONE, GL_ZERO );
glEnable( GL_BLEND );

Si l'on dessine une ou des primitives en utilisant le blending de cette façon, cela n'aura aucun effet de transparence et donc nous aurons les mêmes résultats que si le Blending était désactivé. Pourquoi ? Parce que si l'on se fie au tableau précédent, nous spécifions que les valeurs chromatiques de la source sont multipliées par (1, 1, 1, 1), ce qui ne change absolument rien aux valeurs chromatiques sources. Par contre les valeurs chromatiques de la destination sont écrasées, car elles sont multipliées par (0, 0, 0, 0).

Je vais vous laisser vous amuser avec tous ces facteurs, ils vous offrent beaucoup de possibilités, mais parmi celles-ci, une est souvent utilisée et la voici :

 
Sélectionnez
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_BLEND );

Pour ce qui est d'utiliser le Blending avec des primitives en mouvement, il faut tenir compte que OpenGL calcule toujours la distance entre les yeux de l'utilisateur et la primitive à afficher. Donc, si vous restituez une primitive Opaque devant une primitive Transparente alors OpenGL ne dessinera que la primitive Opaque du fait qu'elle cache la transparente. Mais si la primitive transparente est située devant celle opaque alors il ne faut pas que le tampon de profondeur supprime la primitive opaque, car elle est visible à travers la transparente. Donc il faudra désactiver le tampon de profondeur pendant la restitution de celle-ci. La démarche à suivre est la suivante, commencez à dessiner toutes les surfaces opaques et quand vous serez prêt à dessiner les transparentes, activez le tampon de profondeur en lecture seule. Pour activer le tampon de profondeur en lecture seule, voici la commande :

 
Sélectionnez
glDepthMask( GL_FALSE );  //Tampon en lecture seule
// Primitives transparentes...
glDepthMask( GL_TRUE );   //Retour du tampon en mode lecture / écriture

Dépendamment de votre position par rapport à la primitive, vous pouvez exiger que les surfaces arrière ou avant ne soient pas affichées. Cela peut être pratique pour récupérer du temps machine et surtout éliminer des effets non désirés. N'oubliez pas quand vous créez un polygone de toujours positionner ses sommets de manière à ce qu'ils soient dans le sens contraire des aiguilles d'une montre, cela vous évitera des tonnes de problèmes. Si par contre vous devez les dessiner dans le sens des aiguilles d'une montre alors, utilisez cette commande :

 
Sélectionnez
glFrontFace( GL_CCW );    // Sens contraire des aiguilles d'une montre
glFrontFace( GL_CW );     // Sens des aiguilles d'une montre

Bon et maintenant voici la méthode pour éliminer les surfaces arrière des primitives :

 
Sélectionnez
glCullFace( GL_BACK );
glEnable( GL_CULL_FACE );

//Restitution des primitives...

glDisable( GL_CULL_FACE );

Voici un programme qui vous démontrera les bienfaits du Blending.

Image non disponible

VI-C. Programme relié

Ce petit programme montre un cube en mouvement à l'intérieur d'une pyramide. Chaque face de la pyramide a une valeur de transparence différente.

Je vous laisse vous amuser avec les différentes possibilités de facteurs de blending.

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.