Zapewne nie raz widząc grę w której gracz wciela się w rolę bohatera biegającego po trójwymiarowej mapie zastanawiałeś(-łaś) się w jaki sposób komputer sobie radzi z wyświetlaniem tej całej grafiki, zmienianiem położenia kamery i tak dalej… Tym razem zająłem się zagadnieniem czym jest ruchoma kamera w OpenGL.

W tym artykule chciałbym zająć się uproszczoną wersją tego problemu czyli skupić się na kamerze (poruszaniem obiektów w czasie rzeczywistym zajmę się w niedalekiej przyszłości przy okazji pisząc większy projekt). Aby niepotrzebnie nie komplikować sprawy kamera będzie poruszać się w jednej płaszczyźnie – w prawo i w lewo, tak aby móc swobodnie oglądać wygenerowaną trójwymiarową planszę, oraz do przodu i do tyłu w zależności od naciśniętego klawisza (w – ruch do przodu, s – ruch do tyłu).

W pierwszej kolejności zajmiemy się wygenerowaniem mapy po której będzie się poruszać kamera. Stworzyłem do tego celu klasę Terrain przy użyciu szumu Perlina z biblioteki libnoise. Teren jest rozłożony na płaszczyźnie wyznaczonej przez osie x i y układu współrzędnych składowa z jest generowana przez wspomnianą bibliotekę. Klasa posiada jedną metodę draw() do rysowania wygenerowanych punktów wykorzystywanej podczas wywoływania funkcji renderującej scenę.

Kamerę obsługujemy przy użyciu funkcji gluLookAt() podając jej nowe parametry podczas zaprowadzania jakiejkolwiek zmiany (obrót lub poruszenie). Położenie kamery zaczynamy renderować od początku układu współrzędnych. Jedyną wartością, która jest odchyleniem to stała jej wysokość na osi z wynosząca 2, która nie będzie modyfikowana. Gdy zachodzi obrót kamery (po naciśnięciu lewego przycisku myszki i wykonaniu przesunięcia) zmieniana jest wartość kąta (zmienna angle) o ilość pikseli pomnożonej przez dobrany empirycznie współczynik obrotu. Następnie są obliczane wartości nowego punktu (aim[0] i aim[1]) na który ma być zwrócona kamera i z nowymi wartościami wywoływana jest funkcja gluLookAt(). W przypadku gdy dokonywany jest ruch przy użyciu klawiatury – brany jest pod uwagę kierunek kamery i obliczane są nowe współrzędne jej położenia (eye[0] i eye[1]) i dodawane są do obecnego położenia, po czym wywoływana jest funkcja gluLookAt() z nowymi współrzędnymi.

Od tego wpisu nie będę już umieszczał kodu w bloczku, który był w dwóch poprzednich postach. Za to umieszczę bezpośredni link do projektu w serwisie github.com, który nieco ułatwi mi pracę nad ewentualnymi nowszymi wersjami, a skąd można go sobie łatwo pobrać.

https://github.com/lnkoc/terrain_demo

Jeśli się rozejrzysz, z pewnością zauważysz, że również znajdują się tam pozostałe projekty.

PS. Jeśli chcesz skorzystać z biblioteki libnoise proponuję jej forka, zaktualizowanego pod współczesne systemy linux (wymaga zainstalowanego cmake): https://github.com/qknight/libnoise

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *