Главная страница

Руководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика


Скачать 0.66 Mb.
НазваниеРуководство по работе с графической библиотекой OpenGL. Руководство разработано с учетом опыта чтения курса Компьютерная графика
Дата21.10.2022
Размер0.66 Mb.
Формат файлаdocx
Имя файла221937-83556.docx
ТипРуководство
#747097
страница15 из 30
1   ...   11   12   13   14   15   16   17   18   ...   30
2.

/* условие всегда выполнено и

значение в буфере будет равно 1*/ glStencilFunc (GL_ALWAYS, Oxl, Oxffffffff);

/* в любом случае заменяем значение в буфере, маски*/ glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE);

/* выводим геометрию, по которой

затем будет отсечена тень*/ RenderPlane();

3.

/* условие выполнено и тест дает истину только если значение в буфере маски равно 1 */

8.3. Зеркальные отражения

109

glStencilFunc (GL_EQUAL, 0x1, Oxffffffff);

/* значение в буфере равно 2, если тень уже выведена */ glStencilOp (GL_KEEP, GL_KEEP, GL_INCR);

/* выводим тени */ RenderShadow ();

Строго говоря, даже при применении маскирования остают­ся некоторые проблемы, связанные с работой z-буфера. В част­ности, некоторые участки теней могут стать невидимыми. Для решения этой проблемы можно немного приподнять тени над плоскостью с помощью модификации уравнения, описывающего плоскость. Описание других методов выходит за рамки данного пособия.

8.3. Зеркальные отражения

В этом разделе мы рассмотрим алгоритм построения отра­жений от плоских объектов. Такие отражения придают боль­шую достоверность построенному изображению и их относитель­но легко реализовать.

Алгоритм использует интуитивное представление полной сце­ны с зеркалом как составленной из двух: «настоящей» и «вир­туальной»— находящейся за зеркалом. Следовательно, процесс рисования отражений состоит из двух частей: 1) визуализации обычной сцены и 2) построения и визуализации виртуальной. Для каждого объекта «настоящей» сцены строится его отражен­ный двойник, который наблюдатель и увидит в зеркале.

Для иллюстрации рассмотрим комнату с зеркалом на стене. Комната и объекты, находящиеся в ней, выглядят в зеркале так, как если бы зеркало было окном, а за ним была бы еще одна та­кая же комната с тем же объектами, но симметрично отражен­ными относительно плоскости, проведенной через поверхность




110 Глава 8. Графические алгоритмы на основе OFENGL

Рис. 8.1. Зеркальное отражение

зеркала.

Упрощенный вариант алгоритма создания плоского отраже­ния состоит из следующих шагов:

  1. Рисуем сцену как обычно, но без объектов-зеркал.

  2. Используя буфер маски, ограничиваем дальнейший вывод проекцией зеркала на экран.

  3. Визуализируем сцену, отраженную относительно плоскости зеркала. При этом буфер маски позволит ограничить вывод формой проекции объекта-зеркала.

Эта последовательность действий позволит получить убеди­тельный эффект отражения.

Рассмотрим этапы более подробно.

Сначала необходимо нарисовать сцену как обычно. Не бу­дем останавливаться на этом этапе подробно. Заметим только, что, очищая буферы OpenGL непосредственно перед рисовани­ем, нужно не забыть очистить буфер маски:

8.3. Зеркальные отражения

111

g 1С1 е а г (GL_COLOR_BUFFER_BEr | GL_DEPTH_BUFFTER_BrT | GL_STENCIL_BUFFER_Brr);

Во время визуализации сцены лучше не рисовать объекты, которые затем станут зеркальными.

На втором этапе необходимо ограничить дальнейший вывод проекцией зеркального объекта на экран.

Для этого настраиваем буфер маски и рисуем зеркало

glEnable (GL_STENCIL_TEST) ;

/* условие всегда выполнено и значение в буфере

будет равно 1*/ glStencilFunc(GL_ALWAYS, 1, 0); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

Render Mirror Object ();

В результате мы получили:

  • в буфере кадра — корректно нарисованная сцена, за исклю­чением области зеркала;

  • в области зеркала (там, где мы хотим видеть отражение) значение буфера маски равно 1.

На третьем этапе нужно нарисовать сцену, отраженную от­носительно плоскости зеркального объекта.

Сначала настраиваем матрицу отражения. Матрица отраже­ния должна зеркально отражать всю геометрию относительно плоскости, в которой лежит объект-зеркало. Ее можно получить, например, с помощью такой функции (попробуйте получить эту матрицу самостоятельно в качестве упражнения):

void reflectionmatrix ( GLfloat reflection_matrix [4] [4] ,

GLfloat plane_point [3] , Glfloat plane_normal [3])

{

GLfloat* p;

112 Глава 8. Графические алгоритмы на основе OFENGL

GLfloat* v; float pv;

GLfloat* p = ( Glfloat *) plane_point ; Glfloat* v = ( Glfloat *) plane_normal; float pv = p[0]*v[0] + p[l]*v[l] + p[2]*v[2];

reflect reflect reflect reflect

reflect reflect reflect reflect

reflect reflect reflect reflect

on _mat r on _mat r on _mat r on _mat r

on _mat r on _mat r on _mat r on _mat r

on _mat r on _mat r on _mat r on matr
2 * v[0] * v[0] * v[0] * v[l];

= 1 -= - 2

= - 2 * v[0


* v

:2];

= 2 * pv * v [0] ;

= - 2 * v[0] * v[l];
= 1- 2 * v[l] * v[l];

= - 2 * v[l] * v[2];

= 2 * pv * v [ 1 ] ;

= - 2 * v[0] * v[2];

= - 2 * v[l] * v[2];

= 1 - 2 * v[2] * v[2] ;

= 2 * pv * v [ 2 ] ;


reflection _ matrix reflection _ matrix reflection _ matrix reflection matrix

= 0

= 0

= 0

= 1

}

Настраиваем буфер маски на рисование только в областях, где значение буфера равно 1:

/* условие выполнено и тест дает истину

только если значение в буфере маски равно 1 */ glStencilFunc (GL_EQUAL, Oxl, Oxffffffff);

/* ничего не. меняем в буфере */ glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);

и рисуем сцену еще раз (без зеркальных объектов)

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

113

glPushMatrix ();

glMultMatrixf (( float *) reflection_matrix ) ;

RenderScene ();

glPopMatrix () ;

Наконец, отключаем маскирование: g 1D i s a b 1 e (GL_STENCIL_TEST);

После этого можно опционально еще раз вывести зеркальный объект, например, с альфа-смешением — для создания эффекта замутнения зеркала и т.д.

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

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

  • В результате чего возникает эффект ступенчатости изоб­ражения? Опишите алгоритм устранения ступенчатости.

  • Почему в OpenGL нет встроенной поддержки построения теней?

  • Кратко опишите предложенный метод визуализации зер­кальных объектов. Почему он не работает, если за зеркалом находятся другие объекты сцены? Что будет отражаться в этом случае? Подумайте, как обойти это ограничение?


Глава 9.

Оптимизация программ

9.1. Организация приложения

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

1   ...   11   12   13   14   15   16   17   18   ...   30


написать администратору сайта