ЖУРНАЛ ХАКЕР

Суровая правда жизни о Direct3D

Спецвыпуск Хакер, номер #004, стр. 004-098-8


mat.dcvAmbient.g = (D3DVALUE)1.0;

mat.dcvAmbient.b = (D3DVALUE)0.0;

mat.dcvAmbient.a = (D3DVALUE)1.0;

mat.dcvSpecular.r = (D3DVALUE)0.0;

mat.dcvSpecular.g = (D3DVALUE)1.0;

mat.dcvSpecular.b = (D3DVALUE)0.0;

mat.dcvSpecular.a = (D3DVALUE)1.0;

hr = lpD3DD->SetMaterial(&mat);

if(FAILED(hr)) return hr;

//Создаем нашу лампу

//Она будет белая

//Тип - точечная (светит во все стороны без разбора)

d3dLight.dltType = D3DLIGHT_POINT;

d3dLight.dcvDiffuse.r = 1.0f;

d3dLight.dcvDiffuse.g = 1.0f;

d3dLight.dcvDiffuse.b = 1.0f;

d3dLight.dcvAmbient.r = 1.0f;

d3dLight.dcvAmbient.g = 1.0f;

d3dLight.dcvAmbient.b = 1.0f;

d3dLight.dcvSpecular.r = 1.0f;

d3dLight.dcvSpecular.g = 1.0f;

d3dLight.dcvSpecular.b = 1.0f;

d3dLight.dvPosition.x = 0.0f;

d3dLight.dvPosition.y = 0.0f;

d3dLight.dvPosition.z = -4.0f;

d3dLight.dvAttenuation0 = 1.0f;

//Да пусть светит далеко-далеко

d3dLight.dvRange = D3DLIGHT_RANGE_MAX;

//Регистрируем нашу лампу

hr = lpD3DD->SetLight(0, &d3dLight);

if(FAILED(hr)) return hr;

//Разрешаем ей светить

hr = lpD3DD->LightEnable(0, TRUE);

if(FAILED(hr)) return hr;

Конец листинга 7.

Н-да-а... Сделаем последний рывок и закончим инициализацию. Теперь надо проинициализировать матрицы, они служат для трансформаций. Что это за матрицы и какие преобразования они делают - смотри в имаги.

Сначала надо создать мировую матрицу (Гхм...) без всяких трансформаций. Описывает матрицу структура D3DMATRIX. Чтобы применить ее, воспользуйся методом SetTransform. Первый параметр говорит о том, что мы будем трансформировать (D3DTRANSFORMSTATE_WORLD - трансформирует мир, D3DTRANSFORMSTATE_VIEW - трансформирует вид, но там определенные параметры - довольно сложная вещь, D3DTRANSFORMSTATE_PROJECTION - трансформирует вид проекции - как это будет выглядеть на экране). Второй параметр - адрес матрицы. Все, что тебе потребуется сделать, написано в листинге.

Листинг №8 - Main.cpp, завершение инициализации

D3DMATRIX mat;

mat._11 = mat._22 = mat._33 = mat._44 = 1.0f;

mat._12 = mat._13 = mat._14 = mat._41 = 0.0f;

mat._21 = mat._23 = mat._24 = mat._42 = 0.0f;

mat._31 = mat._32 = mat._34 = mat._43 = 0.0f;

lpD3DD->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat);

//Создаем матрицу вида

D3DMATRIX matView = mat;

matView._43 = 10.0f; //Будем отодвинуты по Z назад на 10

lpD3DD->SetTransform(D3DTRANSFORMSTATE_VIEW, &matView);

//Создаем матрицу проекции

D3DMATRIX matProj = mat;

matProj._11 = 2.0f;

matProj._22 = 2.0f;

matProj._34 = 1.0f;

matProj._43 = -1.0f;

matProj._44 = 0.0f;

lpD3DD->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &matProj);

return S_OK; //Радостно завершаем инициализацию

}

Конец листинга 8.

Теперь будем рендерить. Для начала заставим мир крутиться. Просто измени мировую матрицу, как это написано в листинге. Перед рендерингом надо очистить экран методом Clear. Первый параметр - количество прямоугольников в массиве второго параметра (0). Второй - Указатель на пресловутый массив (NULL). Третий - тип, что будем затирать (D3DCLEAR_TARGET - затрем экран). Четвертый - цвет в хексе (0x00000000 - черный). Пятый и шестой нам не нужны, они относятся к z и stencil буферам (0, 0). Далее идет уже непосредственно рендеринг. Его обязательно надо располагать между вызовами методов BeginScene и EndScene, не имеющих параметров. Вот и выполняй сейчас BeginScene. Собственно рисование осуществляется методом DrawPrimitive. Первым его параметром является тип примитива (в данном случае D3DPT_TRIANGLELIST - список полигонов; еще есть D3DPT_TRIANGLESTRIP - последовательность оных; D3DPT_TRIANGLEFAN - что-то типа веера, см. SDK; D3DPT_LINELIST - список линий; D3DPT_LINESTRIP - последовательность; D3DPT_POINTLIST - список точек). Следующий, второй, параметр - тип данных, в которых указываются вершины примитивов (D3DFVF_VERTEX - поступают в типе D3DVERTEX). Третий параметр - данные наших вершин в том типе, в котором мы указали выше (в нашем случае это переменная vtx). Далее, четвертый параметр - количество вершин в той переменной, которую мы указали (6). Последний параметр - ждать ли рендеринг или плевать на все (в нашем случае я бы даже посоветовал всегда так делать: D3DDP_WAIT). Пора и закончить рендеринг. EndScene. Ну и если ты помнишь про двойную буферизацию, выведем все это на экран. Разрешенный метод Flip интерфейса IDirectDrawSurface7 нам в этом деле поможет. Первый параметр - указатель на серфайсу, куда будем переносить изображение (ставь NULL для того, чтобы перенести его на следующую серфайсу в цепи (экран)). Второй - флаги (DDFLIP_WAIT). Вот и весь рендеринг.

Назад на стр. 004-098-7  Содержание  Вперед на стр. 004-098-9