От проекта к проекту мы постепенно осваиваем приемы программирования DirectX. Как правило, каждый новый проект основывается на предыдущих, поэтому дальше я не буду комментировать все изменения и дополнения, если эти изменения и дополнения уже изучены. Если, например, в новом проекте изменена позиция наблюдателя (матрица трансформации D3DTS_VIEW), то вы можете понять это и без комментариев, так как у вас есть код всех проектов.

Представим, что нам нужно изобразить цилиндр. Естественно мы его имитируем с помощью призмы, ведь нам недоступны кривые линии. Призма, имеющая 64 боковых грани уже достаточно близко соответствует цилиндру, остановимся на этом числе граней. Каждая грань призмы – это прямоугольник, который мы можем отобразить двумя треугольниками. Итого нам нужно 128 треугольников или 128 * 3 = 384 вертекса. Согласитесь, многовато. А ведь позиции каждого вертекса совпадают с позицией еще двух вертексов, принадлежащих другим треугольникам, если мы сможем вместо трех таких вертексов использовать один – мы уменьшим размер вертексного буфера в 3 раза.

И такой способ есть, он заключается в использовании параметра D3DPT_TRIANGLESTRIP вместо D3DPT_TRIANGLELIST в методе  d3dDevice.DrawPrimitive. Рассмотрим принцип его работы. Первые три вертекса из вертексного буфера, как и раньше, соответствуют первому отображаемому треугольнику, а вот следующий треугольник задан не 4-ым, 5-ым, 6-ым, а 2-ым, 3-ым, 4-ым вертексами. Только лицевой уже считается та сторона, на которой вертексы расположены против часовой стрелки. Следующий треугольник задается 3-ым, 4-ым, 5-ым вертексами, на лицевой стороне вертексы опять расположены по часовой стрелке, и так далее. Это можно изобразить так:
 
В результате получается лента из треугольников, где для N треугольников необходимо задать N+2 вертексов. Если наш цилиндр задать такой лентой, свернутой в кольцо, нам понадобится всего 130 вертексов.
Если непосредственно задавать 130 вертексов, это займет много страниц кода. Поэтому переделаем процедуру InitGeometry. Создадим вспомогательную функцию для задания одного вертекса:

код на языке vb
 
Private Function Vertex(X As Single, Y As Single, Z As Single, C As Long) As vFormat
  Vertex.Pos = vec3(X, Y, Z)
  Vertex.Color = C
End Function
 

А InitGeometry будет выглядеть так:

код на языке vb
 
Private Sub InitGeometry()
Dim n As Long
  Set vBuffer = d3dDevice.CreateVertexBuffer(2 * 65 * vSize, 0, vFlag, D3DPOOL_DEFAULT)
  For n = 0 To 64
    Vert(0) = Vertex(Sin(2 * Pi * n / 64), -1, Cos(2 * Pi * n / 64), Rnd * &HFFFFFF)
    Vert(1) = Vertex(Sin(2 * Pi * n / 64), 1, Cos(2 * Pi * n / 64), Rnd * &HFFFFFF)
    D3DVertexBuffer8SetData vBuffer, vSize * 2 * n, vSize * 2, 0, Vert(0)
  Next n
End Sub
 

И заменим в процедуре Render параметр D3DPT_TRIANGLELIST на D3DPT_TRIANGLESTRIP:

код на языке vb
 
  d3dDevice.DrawPrimitive D3DPT_TRIANGLESTRIP, 0, 128
 

Это означает вывод ленты из 128 треугольников из вертексного буфера, начиная с нулевого вертекса. Запускаем программу и видим разноцветный цилиндр.