web-dev-qa-db-fra.com

Pourquoi ma couleur va-t-elle quand je active l'éclairage dans OpenGL?

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?

26
dangerChihuahua007

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).

30
Christian Rau

Essayez glEnable(GL_COLOR_MATERIAL).

Voir piège commun ecengl n ° 14 :

  1. 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 utiliser glColor3f 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 est GL_FRONT_AND_BACK et GL_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'initial glMaterialfv est perdu. Ensuite, l'état de matériau de couleur est mis à jour pour changer simplement le matériau diffus à l'avant. Enfin, le glColor3f 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éfinir glColorMaterial avant d'activer GL_COLOR_MATERIAL.

20
genpfault