Вносим свет
Пока нет освещения, все попытки внести трехмерный реализм обречены на неудачу. Свет отражается по нормали (перпендикуляру) к поверхности. Однако в OpenGL нормаль надо задавать в вершинах, так как в случае произвольной криволинейной поверхности направление нормали различно в каждой ее точке. Чем точнее вычислен вектор нормали, тем реалистичней изображение. Но это дело довольно тонкое. Для тех, кто не любит математику, то есть излишне напрягать свое мышление, – просто отвратительное.
Примеры с автонормалями расслабляют и усыпляют бдительность, так как они скрывают детали реализации. Чтобы с ними работать, тоже надо прилагать усилия и правильно включать вычислители (evaluators). Смотри документацию по функциям giMap*. В нашем же случае все просто. Нормали уже вычислены, осталось включить свет. Сделайте это, вставив изменения в тело функции init. Включите еще два параметра в конечном автомате (state machine) OpenGL.
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
Задайте некоторый поворот, например double gdAngleX=15, gdAngleY=30, и запустите на выполнение. Изображение должно стать значительно лучше, но куда делся цвет куба? Свет исключил цвет. Дело в том, что теперь цвет каждого пиксела вычисляется по формуле, которая учитывает цвет материала поверхности, его отражающие и испускающие свойства, цвет самого света, его направление и законы распространения (точнее, затухания – attenuation). По умолчанию OpenGL учитывает только направление света, но не место расположения источника. По умолчанию же свет направлен вдоль оси Z.
Обратите внимание на то, что индекс 0 в GL_LIGHTO означает, что мы включаем первый из GL_MAX_LIGHTS возможных источников света. Эта константа зависит от платформы. Давайте определим ее для нашей платформы.
Вставьте такой фрагмент:
int Lights; glGetIntegerv(GL_MAX_LIGHTS, &Lights); _asm nор
Внутрь функции Init (после строки glEnable(GL_LIGHTO);) и поставьте точку останова (F9) на строке __asm nор.
Примечание
Ассемблерная вставка _asm nор упрощает просмотр значения переменных в окне Variables, так как не дает новых (и отвлекающих) элементов просмотра. Идея использования такого приема принадлежит Марине Полубенцевой, с которой мы сотрудничаем в Microsoft Authorized Education Center при ФПК СПбГТУ (www.Avalon.ru). В книге использовано еще несколько идей и технологических приемов, автором которых является Полубенцева.
Затем нажмите F5 (Go). Когда выполнение дойдет до точки останова, посмотрите в окно Variables и убедитесь в том, что Lights приняла значение 8. Если хотите, то используйте описанный прием в дальнейшем для выяснения многочисленных параметров и состояний OpenGL. Посмотрите справку по glGet, чтобы получить представление о количестве этих параметров. Теперь уберите отладочный код и включите еще один тумблер в машине состояний OpenGL – учет цвета материала. Для этого вставьте строку:
glEnable(GL_COLOR_MATERIAL);
В функцию Init и запустите приложение. Обратите внимание на отличие оттенков цвета разных граней. Они определяются OpenGL с учетом направления нормалей. Попробуйте изменить их направление и посмотрите, что получится.