Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
семинар 4.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
503.81 Кб
Скачать

Тема: Исследование свойств источника света.

Основывается на лекции 6.

Цели работы:

Закрепить знания о методах расчета освещения;

Научиться создавать и настраивать источники света в OpenGL;

Программа семинара

Введение;

..Разработка тестового приложения;

Создание объектов сцены;

Создание и настройка источников света;

Изучение реализации рассеянного освещения;

Изучение реализации диффузной составляющей освещения;

Изучение реализации зеркальной составляющей освещения;

Контрольные вопросы.

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

Нам потребуется ввести в тестовую программу набор интерактивных визуальных компонентов, с помощью которых будем изменять параметры освещения. Для того чтобы во время исследования постоянно контролировать положение освещаемых объектов, источника света и точки наблюдения будем использовать две проекции. Фронтальная проекция позволит нам видеть результаты сформированного освещения, а вид сверху покажет схему расположения ключевых объектов. Реализуя такой подход при построении сцены, мы разместим центры всех объектов, влияющие на расчет освещения в плоскости XOZ. Примерный внешний вид создаваемого приложения представлен на рисунке 4.1.

По сложившейся схеме, создание программы начнем с процедуры, включающей в себя инициализацию библиотеки и задания общих настроек видового конвейера. Большинство необходимых настроек нам уже знакомо. Установите режим ортографического проецирования. Видимый объем задайте «просторный» - куб со стороной 20 единиц. Задумайтесь над тем, на что влияют размеры видимого объема? Может быть на размер формируемого, на экране изображения? Как мы с вами разбирали в ходе лекций, при преобразовании координат учитываются не величины, а их отношения. Следовательно, изображения модели куба со стороной равной единице при размерах видимого объема 10*10*10 и модели куба со стороной равной 0.01 при видимом объеме размером 0.1*0.1*0.1 будут одинаковы (при неизменном поле вывода). Таким образом, размер видимого объема неявно определяет размеры создаваемой модели, при условии, что мы хотим увидеть всю модель и достаточно подробно.

Далее задайте черный цвет очистки буфера кадра, включите тест глубины и сделайте текущей матрицу видового преобразования. Задайте режим заполнения многоугольников. Новые настройки рассмотрим подробнее. Мы будем работать с освещением, поэтому необходимо включить его обработку в видовом конвейере. Это выполняется командой glEnable c параметром GL_LIGHTING. При расчете освещения важную роль играют нормали. Для корректности вычислений необходимо, чтобы все нормали имели единичную длину. Добиться этого самостоятельными расчетами достаточно сложно. Попробуйте определить вектор единичной длины к произвольно ориентированному в пространстве многоугольнику. Более того, мы можем использовать в модельных или видовых преобразованиях масштабирование, а нормали подвергаются этим преобразованиям также как и примитивы. В результате их длины меняются. Поэтому необходимо включить режим, при котором после выполнения всех трансформаций длины нормалей приводятся к единице. Данный режим включается командой glEnable c параметром GL_NORMALIZE. Для увеличения эффективности командой glEnable(GL_CULL_FACE) можно исключить из обработки конвейером обратные грани. Собственно эта команда только включает режим исключения, а отсекаемые грани определяются командой glCullFace. Но в этом случае в ее использовании нет необходимости, т.к. по умолчанию отсекаются обратные грани.

Создание объектов сцены

Теперь перейдем к созданию объектов, входящих в сцену. Наша сцена будет включать в себя только три объекта – прямоугольник и две сферы.

Прямоугольник мы можем представить одним примитивом OpenGL – многоугольником. Однако, в нашем случае это не лучший вариант. Как вы знаете, расчет интенсивности освещения выполняется только для вершин определяющих примитив, а для получения значений интенсивности всех других точек выполняется интерполяция. Для наших экспериментов четырех точек явно недостаточно, поэтому представим прямоугольник как совокупность n*n стыкующихся прямоугольников меньшего размера. Сделать универсальную процедуру построения такого объекта довольно сложно из-за трудности обеспечения правильного порядка обхода вершин при различной ориентации прямоугольника, поэтому сделаем специализированную процедуру, строящую прямоугольник лежащий в плоскости параллельной плоскости XOY. На вход данной процедуры будем передавать размеры прямоугольника и точку его привязки в пространстве, а также величину, показывающую требуемое количество разбиений. Для оптимизации построения такого объекта мы можем использовать дисплейный список

procedure plate(lx,ly,x,y,z:glFloat; n:glEnum);

var x1,dx, dy :glfloat; i,j:integer;

begin

dx:=lx/n; dy:=ly/n; x1:= x;

glNewList(ListName,GL_COMPILE);

for i:=1 to n do begin

for j:=1 to n do begin

glNormal3i(0,0,1);

glBegin(gl_polygon);

glVertex3f(x, y, z);

glVertex3f(x,y-dy,z);

