Файл: графическая библиотека opengl.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 09.06.2020

Просмотров: 1714

Скачиваний: 4

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 61

6.2. 

Буфер

-

накопитель

 

Буфер

-

накопитель

 

(

accumulation buffer

) – 

это

 

один

 

из

 

дополнительных

 

буферов

 OpenGL. 

В

 

нем

 

можно

 

сохранять

 

визуализированное

 

изображение

применяя

 

при

 

этом

 

попиксельно

 

специальные

 

операции

Буфер

-

накопитель

 

широко

 

используется

 

для

 

создания

 

различных

 

спецэффектов

Изображение

 

берется

 

из

 

буфера

выбранного

 

на

 

чтение

 

командой

  

void 

glReadBuffer

(enum 

buf

 

Аргумент

 

buf 

определяет

 

буфер

 

для

 

чтения

Значения

 

buf

равные

 

GL_BACK

GL_FRONT

определяют

 

соответствующие

 

буферы

 

цвета

 

для

 

чтения

GL_BACK

 

задает

 

в

 

качестве

 

источника

 

пикселей

 

внеэкранный

 

буфер

GL_FRONT

 – 

текущее

 

содержимое

 

окна

 

вывода

Команда

 

имеет

 

значение

если

 

используется

 

дублирующая

 

буферизация

В

 

противном

 

случае

 

используется

 

только

 

один

 

буфер

соответствующий

 

окну

 

вывода

  (

строго

 

говоря

, OpenGL 

имеет

 

набор

 

дополнительных

 

буферов

используемых

в

 

частности

для

 

работы

 

со

 

стереоизображениями

но

 

здесь

 

мы

 

их

 

рассматривать

 

не

 

будем

). 

Буфер

-

накопитель

 

является

 

дополнительным

 

буфером

 

цвета

Он

 

не

 

используется

 

непосредственно

 

для

 

вывода

 

образов

но

 

они

 

добавляются

 

в

 

него

 

после

 

вывода

 

в

 

один

 

из

 

буферов

 

цвета

Применяя

 

различные

 

операции

описанные

 

ниже

можно

 

понемногу

  «

накапливать

» 

изображение

 

в

 

буфере

Затем

 

полученное

 

изображение

 

переносится

 

из

 

буфера

-

накопителя

 

в

 

один

 

из

 

буферов

 

цвета

выбранный

 

на

 

запись

 

командой

 

void 

glDrawBuffer(

enum 

buf) 

 

Значение

 

buf

 

аналогично

   

значению

 

соответствующего

 

аргумента

 

в

 

команде

 

glReadBuffer

Все

 

операции

 

с

 

буфером

-

накопителем

 

контролируются

  

командой

 

void 

glAccum

(enum 

op

,GLfloat 

value

 

Аргумент

 

op 

задает

 

операцию

 

над

 

пикселями

 

и

 

может

 

принимать

 

следующие

 

значения


background image

 62

GL_LOAD

 

Пиксель

 

берется

 

из

 

буфера

выбранного

 

на

 

чтение

его

 

значение

 

умножается

 

на

 

value 

и

 

заносится

 

в

 

буфер

-

накопитель

GL_ACCUM

 

Аналогично

 

предыдущему

но

 

полученное

 

после

   

умножения

 

значение

 

складывается

 

с

 

уже

 

имеющимся

 

в

 

буфере

GL_MULT

 

Эта

 

операция

 

умножает

 

значение

 

каждого

 

пикселя

 

в

 

буфере

 

накопления

 

на

 

value 

GL_ADD

 

Аналогично

 

предыдущему

только

 

вместо

 

умножения

 

используется

 

сложение

GL_RETURN

 

Изображение

 

переносится

 

из

 

буфера

 

накопителя

 

в

 

буфер

выбранный

 

для

 

записи

Перед

 

этим

 

значение

 

каждого

 

пикселя

 

умножается

 

на

 

value. 

Следует

 

отметить

что

 

для

 

использования

 

буфера

-

накопителя

 

нет

 

необходимости

 

вызывать

 

какие

-

либо

 

команды

 

glEnable

Достаточно

 

инициализировать

 

только

 

сам

 

буфер

.  

Пример

 

использования

 

буфера

-

накопителя

 

для

 

устранения

 

погрешностей

 

растеризации

 (

ступенчатости

приведен

 

в

 

разделе

 7.1 

6.3. 

Буфер

 

маски

 

При

 

выводе

 

пикселей

 

в

 

буфер

 

кадра

 

иногда

 

возникает

 

необходимость

 

выводить

 

не

 

все

 

пиксели

а

 

только

 

некоторое

 

подмножество

т

.

е

наложить

 

трафарет

  (

маску

на

 

изображение

Для

 

этого

 OpenGL 

предоставляет

 

так

 

называемый

 

буфер

 

маски

 (stencil 

buffer). 

Кроме

 

наложения

 

маски

этот

 

буфер

 

предоставляет

 

еще

 

несколько

 

интересных

 

возможностей

.  

Прежде

 

чем

 

поместить

 

пиксель

 

в

 

буфер

 

кадра

механизм

 

визуализации

 OpenGL 

позволяет

 

выполнить

 

сравнение

  (

тест

между

 

заданным

 

значением

 

и

 

значением

 

в

 

буфере

 

маски

Если

 

тест

 

проходит

пиксель

 

рисуется

 

в

 

буфере

 

кадра

.  

Механизм

 

сравнения

 

весьма

 

гибок

 

и

 

контролируется

 

следующими

 

командами

:

 

void

 

glStencilFunc

 (

enum

 

func

int

 

ref

uint

 

mask

)  

void

 

glStencilOp 

(

enum

 

sfail

enum

 

dpfail

enum

 

dppass

)  

 


background image

 63

Аргумент

 

ref

 

команды

 

glStencilFunc

 

задает

 

значение

 

для

 

сравнения

Он

 

должен

 

принимать

 

значение

 

от

 0 

до

 2

–1. s – 

число

 

бит

 

на

 

точку

 

в

 

буфере

 

маски

С

 

помощью

 

аргумента

 

func

 

задается

 

функция

 

сравнения

Он

 

может

 

принимать

 

следующие

 

значения

GL_NEVER

 

тест

 

никогда

 

не

 

проходит

т

.

е

всегда

 

возвращает

 false 

GL_ALWAYS

 

тест

 

проходит

 

всегда

GL_LESS, GL_LEQUAL, GL_EQUAL,  

GL_GEQUAL, GL_GREATE, GL_NOTEQUAL

   

тест

 

проходит

 

в

 

случае

если

 

ref

 

соответственно

 

меньше

 

значения

 

в

 

буфере

 

маски

меньше

 

либо

 

равен

равен

больше

больше

 

либо

 

равен

или

 

не

 

равен

Аргумент

 

mask

 

задает

 

маску

 

для

 

значений

Т

.

е

в

 

итоге

 

для

 

этого

 

теста

 

получаем

 

следующую

 

формулу

: ((

ref

 AND 

mask

op

 (svalue AND 

mask

)) 

Команда

 

glStencilOp

 

предназначена

 

для

 

определения

 

действий

 

над

 

пикселем

 

буфера

 

маски

 

в

 

случае

 

положительного

 

или

 

отрицательного

 

результата

 

теста

Аргумент

 

sfail

 

задает

 

действие

 

в

 

случае

 

отрицательного

 

результата

 

теста

и

 

может

 

принимать

 

следующие

 

значения

GL_KEEP, GL_ZERO, GL_REPLACE, 

GL_INCR, GL_DECR, GL_INVERT

 

соответственно

 

сохраняет

 

значение

 

в

 

буфере

 

маски

обнуляет

 

его

заменяет

 

на

 

заданное

 

значение

  (

ref

), 

увеличивает

уменьшает

 

или

 

побитово

 

инвертирует

.  

Аргументы

 

dpfail

 

определяют

 

действия

 

в

 

случае

 

отрицательного

 

результата

 

теста

 

на

 

глубину

 

в

 z-

буфере

а

 

dppass

 

задает

 

действие

 

в

 

случае

 

положительного

 

результата

 

этого

 

теста

Аргументы

 

принимают

 

те

 

же

 

значения

что

 

и

 

аргумент

 

sfail

По

 

умолчанию

 

все

 

три

 

параметра

 

установлены

 

на

 

GL_KEEP

Для

 

включения

 

маскирования

 

необходимо

 

выполнить

 

команду

 

glEnable(GL_STENCIL_TEST);

 

Буфер

 

маски

 

используется

 

при

 

создании

 

таких

 

спецэффектов

как

 

падающие

 

тени

отражения

плавные

 

переходы

 

из

 

одной

 

картинки

 

в

 

другую

 

и

 

пр


background image

 64

Пример

 

использования

 

буфера

 

маски

 

при

 

построении

 

теней

 

и

 

отражений

 

приведен

 

в

 

разделах

 7.3 

и

 7.2.  

6.4. 

Управление

 

растеризацией

 

Способ

 

выполнения

 

растеризации

 

примитивов

 

можно

 

частично

 

регулировать

 

командой

 

glHint (target, mode)

где

 

target

 – 

вид

 

контролируемых

 

действий

принимает

 

одно

 

из

 

следующих

 

значений

 

GL_FOG_HINT

 – 

точность

 

вычислений

 

при

 

наложении

 

тумана

Вычисления

 

могут

 

выполняться

 

по

 

пикселям

 

(

наибольшая

 

точность

или

 

только

 

в

 

вершинах

Если

 

реализация

 OpenGL 

не

 

поддерживает

 

попиксельного

 

вычисления

то

 

выполняется

 

только

 

вычисление

 

по

 

вершинам

GL_LINE_SMOOTH_HINT

 – 

управление

 

качеством

 

прямых

При

 

значении

 mode, 

равным

 

GL_NICEST

уменьшается

 

ступенчатость

 

прямых

 

за

 

счет

 

большего

 

числа

 

пикселей

 

в

 

прямых

GL_PERSPECTIVE_CORRECTION_HINT

 – 

точность

 

интерполяции

 

координат

 

при

 

вычислении

 

цветов

 

и

 

наложении

 

текстуры

Если

 

реализация

 OpenGL 

не

 

поддерживает

 

режим

 

GL_NICEST

то

 

осуществляется

 

линейная

 

интерполяция

 

координат

GL_POINT_SMOOTH_HINT

 – 

управление

 

качеством

 

точек

При

 

значении

 

параметра

 mode 

равным

 

GL_NICEST

 

точки

 

рисуются

 

как

 

окружности

GL_POLYGON_SMOOTH_HINT

 – 

управление

 

качеством

 

вывода

 

сторон

 

многоугольника

Параметра

 

mode

 

интерпретируется

 

следующим

 

образом

GL_FASTEST

 - 

используется

 

наиболее

 

быстрый

 

алгоритм

GL_NICEST

 - 

используется

 

алгоритм

обеспечивающий

 

лучшее

 

качество

GL_DONT_CARE

  - 

выбор

 

алгоритма

 

зависит

 

от

 

реализации

Важно

 

заметить

что

 

командой

 

glHint() 

программист

 

может

 

только

 

определить

 

свои

 

пожелания

 

относительно

 

того

 

или

 

иного

 

аспекта

 

растеризации

 

примитивов

Конкретная

 

реализация

 OpenGL 

вправе

 

игнорировать

 

данные

 

установки


background image

 65

Обратите

 

внимание

что

 

glHint()

 

нельзя

 

вызывать

 

между

 

операторными

 

скобками

 

glBegin()/glEnd()

Контрольные

 

вопросы

 

1. 

Какие

 

буферы

 

изображений

 

используются

 

в

 OpenGL 

и

 

для

 

чего

2. 

Для

 

чего

 

используется

 

команда

 glBlendFunc? 

3. 

Почему

 

для

 

корректного

 

вывода

 

прозрачных

 

объектов

 

требуется

 

соблюдение

 

условий

 

упорядоченного

 

вывода

 

примитивов

 

с

 

прозрачностью

4. 

Для

 

чего

 

используется

 

буфер

-

накопитель

Приведите

 

пример

 

работы

 

с

 

ним

5. 

Как

 

в

 OpenGL 

можно

 

наложить

 

маску

 

на

 

результирующее

 

изображение

6. 

Объясните

для

 

чего

 

применятся

 

команда

 glHint().  

7. 

Каков

 

эффект

 

выполнения

 

команды

 

glHint(

GL_FOG_HINT, 

GL_DONT_CARE)?