Во второй части учебника мы займёмся рендерингом двухмерного разноцветного треугольника.
Основой программы, которую мы будем создавать в этой части послужит программа, созданная в предыдущей, т. е. здесь будут описаны только исправления и добавления, которые надо внести в её код.
В этом примере показано, как создавать пользовательский тип трёхмерных вершин, буффер этих вершин, а также как рисовать с их помощью треугольник.
Для начала объявим объект g_VB, представляющий из себя буффер трёхмерных вершин:
Dim g_VB As Direct3DVertexBuffer8
Объявим тип CUSTOMVERTEX, т. е. пользовательский тип трёхмерных вершин или, иначе, FVF (Flexible Vertex Format), а также константу D3DFVF_CUSTOMVERTEX, описывающую этот тип:
Private Type CUSTOMVERTEX
x As Single 'x
y As Single 'y
z As Single 'z
rhw As Single 'normalized z rhw
color As Long 'цвет 3d вершины
End Type
Const D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZRHW Or D3DFVF_DIFFUSE)
Константа D3DFVF_XYZRHW означает, что тип содержит координаты и RHW вершин (что же это такое?), а константа D3DFVF_DIFFUSE - цвет вершин (цвета вершин плавно переходят из одного в другой).
Добавим функцию InitVB, создающую буффер 3d вершин:
Function InitVB() As Boolean
On Local Error Resume Next
Dim Vertices(2) As CUSTOMVERTEX 'массив 3d вершин, которые затем вставляются в буффер
Dim VertexSizeInBytes As Long 'переменная, содержащая длину типа CUSTOMVERTEX
VertexSizeInBytes = Len(Vertices(0))
'задание координат, цвета и RHW 3d вершин
'треугольник двухмерный, поэтому z всех точек равны
With Vertices(0): .x = 150: .y = 50: .z = 0.5: .rhw = 1: .color = &HFFFF0000: End With
With Vertices(1): .x = 250: .y = 250: .z = 0.5: .rhw = 1: .color = &HFF00FF00: End With
With Vertices(2): .x = 50: .y = 250: .z = 0.5: .rhw = 1: .color = &HFF00FFFF: End With
'создание буффера 3d вершин
Set g_VB = g_D3DDevice.CreateVertexBuffer(VertexSizeInBytes * 3, _
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT)
If g_VB Is Nothing Then Exit Function
'заполнение буффера данными из массива Vertices
D3DVertexBuffer8SetData g_VB, 0, VertexSizeInBytes * 3, 0, Vertices(0)
InitVB = True 'инициализация буффера 3d вершин прошла нормально
End Function
Цвет 3d вершин задаётся в формате ARGB, который содержит кроме красного, зелёного и синего цветов также альфа-компаненту. Так &HFFFF0000 означает красный цвет, &HFF00FF00 - зелёный, а &HFF00FFFF - сине-зелёный. Первый параметр метода CreateVertexBuffer - размер создаваемого буффера в байтах; второй параметр - список флагов, описывающих использование этого ресурса (для начала пойдёт и 0); третий параметр - список флагов описывающий пользовательский тип 3d вершин; четвёртый параметр - одна из констант CONST_D3DPOOL, определяющих в каком типе памяти будет расположен данный ресурс (может принимать следующие значения: D3DPOOL_DEFAULT, D3DPOOL_MANAGED, D3DPOOL_SYSTEMMEM, D3DPOOL_SCRATCH).
При заполнении буффера 3d вершин данными используется процедура D3DVertexBuffer8SetData. Первый её параметр - буффер, заполняемый данными; второй параметр - "отступ" от начала буффера в байтах, после которого в него записываются данные; третий параметр - это размер буффера в байтах; четвёртый параметр - список флагов; последний параметр - данные, записываемые в буффер.
В процедуру Form_Load() после вызова функции InitD3d вставим код, вызывающий функцию InitVB:
If Not InitVB() Then
MsgBox "Невозможно инициализировать буфер вершин."
End
End If
В начало процедуры Render вставим следующие объявления:
Dim v As CUSTOMVERTEX
Dim sizeOfVertex As Long
Между методами BeginScene и EndScene процедуры Render вставим следующий код:
sizeOfVertex = Len(v)
g_D3DDevice.SetStreamSource 0, g_VB, sizeOfVertex
g_D3DDevice.SetVertexShader D3DFVF_CUSTOMVERTEX
g_D3DDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, 1
Сначала переменной sizeOfVertex присваивается размер переменной v, принадлежащей типу CUSTOMVERTEX. Затем происходит рендеринг 3d вершин, разделённый на несколько шагов. Во-первых, с помощью метода SetStreamSource объекта g_D3DDevice устанвливается источник потока (в данном случае поток 0). Первый параметр метода SetStreamSource устанавливает источник потока данных устройства (число от 0 до 1); второй параметр - буффер 3d вершин, связываемый с потоком данных; третий параметр - размер одного компонента в байтах. Во-вторых, метод SetVertexShader даёт Direct3d знать, с каким типом 3d вершин он работает. Единственный его параметр - описание типа 3d вершин. В-третьих, метод DrawPrimitive рисует треугольник по трём его вершинам. Первый параметр метода DrawPrimitive - тип рисуемого примитива, второй параметр - индекс первой загружаемой 3d вершины; последний параметр - количество рисуемых примитивов.
Всё, программа готова! Запускайте её на выполнение и можете любоваться трегольником с плавно перетекающими друг в друга цветами.
Вы можете скачать архив RAR с готовым проектом (3 Кб).
В следующей части мы будем использовать матрицы, чтобы вращать созданный треугольник.