glVertex3f(x+dx,y-dy,z);

glVertex3f(x+dx, y,z);

glEnd;

x:=x+dx;

end;

x:=x1;

y:=y-dy;

end;

glEndList;

end;

Заключенный в операторные скобки glNewList, glEndList фрагмент кода проходит предварительную компиляцию и запоминается для последующих вызовов. Обратите внимание на то, что все команды компилируются с конкретными значениями параметров, которые не могут быть изменены впоследствии. Имя списка задается целым числом, хранимым в переменной ListName. Его можно задать самостоятельно или воспользоваться специальным генератором имен списков glGenLists. Константа GL_COMPILE говорит о том, что список нужно только компилировать без выполнения в отличие от константы GL_COMPILE_AND_EXECUTE. Команда glNormal3i задает нормаль к определяемым вершинам. Созданную процедуру необходимо вызвать однократно, задав необходимые параметры. Сделать это можно там же, где мы устанавливали общие настройки. Задайте прямоугольник размером 10*10 с точкой привязки (-5,5,-5) и количеством разбиений n равным 120. Выполнение заданного процедурой дисплейного списка инициируется вызовом процедуры glCallList с параметром, определяющим имя вызываемого списка. Вызов необходимо сделать в процедуре формирования сцены.

Построение сферы из многоугольников довольно сложно, поэтому воспользуемся объектом библиотеки GLU. В рамках данного семинара мы не будем останавливаться на особенностях работы этой библиотеки. Для получения сферы выполните следующие действия:

  • объявите глобальную переменную типа PGLuQuadric из этой библиотеки (например q);

  • после инициализации OpenGL однократно вызовите функцию gluNewQuadric, которая создаст специальный объект и вернет ссылку на него. Результат выполнения функции присвойте объявленной переменной;

  • в процедуре формирования сцены вызовите процедуру gluSphere, задающую сферу на основе ранее созданного объекта. Ее параметрами являются ссылка на объект, радиус и количество разбиений по двум направлениям (например, gluSphere(q, 2, 50, 32);).

Увеличение количества разбиений, а следовательно, и количества многоугольников, использующихся для аппроксимации поверхности сферы, приводит к повышению качества изображения, снижая при этом эффективность программы. Центр сферы всегда совпадает с началом ее координатной системы. Нам необходимо построить сферу так, чтобы ее центр совпадал с центром прямоугольника. Для этого необходимо сдвинуть координатную систему сферы на 5 единиц в сторону отрицательной полуоси Z координатной системы сцены.

Для каждого объекта сцены необходимо определить отражательные свойства материала, имитацию которого вы хотите получить. В данной программе для нас главное разобраться в принципах работы модели, а не эстетическое впечатление от созданных объектов, поэтому установим различные коэффициенты отражения для разных составляющих освещения. Наши объекты должны выглядеть серыми при воздействии рассеянной составляющей и красными - при воздействии зеркальной. Диффузная составляющая оказывает основное влияние на цвет объекта, поэтому, для того чтобы объекты не сливались, установим для них различные коэффициенты отражения этой составляющей. Прямоугольник должен хорошо отражать зеленый свет, а сферы синий. Еще одно важное свойство материала это пространственное распределение зеркально отраженного света. Значение этого свойства мы также будем устанавливать во время выполнения программы, и для его хранения нам потребуется глобальная переменная целого типа (Sval). Созданная вами процедура должна выглядеть приблизительно так.

procedure TForm1.drawscene;

fl:array[0..3] of glFloat;

begin

fl[0]:=1.0; fl[1]:=1.0; fl[2]:=1.0; fl[3]:=0;

glMaterialfv(GL_FRONT, GL_AMBIENT, @fl); // отражение рассеянного света

fl[0]:=0.1; fl[1]:=0.6; fl[2]:=0.1; fl[3]:=1;

glMaterialfv(GL_FRONT, GL_DIFFUSE, @fl); // отражение диффузного света

fl[0]:=1; fl[1]:=0; fl[2]:=0; fl[3]:=1;

glMaterialfv(GL_FRONT, GL_SPECULAR, @fl);

glMaterialf(GL_FRONT, GL_SHININESS, Sval);

glPushMatrix; // запоминаем систему координат сцены

glRotatef(45,0,0,1); // переходим в систему площадки

glCallList(ListName); // прямоугольная площадка

glPopMatrix; // возврат в к.с. сцены

glPushMatrix;

fl[0]:=0.3; fl[1]:=0.3; fl[2]:=0.9; fl[3]:=1;

glMaterialfv(GL_FRONT, GL_DIFFUSE, @fl);

glTranslatef(-3,0,-5);

gluSphere(q, 1.5, 50, 32); // первая сфера

glPopMatrix;

glPushMatrix;

glTranslatef(-7,0,-5);

gluSphere(q, 1.5, 50, 32); // вторая сфера

glPopMatrix;

end;