Главная -
Статьи -
Проекты -
Ссылки -
Скачать -
Из гельминтов -
Юмор, приколы -
Почитать -
Обо мне -
Мысли -
Гостевая -

Расширения EXT_texture_env_combine и ARB_texture_env_combine в OpenGL

Стандартный OpenGL поддерживает следующие способы наложения текстуры - GL_REPLACE, GL_BLEND, GL_DECAL и GL_MODULATE.

Ниже приводится таблица, объясняющая действие этих режимов.

Таблица 1.
Число компонентGL_REPLACEGL_MODULATEGL_DECALGL_BLEND
1...Cv=At*CfНеопределеноCv=(1-At)*Cf+At*Cc
Av=Af
3Cv=Ct
Av=Af
Cv=Cf*Ct
Av=Af
Cv=Ct
Av=Af
Неопределено
4Cv=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_REPLACEArg0
GL_MODULATEArg0 * Arg1
GL_ADDArg0 + Arg1
GL_SIGNED_ADD_ARBArg0 + Arg1 - 0.5
GL_SUBTRACT_ARBArg0 - Arg1
GL_INTERPOLATE_ARBArg0*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_ARBRGBArg0
GL_OPERAND0_ALPHA_ARBAlphaArg0
GL_OPERAND1_RGB_ARBRGBArg1
GL_OPERAND1_ALPHA_ARBAlphaArg1
GL_OPERAND2_RGB_ARBRGBArg2
GL_OPERAND2_ALPHA_ARBAlphaArg2

Таблица 6.
ЗначениеСмысл
GL_SRC_COLORC
GL_ONE_MINUS_SRC_COLOR1 - C
GL_SRC_ALPHAalpha
GL_ONE_MINUS_SRC_ALPHA1 - 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    );

В данном случае использование мультитекстурирования повзоляет за один проход осуществить вывод объекта с данным законом наложения.

Результат использования расширения texture_env_combine

Рис 1. Пример использования мультитекстурирования.

Исходный код к этому примеру можно скачать здесь.

Дополнительную информацию по данным расширениям можно найти на OpenGL Extension Registry

Хороший рассказ об этом расширении можно найти на www.gamedev.ru.


Copyright © 2003-2004 Алексей В. Боресков

Используются технологии uCoz