12 февраля 2010 в 20:53
Уроки Direct3D - 2.8. Преобразование содержимого моделей
Поставим себе новую задачу – покроем чайник, кроме текстуры отражений, обычной текстурой. Но что делать, если наша модель не содержит в вертексах текстурных координат? Очевидно, нужно их туда добавить. Это можно сделать с помощью функции CloneMeshFVF класса D3DXMesh:
Set Mesh = Mesh.CloneMeshFVF(0, D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_TEX1, d3dDevice)
Эта функция меняет флаговое описание вертекса на новое и соответственно преобразует формат вертекса. Но поменять формат мало, нужно еще записать в новые поля соответствующие данные. Для начала извлечем из модели вертексный буфер, для этого в процедуре InitMesh создадим объектную переменную типа Direct3DVertexBuffer8 и массив для вертексов:
Dim vBuf As Direct3DVertexBuffer8, vCnt As Long, n As Long, Vert() As vFormat
Кроме этого созданы вспомогательные переменные n для использования в цикле и vCnt, которая будет содержать количество вертексов. Для массива Vert() зададим тип:
Private Type vFormat Pos As D3DVECTOR Normal As D3DVECTOR tu0 As Single tv0 As Single End Type
Далее так. Считываем из меша (модели) число вертексов в нем и ассоциируем объектную переменную vBuf с вертексным буфером меша:
Set vBuf = Mesh.GetVertexBuffer vCnt = Mesh.GetNumVertices
Внимательно присмотритесь к первой строке. Функция GetVertexBuffer не создает новый вертексный буфер, а лишь возвращает указатель на имеющийся в меше, а объектная переменная vBuf ассоциируется с ним.
Перезадаем размер массива в соответствие с числом вертексов в буфере и считываем данные вертексов в массив:
ReDim Vert(vCnt - 1) D3DVertexBuffer8GetData vBuf, 0, vCnt * Len(Vert(0)), 0, Vert(0)
Прописываем в вертексы текстурные координаты, тут вариантов может быть множество, например можно поставить текстурные координаты tu0 и tv0 равными координатам x и z соответственно:
For n = 0 To vCnt - 1 Vert(n).tu0 = Vert(n).Pos.x Vert(n).tv0 = Vert(n).Pos.z Next n
Возвращаем данные в вертексный буфер и уничтожаем, больше ненужную, объектную переменную vBuf:
D3DVertexBuffer8SetData vBuf, 0, vCnt * Len(Vert(0)), 0, Vert(0) Set vBuf = Nothing
Теперь модель чайника преобразована, ее вертексы, кроме позиции и нормалей, содержат также текстурные координаты для одной стадии текстурирования. Загрузим две текстуры, текстуру мрамора для нулевой стадии и текстуру отражений для первой, обе текстуры можно взять в папке Pr18:
Set Tex0 = d3dx.CreateTextureFromFile(d3dDevice, "marb.jpg") d3dDevice.SetTexture 0, Tex0 Set Tex1 = d3dx.CreateTextureFromFile(d3dDevice, "sky.jpg") d3dDevice.SetTexture 1, Tex1
Настроим параметры текстурирования для этих стадий:
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
Зададим трансформацию для первой стадии и разрешим ее использование:
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
Осталось инициализировать свет и материал, и программа готова:
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
комментарии отсутствуют
авторизуйтесь