Программирование на Visual C++. Архив рассылки
Шрифт:
В этих формулах z обозначает расстояние от точки, в которой вычисляется интенсивность тумана, до точки наблюдения.
Коэффициенты d, e, s задаются с помощью следующих значений аргумента pname
GL_FOG_DENSITY | param определяет коээфициент d |
GL_FOG_START | param определяет коэффициент s |
GL_FOG_END | param определяет коэффициент e |
Цвет тумана задается с помощью аргумента pname, равного
GL_FOG_COLOR | в
|
Пример:
Прозрачность позволяет использовать полупрозрачные объекты в сцене, что может значительно повысить реалистичность изображения.
В OpenGL прозрачность реализуется с помощью специального режима смешения цветов (blending). Алгоритм смешения комбинирует цвета входящих пикселей (RGBA) с цветами соответствующих пикселей, уже хранящихся в буфере кадра.
Режим включается с помощью команды glEnable(GL_BLEND).
Определить параметры смешения можно с помощью команды:
Параметр src определяет, как получить коэффициент k1 исходного цвета пикселя, a dst определяет способ получения коэффициента k2 для цвета в буфере кадра. Для получения результирующего цвета используется следующая формула: res=с*k1+c*k2, где с – цвет исходного пикселя, c – цвет пикселя в буфере кадра. (res, k1, k2, с c – векторы!).
Приведем наиболее часто используемые значения агрументов src и dst.
GL_SRC_ALPHA | k=(A,A,A,A) |
GL_SRC_ONE_MINUS_ALPHA | k=(1,1,1,1)-(A,A,A,A) |
GL_DST_COLOR | k=(R,G,B) |
GL_ONE_MINUS_DST_COLOR | k=(1,1,1,1) - (R,G,B) |
GL_DST_ALPHA | k=(A,A,A,A) |
GL_DST_ONE_MINUS_ALPHA | k=(1,1,1,1)-(A,A,A,A) |
GL_SRC_COLOR | k=(R,G,B) |
GL_ONE_MINUS_SRC_COLOR | k=(1,1,1,1)- (R,G,B) |
Пример:
Предположим, мы хотим реализовать вывод прозрачных объектов. Коэффициент прозрачности задается alpha-компонентой цвета. alpha, равное 1 – непрозрачный объект; равное 0 – невидимый. Для реализации служит следующий код:
ПРИМЕЧАНИЕ
В случае наличия в сцене нескольких прозрачных объектов, которые могут перекрывать друг друга, корректный вывод можно гарантировать только в случае выполнения следующих условий:
Все прозрачные объекты выводятся после непрозрачных.
При выводе объекты с прозрачностью должны быть упорядочены по уменьшению глубины, т.е. выводиться начиная с наиболее отдаленных.
Как уже говорилось, в OpenGL команды обрабатываются в порядке их поступления, поэтому для реализации перечисленных требований достаточно расставить в соответствующем порядке вызовы команд glVertex...
Буфер накопления (accumulation buffer) – это дополнительный внутренний буфер OpenGL. В нем можно сохранять визуализированное изображение, применяя при этом попиксельно специальные операции.
Изображение берется из буфера, выбранного на чтение командой
Аргумент buf
определяет буфер для чтения. Значения buf, равные GL_BACK, GL_FRONT, определяют соответствующие буфера для чтения.Применяя различные операции, описанные ниже, можно как бы понемногу накапливать изображение в буфере.
Затем картинка переносится из буфера накопления в буфер, выбранный на запись командой
Значение buf аналогично значению соответствующего аргумента в команде glReadBuffer.
Все операции с буфером накопления контролируются командой
Аргумент op задает операцию над пикселями и может принимать следующие значения:
GL_LOAD | Пиксель выбирается из буфера, выбранного на чтение, его значение умножается на value и заносится в буфер накопления. |
GL_ACCUM | Аналогично предыдущему, но полученное после умножения значение складывается с уже имеющимся в буфере. |
GL_MULT | Эта операция умножает значение каждого пикселя в буфере накопления на value. |
GL_ADD | Аналогично предыдущему, только вместо умножения используется сложение. |
GL_RETURN | Изображение переносится из буфера накопления в буфер, выбранный для записи. Перед этим значение каждого пикселя умножается на value. |
Для использования буфера накопления нет необходимости вызывать какие-либо команды glEnable. Достаточно только иметь сам буфер.
В качестве примера использования буфера накопления рассмотрим задачу устранения лестничного эффекта (antialiasing).
Алгоритм ее решения сразу для всей сцены таков:
Для каждого кадра выводим сцену несколько раз, каждый раз немного смещая камеру относительно начального положения (положения камер, например, могут образовывать окружность). Все сцены сохраняем в буфере накопления с коэффициентом 1/n, где n – число сцен для каждого кадра. Чем больше таких сцен (antialiasing samples) – тем хуже производительность, но лучше качество.
ПРИМЕЧАНИЕ
Буфер накопления редко реализуется аппаратно. Поэтому использование устранения ступенчатости сразу для всей сцены практически несовместимо с визуализацией динамических изображений с приемлемой частотой вывода кадров (frame rate).
При выводе пикселей в буфер кадра иногда возникает необходимость выводить не все пиксели, а только некоторое их подмножество, т.е. как бы наложить трафарет на изображение. Для этого OpenGL предоставляет так называемый трафаретный буфер (stencil buffer). Кроме наложения трафарета, этот буфер предоставляет еще несколько интересных возможностей.