netlib.narod.ru< Назад | Оглавление | Далее >

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

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

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

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

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

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

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

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.

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz