Шаг 16 - Назначим материалы

Продолжаем развивать предыдуший шаг. Инициализируем три материала для каждого треугольника:

D3DMATERIAL8 mtrl1;	// первый материал
D3DMATERIAL8 mtrl2;	// второй материал
D3DMATERIAL8 mtrl3;	// третий материал

Более подробно о структурах читайте в разделе Справка по DirectX: "Шаг 65 - Описание структуры D3DMATERIAL8".

Выделим память и назначим им параметры в конструкторе главного окна CMainWnd::CMainWnd(), разместите исходный код перед закрывающей скобкой:

ZeroMemory (&mtrl1, sizeof(D3DMATERIAL8));
mtrl1.Diffuse.r = mtrl1.Ambient.r = 0.0f;
mtrl1.Diffuse.g = mtrl1.Ambient.g = 0.0f;
mtrl1.Diffuse.b = mtrl1.Ambient.b = 1.0f;
mtrl1.Diffuse.a = mtrl1.Ambient.a = 1.0f;

ZeroMemory (&mtrl2, sizeof(D3DMATERIAL8));
mtrl2.Diffuse.r = mtrl2.Ambient.r = 1.0f;
mtrl2.Diffuse.g = mtrl2.Ambient.g = 1.0f;
mtrl2.Diffuse.b = mtrl2.Ambient.b = 0.0f;
mtrl2.Diffuse.a = mtrl2.Ambient.a = 1.0f;

ZeroMemory (&mtrl3, sizeof(D3DMATERIAL8));
mtrl3.Diffuse.r = mtrl3.Ambient.r = 0.0f;
mtrl3.Diffuse.g = mtrl3.Ambient.g = 1.0f;
mtrl3.Diffuse.b = mtrl3.Ambient.b = 0.0f;
mtrl3.Diffuse.a = mtrl3.Ambient.a = 1.0f;

Заметьте только, что мы присваиваем разом и диффузный цвет и цвет подсветки одним значением.

Перейдем в функцию OnPaint и поговорим здесь более подробно. Найдите функцию p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 3); и как Вы уже знаете из прошлых шагов, вместо этой одной функции мы можем написать три:

p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 1);
p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 3, 1);
p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 6, 1);

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

p_d3d_Device->SetMaterial (&mtrl1);
p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 1);
p_d3d_Device->SetMaterial (&mtrl2);
p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 3, 1);
p_d3d_Device->SetMaterial (&mtrl3);
p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 6, 1);

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

Вспомним, что на прошлом шаге мы инициализирали направленный источник света:

vecDir = D3DXVECTOR3 (0.0f, 0.0f, 1.0f); 
D3DXVec3Normalize ((D3DXVECTOR3*)&light.Direction, &vecDir);

Т.е. лучи направлены от камеры и идущие по оси Z (в положительном направлении). Чтобы лучи отразились от треугольника, мы выставим ему нормаль по оси Z как -1. Поэтому мы увидем треугольник в этот момент времени ярким. Теперь беремся за второй треугольник (представляем себе все это в неподвижной сцене), т.к. он у нас расположен параллельно оси Z, то соответственно его мы лучше увидем, если нормаль будет идти от него в некое пространство, т.е. нормаль направляется по оси X и в положительную сторону. Поэтому мы второму треугольнику назначаем 1 по оси Х, и когда он развернется к нам, нормаль будет указывать прямо в камеру, что приведет снова к самому яркому освещению. С третьим у вас не должно возникнуть теперь проблем :). Итак, вот более обновленный код:

CUSTOMVERTEX g_Vertices[] =
{
	{  0.0f,   0.0f,  0.0f, 0.0f, 0.0f, -1.0f,},
	{  0.0f, 100.0f,  0.0f, 0.0f, 0.0f, -1.0f,},
	{ 60.0f,   0.0f,  0.0f, 0.0f, 0.0f, -1.0f,},

	{  0.0f, 100.0f,  0.0f, 1.0f, 0.0f,  0.0f,},
	{ 60.0f,   0.0f, 60.0f, 1.0f, 0.0f,  0.0f,},
	{ 60.0f,   0.0f,  0.0f, 1.0f, 0.0f,  0.0f,},

	{  0.0f,   0.0f,  0.0f, 0.0f, 0.0f,  1.0f,},
	{ 60.0f,   0.0f, 60.0f, 0.0f, 0.0f,  1.0f,},
	{  0.0f, 100.0f,  0.0f, 0.0f, 0.0f,  1.0f,},
};

Компилируем, запускаем, смотрим. Все хорошо :), но нажмите клавиши Alt+TAB и вернитесь обратно в приложение...

Чтобы это не происходило найдите в конструкторе главного окна:

p_d3d_Device->LightEnable (0, true);

и перенесите ее в функцию Transform3D (но лучше всего для этого сделать отдельную функцию). Теперь пробуйте и экспериментируйте :)


Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Хавов Евгений Валерьевич - 30.08.2002