2. Tekstury w Direct3D7

Transkrypt

2. Tekstury w Direct3D7
Direct3D7, cz. 2 - tekstury
W poprzedniej części artykułu stworzyliśmy obracającą się piramidę. Jednak omówienie
posługiwania się teksturami będzie prostsze z wykorzystaniem sześcianu. W tym celu należy
zmodyfikować procedurę geometrii:
Public Sub GEOMETRY()
DX.CreateD3DLVertex -5, -5, -5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(0)
DX.CreateD3DLVertex -5, 5, -5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(1)
DX.CreateD3DLVertex 5, -5, -5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(2)
DX.CreateD3DLVertex 5, 5, -5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(3)
DX.CreateD3DLVertex 5, -5, 5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(4)
DX.CreateD3DLVertex 5, 5, 5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(5)
DX.CreateD3DLVertex -5, -5, 5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(6)
DX.CreateD3DLVertex -5, 5, 5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(7)
DX.CreateD3DLVertex -5, -5, -5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(8)
DX.CreateD3DLVertex -5, 5, -5, DX.CreateColorRGB(1, 1, 1), 1, 0, 0, Wierzcholek(9)
End Sub
Nie zapomnijmy o zwiększeniu tablicy wierzchołków. Teraz potrzebujemy ich dziesięć:
Public Wierzcholek(10) As D3DLVERTEX 'tablica wierzchołków
Nalezy też zwiększyć liczbę wyświetlanych wierzchołków w metodzie DrawPrimitive w procedurze
RENDERLOOP:
Call Device.DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, Wierzcholek(0), 10,
D3DDP_DEFAULT)
Zmieniamy też flagę na D3DPT_TRIANGLESTRIP, bowiem teraz naszą bryłę tworzymy z trójkątów.
Tworzenie i nakładanie tekstury
Teksturanie jest niczym innym jak "naciągniętą" bitmapą na powierzchnię bryły. Będziemy
wykorzystywać jedynie bitmapy (pliki bmp), choć istnieje możliwość korzystania z innych formatów
graficznych, jednak na razie nie wiem, jak je załadować na powierzchnię DirectDraw. Jeszcze jedna
drobna uwaga: wymiary bitmapy powinny być (choć nie muszą) potęgami liczby 2, czyli np. 256x256
pikseli.
Do naszego projektu dołożymy dodatkową procedurę, tworzącą teksturę:
Public Sub CREATETEXTURE()
'...........
'...........
End Sub
Oczywiście dodajemy też jej wywołanie w funkcji main. Teksturę możemy tworzyć przed lub po stworzeniu
wierzchołków bryły, ale oczywiście przed renderowaniem.
Tak więc nasz main wygląda teraz tak:
Public Sub MAIN()
frmMain.Show
step = 1
Call INIT
Call GEOMETRY
Call CREATETEXTURE
Call RENDERLOOP
Call ENDIT
End Sub
'procedura inicjacji
'tworzenie wierzchołków
'tworzenie tekstury
'procedura renderowania
'procedura kończąca
Deklarujemy też dodatkową zmienną - powierzchnię, która będzie przechowywała teksturę:
Public tekstura As DirectDrawSurface7 'powierzchnia tekstury
Teraz zajmiemy się właściwym stworzeniem tekstury.
W procedurze CreateTexture deklarujemy zmienną opisu powierzchni DirectDrawSurface7:
Dim TekstDesc As DDSURFACEDESC2
Ustawiamy flagi tego opisu, tak, aby można było potem opisać pole DDSD_CAPS:
TekstDesc.lFlags = DDSD_CAPS
Należy zaznaczyć, że tworzona powierzchnia będzie teksturą - ustawiamy odpowiednią flagę:
TekstDesc.ddsCaps.lCaps = DDSCAPS_TEXTURE
Mamy już gotowy opis. Wywołujac metodę CreateSurfaceFromFile z obiektu DirectDraw tworzymy teksturę
z pliku bitmapy:
Set tekstura = DD.CreateSurfaceFromFile(App.path & "/" & "1TeksturaD3D.bmp", TekstDesc)
Na koniec musimy jeszcze ustawić teksturę na urządzeniu renderującym. Służy do tego odpowiednia
metodą obiektu Direct3DDevice7:
Device.SetTexture 0, tekstura
Jako drugi parametr należy przekazać nazwę powierzchni przechowującej teksturę, zaś jako pierwszy 0.
Spójrzmy na efekt naszej pracy. Na razie nie wygląda zbyt ciekawie.
Po prostu musimy odpowiednio naciągnąć teksturę na naszą bryłę. Zasady przedstawia poniższy rysunek:
Do ustawiania współrzędnej tekstury na wierzchołku służą parametry tu (odpowiada współrzędnej
poziomej) oraz tv (współrzędnej pionowej). Tak więc procedurę geometrii należy zmodyfikować np. w ten
sposób:
Public Sub GEOMETRY()
DX.CreateD3DLVertex 0, 10, 0, DX.CreateColorRGBA(0, 1, 0, 1), 1, 0.5, 0, Wierzcholek(0)
DX.CreateD3DLVertex 0, -5, 10, DX.CreateColorRGBA(1, 1, 1, 1), 1, 1, 1, Wierzcholek(1)
DX.CreateD3DLVertex 10, -5, 0, DX.CreateColorRGBA(1, 1, 1, 1), 1, 0, 1, Wierzcholek(2)
DX.CreateD3DLVertex 0, -5, -10, DX.CreateColorRGBA(1, 0, 0, 1), 1, 1, 1, Wierzcholek(3)
DX.CreateD3DLVertex -10, -5, 0, DX.CreateColorRGBA(1, 1, 0, 1), 1, 0, 1, Wierzcholek(4)
DX.CreateD3DLVertex 0, -5, 10, DX.CreateColorRGBA(1, 1, 1, 1), 1, 1, 1, Wierzcholek(5)
End Sub
Jedynka we współrzędnych oznacza wykorzystanie całej długości bądź szerokości tekstury. Jesli chcemy
skorzystać tylko z jej części, to współrzędna musi być mniejsza od jednego.
A oto efekt naszej dotychczasowej pracy:
Rozciągnięcie tekstury możemy zmieniać poprzez modyfikację współrzędnych tu i tv dla poszczególnych
wierzchołków. Dzięki temu, można używać tylko fragmentu tekstury lub nałożyć ją kilka razy. Poniżej mamy
przykład:
Przemnożyliśmy każdą współrzędną przez 0.5 - uzyskaliśmy nałożenie tylko fragmentu tekstury, a przez to
jej rozciągnięcie.
Tutaj przemnożyliśmy każdą współrzędną przez 2. Uzyskaliśmy dwukrotne wklejenie tekstury wzdłuż
każdej z osi współrzędnych. Oczywiście wartości tu i tv mogą być przemnażane niezależnie dla każdego
wierzchołka - radzę poeksperymetować.
Tryby adresowe tekstury (Texture adressing modes)
Przemnóżmy każdą współrzędną tu i tv dla każdego wierzchołka przez 3.
- ęłęóD3DTADDRESS_WRAP - to tryb domyślny (owijanie). Jego efekt widzieliśmy powyżej.
- D3DTADDRESS_MIRROR - to efekt lustra. Jego działanie widzimy poniżej:ęłęó
Jak widać każde kolejne nałożenie tekstury na ścianę jest lustrzanym odbiciem poprzedniego. W
pojedyńczym pasie używane jest odbicie względem pionowej osi. Poszczególne pasy są odbijane
wzdłuż poziomej osi.
- D3DTADRESS_CLAMP - tryb "zaciskania" (jeśli dobrze przetłumaczyłem). Pomimo
przemnażania wspólrzednych przez liczbę większą od 1, Direct3D ustawia pojedyńczą teksturę,
zaś na pozostałej części bryły rozmazuje ją. Efekt widoczny poniżej na przykładzie kraty:
tekstura (256x256) i jej nałożenie z użyciem trybu Clamp (w przykładzie współrzędne są
przemnożone przez 2).
Jest jeszcze czwarty tryb - D3DTADDRESS_BORDER, ale w chwili obecnej nie potrafię go
użyć.
Tryby ustawiamy za pomocą metody obiektu Direct3DDevice7:
Device.SetTextureStageState 0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP
gdzie ostatnim parametrem jest właśnie tryb adresowania tekstury.
Tryby możemy także ustawiać niezależnie dla osi poziomej i pionowej. Wtedy jako drugi
parametr w powyzszej metodzie należy przekazać stałą D3DTSS_ADDRESSU (dla osi X) lub
D3DTSS_ADDRESSV (dla osi Y).
Określanie zachowania się tekstury i wierzchołków
Załóżmy, że nasza bryła ma jakieś kolorowe wierzchołki, np. czerwone. Po nałożeniu tekstury
zobaczymy pewien kolor wynikowy, będący odpowiednim złożeniem koloru wierzchołków i
koloru tekstury. Przykład widzimy poniżej:
Dla porównania wierzchołki po prawej stronie mają kolor biały, aby można było zobaczyć
faktyczny kolor tekstury.
Domyślną operacją przy nakładaniu tekstury na bryłę jest przemnożenie kolorów tekstury przez
koloy wierzchołków. Dzięki temu otrzymujemy pewien kolor wypadkowy. Dla operacji takiej
potrzebne są dwa argumenty - domyślnie jest to kolor wierzchołków oraz kolor tekstury
Pierwszy argument można określić w ten sposób:
SetRenderState 0, D3DTS_COLORARG1, wartość
Jako wartość najczęściej podstawiamy:
D3DTA_DIFFUSE - argumentem jest kolor wierzchołków
D3DTA_TEXTURE - argumentem jest kolor tekstury
D3DTA_SPECULAR - argumentem jest kolor składowej odblasków zawarty w wierzchołkach
Drugi argument można określić w podobny sposób, z tą różnicą, że w funkcji
SetRenderStageState jako drugi argument ustawiamy D3DTS_COLORARG2.
Pozostał jeszcze sposób operacji wykonywanej na tych argumentach. Pod pojęciem operacji kryją
się działania logiczne na poszczególnych składowych kolorów (np. mnożenie:
REDARG1*REDARG2, GREENARG1*GREENARG2, BLUEARG1*BLUEARG2).
device.SetTextureStageState 0, D3DTSS_COLOROP, wartość
Jako wartość stosujemy zwykle:
D3DTOP_DISABLE - tekstura nie jest w ogóle brana pod uwagę. Przy ustawieniach domyślnych
dla argumentów bryła będzie miała taki kolor jak wierzchołki
D3DTOP_SELECTARG1 - pierwszy z argumentów zostanie przepisany bez zmian na wyjście.
Oznacza to, że jeśli np. ustawiliśmy - pierwszy argument - kolor wierzchołków, żaś drugi - kolor
tekstury, to bryła będzie miała wyłącznie kolor wierzchołków. Gdybysmy zrobili odwrotnie
(argument1 = kolor tekstury, argument2 = kolor wierzchołków) to bryła będzie miała tylko kolor
tekstury. Analogicznie jak dla D3DTOP_SELECTARG2
Przykład widzimy poniżej:
Ustawienia wspólne dla obu obrazków
device.SetTextureStageState 0, D3DTSS_COLORARG1, D3DTA_TEXTURE - pierwszym
argumentem jest kolor tekstury
device.SetTextureStageState 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE - drugim
argumentem jest kolor wierzchołków
device.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 (dla obrazka po
lewo)
device.SetTextureStageState 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 (dla obrazka po
prawo)
D3DTOP_MODULATE - jest to przemnożenie przez siebie argumentu pierwszego przez
argument drugi. Wartość domyślna. Efekt dla czerwonych wierzchołkówi używanej wcześniej
tekstury:
D3DTOP_MODULATE2X - przemnożenie przez siebie pierwszego i drugiego argumentu i
dodatkowo przemnożenie jeszcze wyniku przez 2. Dzięki temu zwiększa się jasność.
D3DTOP_MODULATE4X - podobnie jak poprzednio, z tym, że teraz wykonujemy dodatkowo
przemnożenie przez 4:
D3DTOP_ADD - dodawanie logiczne poszczególnych składowych do siebie (czyli: składowa
zielona arg1 OR składowa zielona arg2…):
Jeśli coś wyszło poza zakres (tzn np. otrzymaliśmy kolor 1.2, 1.5, 1.1)to jest on przycinany to
maksymalnej wartości, czyli do koloru białego (1.0, 1.0, 1.0). Efekt taki powstał na prawej stronie
bryły.
Istnieje jeszcze wiele innych flag - zapraszam do lektury DirectX7 SDK.

Podobne dokumenty