Главная » Просмотр файлов » Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC)

Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366), страница 11

Файл №1124366 Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (Ю.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC)) 11 страницаЮ.М. Баяковский, А.В. Игнатенко - Начальный курс OpenGL (DOC) (1124366) страница 112019-05-11СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 11)

/* Делаем тени полупрозрачными с использованием

смешивания цветов(blending) */ glEnable (GL_BLEND) ;

glBlendFunc (GL_SRC_ALPHA,GL_ONE_MNUS_SRC_ALPHA); glDisable (GL_LIGHTING); glColor4f(0.0, 0.0, 0.0, 0.5); glPushMatrix ();

/* Проецируем тень */

glMultMatrixf ((GLfloat *) floorShadow);

/* Визуализируем сцену в проекции */

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

RenderGeometry (); glPopMatrix (); glEnable (GL_LIGHTING); glDisable(GL_BLEND);

Матрица floorShadow может быть получена из уравнения 8.1 с помощью следующей функции:

/* параметры:

plane — коэффициенты уравнения плоскости lightpos — координаты источника света возвращает: matrix — результирующая матрица

*/

void shadowmatrix( GLfloat matrix [4] [4] ,

GLfloat plane [4] , GLfloat lightpos [4])

{

GLfloat dot ;

dot = plane [0] * lightpos [0] +

plane[l] * lightpos [1] +

plane[2] * lightpos [2] +

plane [3] * lightpos [3];



atrix

ol [

atrix

11 [

atrix

21 [

atrix

3] [

atrix

ol f

atrix

11 [

atrix

21 [

atrix

3] [

atrix

ol f

atrix

11 [

atrix

21 [

atrix

31 f

0] = dot

0] = O.f

0] = O.f

01 = O.f

] = O.f dot O.f O.f

O.f O.f dot O.f

lightpos lightpos lightpos lightpos

lightpos lightpos lightpos lightpos

lightpos lightpos lightpos lightpos



*

plane

0]

*

plane

lj

*

plane

2J

*

plane

3J

*

plane

o]

*

plane

lj

*

plane

2J

*

plane

3J

*

plane

o]

*

plane

lj

*

plane

2J

*

plane

3|

8.2. Построение теней

107

matrix [0][3] = O.f - lightpos [3] * plane[0]

matrix[l][3] = O.f - lightpos [3] * plane [1]

matrix [2][3] = O.f - lightpos [3] * plane[2]

}


matrix [3][3] = dot - lightpos [3] * plane [3]

Заметим, что тени, построенные таким образом, имеют ряд недостатков:

  • Описанный алгоритм предполагает, что плоскости беско­нечны, и не отрезает тени по границе. Например, если неко­торый объект отбрасывает тень на стол, она не будет отсе­каться по границе, и, тем более, «заворачиваться» на боко­вую поверхность стола.

  • В некоторых местах теней может наблюдаться эффект «двойного смешивания» (rcblcnding), т.е. темные пятна в тех участках, где спроецированные треугольники перекры­вают друг друга.

  • С увеличением числа поверхностей сложность алгоритма резко увеличивается, т.к. для каждой поверхности нужно заново строить всю сцену, даже если проблема отсечения теней по границе будет решена.

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

Имеется решение первой и второй проблемы. Для этого ис­пользуется буфер маски (см. п. 7.2).

Итак, задача — отсечь вывод геометрии (тени) по границе некоторой произвольной области и избежать «двойного смеши-

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

вания». Общий алгоритм решения с использованием буфера мас­ки таков:

  1. очищаем буфер маски значением 0;

  2. отображаем заданную область отсечения, устанавливая значения в буфере маски в 1;

  3. рисуем тени в тех областях, где в буфере маски установ­лены значения; если тест проходит, устанавливаем в эти области значение 2.

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

/* очищаем буфер маски*/

glClearStencil(OxO)

glClear (GL_STENCIL_BUFFER_BIT);

/* включаем тест */

gl En able (GL_STENCIL_TEST);

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

= 1 -= - 2

= - 2 * v[0


2 * v[0] * v[0] * v[0] * v[l];

* 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, определяется в первую очередь производительностью реализации самой биб­лиотеки. Это верно, однако организация всего приложения так­же очень важна.

Характеристики

Тип файла
Документ
Размер
3,41 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6432
Авторов
на СтудИзбе
306
Средний доход
с одного платного файла
Обучение Подробнее