Подтвердить что ты не робот

Почему мой цвет исчезает, когда я включаю освещение в OpenGL?

Я разрабатываю графическое приложение на С++ с OpenGL API и GLUT.

Чтобы добавить освещение, я внес следующие изменения в мою модельную модель:

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

Освещение в основном работает, я верю, но цвета моих объектов все уходят. Все, что я вижу, это черный/белый силуэт моей общей фигуры.

Мне было интересно, почему это?

4b9b3361

Ответ 1

Когда освещение включено, цвет вершины не определяется цветом, установленным glColor или glColorPointer, а текущими установленными цветами материала в сочетании с цветами огней с использованием вычислений освещения.

Итак, чтобы изменить цвет объекта, перед рендерингом вам нужно изменить настройку материала (который по умолчанию является диффузным серым материалом), используя glMaterial. По существу, имеется соответствующий цвет материала для каждого из разных светлых цветов (GL_DIFFUSE,...) наряду с некоторыми дополнительными свойствами для приближения светоизлучающих материалов (GL_EMISSION) и контроля шероховатости материала (GL_SHININESS). Прочтите некоторые вводные материалы по функциям освещения OpenGL, чтобы понять их работу.

Что вы можете сделать, чтобы быстро адаптировать свой код от простой раскраски к освещению (или для включения свойств материала на вершине), использовать цветной материал. Вызывая glEnable(GL_COLOR_MATERIAL) и устанавливая соответствующее сопоставление с glColorMaterial, вы можете настроить OpenGL для изменения определенного цвета материала, всякий раз, когда вы меняете текущую вершину цвет (используя либо glColor, либо glColorPointer).

Ответ 2

Попробуйте glEnable(GL_COLOR_MATERIAL).

См. Общий OpenGL Pitfall # 14:

  1. Осторожно Включение цветного материала

Функция материала цвета OpenGL обеспечивает менее дорогостоящий способ изменить параметры материала. При включенном цветовом материале материал цвета отслеживают текущий цвет. Это означает, что вместо использования относительно дорогостоящая процедура glMaterialfv, вы можете использовать glColor3f.

Вот пример использования функции цветного материала для изменения диффузный цвет для каждой вершины треугольника:

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();

Рассмотрим более дорогую кодовую последовательность, если glMaterialfvявно используется:

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();

Если вы рендерите объекты, требующие частого простого материала изменения, попробуйте использовать режим цветных материалов. Однако существует общая ошибка, возникающая при включении режима цветного материала. когда цветной материал включен, OpenGL немедленно изменяет материал цвета, контролируемые состоянием цветного материала. Рассмотрим следующее фрагмент кода для инициализации нового контекста рендеринга OpenGL:

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

В каком состоянии будут отображаться цвета передних окружающих и диффузных материалов выполнение вышеуказанного фрагмента кода? Хотя программист может иметь Предполагалось, что состояние окружающего материала должно быть (0.1, 0.1, 0.1, 1.0) и состояние диффузного материала (0.3, 0.5, 0.6, 1.0), то есть что происходит.

Результирующее состояние диффузного материала - это то, что планировал программист, но полученное состояние окружающего материала довольно неожиданно (1.0, 1.0, 1.0, 1.0). Как это произошло? Ну, помните, что режим цветного материала сразу начинает отслеживать текущий цвет, когда включен. Начальное значение для параметров цветового материала GL_FRONT_AND_BACK и GL_AMBIENT_AND_DIFFUSE (вероятно, не то, что вы ожидали!).

Так как включение режима цветного материала сразу начинает отслеживать текущий цвет, как состояния окружающего, так и диффузного материала обновлено до (1.0, 1.0, 1.0, 1.0). Обратите внимание, что эффект начальный glMaterialfv теряется. Далее, состояние цветного материала чтобы просто изменить передний диффузный материал. Наконец, Вызов glColor3f изменяет диффузный материал на (0.3, 0.5, 0.6, 1.0). Состояние окружающего материала заканчивается (1.0, 1.0, 1.0, 1.0).

Проблема в фрагменте кода выше заключается в том, что режим цветного материала активируется перед вызовом glColorMaterial. Режим цветного материала очень эффективен для эффективных простых изменений материала, но избегать приведенная выше ошибка, всегда будьте осторожны, чтобы установить glColorMaterial до вы включаете GL_COLOR_MATERIAL.