Сегодня мы поговорим о том, как использовать эффекты прозрачности в ваших проектах. Данным методом пользуются во многих случаях. Когда вам нужно изобразить огонь, воду, дым, стекло, различные зеркала, обычные прозрачные объекты и т.д. Прозрачность достигается путем смешивания текущего пикселя, с пикселем уже находящимся в заднем буфере. Тип смешивания (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);
}

Все самое главное мы рассмотрели и опустили лишь мелкие детали.