{
Haha, ces deux leçons ont été traduites il y a longtemps, mais elles n'ont pas encore été publiées. Tout le monde attend depuis longtemps (est-ce que quelqu'un attend encore ?)
transparence simple
La grande majorité des effets spéciaux dans OpenGL sont liés à un certain type de mélange (de couleurs).
Le mélange de couleurs est défini comme la combinaison de la couleur d'un certain pixel avec la couleur de son pixel correspondant dessiné sur l'écran.
La manière dont les deux couleurs sont combinées dépend des valeurs des composants du canal alpha de la couleur et/ou de la fonction de mélange de couleurs utilisée.
Alpha est généralement le 4ème composant de couleur à la fin de la valeur de couleur.
Dans les leçons précédentes, nous avons utilisé GL_RGB pour spécifier les trois composantes de la couleur.
Le GL_RGBA correspondant peut spécifier la valeur de la composante alpha.
Pour aller plus loin, nous pouvons utiliser glColor4f() au lieu de glColor3f().
La plupart des gens conviennent que le composant Alpha représente la transparence d'un matériau.
Cela signifie qu'une valeur alpha de 0,0 représente un matériau complètement transparent.
Une valeur alpha de 1,0 représente un matériau complètement opaque.
formule de mélange de couleurs
Si les mathématiques ne vous intéressent pas et que vous souhaitez simplement voir comment parvenir à la transparence, ignorez cette section.
Si vous souhaitez mieux comprendre le fonctionnement du mélange (de couleurs), cette section devrait être faite pour vous.
{Ajout de CKER : ce n’est en fait pas difficile ^-^. La formule de l'article original est la suivante, laissons CKER en reparler.
En fait, le principe de base du mixage est de séparer la couleur de chaque pixel et la couleur de fond de l'image à séparer selon les règles RVB.
Selon - Composante de couleur RVB de l'image * valeur alpha + Composante de couleur RVB de l'arrière-plan * (valeur alpha 1)
-Après avoir mixé avec une formule aussi simple, les composants RVB obtenus par mixage sont enfin re-fusionnés. 』
La formule est la suivante :
(Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da)
OpenGL calcule le résultat du mélange des couleurs de ces deux pixels selon la formule ci-dessus.
Les minuscules s et r représentent respectivement les pixels source et les pixels cibles. Les majuscules S et D sont les facteurs de mélange de couleurs correspondants.
Ceux-ci déterminent la manière dont vous mélangez les couleurs de ces pixels.
Dans la plupart des cas, les valeurs de mélange alpha de chaque canal de couleur sont les mêmes.
De cette façon, nous avons (As, As, As, As) pour le pixel source,
Les pixels cibles sont 1, 1, 1, 1) - (As, As, As, As).
La formule ci-dessus devient la suivante :
(Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bs (1 - As), As As + Ad (1 - As))
Cette formule produit un effet transparent/translucide.
Mélange de couleurs dans OpenGL
Les étapes pour implémenter le mélange de couleurs dans OpenGL sont similaires au processus OpenGL que nous avons mentionné précédemment.
Définissez ensuite la formule et désactivez le cache de profondeur d'écriture lors du dessin d'objets transparents.
Parce que nous voulons dessiner l'objet derrière une forme semi-transparente.
Ce n'est pas la bonne façon de mélanger les couleurs, mais la plupart du temps, cela fonctionne bien sur des projets simples.
Ajout de Rui Martins : Le processus correct de mélange des couleurs doit consister à dessiner d'abord la scène entière, puis à dessiner les graphiques transparents.
Et ils sont dessinés dans l'ordre inverse du tampon de profondeur (les objets les plus éloignés sont dessinés en premier).
Envisagez de mélanger alpha deux polygones (1 et 2). Différents ordres de dessin donneront des résultats différents.
(Ici, on suppose que le polygone 1 est le plus proche de l'observateur, alors le processus correct devrait d'abord dessiner le polygone 2, puis dessiner le polygone 1.
Comme vous pouvez le constater en réalité,
La lumière venant de derrière ces deux polygones <transparents> passe toujours par le polygone 2 en premier.
Ensuite, il traverse le polygone 1 et atteint enfin les yeux de l'observateur. )
Lorsque la mise en cache de profondeur est activée, vous devez trier les graphiques transparents par profondeur,
Et dessinez ces objets transparents une fois que toutes les scènes sont dessinées. Sinon, vous obtiendrez des résultats incorrects.
Je sais que c'est douloureux de faire ça de temps en temps, mais c'est la bonne façon de le faire.
Nous utiliserons le code de la leçon 7.
Commencez par ajouter deux nouvelles variables au début du code. J'ai réécrit tout le code pour plus de clarté.
}
Var
h_RC : HGLRC ; // Contexte de rendu (tableau de description d'ombrage).
h_DC : HDC ; // Contexte du périphérique (tableau de description du périphérique)
h_Wnd : HWND ; // handle de fenêtre
h_Instance : HINST ; // Instance de programme (instance).
keys : Array[0..255] Of Boolean; // Tableau pour les routines de clavier
light : Booléen ; // source lumineuse activée/désactivée
blend : Booléen ; // Mélange OFF/ON (nouveau)
lp : Boolean; // La touche L est-elle enfoncée ?
fp : Boolean; // La touche F est-elle enfoncée ?
bp : Boolean; // La touche B est-elle enfoncée ?
xrot : GLfloat; // Rotation X
yrot : GLfloat; // rotation Y
xspeed : GLfloat; // Vitesse de rotation X
yspeed : GLfloat; // Vitesse de rotation Y
z : GLfloat = -5.0 f; // Distance en profondeur dans l'écran
LightAmbient : Array[0..3] Of GLfloat = (0.5, 0.5, 0.5, 1.0 //Paramètres de lumière ambiante (nouveau) ;
LightDiffuse : Array[0..3] Of GLfloat = (1.0, 1.0, 1.0, 1.0) // Paramètres de lumière diffuse (nouveau) ;
LightPosition : Array[0..3] Of GLfloat = (0.0, 0.0, 2.0, 1.0) // Position de la source lumineuse (nouveau) ;
filtre : GLuint; // Type de filtre
texture : Array[0..2] Of Gluint; // Espace de stockage pour 3 textures
PRocédure glGenTextures(n : GLsizei ; Var textures : GLuint stdcall );
opengl32;
Procédure glBindTexture(cible : GLenum ; texture : GLuint externe) ;
opengl32;
Fonction gluBuild2DMipmaps(cible : GLenum ; composants, largeur, hauteur : GLint ;
format, type : GLenum ; données : Pointeur : Entier ; nom glu32 externe ;
'gluBuild2DMipmaps';
{
Passez ensuite à LoadGLTextures().
Rechercher si (TextureImage[0]=LoadBMP('Data/Crate.bmp'))
Cette ligne. Nous utilisons maintenant une texture de verre teinté à la place de la texture de boîte en bois de la leçon précédente.
if (TextureImage[0]=LoadBMP("Data/glass.bmp")); // Charger le bitmap en verre (modifié)
}
Function LoadTexture: boolean; //Charge le bitmap et convertit-le en texture
Var
Statut : booléen; // Indicateur d'état
TextureImage : Array[0..1] Of PTAUX_RGBImageRec; // Créer un espace de stockage de texture
Commencer
Statut := faux ;
ZeroMemory (@TextureImage, sizeof(TextureImage)); // Place le pointeur sur NULL
TextureImage[0] := LoadBMP('Walls.bmp');
Si TextureImage[0] <> Nil Alors
Commencer
Statut := VRAI ; // Définir le statut sur VRAI
glGenTextures(1, texture[0]); // Créer une texture
// Créer une carte de filtre la plus proche
glBindTexture(GL_TEXTURE_2D, texture[0]);
// Générer une texture
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST // (nouveau) ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST // (nouveau) ;
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data);
glBindTexture(GL_TEXTURE_2D, texture[1]); //Utiliser une texture typique générée à partir de données bitmap
// Générer une texture
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrage linéaire
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Filtrage linéaire
//Créer une texture MipMappée
glBindTexture(GL_TEXTURE_2D, texture[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_NEAREST); // (nouveau)
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0].sizeX,
TextureImage[0].sizey, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data); //(nouveau) }
Fin;
Si assigné(TextureImage[0]) Alors // Si la texture existe
Si attribué(TextureImage[0].data) Then // Si l'image de texture existe
TextureImage[0].data := Nil; // Libère la mémoire occupée par l'image de texture
TextureImage[0] := Nil; // Libère la structure de l'image
résultat := Statut ; // Retourne le statut
Fin;
{
Ajoutez les deux lignes suivantes à la section de code glInit().
La première ligne dessine cet objet en pleine luminosité et lui donne un mélange alpha de 50 % (semi-transparent).
Lorsque l'option de fusion est activée, cet objet sera transparent à 50 %.
La deuxième ligne définit le type de mélange utilisé.
Ajouté par Rui Martins :
Une valeur de canal alpha de 0,0 signifie que le matériau de l'objet est complètement transparent.
1.0 signifie complètement opaque.
}
Procédure glInit(); // Démarrez tous les paramètres pour OpenGL ici
Commencer
If (Not LoadTexture) Then // Appel du sous-programme de chargement de texture
exit; // Si le chargement échoue, quittez
glEnable(GL_TEXTURE_2D); // Activer le mappage de texture
glShadeModel(GL_SMOOTH); // Activer le lissage des ombres
glClearColor(0.0, 0.0, 0.0, 0.0); // fond noir
glClearDepth(1.0); //Définit le tampon de profondeur
glEnable(GL_DEPTH_TEST); // Activer les tests de profondeur
glDepthFunc(GL_LESS); // Type de test de profondeur effectué
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //Calcul de projection en perspective hautement optimisé
glLightfv(GL_LIGHT1, GL_AMBIENT, @LightAmbient[0]); // Définir la lumière ambiante
glLightfv(GL_LIGHT1, GL_DIFFUSE, @LightDiffuse[0]); // Définir la lumière diffuse
glLightfv(GL_LIGHT1, GL_POSITION, @LightPosition); // Position de la source lumineuse
glEnable(GL_LIGHT1); // Activer la source lumineuse n°1
glColor4f(1.0, 1.0, 1.0, 0.5); // Pleine luminosité, mélange Alpha à 50 % (nouveau)
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // Fonction de fusion translucide basée sur la valeur du canal alpha du pixel source (nouveau)
Fin;
{Trouvez l'extrait de code suivant vers la fin de la leçon 7.
Si touches[VK_LEFT] Alors //La touche de direction gauche est-elle enfoncée ?
yspeed := yspeed - 0.01; //Si oui, réduisez yspeed
Suite au code ci-dessus, nous ajoutons le code suivant.
Ces lignes contrôlent si la touche B est enfoncée.
Si tel est le cas, l'ordinateur vérifie si l'option de fusion est activée.
Ensuite, réglez-le sur l'état opposé.
}
If (keys[ord('B')] And Not bp) Then //La touche B est enfoncée et bp est FALSE ?
Commencer
bp := TRUE; // Si oui, bp est défini sur TRUE
blend := Pas de mélange ; // Bascule les options de fusion sur TRUE / FALSE
Si (mélanger) Alors // Le mélange est-il activé ?
Commencer
glEnable(GL_BLEND); // Activer le mélange
glDisable(GL_DEPTH_TEST); // Désactiver les tests de profondeur
Fin
Sinon // autre
Commencer
glDisable(GL_BLEND); // Désactive le mélange
glEnable(GL_DEPTH_TEST); // Activer le test de profondeur
Fin;
Fin;
If (Not keys[ord('B')]) Then // La touche B est-elle relâchée ?
Commencer
bp := FALSE; // Si oui, définissez bp sur FALSE
Fin;
{
Mais comment spécifier la couleur du mélange lorsque vous utilisez le mappage de texture ? C'est très simple.
Lors du réglage du mode texture, la couleur de chaque pixel de la texture est déterminée par le paramètre du canal alpha.
Obtenu en multipliant la couleur actuelle du pixel.
Par exemple, la couleur dessinée est (0,5, 0,6, 0,4),
Nous allons multiplier les couleurs ensemble pour obtenir (0,5, 0,6, 0,4, 0,2)
(Lorsque le paramètre alpha n'est pas spécifié, sa valeur par défaut est zéro).
C'est ça! Implémenter le mélange Alpha dans OpenGL est en effet très simple !
}
{
Note originale (13/11/99)
Mon code de mélange de couleurs (NeHe) a été modifié pour rendre les objets affichés plus réalistes.
L'utilisation du paramètre alpha pour mélanger simultanément les pixels source et les pixels de destination rendra les traces artificielles de l'objet évidentes.
Cela rendra l'arrière de l'objet plus sombre sur les côtés.
Fondamentalement, l'objet aura l'air bizarre.
La méthode de mélange des couleurs que j’ai utilisée n’est peut-être pas la meilleure, mais elle fonctionne.
Avec les lumières activées, les objets semblent réalistes.
Merci à Tom d'avoir fourni le code original. La méthode de mélange des couleurs qu'il a utilisée est correcte.
Mais l'objet n'a pas l'air aussi attrayant que prévu :)
Le code a été à nouveau modifié en raison de problèmes liés à la fonction glDepthMask() sur certaines cartes graphiques.
Cette commande ne semble pas très efficace lors de l'activation ou de la désactivation du test du tampon de profondeur sur certaines cartes,
J'ai donc converti le code pour activer ou désactiver le test du tampon de profondeur en glEnable et glDisable à l'ancienne.
Mélange alpha de cartes de texture
Le paramètre alpha utilisé pour la carte de texture peut être lu à partir de la carte du problème, tout comme la couleur.
La méthode est la suivante, vous devez charger le matériel requis et obtenir son paramètre alpha en même temps.
Utilisez ensuite le format de couleur GL_RGBA lors de l'appel de glTexImage2D().
}