Введение в программирование трехмерных игр с DX9

       

Пример приложения: прозрачный чайник


Пример приложения, который мы будем рассматривать, рисует прозрачный чайник поверх фоновой текстуры с изображением ящика, как показано на Рисунок  7.2. Данные альфа-компоненты в этом примере берутся из материала. Приложение позволяет увеличивать и уменьшать значение альфа-компоненты нажатием на клавиши A и S. Нажатие на клавишу A увеличивает значение альфа-компоненты; нажатие на клавишу S — уменьшает его.

Чтобы использовать смешивание необходимо выполнить следующие действия:

Установить коэффициенты смешивания D3DRS_SRCBLEND и D3DRS_DESTBLEND.

Если используется альфа-компонента, указать ее источник (материал или альфа-канал текстуры).

Установить режим визуализации с альфа-смешиванием.

В примере мы объявляем несколько самодокументируемых глобальных переменных:

ID3DXMesh* Teapot = 0; // чайник D3DMATERIAL9 TeapotMtrl; // материал чайника

IDirect3DVertexBuffer9* BkGndQuad = 0; // квадрат фона IDirect3DTexture9* BkGndTex = 0; // текстура ящика D3DMATERIAL9 BkGndMtrl; // материал фона

Метод Setup делает много вещей, но мы опустим большую часть кода, которая не относится к рассматриваемой в этой главе теме. Что касается смешивания, метод Setup задает источник из которого будут браться значения альфа-компонент. В рассматриваемом примере мы указываем, что значения альфа-компонент будут браться из соответствующей компоненты материала. Обратите внимание, что для материала чайника мы задаем значение альфа-компоненты равное 0.5, а это значит, что чайник будет визуализирован с 50% прозрачностью. Помимо вышеперечисленных действий мы также задаем коэффициенты смешивания. Обратите внимание, что в этом методе мы не разрешаем альфа-смешивание. Дело в том, что альфа-смешивание — это ресурсоемкая операция, которая должна включаться только при визуализации тех объектов, для которых она нужна. Например, в рассматриваемой программе визуализация с альфа-смешиванием нужна только для чайника и не требуется для квадрата с фоновой текстурой. Поэтому мы разрешаем альфа-смешивание в функции Display.


bool Setup() { TeapotMtrl = d3d::RED_MTRL; TeapotMtrl.Diffuse.a = 0.5f; // 50% прозрачность BkGndMtrl = d3d::WHITE_MTRL;
D3DXCreateTeapot(Device, &Teapot, 0);
...// Код создания квадрата фона опущен
...// Код установки освещения и текстур опущен
// В качестве источника альфа-компоненты используем параметры материала Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
// Устанавливаем коэффициенты смешивания таким образом, // чтобы альфа-компонента определяла прозрачность Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
...// установка матриц проекции/вида опущена


return true; }
В функции Display мы проверяем нажаты ли клавиши A или S и, если да, то соответственно увеличиваем или уменьшаем значение альфа-компоненты материала. Обратите внимание, что метод гарантирует, что значение альфа-компоненты не выйдет за пределы диапазона [0, 1]. Затем мы разрешаем альфа-смешивание, визуализируем чайник с включенным альфа-смешиванием, после чего выключаем альфа-смешивание.
bool Display(float timeDelta) { if(Device) { // // Обновление //
// Увеличение/уменьшение альфа-компоненты с помощью клавиатуры if(::GetAsyncKeyState('A') & 0x8000f ) TeapotMtrl.Diffuse.a += 0.01f; if( ::GetAsyncKeyState('S') & 0x8000f ) TeapotMtrl.Diffuse.a -= 0.01f;
// Проверяем не вышло ли значение за интервал [0, 1] if(TeapotMtrl.Diffuse.a > 1.0f) TeapotMtrl.Diffuse.a = 1.0f; if(TeapotMtrl.Diffuse.a < 0.0f) TeapotMtrl.Diffuse.a = 0.0f;
// // Визуализация //
Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); Device->BeginScene();
// Рисуем фон D3DXMATRIX W; D3DXMatrixIdentity(&W); Device->SetTransform(D3DTS_WORLD, &W); Device->SetFVF(Vertex::FVF); Device->SetStreamSource(0, BkGndQuad, 0, sizeof(Vertex)); Device->SetMaterial(&BkGndMtrl); Device->SetTexture(0, BkGndTex); Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

// Рисуем чайник Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
D3DXMatrixScaling(&W, 1.5f, 1.5f, 1.5f); Device->SetTransform(D3DTS_WORLD, &W); Device->SetMaterial(&TeapotMtrl); Device->SetTexture(0, 0); Teapot->DrawSubset(0);
Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
Device->EndScene(); Device->Present(0, 0, 0, 0); } return true; }
ПРИМЕЧАНИЕ
На веб- сайте этой книги есть еще один пример к данной главе, texAlpha, который демонстрирует использование альфа-канала текстуры. Единственное отлтчие кода этого примера от рассмотренного выше заключается в том, что мы указываем в качестве источника альфа-компоненты не материал, а альфа-канал текстуры.
// Использовать альфа-канал в качестве источника альфа-компонент Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
Приложение загружает файл DDS, содержащий альфа-канал, созданный с помощью утилиты DX Tex Tool, рассмотренной в разделе 7.4.
Содержание раздела