Опубликован: 08.07.2007 | Доступ: свободный | Студентов: 1364 / 144 | Оценка: 4.43 / 4.02 | Длительность: 13:47:00
Специальности: Программист
Лекция 4:

Полупрозрачность. Цветовой ключ. Буфер трафарета

< Лекция 3 || Лекция 4: 12345 || Лекция 5 >

Цветовой ключ

В библиотеке Direct3D имеется функция D3DXCreateTextureFromFileEx(), которая позволяет задать так называемый цветовой ключ ( color key ). Механизм цветового ключа заключается в том, что оговаривается заданный цвет, который становится прозрачным при выводе текстуры на некоторую поверхность. Данная функция имеет 14 параметров, но нам для рассмотрения примера потребуется всего 4, для остальных параметров зададим значения по умолчанию. Первый параметр функции представляет собой указатель на устройство вывода, второй содержит имя загружаемого графического файла текстуры, одиннадцатый параметр и представляет собой цветовой ключ в формате ARGB, причем значение альфа составляющей должно обязательно быть 255, и последний параметруказатель на переменную, в которую будет возвращен результат вызова. Ниже приведен пример вызова этой функции.

C++
D3DXCreateTextureFromFileEx(device, "tree.bmp", D3DX_DEFAULT,       
                        D3DX_DEFAULT, D3DX_DEFAULT, 0,
                        D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
                        D3DX_DEFAULT, D3DX_DEFAULT, 
                    D3DCOLOR_ARGB(255,0,0,0), NULL, NULL, &tex);
Pascal
D3DXCreateTextureFromFileEx(device, 'tree.bmp', D3DX_DEFAULT,       
                        D3DX_DEFAULT, D3DX_DEFAULT, 0,
                        D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
                        D3DX_DEFAULT, D3DX_DEFAULT, 
                        D3DCOLOR_ARGB(255,0,0,0), nil, nil, tex);

После загрузки текстуры с цветовым ключом необходимо включить режим полупрозрачности и выставить необходимые параметры смешивания цветов:

device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

Ниже приведен пример вывода текстуры, в которой в качестве цветового ключа объявлен черный цвет. Вывод специально производится на другую текстуру, чтобы продемонстрировать работу механизма цветовых ключей в действии.


Буфер трафарета

Библиотека Direct3D располагает средствами работы с так называемым буфером трафарета. Буфер трафарета представляет собой двумерный массив с размерами как у буфера кадра и z-буфера, причем пиксель с координатами (x,y) в буфере трафарета будет соответствовать пикселю с такими же координатами в буфере кадра. Буфер трафарета работает как маска (трафарет), позволяя нам блокировать вывод некоторых пикселей на экран по заданному правилу. Принцип работы с буфером трафарета – это, как правило, двухпроходный алгоритм. Сначала мы разбиваем область вывода на зоны и каждой зоне присваиваем номер, при этом ничего не выводится на экран. Затем на основании некоторого установленного правила, мы производим непосредственный вывод сцены на экран, причем одни зоны могут быть выведены, другие нет.

По умолчанию тест трафарета выключен (заблокирован). Чтобы его включить необходимо установить значение переменной D3DRS_STENCILENABLE в true. Программно это выглядит следующим образом:

C++
device->SetRenderState( D3DRS_STENCILENABLE, true ); // включение
device->SetRenderState( D3DRS_STENCILENABLE, false ); // выключение
Pascal
device.SetRenderState( D3DRS_STENCILENABLE, 1 ); // включение
device.SetRenderState( D3DRS_STENCILENABLE, 0 ); // выключение

Очистка буфера трафарета осуществляется с помощью вызова метода Clear интерфейса IDirect3DDevice9, который использовался нами и для очистки буфера кадра.

C++
device->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_STENCIL,             
                         D3DCOLOR_XRGB(255,255,255), 0.0f, 0 );
Pascal
device.Clear( 0, nil, D3DCLEAR_TARGET or D3DCLEAR_STENCIL,
                       D3DCOLOR_XRGB(255,255,255), 0.0, 0 );

Добавленная константа (D3DCLEAR_STENCIL) в третий аргумент метода указывает, что мы собираемся очищать еще и буфер трафарета. А последний параметр метода (в нашем случае он ноль) определяет значение, которым будет заполнен буфер трафарета.

В силу того, что буфер трафарета может работать только совместно с буфером глубины, нам придется сказать несколько слов и о нем. Буфер глубины или z-буфер – это вспомогательный "экран" необходимый для удаления невидимых наблюдателю граней и поверхностей. Буфер глубины представляет собой двумерный массив, хранящий z-координаты каждого пикселя. Программно буфер глубины может быть инициализирован с помощью заполнения двух полей структуры D3DPRESENT_PARAMETERS:

C++
D3DPRESENT_PARAMETERS params;
…
ZeroMemory( &params, sizeof(params) );
…
params.EnableAutoDepthStencil = true;
params.AutoDepthStencilFormat = D3DFMT_D16;
…
Pascal
var
params: TD3DPresentParameters;
…
ZeroMemory( @params, SizeOf(params) );
…
params.EnableAutoDepthStencil := true;
params.AutoDepthStencilFormat := D3DFMT_D16;
…

Установка поля EnableAutoDepthStencil в значение true разрешает работы с буферами глубины и трафарета. Поле AutoDepthStencilFormat задает их формат. В приведенном выше примере задается формат только для буфера глубины, который имеет 16-ти битный формат памяти.

Буфер трафарета может быть создан в тот же момент, когда создается буфер глубины. Определяя формат буфера глубины, мы можем указать формат и для трафаретного буфера. Z-буфер и буфер трафарета представляют собой внеэкранные поверхности одинакового размера но разного формата.

Ниже приведены константы, которые позволяют задать формат буфера глубины и трафарета совместно:

D3DFMT_D24S8 буфер глубины определяется 24 битами на пиксель; трафаретный буфер задан 8-ю битами на пиксель.
D3DFMT_D15S1 буфер глубины определяется 15 битами на пиксель; трафаретный буфер задан одним битом на пиксель.
D3DFMT_D24X4S4 буфер глубины определяется 24 битами на пиксель; трафаретный буфер задан 4-мя битами на пиксель и 4 бита не используются

Следует отметить, что не все видеокарты могут поддерживать 8-ми битный буфер трафарета.

Как мы поняли, трафаретный буфер позволяет блокировать вывод некоторых пикселей и регионов в буфере кадра. Это достигается с помощью так называемого теста трафарета, который задает функцию сравнения значения находящего в буфере трафарета ( value ) с некоторым заданным ( ref ). Эта идея может быть описана следующим псевдоматематическим выражением:

(ref & mask) ОперацияСравнения (value & mask),

где символ "&" означает побитовую операцию AND,

mask – некоторая заданная маска сравнения, которая может быть использована для того чтобы скрыть (выключить) некоторые биты одновременно в двух параметрах: value и ref (по умолчанию mask = 0xffffffff ).

Изменить значение маски трафарета можно следующим образом:

C++ device->SetRenderState( D3DRS_STENCILMASK, 0xff00ffff );
Pascal device.SetRenderState( D3DRS_STENCILMASK, $ff00ffff );

Значение, задаваемое параметром ref по умолчанию равно нулю. Изменить его можно с помощью следующих строк:

C++ device->SetRenderState( D3DRS_STENCILREF, 1 );
Pascal device.SetRenderState( D3DRS_STENCILREF, 1 );
< Лекция 3 || Лекция 4: 12345 || Лекция 5 >
Олег Корсак
Олег Корсак
Латвия, Рига
Ренат Файзуллин
Ренат Файзуллин
Россия, Казань