Иллюстрированный самоучитель по Visual Studio .NET

Создание сферы

Формула учета освещенности

Семейство функций glLightModel* позволяет установить общие параметры освещенности сцены. В частности, первый параметр GL_LIGHT_MODEL_AMBIENT сообщает OpenGL, что второй параметр содержит четыре компонента, задающие RGBA-интенсивность освещенности всей сцены. По умолчанию вектор освещенности сцены равен (0.2, 0.2, 0.2, 1.0). Команда glLight* устанавливает параметры источника света. Мы пользуемся ею два раза для задания диффузного и рефлективного компонента интенсивности света. Если вы обратитесь к документации, то увидите, что с помощью glLight* можно задать еще более десятка параметров источника света. Формулу учета освещения я нашел в документации лишь в словесном описании, но рискну привести ее в виде математического выражения.

В режиме RGBA-интенсивность каждого из трех компонентов цвета освещенной вершины вычисляется как сумма нескольких составляющих. Первая составляющая учитывает эмиссию света материалом, вторая – освещенность окружения (ambient) или всей сцены, третья – является суммой вкладов от всех источников света. Максимально допустимое число источников, как вы помните, определено константой GL_MAX_LIGHTS, которая в нашем случае равна 8:

L=Me+MaLaf+Сумма(MaLai+MdLdi(N*Vl)+MsLsi(Ve*Vl)^h)

Здесь символ т обозначает некоторое свойство материала, а символ / – свойство света. Индекс е в применении к материалу обозначает эмиссию, а в применении к вектору v – eye (глаз). Остальные индексы в применении к материалу обозначают различные компоненты его отражающих свойств.

  • Mа коэффициент отражения окружающего (ambient) света,
  • Md коэффициент отражения рассеянного (diffuse) отражения,
  • Ms коэффициент отражения зеркального (specular) отражения,
  • N – вектор нормали вершины, который задан командой glNormal,
  • V1 – нормированный вектор, направленный от вершины к источнику света,
  • Ve – нормированный вектор, направленный от вершины к глазу наблюдателя,
  • h – блесткость (shininess) материала.

Члены в круглых скобках – это скалярные произведения векторов. Если они дают отрицательные значения, то конвейер заменяет их нулем. Alpha-компонент результирующего цвета освещения устанавливается равным alpha-компоненту диффузного отражения материала. Так как мы задали лишь один источник света (LIGHTO), то знак суммы можно опустить. Обратите внимание на то, что блесткость материала уменьшает (обостряет) пятно отраженного света, так как возведение в степень h > 1 чисел (v, -v,), меньших единицы, уменьшает их значение. Параллельные векторы v, и v, дадут максимальный вклад. Чем больше их рассогласование, тем меньший вклад даст последний член формулы.

Ориентация поверхности

Кроме установки параметров света код функции init содержит довольно много других установок, которые мы осуществляем впервые, поэтому обсудим их более подробно. Возможно, вы помните из курса аналитической геометрии, что некоторые поверхности имеет ориентацию. По умолчанию поверхность любого полигона считается лицевой (FRONT), если вы задали ее обходом вершин против часовой стрелки, и она считается изнаночной (BACK), если направление обхода было обратным. В частности, ориентация поверхности влияет на ориентацию нормали.

Примечание
Вы можете реверсировать эту установку, задав режим glfrontFace (GL_CW). По умолчанию действует установка glFrontFace(GL_CCW). Аббревиатура CW означает clockwise (по часовой стрелке), a CCWcounterclockwise (против часовой стрелки). Кстати, вы, вероятно, видели в литературе изображение ленты Мебиуса или бутылки Клейна, поверхности которых односторонние и поэтому не имеют ориентации
.

Команда glEnable (GL_CULL_FACE); включает механизм учета ориентации поверхности полигонов. Она должна сопровождаться одним из флагов, определяющих сторону поверхности, например glCullFace(GL_BACK);. Таким образом, мы сообщаем конвейеру OpenGL, что обратные стороны полигонов можно не учитывать. В этом случае рисование полигонов ускоряется. Мы не собираемся показывать внутреннюю поверхность замкнутой сферы, поэтому эти установки нам вполне подходят.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.