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