Статьи/Цикл уроков по DirectX 9.0/Урок 04: Прозрачность
Урок 04: Прозрачность


Сегодня мы поговорим о том, как использовать эффекты прозрачности в ваших проектах. Данным методом пользуются во многих случаях. Когда вам нужно изобразить огонь, воду, дым, стекло, различные зеркала, обычные прозрачные объекты и т.д. Прозрачность достигается путем смешивания текущего пикселя, с пикселем уже находящимся в заднем буфере. Тип смешивания (blending) указывает так называемый Alpha канал. Его можно задавать несколькими способами:

1. В цвете вершин полигонов модели вместо D3DCOLOR_XRGB() можно указать D3DCOLOR_ARGB(a, r, g, b), где первый элемент указывает Alpha канал, 2 - красный компонент цвета, 3 - зеленый, 4 - синий.
2. Использовать текстуру формата, поддерживающим альфа компонент.
3. Указать Альфу в текущем материале.
В данной статье мы рассмотрим первые два метода.

В основе положим урок №3 из этого цикла и немного его модифицируем.
И так, начнем.

После основных Direct3D определений, обьявим несколько новых переменных, отвечающих за показ FPS в заголовке окна.
float FPS;		// Время за которое отрисовался последний кадр
float mlsec=0.0f;		// Переменная для обновления FPS в окне
char Capture[64];		// Название приложения
char WindowText[64];	// Заголовок окна

Далее обьявим тип смешивания: 0 - смешивание не используем, 1 - Alpha берется из вершин, Alpha берется из текстуры.
int BlendingType=2;		// Тип смешивания

Потом как обычно обьявляем вершинный буфер, а также две текстуры: одна обычная, другая - с Альфа каналом.
Следом идет структура вершин и их формат:
LPDIRECT3DVERTEXBUFFER9	MyVertexBuffer;	// Вертекс буфер для отрисовки кубика
LPDIRECT3DTEXTURE9		MyTexture;	// Обычная текстура
LPDIRECT3DTEXTURE9		MyAlphaTexture;	// Текстура с Альфа  каналом

struct MyVertex
{
	float	x,y,z;
	DWORD	color;
	float	tx,ty;
};
DWORD MyVertex_FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;

Переходим к функции инициализации AllInit и заменям там все строки типа D3DCOLOR_XRGB( 255, 0, 0) на D3DCOLOR_ARGB( alpha, 255, 0, 0). В конце данной функции добавляем загрузку двух наших текстур: Обычную (*.BMP) и с прозрачностью (*.DDS). Для создания текстур, я использовал специальную утилиту DxTex. Но вы можете пользоваться любым доступным редактором, поддерживающим Альфа канал (например, PhotoShop).
	// Загружаем текстуру из файла
	D3DXCreateTextureFromFile(g_pd3dDevice, "Texture.bmp", &MyTexture);
	D3DXCreateTextureFromFile(g_pd3dDevice, "Texture.dds", &MyAlphaTexture);

Теперь в Render().
Чтобы использовать AlphaBlending нам нужно задать функции смешивания текущего пикселя с пикселем из буфера кадра:
	// Функции смешивания
	g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);     // Для источника.
	g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); // Для цели.

Далее в соответствии с состоянием BlendingType выставляем нужные стейты и активируем текстуры.
	if(BlendingType==1) // Не используем прозрачность
	{
		// Выключаем альфаблендинг
		g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,  false);
	}
	else if(BlendingType==2) // Прозрачность в текстуре
	{
		if( MyAlphaTexture != NULL )
			g_pd3dDevice->SetTexture(0, MyAlphaTexture); // Ставим текстуру

		// Включаем альфаблендинг и выключаем запись в Z-буфер
		g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,  true);
		g_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);
	}
	else if(BlendingType==3) // Прозрачность в вершинах
	{
		if( MyTexture != NULL )
			g_pd3dDevice->SetTexture(0, MyTexture); // Ставим текстуру

		// Включаем альфаблендинг и выключаем запись в Z-буфер
		g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,  true);
		g_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);

		// Устанавливаем стейты для отображения текстуры ...
		g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
		g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

		g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
		g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
		g_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
	}

Отрисовка кубика и включение записи в Z-буфер.
	// Производим отрисовку
	g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 12);
	g_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, true);

Как обычно осталось только все использованые интерфейсы правильно освободить:
void AllShutdown()
{
	Cleanup();
	// ОСвобождаем память из-под текстур
	SAFE_RELEASE(MyTexture);
	SAFE_RELEASE(MyAlphaTexture);

	SAFE_RELEASE(MyVertexBuffer);
	SAFE_RELEASE(g_pd3dDevice);
	SAFE_RELEASE(g_pD3D);
}

Все самое главное мы рассмотрели и опустили лишь мелкие детали. Чтобы лучше понять материал качайте исходник (~326Kb) к этой статье. Ждите новых уроков... Всем Bye-Bye.

Автор: L1f 





Рейтинг@Mail.ru