Создание и отрисовка одного треугольника

После того, как мы создали с вами простое приложение и инициализировали D3D8, мы можем начать рисовать то, что нам необходимо. В данном уроке мы научимся создавать и рисовать одиночный треугольник (точнее два треугольника :). Я надеюсь, что вы уже знакомы с основами трехмерной геометрии, поэтому не буду здесь приводит выкладки по данной теме. Приступим сразу к реализации данных принципов с использованием D3D8.

Начнем с реализации и отрисовки двухмерных треугольников.

Мы будем использовать концепцию буферов вершин (Vertex buffers) - они используются для хранения и отображения вершин. Вершины могут быть объявлены многими различными способами указанием пользовательской структуры для одной вершины и соответствующего пользовательского гибкого формата вершины (flexible vertex format - FVF). Для формата вершины мы будем использовать нижеследующее объявление :


struct CUSTOMVERTEX { FLOAT x, y, z, rhw; DWORD color; };

оно показывает, что у нашей вершины будут такие параметры, как положение ( X , Y , Z ), для уже трансформированной вершины (у нас двухмерный случай, не забыли?) параметр RHW , и цвета ( color ).

Далее нам необходимо объявить FVF :


#define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE )

мы показываем, что наша вершина содержит компоненты положения и трансформации ( D3DFVF_XYZRHW ) и компоненту цвета( D3DFVF_DIFFUSE ).

Далее, после того как у нас объявлен формат вершины, мы можем инициализировать вершины в буфере вершин. Для этого нам понадобится указатель на интерфейс буфера вершин IDirect3DVertexBuffer8 :


LPDIRECT3DVERTEXBUFFER8 p_VertexBuffer = NULL; // our VertexBuffer

Теперь все первоначальные настройки у нас готовы и мы можем приступать к самой интересной части - инициализация вершин и вывод треугольников на экран.

Начнем, соответственно, с инициализации вершин в буфере вершин :


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, },

	{  80.0f, 220.0f, 0.5f, 1.0f, 0xff0000ff, },
	{ 220.0f,  80.0f, 0.5f, 1.0f, 0xff00ff00, },
	{ 220.0f, 220.0f, 0.5f, 1.0f, 0xffffff00, },
};

p_d3d_Device->CreateVertexBuffer (6*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();

-- Сперва мы инициализируем наши вершины, всего шеть штук, задаем им необходимые параметры положения и цвета.
-- Следующим шагом мы создаем буфер вершин - первым параметром идет размер буфера ( 6*sizeof(CUSTOMVERTEX) ), потом флаг импользования контроля (нам он пока не нужен, поэтому приравнивем его 0 ), далее FVF для описания вершины ( D3DFVF_CUSTOMVERTEX ), затем параметр отвечающий за использование памяти (нам он тоже пока не нужен, ставим по умолчанию - D3DPOOL_DEFAULT ), и последним параметром идет указатель на интерфейс буфера вершин с которым мы будем работать ( &p_VertexBuffer ).
-- после того как мы инициализировали буфер вершин, нам необходимо поместить информацию о наших, ранее указанных, вершинах в этот буфер. За это отвечают следующие далее строки :

-- Блокируем буфер вершин для доступа,
-- Копируем информацию о наших вершинах в буфер,
-- Разблокируем буфер.

Теперь у нас есть готовый к дальнейшей работе буфер вершин. Теперь нам необходимо отобразит на экране. Делаем это следующим образом, в функцию отрисовки экрана RenderScreen() , между строками начала и конца сцены, вставляем следующие строки, которые будут рисовать наши треугольники :


p_d3d_Device->SetVertexShader (D3DFVF_CUSTOMVERTEX);
p_d3d_Device->SetStreamSource (0, p_VertexBuffer, sizeof(CUSTOMVERTEX));
p_d3d_Device->DrawPrimitive (D3DPT_TRIANGLELIST, 0, 2);

-- Первой строкой мы даем знать D3D о том, какой тип вершин мы будем сейчас использовать.
-- Затем задаем поток, с которым мы будем работать - первый параметр это номер потока, второй параметр связывает данный номер потока с источником данных (в нашем случае - p_VertexBuffer ), и третий параметр это размер необходимых нам данных.
-- Последней, третьей, строкой мы рисуем наши примитивы. В данном методе присутствуют следующие параметры - первый это тип отображаемого примитива ( D3DPT_TRIANGLELIST ), второй - индекс первой вершины, с которой мы начнем рисовать ( 0 ), и третий - количество заданных примитивов (в нашем случае это 2 треугольника).

Теперь запустив приложение вы должны увидеть нечто следующее :

Вот и все...

Ах да, чуть не забыл, после работы с интерфейсом буфера вершин, его также необходимо удалить в функции DestroyDirect3D8() :


	_RELEASE_ (p_VertexBuffer);

Вот теперь все...



Опубликовал admin
28 Окт, Четверг 2004г.



Программирование для чайников.