DirectX: Labirynt 3D od podstaw
15.03.2010 - Adam Błaszkiewicz
Z ramki po lewej stronie można pobrać dotychczasowy projekt. Wierzchołki i tekstury Będziemy używać paru funkcji i typów zdefiniowanych w D3DX, na przykład macierzy i wczytywania tekstur z plików. Musimy więc dołączyć odpowiedni plik nagłówkowy:
Oprócz tego, musimy dołączyć do projektu plik d3dx9.lib. Robimy to tak samo, jak poprzednio. Dopisujemy nazwę nowego pliku, oddzielając ją spacją od poprzedniej: Aby utworzyć nasz pierwszy trójkąt, będziemy potrzebowali bufora wierzchołków. Będziemy chcieli nałożyć na niego teksturę. Potrzebujemy do tego dwóch kolejnych interfejsów, do których wskaźniki będziemy pamiętać globalnie:
Utwórzmy też w tym miejscu zmienną typu HRESULT, której będziemy często chwilowo używać do sprawdzania wyniku wywołań funkcji:
Następnie utworzymy strukturę wierzchołka wraz z jej opisem dla Direct3D (FVF - Flexible Vertex Format). Wierzchołkami w postaci tej struktury będziemy wypełniać bufor wierzchołków.
Flaga D3DFVF_XYZ mówi Direct3D, że w strukturze wierzchołka znajdują się jego współrzędne x, y, z. D3DFVF_TEX1 mówi, że wierzchołek przechowuje współrzędne jednej tekstury. Pola w strukturze muszą być ułożone w odpowiedniej kolejności. Zmiana kolejności flag D3DFVF oczywiście nie przynosi żadnych efektów - jest to zwykła operacja "lub" na bitach. Kolejność danych w strukturze wierzchołka jest z góry ustalona. Przejdźmy do funkcji obsługi komunikatów okna i usuńmy całkowicie obsługę zdarzenia WM_PAINT. Będziemy renderowali kolejne klatki animacji nieustannie, więc zdarzenie to nie będzie nam potrzebne. W miejscu, w którym utworzyliśmy już urządzenie Direct3D (najlepiej jeszcze przed ShowWindow), możemy utworzyć nasz bufor wierzchołków. Robimy to za pomocą metody CreateVertexBuffer interfejsu D3DDevice. Przekazujemy jej między innymi zdefiniowany przez nas FVF, opisujący naszą strukturę wierzchołka. Gotowy bufor wypełniamy wierzchołkami, po uprzednim zablokowaniu go za pomocą metody Lock. Następnie, bufor należy odblokować poprzez Unlock.
Lock daje nam wskaźnik do miejsca w pamięci (tutaj zapisywany jest do pVertices), gdzie powinniśmy zapisać tablicę naszych wierzchołków. Następnie ustawimy następujące parametry:
D3DRS_CULLMODE określa, z której strony renderowane trójkąty mają być widoczne. Ustawienie D3DCULL_NONE mówi, że mają być widoczne z obu stron. D3DRS_LIGNTING określa, czy używamy oświetlenia. D3DRS_ZENABLE mówi Direct3D, czy chcemy używać bufora głębi. Bufor ten jest używany do zasłaniania trójkątów znajdujących się dalej od kamery przez te, które znajdują się bliżej. Stworzymy także teksturę z pliku "tekstura.bmp". Plik ten musimy umieścić w katalogu z naszą grą. Jego wymiary powinny być potęgą dwójki - np. 512x512.
Następnie, zmodyfikujemy główną pętlę programu:
Zamieniliśmy tu funkcję GetMessage na PeekMessage. Ta pierwsza zatrzymuje wykonywanie programu do czasu, aż do programu przybędzie jakiś komunikat. Natomiast PeekMessage, nawet w przypadku braku komunikatów, nie wstrzymuje wykonywania. Zwraca prawdę, jeśli pobrano nowy komunikat. W powyższym przykładzie, jeśli program nie otrzymał żadnego komunikatu, wywoływana jest funkcja Render, którą za chwilę napiszemy. W przeciwnym wypadku komunikat jest przetwarzany. Pamiętajmy także o zwolnieniu nowych interfejsów:
Powinniśmy to zrobić przed zwolnieniem D3DDevice i D3D. Pozostało nam napisanie funkcji renderującej.
W Direct3D powinniśmy ustawić trzy główne macierze, tak, jak zrobiliśmy to powyżej. Macierz świata transformuje wszystkie wierzchołki na scenie. W naszym przypadku jest to macierz identycznościowa obrócona wokół osi Y o zmienny kąt. Kolejną macierzą jest macierz widoku, która określa pozycję i obrót kamery, czyli punktu, z którego widzimy scenę. Używamy tu funkcji obliczającej macierz na podstawie współrzędnych kamery, współrzędnych punktu, w którego kierunku kamera jest skierowana i wektora wskazującego kierunek, który jest dla kamery kierunkiem w górę. Ostatnia macierz to macierz projekcji, która przekształca trójwymiarowe współrzędne wierzchołka na jego dwuwymiarowe współrzędne na ekranie. W prawdziwym programie wierzchołki są transformowane przez dużo innych macierzy (a właściwie macierze najpierw mnożone są przez siebie, a następnie grupy wierzchołków są przemnażane przez tylko jedną, połączoną macierz). Po pomnożeniu wierzchołków przez macierz świata i macierz widoku, ich współrzędne są takie, jakby kamera była umieszczona w punkcie 0,0,0 i skierowana wzdłuż rosnącej osi Z. Wtedy wystarczy użyć macierzy projekcji, aby rzutować punkty na dwuwymiarowy ekran. Aby wyrenderować trójkąt w powyższym kodzie, wybieramy odpowiednią teksturę, bufor wierzchołków i FVF, po czym wywołujemy DrawPrimitive. Funkcja ta jako argument dostaje między innymi liczbę trójkątów, które ma wyrenderować - w naszym przypadku num_v/3. Spróbujmy uruchomić nasz program (pamiętając o umieszczeniu tekstury "tekstura.bmp" w katalogu z projektem) i pozmieniać niektóre wartości w kodzie, takie jak kąt widzenia kamery, który ustawiamy jako argument funkcji D3DXMatrixPerspectiveFovLH - D3DX_PI / 3.0f, czyli 60 stopni. W drugiej części tego tutoriala zajmiemy się już właściwym labiryntem. Dotychczasowy kod źródłowy można pobrać z ramki po lewej. (6 ocen) |
Copyright © 2008-2010 Wrocławski Portal Informatyczny
design: rafalpolito.com