Je développe une application graphique en C++ avec l'API OpenGL et Glut.
Pour ajouter de l'éclairage, j'ai apporté les modifications suivantes dans ma matrice Modelview:
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// Create light components.
GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
GLfloat position[] = { 0.0f, 0.0f, 0.0f, 1.0f };
// Assign created components to GL_LIGHT0.
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
glLightfv(GL_LIGHT0, GL_POSITION, position);
L'éclairage travaille en grande partie je crois, mais les couleurs de mes objets vont tous disparaître. Tout ce que je vois, c'est une silhouette noire/blanche de ma figure globale.
Je me demandais pourquoi c'est?
Lorsque l'éclairage est activé, une couleur de sommet n'est pas déterminée à partir de la couleur définie par glColor
ou glColorPointer
, mais par les couleurs de matériau actuellement définies combinées aux couleurs des lumières utilisant les calculs d'éclairage.
Donc, afin de modifier la couleur d'un objet, vous devez modifier le réglage de la matière (par défaut, un matériau gris diffus) avant de rendu, à l'aide de glMaterial
fonctions. Il existe essentiellement une couleur de matériau correspondante pour chacune des différentes couleurs de lumière (GL_DIFFUSE
, ...) ainsi que des propriétés supplémentaires pour approximatiser les matériaux émetteurs de la lumière (GL_EMISSION
) Et contrôler la rugosité du matériau ( GL_SHININESS
). Lisez du matériel d'introduction sur les fonctionnalités d'éclairage de OpenGL pour comprendre leur fonctionnement.
Ce que vous pouvez faire pour adapter rapidement votre code à partir de la coloration claire à l'allumage (ou d'activer les propriétés de matériau Per-Vertex) est d'utiliser des matériaux de couleur. En appelant glEnable(GL_COLOR_MATERIAL)
et définition d'un mappage approprié avec glColorMaterial
Vous pouvez configurer OpenGL pour modifier une couleur de matériau spécifique, chaque fois que vous modifiez la couleur de sommet actuelle (en utilisant soit glColor
ou glColorPointer
).
Essayez glEnable(GL_COLOR_MATERIAL)
.
Voir piège commun ecengl n ° 14 :
- Matériau de couleur active prudent
La fonction de matériau de couleur de OpenGL offre un moyen moins coûteux de modifier les paramètres de matériau. Avec matériau de couleur activé, les couleurs matérielles suivent la couleur actuelle. Cela signifie que au lieu d'utiliser la routine
glMaterialfv
relativement coûteuse, vous pouvez utiliserglColor3f
routine.Voici un exemple utilisant la fonction de matériau de couleur pour modifier la couleur diffuse de chaque sommet d'un triangle:
glColorMaterial(GL_FRONT, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); glBegin(GL_TRIANGLES); glColor3f(0.2, 0.5, 0.8); glVertex3f(1.0, 0.0, 0.0); glColor3f(0.3, 0.5, 0.6); glVertex3f(0.0, 0.0, 0.0); glColor3f(0.4, 0.2, 0.2); glVertex3f(1.0, 1.0, 0.0); glEnd();
Considérez la séquence de code plus coûteuse nécessaire si
glMaterialfv
est utilisé explicitement:GLfloat d1[] = { 0.2, 0.5, 0.8, 1.0 }; GLfloat d2[] = { 0.3, 0.5, 0.6, 1.0 }; GLfloat d3[] = { 0.4, 0.2, 0.2, 1.0 }; glBegin(GL_TRIANGLES); glMaterialfv(GL_FRONT,GL_DIFFUSE,d1); glVertex3f(1.0, 0.0, 0.0); glMaterialfv(GL_FRONT,GL_DIFFUSE,d2); glVertex3f(0.0, 0.0, 0.0); glMaterialfv(GL_FRONT,GL_DIFFUSE,d3); glVertex3f(1.0, 1.0, 0.0); glEnd();
Si vous rendu des objets nécessitant des modifications de matériau simples fréquentes, essayez d'utiliser le mode de matériau de couleur. Cependant, il existe un piège commun rencontré lors de l'activation du mode de matériau de couleur. Lorsque le matériau de couleur est activé, OpenGL modifie immédiatement les couleurs de matériau contrôlées par l'état de matériau de couleur. Considérez la pièce de code suivante pour initialiser un contexte de rendu OpenGL nouvellement créé:
GLfloat a[] = { 0.1, 0.1, 0.1, 1.0 }; glColor4f(1.0, 1.0, 1.0, 1.0); glMaterialfv(GL_FRONT, GL_AMBIENT, a); glEnable(GL_COLOR_MATERIAL); /* WARNING: Ambient and diffuse material latch immediately to the current color. */ glColorMaterial(GL_FRONT, GL_DIFFUSE); glColor3f(0.3, 0.5, 0.6);
Dans quel état seront-ils les couleurs de matériau ambiant et diffuse avant après avoir exécuté le fragment de code ci-dessus? Pendant que le programmeur ait eu l'intention de l'état de matériau ambiant d'être
(0.1, 0.1, 0.1, 1.0)
et l'état de matériau diffus à être(0.3, 0.5, 0.6, 1.0)
, ce n'est pas tout à fait ce qui se passe.L'état de matériau diffus résultant est ce que le programmateur a voulu, mais l'état de matériau ambiant résultant est plutôt inattendu
(1.0, 1.0, 1.0, 1.0)
. Comment est-ce arrivé? Eh bien, rappelez-vous que le mode de matériau de couleur commence immédiatement à suivre la couleur actuelle lorsqu'il est activé. La valeur initiale pour les paramètres de matériau de couleur estGL_FRONT_AND_BACK
etGL_AMBIENT_AND_DIFFUSE
(probablement pas ce que vous attendiez!).Étant donné que l'activation du mode de matériau de couleur commence immédiatement à suivre la couleur actuelle, les états de matériaux ambiants et diffus sont mis à jour pour être
(1.0, 1.0, 1.0, 1.0)
. Notez que l'effet de l'initialglMaterialfv
est perdu. Ensuite, l'état de matériau de couleur est mis à jour pour changer simplement le matériau diffus à l'avant. Enfin, leglColor3f
L'invocation change le matériau diffus à(0.3, 0.5, 0.6, 1.0)
. L'état de matériau ambiant finit par être(1.0, 1.0, 1.0, 1.0)
.Le problème dans le fragment de code ci-dessus est que le mode matériau de couleur est activé avant d'appeler
glColorMaterial
. Le mode de matériau de couleur est très efficace pour des modifications matérielles simples efficaces, mais pour éviter le piège ci-dessus, faites toujours attention à définirglColorMaterial
avant d'activerGL_COLOR_MATERIAL
.