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); // выводим объект


⇐ вернуться назад | | далее ⇒