Чтение онлайн

на главную - закладки

Жанры

Программирование на Visual C++. Архив рассылки

Jenter Алекс

Шрифт:

Применяя различные операции, описанные ниже, можно как бы понемногу накапливать изображение в буфере.

Затем картинка переносится из буфера накопления в буфер, выбранный на запись командой

void glDrawBuffer(enum buf)

Значение buf аналогично значению соответствующего аргумента в команде glReadBuffer.

Все операции с буфером накопления контролируются командой

void glAccum(enum op, GLfloat value)

Аргумент op задает операцию над пикселями и может принимать следующие значения:

GL_LOAD Пиксель
выбирается из буфера, выбранного на чтение, его значение умножается на value и заносится в буфер накопления.
GL_ACCUM Аналогично предыдущему, но полученное после умножения значение складывается с уже имеющимся в буфере.
GL_MULT Эта операция умножает значение каждого пикселя в буфере накопления на value.
GL_ADD Аналогично предыдущему, только вместо умножения используется сложение.
GL_RETURN Изображение переносится из буфера накопления в буфер, выбранный для записи. Перед этим значение каждого пикселя умножается на value.

Для использования буфера накопления нет необходимости вызывать какие-либо команды glEnable. Достаточно только иметь сам буфер.

В качестве примера использования буфера накопления рассмотрим задачу устранения лестничного эффекта (antialiasing).

Алгоритм ее решения сразу для всей сцены таков:

Для каждого кадра выводим сцену несколько раз, каждый раз немного смещая камеру относительно начального положения (положения камер, например, могут образовывать окружность). Все сцены сохраняем в буфере накопления с коэффициентом 1/n, где n – число сцен для каждого кадра. Чем больше таких сцен (antialiasing samples) – тем хуже производительность, но лучше качество.

for (i=0; i<samples_count; ++i)

/* обычно samples_count лежит в пределах от 5 до 10 */

{

 ShiftCamera(i); /* сдвигаем камеру */

 RenderScene;

 if (i==0)

/* на первой итерации загружаем изображение */

glAccum(GL_LOAD, 1/(float)samples_count);

 else

/* добавляем к уже существующему */

glAccum(GL_ADD, 1/(float)samples_count);

}

/* Пишем то, что получилось, назад в исходный буфер */

glAccum(GL_RETURN, 1.0);

ПРИМЕЧАНИЕ

Буфер накопления редко реализуется аппаратно. Поэтому использование устранения ступенчатости сразу для всей сцены практически несовместимо с визуализацией динамических изображений с приемлемой частотой вывода кадров (frame rate).

Трафаретный буфер

При выводе пикселей в буфер кадра иногда возникает необходимость выводить

не все пиксели, а только некоторое их подмножество, т.е. как бы наложить трафарет на изображение. Для этого OpenGL предоставляет так называемый трафаретный буфер (stencil buffer). Кроме наложения трафарета, этот буфер предоставляет еще несколько интересных возможностей.

Прежде чем поместить пиксель в буфер кадра, механизм визуализации OpenGL позволяет выполнить сравнение (тест) между заданным значением и значением в трафаретном буфере. Если тест проходит, пиксель визуализируется в буфере кадра.

Механизм сравнения контролируется следующими командами:

void glStencilFunc(enum func, int ref, uint mask)

void glStencilOp(enum sfail, enum dpfail, enum dppass)

Аргумент ref команды StencilFunc задает значение для сравнения. Он должен принимать значение от 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 ))

Команда StencilOp предназначена для определения действий над пикселем трафаретного буфера в случае положительного или отрицательного результата теста.

Аргумент sfail задает действие в случае отрицательного результата теста, и может принимать следующие значения:

GL_KEEP, GL_ZERO, GL_REPLACE, GL_INCR, GL_DECR, GL_INVERT соответственно сохраняет значение в трафаретном буфере, обнуляет его, заменяет на заданное значение (ref), увеличивает, уменьшает или побитово инвертирует.

Аргументы dpfail определяют действия в случае отрицательного результата теста на глубину в z-буфере. dppass задает действие в случае положительного результата этого теста. Аргументы принимают те же значения, что и аргумент sfail. По умолчанию все три параметра установлены на GL_KEEP.

Для включения трафаретного теста необходимо выполнить команду glEnable(GL_STENCIL_TEST);

Трафаретный тест используется при создании таких спецэффектов, как тени, отражения, плавные переходы из одной картинки в другую, создания конструктивной геометрии (CSG) и др.

Пример использования трафаретного теста при создании теней описан в Приложении.

[Текст "Приложения" к сожалению не влезает даже в расширенный выпуск и всех интересующихся отсылаю к оригиналу статьи на RSDN.] 

Поделиться:
Популярные книги

Черный дембель. Часть 5

Федин Андрей Анатольевич
5. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 5

30 сребреников

Распопов Дмитрий Викторович
1. 30 сребреников
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
30 сребреников

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Охота на разведенку

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
6.76
рейтинг книги
Охота на разведенку

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Возвышение Меркурия. Книга 4

Кронос Александр
4. Меркурий
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Возвышение Меркурия. Книга 4

Надуй щеки! Том 3

Вишневский Сергей Викторович
3. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 3

Идеальный мир для Лекаря 16

Сапфир Олег
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 16

По воле короля

Леви Кира
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
По воле короля

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»