glDisable(GL_LIGHTING); // отключаем освещение lcam.draw();
// восстанавливаем настройки glPopAttrib() ;
// выводим две сферы glTranslatef(0, 0, -90) ; glCallList(1); glTranslatef(40, 0,0); glCallList(1) ;
>
Наложение теней
OpenGL не поддерживает напрямую наложение теней. Однако имеющиеся средства позволяют дополнить сцену тенями различными способами, различающимися сложностью и качеством результата. Один из простых способов - это создание тени с использованием проективного преобразования, так как с геометрической точки зрения, тень есть проекция объекта на некую плоскость, где в роли наблюдателя выступает источник света.
Пусть свет направлен вдоль оси Z, тогда следующий код может использоваться для отображения тени на плоскости XY:
… // преобразование камеры glScalef(1,1,0); // проецируем объект
… // позиционируем объект glColor3fv(shodow_color); // цвет тени … // выводим объект Обычно тень выводят не в самой плоскости, а чуть-чуть отодвигают ее от плоскости, иначе появляются артефакты.
К сожалению, в реальной сцене приходится учитывать угол рассеивания источника света и проецировать не на бесконечную плоскость, а на полигон. В этом случае не обойтись без буфера трафарета.
Более сложные методы, такие как использование объема тени или генерация маски тени и наложение ее на полигон в качестве текстуры, позволяют получить лучший результат с полутенями.
/*
Демонстрация наложения проективной тени.
Вторая камера служит источником света.
Для активации управления камерой нажмите ESC.
*/
GLobj cam[2];
Models m; // объект моделей
// плоскость, на которую падает тень float plane[4]={0,1,0,0 } ;
int lookactive=0; // активная камера для обзора
int inputactive=0; // активная камера для ввода
void example_init()
{
gl.set (5);
glEnable(GL_DEPTH_TEST); glClearColor(0.9, 0.9, 0.9, 1) ; cam[l] .position(0, 50,- 60) ; cam[0] .position(-20, 5,0) ;
>
void example_deinit() f
gl.deinit() ;
>
// обработка ввода void input() f
cam[inputactive] .input(& i n); switch(in.vkey) f
case VK_F1:
lookactive=(lookactive+1)%2; break; case VK_F2:
inputactive=(inputactive+1)% 2; break; default:;
>
in.vkey=0;
}
void draw() // вывод сцены f
input();
// очищение буфера кадра
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadldentity();
cam[lookactive].transform();
cam[0] .draw ( ); cam[1].draw();
// выводим плоскость glColor3f(0,0,1); m.planeXZ(-50,-50,50,50);
// выводим освещаемый объект glColor3f(0,1,1); glPushMatrix() ;
glTranslatef(0,5,-5) ; // позиционируем объект m.cube(10); // выводим объект
glPopMatrix();
// выводим тень glColor3f(0,0,0.8); // цвет тени
glTranslatef(0,0.1,0); // приподнимаем тень
cam[1].shadow(plane); // проецируем на плоскость
glTranslatef(0,5,-5); // позиционируем объект
m.cube(10); // выводим объект