8 февраля 2010 в 20:45
Уроки Direct3D - 2.4. Мультитекстурирование
До сих пор мы накладывали на наши модели не более одной текстуры, в то время как Direct3D позволяет использовать одновременно до восьми текстур. Мы уже не раз использовали такую команду:
d3dDevice.SetRenderState D3DRS_LIGHTING, 0
Можно было написать:
d3dDevice.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1
И текстура станет видимой! Вместо того, чтобы выключить свет, мы изменили способ, каким смешиваются
аргументы нулевой стадии текстурирования. По умолчанию действовали следующие установки:
d3dDevice.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE d3dDevice.SetTextureStageState 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE d3dDevice.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_MODULATE
То есть первый аргумент – текстура, второй – цвет, действие – умножение. Мы заменили умножение D3DTOP_MODULATE на выбор первого аргумента D3DTOP_SELECTARG1.
Попробуем добиться какого-нибудь полезного эффекта, используя две текстуры. За основу берем проект из главы «Мип-мэппинг, фильтрация текстур». Для начала то, что мы уже отладили – фильтрация текстур, перенесем в модуль ModDX. Для этого создадим такую процедуру:
Public Sub TexFilter(Stage As Long, TF As TexF, Optional MaxAnisotropy As Long = 2) Select Case TF Case TexF_None d3dDevice.SetTextureStageState Stage, D3DTSS_MIPFILTER, D3DTEXF_NONE d3dDevice.SetTextureStageState Stage, D3DTSS_MAGFILTER, D3DTEXF_NONE d3dDevice.SetTextureStageState Stage, D3DTSS_MINFILTER, D3DTEXF_NONE Case TexF_BiLinear d3dDevice.SetTextureStageState Stage, D3DTSS_MIPFILTER, D3DTEXF_POINT d3dDevice.SetTextureStageState Stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR d3dDevice.SetTextureStageState Stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR Case TexF_TriLinear d3dDevice.SetTextureStageState Stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR d3dDevice.SetTextureStageState Stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR d3dDevice.SetTextureStageState Stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR Case TexF_Anisotropic d3dDevice.SetTextureStageState Stage, D3DTSS_MIPFILTER, D3DTEXF_LINEAR d3dDevice.SetTextureStageState Stage, D3DTSS_MAGFILTER, D3DTEXF_LINEAR If Caps.MaxAnisotropy >= MaxAnisotropy Then d3dDevice.SetTextureStageState Stage, D3DTSS_MINFILTER, D3DTEXF_ANISOTROPIC d3dDevice.SetTextureStageState Stage, D3DTSS_MAXANISOTROPY, MaxAnisotropy ElseIf Caps.MaxAnisotropy >= 2 Then d3dDevice.SetTextureStageState Stage, D3DTSS_MINFILTER, D3DTEXF_ANISOTROPIC d3dDevice.SetTextureStageState Stage, D3DTSS_MAXANISOTROPY, Caps.MaxAnisotropy Else d3dDevice.SetTextureStageState Stage, D3DTSS_MINFILTER, D3DTEXF_LINEAR End If End Select End Sub
Аргументами процедуры TexFilter являются номер стадии текстурирования, один из четырех стандартных вариантов фильтрации и, необязательный аргумент – уровень анизотропии. Для вариантов фильтрации можно сделать набор констант, чтобы обращаться к ним по именам:
Public Enum TexF TexF_None TexF_BiLinear TexF_TriLinear TexF_Anisotropic End Enum
Имена констант говорят сами за себя, так что расшифровывать не буду.
Теперь нам понадобится две пары текстурных координат, поэтому переделаем формат вертекса:
Private Type vFormat Pos As D3DVECTOR tu0 As Single tv0 As Single tu1 As Single tv1 As Single End Type
Так же переделаем его флаговое описание:
Private Const vFlag = D3DFVF_XYZ Or D3DFVF_TEX2
И функцию Vertex:
Private Function Vertex(x As Single, y As Single, z As Single, tu0 As Single _ , tv0 As Single, tu1 As Single, tv1 As Single) As vFormat Vertex.Pos = vec3(x, y, z) Vertex.tu0 = tu0 Vertex.tv0 = tv0 Vertex.tu1 = tu1 Vertex.tv1 = tv1 End Function
Вспомним, как мы генерировали цилиндр, и немного переделаем с учетом применения двух текстур:
Private Sub InitGeometry() Dim Vert(1) As vFormat Dim n As Long vSize = Len(Vert(0)) Set vBuf = 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), _ 3 * n / 64, 0, 12 * n / 64, 0) Vert(1) = Vertex(Sin(2 * Pi * n / 64), -1, Cos(2 * Pi * n / 64), _ 3 * n / 64, 1, 12 * n / 64, 4) D3DVertexBuffer8SetData vBuf, vSize * 2 * n, vSize * 2, 0, Vert(0) Next n End Sub
Создадим две текстуры:
Set Tex0 = d3dx.CreateTextureFromFile(d3dDevice, App.Path & "\brick.jpg") Set Tex1 = d3dx.CreateTextureFromFile(d3dDevice, App.Path & "\detail.jpg")
Файлы brick.jpg" alt="Фото" /> и detail.jpg есть в папке Pr14.
Также подберите подходящие матрицы для основных трансформаций (это вы уже можете), впишите все необходимое для создания и уничтожения цилиндра с двумя текстурами и инициализации QueryPerformanceCounter. В основной цикл можно вписать такие строки:
D3DXMatrixRotationY Mtrx, QTime * 0.5 d3dDevice.SetTransform D3DTS_WORLD, Mtrx D3DXMatrixLookAtLH Mtrx, vec3(0, 0, -7 + 5 * Sin(QTime * 0.5)), vec3(0, 0, 0), vec3(0, 1, 0) d3dDevice.SetTransform D3DTS_VIEW, Mtrx
Здесь мы заставляем выводимую геометрию вращаться, а камеру циклично приближаться и удаляться от начала координат. Можно также включить фильтрацию текстур обеих стадий, не зря же мы писали процедуру
TexFilter: TexFilter 0, TexF_TriLinear TexFilter 1, TexF_TriLinear
Запускаем программу – цилиндр черный. Это мы уже проходили! Настраиваем нулевую стадию текстурирования:
d3dDevice.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 d3dDevice.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE
Теперь все в порядке, цвет появился, но текстура только одна, первая стадия текстурирования выключена. Во-первых, в процедуре Render нужно указывать не одну, а две текстуры:
d3dDevice.SetTexture 0, Tex0 d3dDevice.SetTexture 1, Tex1
Во-вторых, укажем аргументы и оператор для первой стадии:
d3dDevice.SetTextureStageState 1, D3DTSS_COLOROP, D3DTOP_MODULATE2X d3dDevice.SetTextureStageState 1, D3DTSS_COLORARG1, D3DTA_TEXTURE d3dDevice.SetTextureStageState 1, D3DTSS_COLORARG2, D3DTA_CURRENT
Здесь мы первый аргумент, текстуру, умножаем на второй – D3DTA_CURRENT, этот аргумент – результат работы предыдущей стадии текстурирования. Обратите внимание, что умножение используется не D3DTOP_MODULATE, а D3DTOP_MODULATE2X. Этот оператор домножает результат перемножения аргументов на 2, что позволяет использовать одну текстуру в качестве карты теней для другой. Вспомните, что в Direct3D компоненты цвета лежат в диапазоне от 0 до 1. Если использовать в качестве второго аргумента серую текстуру (R = 128, G = 128, B = 128), мы умножаем первый аргумент сначала на 0.5, потом на 2 – то есть не меняем. Если на серой текстуре сделать более темные и более светлые места – в этих местах первый аргумент будет соответственно затемняться и высветляться.
Обратите внимание, что текстурные координаты у первой текстуры расположены более «густо», чем у нулевой. Это позволяет добиться детализации нулевой текстуры при сильном приближении.
24 ноября 2016 в 13:11
To why viagra for sale It solid and nutty /nati/http://c9superactive.com/ , -commercial.
24 ноября 2016 в 13:11
Receive a Trade Alert for generichttp://c9superactive.com/ , cialis tadalafil directly to your email.
авторизуйтесь
или войдите через