Поставим себе новую задачу – покроем чайник, кроме текстуры отражений, обычной текстурой. Но что делать, если наша модель не содержит в вертексах текстурных координат? Очевидно, нужно их туда добавить. Это можно сделать с помощью функции CloneMeshFVF класса D3DXMesh:

код на языке vb
 
  Set Mesh = Mesh.CloneMeshFVF(0, D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_TEX1, d3dDevice)
 

Эта функция меняет флаговое описание вертекса на новое и соответственно преобразует формат вертекса. Но поменять формат мало, нужно еще записать в новые поля соответствующие данные. Для начала извлечем из модели вертексный буфер, для этого в процедуре InitMesh создадим объектную переменную типа Direct3DVertexBuffer8 и массив для вертексов:

код на языке vb
 
Dim vBuf As Direct3DVertexBuffer8, vCnt As Long, n As Long, Vert() As vFormat
 

Кроме этого созданы вспомогательные переменные n для использования в цикле и vCnt, которая будет содержать количество вертексов. Для массива Vert() зададим тип:

код на языке vb
 
Private Type vFormat
  Pos As D3DVECTOR
  Normal As D3DVECTOR
  tu0 As Single
  tv0 As Single
End Type
 

Далее так. Считываем из меша (модели) число вертексов в нем и ассоциируем объектную переменную vBuf с вертексным буфером меша:

код на языке vb
 
  Set vBuf = Mesh.GetVertexBuffer
  vCnt = Mesh.GetNumVertices
 

Внимательно присмотритесь к первой строке. Функция GetVertexBuffer не создает новый вертексный буфер, а лишь возвращает указатель на имеющийся в меше, а объектная переменная vBuf ассоциируется с ним.
Перезадаем размер массива в соответствие с числом вертексов в буфере и считываем данные вертексов в массив:

код на языке vb
 
  ReDim Vert(vCnt - 1)
  D3DVertexBuffer8GetData vBuf, 0, vCnt * Len(Vert(0)), 0, Vert(0)
 

Прописываем в вертексы текстурные координаты, тут вариантов может быть множество, например можно поставить текстурные координаты tu0 и tv0 равными координатам x и z соответственно:

код на языке vb
 
  For n = 0 To vCnt - 1
    Vert(n).tu0 = Vert(n).Pos.x
    Vert(n).tv0 = Vert(n).Pos.z
  Next n
 

Возвращаем данные в вертексный буфер и уничтожаем, больше ненужную, объектную переменную vBuf:

код на языке vb
 
  D3DVertexBuffer8SetData vBuf, 0, vCnt * Len(Vert(0)), 0, Vert(0)
  Set vBuf = Nothing
 

Теперь модель чайника преобразована, ее вертексы, кроме позиции и нормалей, содержат также текстурные координаты для одной стадии текстурирования. Загрузим две текстуры, текстуру мрамора для нулевой стадии и текстуру отражений для первой, обе текстуры можно взять в папке Pr18:

код на языке vb
 
  Set Tex0 = d3dx.CreateTextureFromFile(d3dDevice, "marb.jpg")
  d3dDevice.SetTexture 0, Tex0
  Set Tex1 = d3dx.CreateTextureFromFile(d3dDevice, "sky.jpg")
  d3dDevice.SetTexture 1, Tex1
 

Настроим параметры текстурирования для этих стадий:

код на языке vb
 
  d3dDevice.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
  d3dDevice.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
  d3dDevice.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE
 
  d3dDevice.SetTextureStageState 1, D3DTSS_COLOROP, D3DTOP_ADD
  d3dDevice.SetTextureStageState 1, D3DTSS_COLORARG1, D3DTA_TEXTURE
  d3dDevice.SetTextureStageState 1, D3DTSS_COLORARG2, D3DTA_CURRENT
  d3dDevice.SetTextureStageState 1, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR
 

Зададим трансформацию для первой стадии и разрешим ее использование:

код на языке vb
 
  d3dDevice.SetTextureStageState 1, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2
  D3DXMatrixTranslation Mtrx, 0.5, 0.5, 0
  d3dDevice.SetTransform D3DTS_TEXTURE1, Mtrx
  D3DXMatrixScaling Mtrx, 0.5, 0.5, 1
  d3dDevice.MultiplyTransform D3DTS_TEXTURE1, Mtrx
 

Осталось инициализировать свет и материал, и программа готова:

код на языке vb
 
Private Sub InitLight()
Dim Light As D3DLIGHT8
  Light.Type = D3DLIGHT_DIRECTIONAL
  Light.Direction = vec3(-1, -1, 1)
  Light.diffuse.r = 1
  Light.diffuse.g = 1
  Light.diffuse.b = 1
  d3dDevice.SetLight 0, Light
  d3dDevice.LightEnable 0, 1
End Sub
 
Private Sub InitMaterial()
Dim Mat As D3DMATERIAL8
  Mat.diffuse.r = 1
  Mat.diffuse.g = 1
  Mat.diffuse.b = 1
  Mat.Ambient = Mat.diffuse
  d3dDevice.SetMaterial Mat
End Sub