Продолжаем развивать предыдуший шаг. Инициализируем три материала для каждого треугольника:
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 (но лучше всего для этого сделать отдельную функцию). Теперь пробуйте и экспериментируйте :)