Trójwymiarowa wizualizacja danych przestrzennych

Transkrypt

Trójwymiarowa wizualizacja danych przestrzennych
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Trójwymiarowa wizualizacja
danych przestrzennych
Laboratorium 5. Podstawy OpenGL
1
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Wprowadzenie
OpenGL jest jednym z najpopularniejszych API do tworzenia grafiki trójwymiarowej (a także
dwuwymiarowej) z wykorzystaniem akceleracji sprzętowej. Jako że jest to standard
wieloplatformowy, aplikacje korzystające z technologii OpenGL powstają w wielu różnych
językach programowania. Na najbliższych kilku ćwiczeniach zajmiemy się tworzeniem
prostych programów korzystających z możliwości udostępnianych przez OpenGL za pomocą
biblioteki JOGL napisanej w języku Java.
Dzisiejsze zadanie należy rozpocząć od otwarcia projektu startowego w środowisku
NetBeans. Domyślnie projekt ten korzysta z bibliotek przeznaczonych dla systemów
Windows oraz Linux wyposażonych w 64-bitową wersję platformy Java. Najważniejszą klasę
w projekcie stanowi WorldMain, która zawiera metody odpowiedzialne m.in. za tworzenie
nowego okna (main), inicjalizację kontekstu graficznego (init), rysowanie zawartości sceny
(display), a także posiada ona klasy zagnieżdżone pozwalające na obsługę myszki
(WorldMouseAdapter) i klawiatury (WorldKeyAdapter). Większość elementów sceny składa
się z obiektów dziedziczących po klasie GameObject, które zostały umieszczone w kolekcji
objects w głównej klasie projektu – wyjątek stanowi klasa Camera, której zadaniem jest
umożliwienie użytkownikowi zmiany położenia widoku (za pomocą klawiszy W,S,A,D,Q,E)
oraz kąta patrzenia (za pomocą strzałek na klawiaturze). Oprócz tego rysowany jest tekst
informujący użytkownika o liczbie wyświetlanych klatek na sekundę – można wyłączyć jego
widoczność za pomocą klawisza F1.
Istnieje wiele sposobów rysowania obiektów z użyciem kontekstu OpenGL. Najprostszy
z nich sprowadza się do wykonania następujących kroków:
1. Odłożenia aktualnego stanu macierzy transformacji modeli na stos: gl.glPushMatrix();
2. Przesunięcia obiektu we właściwe miejsce: gl.glTranslatef(x, y, z);
3. Zmianie stanu atrybutów sceny, które chcemy zmodyfikować, zachowując poprzednie
wartości tych atrybutów na stosie. Poniżej przedstawiono przykład prawidłowego
sposobu wyłączenia oświetlenia dla aktualnego obiektu:
a) gl.glPushAttrib(GL2.GL_LIGHTING); // zachowanie aktualnego stanu
b) gl.glDisable(GL2.GL_LIGHTING); // zmiana aktualnego stanu oświetlenia
4. Rozpoczęcia procedury definiowania kształtu obiektu: gl.glBegin(tryb_rysowania);
5. Podaniu zestawu współrzędnych kolejnych punktów obiektu: gl.glVertex3f(x, y, z);
6. Zakończeniu procedury definiowania powierzchni modelu: gl.glEnd();
7. Przywróceniu poprzedniego stanu zmienionych atrybutów oraz macierzy transformacji
z użyciem funkcji gl.glPopAttrib() oraz gl.glPopMatrix(). Uwaga: liczba wywołań
funkcji glPopAttrib() musi być równa liczbie wywołań funkcji glPushAttrib(), to samo
dotyczy metod glPushMatrix() oraz glPopMatrix().
W kroku piątym oprócz położenia wierzchołków modelu można również zmieniać inne ich
parametry poprzez wywołanie odpowiednich metod przed wywołaniem funkcji
gl.glVertex3f(x, y, z) dla danego punktu. Przykładowe funkcje:
1. gl.glColor3f(r, g, b): zmienia kolor aktualnego punktu
2. gl.glNormal3f(x, y, z): definiuje wektor normalny wierzchołka, który decyduje
o sposobie wyliczania jego cieniowania (potrzebna tylko gdy obiekt reaguje na
oświetlenie)
2
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
3. gl.glTexCoord2f(u, v): podaje współrzędne danego punktu w przestrzeni tekstury
(wymagana tylko gdy musimy zmapować jakąś teksturę)
Warto dodać, że większość z powyższych metod wymaga podania parametrów
zmiennoprzecinkowych z zakresu <0, 1>.
Zadanie 1. (0,5 punktu)
Dodaj możliwość poruszania źródłem światła wzdłuż osi X oraz osi Z za pomocą przycisków
na klawiaturze numerycznej.
Zadanie 2. (0,5 punktu)
Zmodyfikuj plik źródłowy klasy TexturedBox w taki sposób, żeby tekstura nakładana na jej
obiekt była zmapowana według rysunku sporządzonego przez prowadzącego laboratorium.
Zadanie 3. (0,25 punktu)
Za pomocą nowego obiektu klasy TextRenderer rysuj na scenie dowolny tekst i umieść go w
głębi sceny (współrzędna Z musi być ujemna), a także zmień jego domyślny kolor.
Zadanie 4. (0,25 punktu)
Dodaj do sceny nowy obiekt klasy Quad dostępnej w pakiecie twdp.objects. Następnie
zmodyfikuj kod tej klasy w taki sposób, żeby korzystała ona z teksturowania, a także
odkomentuj fragment pliku źródłowego odpowiedzialny za tzw. blending. W konstruktorze
obiektu przekaż mu pierwszą z tekstur dostępnych w kolekcji textures (plik particle.jpg).
Zadanie 5. (1 punkt)
Stwórz nową klasę dziedziczącą po GameObject definiującą model o kształcie zbliżonym do
rysunku wykonanego przez prowadzącego. Dodaj nowy obiekt tej klasy do kolekcji objects.
Do zdefiniowania kształtu obiektu wykorzystaj tryb rysowania GL_LINE_STRIP. Nadaj temu
obiektowi kolor inny od białego i spraw, żeby nie reagował on na zmianę oświetlenia.
Wskazówka: skorzystaj ze wzoru na rysowanie okręgu:
x = promień ⋅cos (α)
z = promień ⋅sin(α)
Zadanie 6. (1 punkt)
Zmodyfikuj klasę Light w taki sposób, żeby zawierała ona własny, oteksturowany obiekt
klasy Quad korzystający z tej samej tekstury co w zadaniu 4. Przepisz odpowiednio klasę
Light, żeby położenie jej obiektu Quad było zawsze zgodne z położeniem źródła światła.
Zadanie 7. (0,5 punktu)
Dodaj do aplikacji funkcjonalność umożliwiającą zmianę koloru światła za pomocą
wybranych przez Ciebie przycisków na klawiaturze. Skorzystaj z metody setDiffuseColour()
w klasie Light. Spraw także, by zmiana koloru światła odpowiednio modyfikowała kolor
obiektu Quad w klasie Light.
3
Marek Kulawiak – Katedra Systemów Geoinformatycznych, Wydział ETI
Przykładowe zadania poprawkowe:
1. Za pomocą polecenia gl.glEnable(GL2.GL_FOG); dodaj do aplikacji efekt mgły.
Wysteruj dostępne parametry OpenGL w taki sposób, żeby mgła była łatwa do
dostrzeżenia, ale jednocześnie nie zasłaniała obiektów położonych blisko kamery.
(1 punkt)
Dodatkowe informacje
1. JOGL (Java OpenGL) Tutorial: http://www.land-of-kain.de/docs/jogl/
2. Drawing in Space: Geometric Primitives and Buffers in OpenGL:
http://www.informit.com/articles/article.aspx?p=328646&seqNum=6
3. Specyfikacja klasy TextRenderer dostępnej w pakiecie com.jogamp.opengl.util.awt:
https://jogamp.org/deployment/jogampnext/javadoc/jogl/javadoc/com/jogamp/opengl/util/awt/TextRenderer.html
4