Наша задача в этом шаге создать и отобразить разноцветный треугольник, каждая вершина которого будет покрашена в свой цвет. Для начала присвоим фону постоянный цвет - черный, для этого перейдем в функцию RenderScene() и удалим объявление переменной static int color=0; и соответсвтенно функция p_d3d_Device->Clear должна предстать перед нами в обновленном виде (вместо color++ ставим жестко 0 - если присвоены все значения RGB ноль, получаем черный цвет, если 255 - белый):
p_d3d_Device->Clear (0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB (0, 0, 0), 0.0f, 0);
Объявим структуру вершин, в которой будем хранить координаты и цвет каждой вершины. Она у нас будет иметь вот такой вид:
#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE ) LPDIRECT3DVERTEXBUFFER8 p_VertexBuffer = NULL; // наш буфер вершин struct CUSTOMVERTEX { FLOAT x, y, z, rhw; DWORD color; };
p_VertexBuffer - это указаетль на нашу структуру, где будут храниться наши вершинки.
В функции AppInit() после создания устройства (перед return) объявите g_Vertices как массив, чтобы позже (в следующих шагах) нам можно было в эту же структуру занести другие треугольники, для разнообразия и занесите в нее параметры:
CUSTOMVERTEX g_Vertices[] = { { 60.0f, 60.0f, 0.5f, 1.0f, 0xffff0000, }, { 200.0f, 60.0f, 0.5f, 1.0f, 0xff00ff00, }, { 60.0f, 200.0f, 0.5f, 1.0f, 0xff0000ff, }, };
координаты вершин и их цвета. Координаты начинаются с верхнего левого угла 0, 0 и заканчиваются правым нижним углом приложения. Третья координата (Z) установлена в 0.5, но она может сейчас быть любой, на отображение это не повлияет, т.к. нет буфера глубины.
Ниже напишите следующее:
p_d3d_Device->CreateVertexBuffer (3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &p_VertexBuffer); VOID* pVertices; p_VertexBuffer->Lock (0, sizeof(g_Vertices), (BYTE**)&pVertices, 0); memcpy (pVertices, g_Vertices, sizeof(g_Vertices)); p_VertexBuffer->Unlock();
Определяем место в устройстве Direct3D для вершин, т.е. выделяем в нем буфер, который занимает размером 3 вершины (3*sizeof(CUSTOMVERTEX)) и присваиваем его нашему указаетлю. Далее при помощи команды Lock мы заперещаем любые изменения буфера вершин, чтобы его не повредить случайно. Копируем все символы из буфера в буфер. И последней функцией Unlock снова разрешаем доступ.
Добавьте код между функциями BeginScene и EndScene находящихся в RenderScene:
p_d3d_Device->BeginScene (); p_d3d_Device->SetVertexShader (D3DFVF_CUSTOMVERTEX); p_d3d_Device->SetStreamSource (0, p_VertexBuffer, sizeof(CUSTOMVERTEX)); p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 1); p_d3d_Device->EndScene ();
SetVertexShader - какой тип вершин мы будем сейчас использовать, в данному случае FVF.
SetStreamSource - задаем поток, с которым мы будем в дальнейшем работать. Первый параметр - это номер потока, второй - это данные, которые присваиваются к этому потоку (нам нужен треугольник, а указывает на него только p_VertexBuffer), и третий параметр - размер занимаемой в памяти одной вершины входящий в треугольник.
DrawPrimitive - рисуем примитивы (3d объекты), первый параметр: D3DPT_TRIANGLELIST - это тип отображаемого примтива, второй парметр: индекс первой вершины, с которой нам нужно начать рисовать (0) и третий параметр - это количество примитивов (у нас один треугольник).
Откомпилируйте и запустите, вот что у нас должно в итоге получиться:
Симпатичный треугольник ;) Вы ничего больше не забыли? Хорошие программисты - это люди аккуратные и как Вы должны помнить из предыдущих шагов создавая указатель не забывайте его удалять, иначе в памяти Вашего компьютера будет мусор и у него начнутся неадекватные действия. Итак, добавьте:
void DestroyDirect3D8 (void) { _RELEASE_ (p_VertexBuffer); _RELEASE_ (p_d3d_Device); _RELEASE_ (p_d3d); };
Тем самым Вы себя лишаете в будущем лишних проблем :) Идем дальше...