Создание и настройка источников света
Формирование двух проекций сцены и задание параметров источника света произведем в процедуре Draw. Начнем процедуру с очистки буфера кадра и перехода к координатной системе, совпадающей с мировой. Для изучения модели освещения нам потребуется изменять положение наблюдателя относительно источника света и объектов сцены. А так как в OpenGL положение наблюдателя зафиксировано в начале мировой координатной системы, то нам придется изменять положение объектов сцены и источника за счет изменения их координатных систем. Так как мы договорились не выводить центра объектов из плоскости XOZ, то для этого достаточно простого переноса вдоль оси Х. Величина сдвига будет изменяться, и для ее хранения необходима глобальная переменная (VPpos). Мы могли бы выполнять перенос и по оси Z, но это приведет к усложнению программы, не давая никаких преимуществ. Далее определим основные свойства нулевого источника. Диффузную и зеркальную составляющие определим белыми, смешав все три компоненты в равных пропорциях с единичной интенсивностью. В OpenGL нельзя включать или выключать отдельные составляющие светового потока, испускаемого источником. Для того чтобы отдельно рассмотреть воздействие диффузной или зеркальной составляющих освещения мы будем присваивать другой нулевое значение интенсивности. Управлять составляющими будем с помощью двух логических переменных – eDiffuse и eSpecular. Интенсивность рассеянной составляющей зададим равной 0.1, в результате свет получится темно серым, и не будет оказывать большого влияния на результат. Эта составляющая будет присутствовать постоянно. При задании позиции источника нам также необходимо обеспечить его перемещение в плоскости XOZ. Мы будем управлять положением источника за счет изменения значений переменных Xpos и Zpos. Включим в нашу программу возможность использовать два варианта задания направления светового конуса, а точнее его центральной оси. В первом варианте световой конус будет направлен в сторону отрицательной полуоси WC, а во втором - в сторону центра сцены. Для переключения будем использовать логическую переменную еDirectionCenter. Реализация первого варианта проста, вектор направления совпадает со значением по умолчанию, но мы будем устанавливать данный вектор, чтобы обеспечить восстановление направления при переходе из второго режима. Для определения вектора, направленного из источника в центр сцены достаточно вычесть координаты его начала из координат конца вектора. Нам осталось задать угол, определяющий «ширину» раскрытия конуса и распределение светового потока внутри конуса – фокусировку. Соответствующие величины будем хранить в переменных CUTOFFval и EXPval. Теперь все необходимые параметры источника установлены, и мы включаем источник. Еще раз подчеркнем, что не имеет значения, включаем мы источник до настройки параметров или после ее. И установка параметров, и включение источников приводит к изменению переменных состояния OpenGL, а опрашиваться эти переменные будут только в момент обработки конвейером графических примитивов. Завершая настройки освещения, обеспечим управление параметром GL_LIGHT_MODEL_LOCAL_VIEWER модели освещения, значение параметра будет определять переменная LVval типа glBoolean.
procedure draw;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glTranslatef(VPpos,0,0);
fl[0]:=1; fl[1]:=1; fl[2]:=1; fl[3]:=0;
if not eDiffuse then begin fl[0]:=0; fl[1]:=0; fl[2]:=0; fl[3]:=0; end;
glLightfv(GL_LIGHT0, GL_DIFFUSE, @fl);
fl[0]:=1; fl[1]:=1; fl[2]:=1; fl[3]:=0;
if not eSpecular then begin fl[0]:=0; fl[1]:=0; fl[2]:=0; fl[3]:=0; end;
glLightfv(GL_LIGHT0, GL_SPECULAR, @fl);
fl[0]:=0.1; fl[1]:=0.1; fl[2]:=0.1; fl[3]:=0;
glLightfv(GL_LIGHT0, GL_AMBIENT, @fl);
fl_pos[0]:=Xpos; fl_pos[1]:=0; fl_pos[2]:=Zpos; fl_pos[3]:=1;
glLightfv(GL_LIGHT0, GL_POSITION, @fl_pos);
fl[0]:=0; fl[1]:=0; fl[2]:=-1; fl[3]:=0;
if DirectionCenter then begin fl[0]:=0-Xpos; fl[1]:=0; fl[2]:=-5-Zpos; fl[3]:=0; end;
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, @fl);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, Cval);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, ExpVal);
glEnable(GL_LIGHT0);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,LVval);
glViewport(0,form1.panel.Height,round(form1.clientwidth/2),round(form1.clientheight-form1.panel.Height));
DrawLight(GL_LIGHT0);
DrawScene;
// вывод схемы освещения
glDisable(GL_LIGHTING);
glColor3f(0.4,0.4,0.4);
glLoadIdentity;
glRotatef(89.2,1,0,0);
glTranslatef(VPpos,0,0);
glviewport(round(form1.clientwidth/2),form1.panel.Height,round(form1.clientwidth/2),round(form1.clientheight-form1.panel.Height));
DrawAxis;
DrawLight1(GL_LIGHT0);
Drawscene;
glEnable(GL_LIGHTING);
glFlush;
swapglbuffers;
end;
