
10.3. Пример трехмерной графики
Рассмотрим пример ЗБ-программы OpenGL. Файл studexsi.cpp:
Результат работы программы показан на рис. 10.2.
Рис. 10.2. Изображение объектов и направление осей мировых координат
в программе StudexSl
Для иллюстрации работы Z-буфера (в OpenGL он называется буфером глубины — depth buffer) сначала рисуем грани пирамиды, а потом шахматное поле, которое расположено ниже. Грани пирамиды также рисуем все пять (хотя здесь видны только две), причем так, чтобы при отсутствии Z-буфера получался бы заведомо неправильный результат. Проверьте это, попробуйте отключить Z-буфер. Для этого достаточно удалить из текста оператор glEnable (GL_depth_test) . Что получится?
Программа StudexSl может служить простейшим примером построения изображения трехмерных объектов в заданной проекции. Изображение на рис. 10.2 вполне правдоподобно передает форму объектов. Однако в данной программе отсутствуют многие важные элементы построения реалистичных изображений. В первую очередь это относится к освещению. Так, например, грани пирамиды здесь закрашены разными цветами — передняя грань более светлым цветом, а боковая грань более темным. Эти цвета мы задали вызовом функций gicoior3f перед выводом соответствующих граней. Значения цветов выбраны произвольно. Здесь никак не были использованы возможности, которые предоставляет OpenGL для моделирования освещения.
10.4. Моделирование освещения
Для того чтобы поручить OpenGL изображать объекты в соответствии с некоторой моделью освещения, необходимо вызвать функцию glEnabie (gl_lighting) . Может быть использовано несколько источников света. Максимальное количество источников света зависит от версии реализации OpenGL. Источники света имеют номера от 0 до некоторого максимального значения. Включение i-го источника выполняется функцией
glEnabie (GL_LIGHTi), а выключение — функцией glDisable (GL_LIGHTi) . Так,
например, чтобы заставить светить нулевой источник, необходимо вызвать
функцию glEnabie (GL_LIGHT0).
Каждый источник света можно (и нужно) настроить индивидуально. Делается ЭТО ВЫЗОВОМ функций glLightf, glLighti ИЛИ glLightfv, glLightiv (век-
торные разновидности). Функции различаются типами и количеством аргументов. Рассмотрим некоторые примеры настройки.
Определить положение источника света gl_lighto можно следующим образом:
В массив lightpos [ ] необходимо записать однородные мировые координаты источника света в виде (x, у, z, w). При вызове glLightfv эти координаты будут преобразованы в соответствии с ракурсом показа, определяемом видовой матрицей. При w=1 будет обеспечено правильное соответствие закрашивания объектов расположению источника.
Направление действия источника света задается так:
В массиве iightdirection[] должны быть указаны координаты радиус-вектора в относительных единицах (х, у, z), направленного от источника света.
Угол распространения света от точечного направленного источника можно задать так:
где angle — угол в градусах в диапазоне от 0 до 90°. При этом свет в пространстве ограничивается конусом. Также допустимо значение angle = 180, которое соответствует равномерному распространению света во все стороны.
Этим далеко не исчерпываются возможности функций glLightf, glLighti, glLightfv и glLightiv для установки параметров источников света. Для наиболее полного ознакомления обратитесь к документации по Win32 SDK [61].
Необходимо учитывать, что многие параметры, в том числе и для источников света, в OpenGL установлены по умолчанию. Так, например, для источника gllighto установлен по умолчанию равномерный рассеянный свет (angle = 180). Кроме того, установки по умолчанию неодинаковы для различных ИСТОЧНИКОВ GLLIGHTi.
Кроме параметров настройки источника света еще одним важнейшим аспектом моделирования освещения является задание нормалей к поверхностям. При выводе каждого объекта OpenGL определяет взаимную ориентацию вектора направления источника света и текущего вектора нормали. По умолчанию установлено направление вектора нормали как (0, 0, 1), то есть вектор направлен вдоль оси z мировых координат. Направление текущего вектора нормали не изменяется до тех пор, пока не будет вызвана функция giNomai, например:
где пх, пу и nz — это координаты радиус-вектора нормали. Для данной функции они должны быть в диапазоне (-1.0, 1.0). Существуют и другие разновидности для glNormai, отличающиеся типами числовых значений координат.
Таким образом, при выводе каждой отдельной полигональной грани необходимо вначале устанавливать направление текущего вектора нормали. Для корректного расчета взаимного расположения векторов нормалей и направлений источников света при различных ракурсах показа необходимо установить режим нормализации векторов
Для правильного вывода освещаемых объектов нужно также определять свойства материала поверхности. Если предполагается изображать освещенными цветные объекты, то следует установить
Суммируем полученные сведения в программе studex52.
Результат работы программы studex52 показан на рис. 10.3.
Рис. 10.3. Моделирование освещения (свет справа сверху)