Расширения EXT_texture_env_combine и ARB_texture_env_combine в OpenGL
Стандартный OpenGL поддерживает следующие способы наложения текстуры - GL_REPLACE, GL_BLEND, GL_DECAL и GL_MODULATE.
Ниже приводится таблица, объясняющая действие этих режимов.
Таблица 1.
Число компонент | GL_REPLACE | GL_MODULATE | GL_DECAL | GL_BLEND |
1 | ... | Cv=At*Cf | Неопределено | Cv=(1-At)*Cf+At*Cc Av=Af |
3 | Cv=Ct Av=Af | Cv=Cf*Ct Av=Af | Cv=Ct Av=Af | Неопределено |
4 | Cv=Ct Av=At | Cv=Cf*Ct Av=Af*At | Cv=(1-At)*Cf+At*Ct Av=Af | Неопределено |
Здесь используются следующие обозначения:
C - RGB-значение
A - альфа-значение
f - значение RGB или альфа, получаемое из фрагмента, на который
осуществляется наложение (значение, получаемое в результате
вычисления освещенности или задаваемое командой glColor, в
случае, когда расчет освещенности выключен)
t - значение RGB или альфа, получаемое из текстуры
c - значение RGB или альфа, заданное GL_TEXTURE_ENV_COLOR
Однако для получения реалистических изображений в реальном времени этих способов наложения часто
бывает недостаточно. Расширение texture_env_add, рассмотренное ранее предоставляет еще один режим -
GL_ADD.
Но желательно получить возможность задавать достаточно сложные режимы наложения, не входящие в число
указанных выше.
Именно такую возможность и дает использование расширений ARB_texture_env_combine и
EXT_texture_env_combine.
Эти расширения позволяют получать режимы наложения текстуры довольно общего вида, причем раздельно
для цветовых компонент (RGB) и для альфа-канала (alpha).
Для проверки его поддержки следует использовать один из следующих вызовов
isExtensionSupported ( "GL_ARB_texture_env_combine" )
isExtensionSupported ( "GL_EXT_texture_env_combine" )
Данные расширения не вводят новых функций, но добавляют целый набор новых констант.
Данные расширения позволяют задавать один из следующих режимов наложения (отдельно для цветовых
компонент и отдельно для альфа-компоненты):
Таблица 2.
Тип | Формула наложения |
GL_REPLACE | Arg0 |
GL_MODULATE | Arg0 * Arg1 |
GL_ADD | Arg0 + Arg1 |
GL_SIGNED_ADD_ARB | Arg0 + Arg1 - 0.5 |
GL_SUBTRACT_ARB | Arg0 - Arg1 |
GL_INTERPOLATE_ARB | Arg0*Arg2 + Arg1*(1-Arg2) |
Для получения операндов Arg0, Arg1 и Arg2 может использоваться
один из следующих источников:
Таблица 3.
Константа | Соответствующий источник |
GL_PRIMARY_COLOR_ARB | Основной цвет фрагмента (Cf, Af) |
GL_TEXTURE | Цвет текстуры (Ct, At) |
GL_CONSTANT_ARB | Цвет, заданный при помощи glTexEnfv |
GL_PREVIOUS_ARB | Результат предыдущей операции, для первого текстурного блока эквивалентен GL_PRIMARY_COLOR_ARB |
Поскольку RGB- и альфа-компоненты для операндов Arg0, Arg1 и Arg2 задаются независимо, то цвет и
альфа-значение могут браться из разных источников.
Кроме того, для каждого из операндов (и из RGB- и альфа-частей этих операндов), можно задать
используется в качестве соответствующего операнда само исходное значение (в соответствии
с таблицей 3)(т.е. С или alpha) или же его дополнение до единицы (т.е. 1 - С или 1 - alpha соответственно).
Также можно умножить результат операции (отдельно для цветовых компонент и отдельно для альфа-компоненты)
на множитель, равный 2 или 4.
Рассмотрим теперь подробнее задание всех этих параметров.
Сначала задается режим наложения GL_COMBINE_ARB -
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
Далее следует задать закон наложения отдельно для RGB части и отдельно для альфа-части.
Задание закона наложения осуществляется следующей командой:
glTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, expr );
для цветовой части и
glTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, expr );
для ее альфа-части.
Параметр expr задает используемый закон наложения и принимает одно из значений, перечисленных в таблице 2.
Далее следует для каждого из используемых операндов (Arg0, Arg1 и Arg2) (и его части - цветовой и альфа)
задать его источник и способ получения.
Для задания того, откуда следует взять соответствующую часть операнда служит следующий вызов:
glTexEnvi ( GL_TEXTURE_ENV, operand, expr );
Здесь параметр operand задает как сам операнд (его номер - 0, 1, 2), так и его часть (цветовую или альфа)
и принимает одно из следующих значений:
Таблица 4.
Операнд | Смысл |
GL_SOURCE0_RGB_ARB | Цветовая часть для операнда Arg0 |
GL_SOURCE0_ALPHA_ARB | Альфа часть для операнда Arg0 |
GL_SOURCE1_RGB_ARB | Цветовая часть для операнда Arg1 |
GL_SOURCE1_ALPHA_ARB | Альфа часть для операнда Arg1 |
GL_SOURCE2_RGB_ARB | Цветовая часть для операнда Arg2 |
GL_SOURCE2_ALPHA_ARB | Альфа часть для операнда Arg2 |
Параметр expr задает источник для получения соответствующего операнда и принимает одно
из значений из таблицы 3.
После этого следует задать способ получения операнда из данного источника -
glTexEnvi ( GL_TEXTURE_ENV, operand, method );
Параметр operand задается таблицей 5. Способ получения соответствующего операнда
из источника определяется параметром method, возможные значения для которого перечислены в
таблице 6.
Таблица 5.
Значение | Компонент | Операнд |
GL_OPERAND0_RGB_ARB | RGB | Arg0 |
GL_OPERAND0_ALPHA_ARB | Alpha | Arg0 |
GL_OPERAND1_RGB_ARB | RGB | Arg1 |
GL_OPERAND1_ALPHA_ARB | Alpha | Arg1 |
GL_OPERAND2_RGB_ARB | RGB | Arg2 |
GL_OPERAND2_ALPHA_ARB | Alpha | Arg2 |
Таблица 6.
Значение | Смысл |
GL_SRC_COLOR | C |
GL_ONE_MINUS_SRC_COLOR | 1 - C |
GL_SRC_ALPHA | alpha |
GL_ONE_MINUS_SRC_ALPHA | 1 - alpha |
Обратите внимание, что для RGB-канала в качестве источника можно взять как RGB-канал, так и
alpha-канал. В этом случае все цветовые компоненты будут равны значению alpha.
После того, как все используемые части всех используемых операндов будут заданы, можно задать
числовой множитель, на который следует умножить получаемый результат.
Как уже говорилось, данный множитель задается отдельно для цветовой и альфа-частей.
Для его задания служит вызов:
glTexEnvi ( GL_TEXTURE_ENV, component, constant );
Здесь параметр component задает какую именно часть результата следует умножить, а параметр
constant - коэффициент умножения.
Параметр component принимает одно из следующих двух значений - GL_RGB_SCALE_ARB и GL_ALPHA_SCALE_ARB.
Рассмотрим несколько простых примеров.
Пример. Пусть мы хотим смешать две текстуры t1 и t2 исползуя alpha-канал первой текстуры (t1)
в качестве веса, т.е. результирующий цвет будет задаваться следующей формулой:
C = C(t1)*A(t1) + C(t2)*(1-A(t1))
Примером использования такого закона может быть наложения environment mapping'а на поверхность текстурой,
alpha-канал текстуры определяет силу отржения на поврехности в точке.
В данном случае естественным режимом для наложения цветовых компонент является GL_INTERPOLATE_ARB, где
Arg0 и Arg1 выступают RGB-части текстур t1 и t2, а в качестве Arg2 выступает alpha-канал текстуры t1.
Нам понадобятся два текстурных блока для размещения исходных текстур (что позволит осуществить вывод
за один проход).
В нулевом текстурном блоке мы разместим текстуру t1 и зададим закон ее вывода как GL_REPLACE.
В результате после ее вывода мы получим саму текстуру, которую можно получить как результат предыдущей операции
(GL_PREVIOUS_ARB).
glActiveTextureARB ( GL_TEXTURE0_ARB );
glBindTexture ( GL_TEXTURE_2D, t1 );
В первом текстурном блоке мы разместим текстуру t2. Для ее вывода мы используем закон наложения
GL_INTERPOLATE_ARB для цветовых компонент и REPLACE для alpha-канала.
При этом для вывода цветовых компонент в качестве Arg0 будет выступать результат предыдущей операции
(GL_PREVIOUS_ARB), в качестве Arg1 выступает сама текстура (GL_TEXTURE), а в качестве Arg2 следует
взять alpha-канал из текстуры t1, т.е. GL_PREVIOUS_ARB.
Таким образом мы приходим к следующему фрагменту кода:
glActiveTextureARB ( GL_TEXTURE1_ARB );
glBindTexture ( GL_TEXTURE_2D, t2 );
glTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
glTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
glTexEnvi ( GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE );
// now setup Arg0
glTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB );
glTexEnvi ( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
// now setup Arg1
glTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE );
glTexEnvi ( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
// now setup Arg2
glTexEnvi ( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PREVIOUS_ARB );
glTexEnvi ( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA );
В данном случае использование мультитекстурирования повзоляет за один проход осуществить вывод объекта
с данным законом наложения.
Рис 1. Пример использования мультитекстурирования.
Исходный код к этому примеру можно скачать здесь.
Дополнительную информацию по данным расширениям можно найти на
OpenGL Extension Registry
Хороший рассказ об этом расширении можно найти на
www.gamedev.ru.
|