Ausarbeitung

Werbung
Stefan Omert
Java Bindings for OpenGL
Java Bindings
for OpenGL
(JOGL)
Eine Ausarbeitung von
Stefan Omert
im Rahmen der Lehrveranstaltung
Graphisch Interaktive Systeme
1
Stefan Omert
Java Bindings for OpenGL
Inhaltsverzeichnis
1. Einleitung.........................................................................................................................3
2. Was ist JOGL?.................................................................................................................3
3. Abgrenzung von JOGL zu anderen Bindings...............................................................4
4. Installation.......................................................................................................................5
4.1 Voraussetzungen...................................................................................................5
4.2 Windows XP............................................................................................................5
4.3 Einrichten der Entwicklungsumgebung Eclipse......................................................7
5. Aufbau von JOGL............................................................................................................8
5.1 Klassenhierarchie...................................................................................................8
5.2 Interfacehierarchie................................................................................................10
5.3 Wichtige Klassen und Interfaces...........................................................................10
6. Grundgerüst eines JOGL-Programm..........................................................................12
6.1 Verwendung von GLCanvas.................................................................................12
6.2 Verwendung von GLJPanel..................................................................................13
7. Tutorial............................................................................................................................14
7.1 Einfaches Fenster.................................................................................................14
7.2 Fenster mit RGB-Würfel........................................................................................17
7.3 Maussteuerung.....................................................................................................20
7.4 Tastatursteuerung.................................................................................................22
7.5 Animation (kreisende Kugel).................................................................................23
8. Schlusswort...................................................................................................................26
9. Anhang...........................................................................................................................27
9.1 Quellen..................................................................................................................27
2
Stefan Omert
Java Bindings for OpenGL
1. Einleitung
Im Mai 1995 wurde Java offiziell als Programmiersprache vorgestellt. Java ist eine
objektorientierte
und
plattformunabhängige
Hochsprache
mit
umfangreichen
Bibliotheken und einer guten, übersichtlichen Dokumentation. Java kann für
unterschiedlichste Aufgaben, wie z.B. zur Anwendungsentwicklung oder zur
Netzwerkprogrammierung, eingesetzt werden. In der Entwicklung für Computerspiele
konnte sich Java aber nicht durchsetzen, da es keine Unterstützung für OpenGL gab,
und OpenGL als Standard für die Entwicklung von 2D- und 3D-Applikationen gilt.
Deshalb versuchte man dies mit der Eigenentwicklung Java3D zu kompensieren.
Diese konnte sich aber wegen der geringeren Performance bei der Umsetzung von
3D-Objekten
nicht
in
der
Spielentwicklung
durchsetzen.
Deshalb
wurden
verschiedene Bindings entwickelt, darunter auch das Java Binding for OpenGL (JSR
231, JOGL).
2. Was ist JOGL?
JOGL ist ein Open-Source Projekt, welches 2003 von der Game Technology
Group von Sun Microsystems ins Leben gerufen wurde. JOGL wurde mit dem Ziel
entwickelt
hardwarebeschleunigte
3D-Grafiken
mit
Hilfe
einer
low-level
Grafikbibliothek in Java verwirklichen zu können. Da heutzutage OpenGL das
Standard low-level 3D Application Programming Interface (API) auf dem Markt ist,
hat man sich für ein Binding mit dieser Grafikbibliothek entschieden. Die
Entwicklung wird von Sun Microsystems (Java) und Silicon Graphics Incorporated
(OpenGL) unterstützt, wodurch die ständige Weiterentwicklung und Pflege des
Projektes gesichert ist.
Mithilfe von JOGL kann ein Programmierer in Java auf die Funktionen von
OpenGL
zugreifen.
Zu
diesem
Zweck
besitzt
JOGL
spezielle
Java-
Wrapperklassen, welche als Schnittstellen zu den nativen Funktionen von OpenGL
dienen. Die Methoden dieser Schnittstellen führen dabei einfach den C-Code der
entsprechenden Funktionen aus. Dies wird mit Hilfe des Java Native Interface
(JNI) erreicht. Das JNI ermöglicht es betriebssystemspezifische Funktion und
Methoden aus dem bertriebssystemunabhängigen Java heraus aufzurufen. So
besteht die Möglichkeit auf Bibliotheken des Betriebssystems zuzugreifen die auch
in einer anderen Sprache, wie z.B. C oder C++, verfasst sein können. Durch den
direkten
Zugriff
auf
den
nativen
3
C-Code
entstehen
auch
kaum
Stefan Omert
Java Bindings for OpenGL
Geschwindigkeitseinbußen.
JOGL stellt die meisten Features von OpenGL, der GLU und der GLUT
Bibliotheken zur Verfügung. Funktionen der OpenGL Utility Library (GLU) sind z.B.
die Unterstützung beim Rendern von Kugeln, Zylindern und anderen grafischen
3D-Objekten aber auch die Kamerapositionierung usw. JOGL implementiert aber
nur einen Teil der Funktionen des OpenGL Utility Toolkit (GLUT) wie
beispielsweise
die
Realisierung
von
grafischen
Grundprimitiven.
Die
Fenstersystemfunktionen der GLUT wurden nicht mit übernommen, da Java sein
eigenes high-level Fenstersystem mitbringt. Das heißt Java-Programmierer
müssen sich nicht mit neuen Funktionen aus der GLUT befassen sondern können
Fenster mit den AWT- und Swing-Komponenten realisieren, was den Einstieg in
JOGL wesentlich erleichtert.
3. Abgrenzung von JOGL zu anderen Bindings
Um 2D- und 3D-Grafiken mit Java realisieren zu können, wurden von den
Entwicklern einige OpenGL-Bindings auf den Markt gebracht. Die drei bekanntesten
sind gl4java (OpenGL for Java), Magician und LWJGL (Lightweight Java Game
Library). Doch alle diese Bindings haben ihre Probleme oder verfolgen andere Ziele
als JOGL.
Gl4Java unterstützt OpenGL nur bis zur Version 1.3, neuere I/O-Geräte werden nur
teilweise unterstützt, außerdem macht es die sehr umfangreiche API Entwicklern
schwer den Einstieg zu finden.
Das Problem von Magician liegt darin das es weder neue I/O-Geräte unterstützt noch
wird es nicht weiterentwickelt. Zudem ist es kein Open-Source-Projekt, was einen
weiteren Nachteil darstellt.
Die LWJGL unterstützt zwar neuste I/O-Geräte und auch die aktuelle Version von
OpenGL, jedoch liegt ihr Nachteil in der unzulässigen Einbindung von AWT- und
Swing-Komponenten.
Mit diesen Bindings war der Anfang gemacht. Nun versuchte man 2003 mit der
Entwicklung von JOGL die Vorteile dieser Technologien zu vereinen und die Probleme
zu beheben. Ken Russell und Kris Kline legten den Grundstein für JOGL. Die weitere
Entwicklung wurde dann von der Game Technology Group, mit Unterstützung von
Sun und SGI, übernommen.
4
Stefan Omert
Java Bindings for OpenGL
4. Installation
4.1 Voraussetzungen
JOGL setzt eine vorhandene Java Installation voraus. Falls diese nicht vorhanden
ist
muss
im
Vorfeld
die
J2SDK
in
der
aktuellen
Version
von
Sun
(www.java.sun.com) heruntergeladen und installiert werden.
4.2 Windows XP
a) Um JOGL verwenden zu können muss man sich das aktuelle JOGL- Paket von
der Jogl-Seite (https://jogl.dev.java.net/) herunterladen. Hier findet man das
Paket unter „Current nightly build“. Für Windows ist es zurzeit z.B. das Zip-Archiv
„jogl-1.1.1-rc6-windows-i586.zip“.
b) Im zweiten Schritt entpackt man das Archiv in einen beliebigen Ordner. Dieser
sollte nun mindestens die folgende Dateien enthalten:
Userguide.html (Kleines Handbuch mit Installationsanleitung)
Im Unterordner lib:
jogl.jar
gluegen-rt.jar
jogl.dll
gluegen-rt.dll
jogl_awt.dll
jogl_cg.dll
c) Nun müssen die kompletten Pfade zu den Dateien jogl.jar und gluegenrt.jar in die Umgebungsvariable CLASSPATH eingetragen werden. Die
Umgebungsvariablen sind zu finden unter: Systemsteuerung à System à
Erweitert à Umgebungsvariablen
5
Stefan Omert
Java Bindings for OpenGL
Bild1: Screenshots zum Einrichten der Umgebungsvariablen
d) Im letzten Schritt muss nun noch der Pfad zum Unterordner lib in die
Umgebungsvariable PATH eingetragen werden. Vorgehensweise siehe Punkt c.
e) Nachdem man sein System neu gebootet hat kann man seine JOGL-Installation
testen. Hierzu nimmt man sich eine JOGL-Datei, beispielsweise ein einfaches
Beispiel aus dem Internet, hier Jogl_test.java, und führt diese aus. Dazu öffnet
man sich ein Konsolenfenster, kompiliert die entsprechende Datei mit dem Befehl
javac Jogl_test.java und führt diese mit dem Befehl java Jogl_test
aus. Nun müsste sich ein Fenster mit dem, dem Programm entsprechenden Inhalt
öffnen, hier ein leeres Fenster.
6
Stefan Omert
Java Bindings for OpenGL
Bild2: Screenshot des Installationstests
4.3 Einrichten der Entwicklungsumgebung Eclipse
a) Zuerst muss man sich in Eclipse ein neues Javaprojekt für sein JOGLProgramm erstellen.
b) Im zweiten Schritt muss man in seinem Projekt die Dateien jogl.jar und
gluegen-rt.jar zum Java-Erstellungspfad hinzufügen. Dazu öffnet man die
Eigenschaften seines Projekts, wählt hier Java-Erstellungspfad und klickt im Reiter
Bibliotheken auf den Button „Externe JARs hinzufügen...“.
7
Stefan Omert
Java Bindings for OpenGL
Bild3: Screenshots zum Hinzufügen externer JARs
5. Aufbau von JOGL
5.1 Klassenhierarchie
•
class java.lang.Object
• class com.sun.opengl.util.Animator
• class com.sun.opengl.util.FPSAnimator
• class javax.media.opengl.AWTGraphicsConfiguration (implements
javax.media.opengl.AbstractGraphicsConfiguration)
• class javax.media.opengl.AWTGraphicsDevice (implements
javax.media.opengl.AbstractGraphicsDevice)
• class com.sun.opengl.util.BufferUtil
• class com.sun.opengl.cg.CGannotation
• class com.sun.opengl.cg.CGcontext
• class com.sun.opengl.cg.CGeffect
• class com.sun.opengl.cg.CgGL
• class com.sun.opengl.cg.CGparameter
• class com.sun.opengl.cg.CGpass
• class com.sun.opengl.cg.CGprogram
• class com.sun.opengl.cg.CGstate
• class com.sun.opengl.cg.CGstateassignment
• class com.sun.opengl.cg.CGtechnique
• class java.awt.Component (implements java.awt.image.ImageObserver,
java.awt.MenuContainer, java.io.Serializable)
• class java.awt.Canvas (implements javax.accessibility.Accessible)
• class javax.media.opengl.GLCanvas (implements
8
Stefan Omert
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Java Bindings for OpenGL
javax.media.opengl.GLAutoDrawable)
• class java.awt.Container
• class javax.swing.JComponent (implements
java.io.Serializable)
• class javax.swing.JPanel (implements
javax.accessibility.Accessible)
• class javax.media.opengl.GLJPanel (implements
javax.media.opengl.GLAutoDrawable)
• class java.awt.Panel (implements javax.accessibility.Accessible)
• class java.applet.Applet
• class com.sun.opengl.util.JOGLAppletLauncher
class com.sun.opengl.util.texture.spi.DDSImage
class com.sun.opengl.util.texture.spi.DDSImage.ImageInfo
class javax.media.opengl.DebugGL (implements javax.media.opengl.GL)
class javax.media.opengl.DefaultGLCapabilitiesChooser (implements
javax.media.opengl.GLCapabilitiesChooser)
class com.sun.opengl.util.FileUtil
class com.sun.opengl.util.Gamma
class javax.media.opengl.GLCapabilities (implements java.lang.Cloneable)
class javax.media.opengl.GLContext
class javax.media.opengl.GLDrawableFactory
class javax.media.opengl.glu.GLU
class com.sun.opengl.util.GLUT
class javax.media.opengl.glu.GLUtessellatorCallbackAdapter (implements
javax.media.opengl.glu.GLUtessellatorCallback)
class com.sun.opengl.util.ImageUtil
class com.sun.opengl.util.j2d.Overlay
class com.sun.opengl.util.Screenshot
class com.sun.opengl.util.texture.spi.SGIImage
class com.sun.opengl.util.StreamUtil
class com.sun.opengl.util.j2d.TextRenderer
class com.sun.opengl.util.j2d.TextRenderer.DefaultRenderDelegate
(implements com.sun.opengl.util.j2d.TextRenderer.RenderDelegate)
class com.sun.opengl.util.texture.Texture
class com.sun.opengl.util.texture.TextureCoords
class com.sun.opengl.util.texture.TextureData
class com.sun.opengl.util.texture.TextureIO
class com.sun.opengl.util.j2d.TextureRenderer
class com.sun.opengl.util.texture.spi.TGAImage
class com.sun.opengl.util.texture.spi.TGAImage.Header
class com.sun.opengl.util.TGAWriter
class javax.media.opengl.Threading
class java.lang.Throwable (implements java.io.Serializable)
• class java.lang.Exception
• class java.lang.RuntimeException
• class com.sun.opengl.cg.CgException
• class javax.media.opengl.GLException
class com.sun.opengl.util.TileRenderer
class javax.media.opengl.TraceGL (implements javax.media.opengl.GL)
Quelle: /JOAP/
9
Stefan Omert
Java Bindings for OpenGL
5.2 Interfacehierarchie
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
interface javax.media.opengl.AbstractGraphicsConfiguration
interface javax.media.opengl.AbstractGraphicsDevice
interface javax.media.opengl.ComponentEvents
• interface javax.media.opengl.GLAutoDrawable (also extends
javax.media.opengl.GLDrawable)
• interface javax.media.opengl.GLPbuffer
interface java.util.EventListener
• interface javax.media.opengl.GLEventListener
interface javax.media.opengl.GL
interface javax.media.opengl.GLCapabilitiesChooser
interface javax.media.opengl.GLDrawable
• interface javax.media.opengl.GLAutoDrawable (also extends
javax.media.opengl.ComponentEvents)
• interface javax.media.opengl.GLPbuffer
interface javax.media.opengl.glu.GLUnurbs
interface javax.media.opengl.glu.GLUquadric
interface javax.media.opengl.glu.GLUtessellator
interface javax.media.opengl.glu.GLUtessellatorCallback
interface com.sun.opengl.util.j2d.TextRenderer.RenderDelegate
interface com.sun.opengl.util.texture.TextureData.Flusher
interface com.sun.opengl.util.texture.spi.TextureProvider
interface com.sun.opengl.util.texture.spi.TextureWriter
Quelle: /JOAP/
5.3 Wichtige Interfaces und Klassen
Interface
Beschreibung
GLAutoDrawable Eine high-level Abstraktion, die einen eventbasierenden
Mechanismus für OpenGL Rendering anbietet.
GLEventListener Bietet Events an, welche im Code benutzt werden können um das
OpenGL Rendering in GLAutoDrawable zu managen. OpenGLCallbackmethoden wie init(), display(), reshape() und
displayChanged() sind im Interface zu implementieren.
GL
GL ist das Hauptinterface für OpenGL. Es bietet Zugang zur
gesamten OpenGL-Funktionalität an.
GLDrawable
Eine Abstraktion für ein OpenGL Rendering Target. Kann einen
OpenGL-Kontext erstellen, welcher benutzt werden kann um das
Rendering auszuführen.
10
Stefan Omert
Java Bindings for OpenGL
Klasse
Animator
Beschreibung
Ruft die display()-Methode einer oder mehrer GLAutoDrawable
Insatzen in einer Schleife auf. Kreiert einen Hintergrund-Thread um
diese Aufgabe zu erfüllen.
FPSAnimator
Direkte Unterklasse des Animator. Hier kann man eine Frames-PerSecond-Rate angeben und dadurch bestimmen wie oft die display()Methode aufgerufen wird. Dabei wird das Erfüllen der Rate nicht
garantiert aber angestrebt.
Component
Component ist eine abstrakte Klasse. Ein Component repräsentiert
ein Objekt, welches auf dem Ausgabefeld angezeigt werden kann und
mit dem Benutzer interagieren kann. Beispiele für Components sind
Buttons, Checkboxes oder Scrollbars.
Canvas
Canvas repräsentiert einen leeren rechteckigen Bereich auf dem
Display. In diesen Bereich kann eine Applikation zeichnen oder von
dort Benutzereingaben entgegen nehmen. Für eine sinnvolle
Verwendung von Canvas muss eine Unterklasse erstellt werden, in
der die paint()-Methode überschrieben wird, um entsprechende
Grafiken auf der Canvas auszugeben.
GLCanvas
GLCanvas ist eine AWT-Komponente, welche OpenGL
Renderingunterstützung anbietet. GLCanvas ist die
Hauptimplementation des GLDrawable-Interfaces.
Container
Ein Container ist eine AWT-Komponente die andere AWTKomponenten enthalten kann.
JPanel
GLJPanel
JPanel ist ein generischer leichtgewichtiger Container.
Eine leichtgewichtige Swing Komponente, welche OpenGL
Renderingunterstützung anbietet. Kompatibel mit Swing UserInterfaces.
Panel
Panel stellt einen einfachen Container dar. In diesen kann eine
Applikation alle anderen möglichen Komponenten einfügen.
GLU
Über GLU hat man Zugriff auf die OpenGL Utility Library (GLU). Die
Methoden entsprechen den Methoden der orginal C-Implementation.
GLUT
GLUT stellt eine Teilmenge des OpenGL Utility Toolkit dar. Nicht alle
Methoden des GLUT wurden implementiert. Die Methoden weichen
ein wenig von der orginal C-Implementation ab.
11
Stefan Omert
Java Bindings for OpenGL
6. Grundgerüst eines JOGL-Programm
JOGL besitzt die zwei Haupt-GUI-Klassen GLCanvas und GLJPanel. Diese
implementieren das Interface GLAutoDrawable. Die beiden Klassen werden als
„Zeichenfläche“ für die OpenGL Kommandos benutzt.
GLCanvas ist der Canvas von AWT sehr ähnlich. Es ist eine heavyweigth
Komponente, deswegen muss man aufpassen wenn man diese mit Swing
Komponenten
kombiniert.
OpenGL
Operationen
werden
durch
die
Hardwarebeschleunigung sehr schnell ausgeführt.
GLJPanel ist eine lightweight Komponente, welche ohne Probleme mit Swing
Komponenten klar kommt. Im Gegensatz zu GLCanvas ist GLJPanel etwas
langsamer in der Ausführung der OpenGL Operationen.
6.1 Verwendung von GLCanvas
Bild4: Grundaufbau eins JOGL-Fensters mit GLCanvas. Quelle: /PJ3D/
Die GLCanvas wird meist direkt ein JFrame eingefügt. Es besteht aber auch die
Möglichkeit die GLCanvas in ein JPanel zu verpacken, dadurch ist es möglich
mehrere lightweight GUI Komponenten in ein JFrame einzufügen. Die GLCanvas
wird immer in Verbindung mit einem GLEventListener verwendet, welcher die
Änderungen in der Canvas bearbeitet. Bei einem OpenGL-Programm übernimmt
normalerweise OpenGL zur Laufzeit die Kontrolle über das Programm und ruft die
entsprechenden Callback-Methoden auf. Diese Funktion wird bei JOGL durch den
GLEventListener übernommen. Wenn die Canvas nun das erste Mal erstellt wird,
wird die init()-Methode des GLEventListeners aufgerufen. Die init()-Methode wird
12
Stefan Omert
Java Bindings for OpenGL
deshalb im eigenen Programm überschrieben um den OpenGL Status zu
initialisieren. Jedes Mal wenn die die Größe der Canvas oder deren Position
verändert wird, wird die reshape()-Methode des Eventlisteners ausgeführt. Hier
kann man den entsprechenden Code platzieren, um z.B. den Viewport zu
initialisieren. Immer wenn die display()-Methode der Canvas aufgerufen wird, wird
auch die Methode display() des Eventlisteners ausgeführt. In dieser Methode kann
der Code für das Rendern der 3D Szene, die in der Canvas dargestellt werden soll
platziert
werden.
displayChanged().
Der
Diese
Eventlistener
wird
enthält
ausgeführt
auch
wenn
noch
sich
die
Methode
beispielsweise
die
Einstellungen des Monitors ändern oder die Canvas auf einen anderen Monitor
verschoben wird. Für einige grafische Anwendungen wie z.B. Animationen oder
Spiele ist es nötig die Canvas regelmäßig zu aktualisieren. Mit einem FPSAnimator
kann der Benutzer eine feste Frequenz einstellen mit der die display()-Methode der
Canvas, und somit auch die des Eventlisteners, aufgerufen werden soll. Nach
diesem Grundgerüst sind die meisten einfachen JOGL-Programme aufgebaut.
6.2 Verwendung von GLJPanel
Bild5: Grundaufbau eins JOGL-Fensters mit GLJPanel. Quelle: /PJ3D/
Da das GLJPanel eine lightweight Swing Komponente ist kann sie direkt in das
JFrame eingebettet werden, und es können auch noch weitere lightweight
Komponenten hinzu gefügt werden. Der Rest dieses Aufbaus verhält sich ebenso
wie der Aufbau mit einer GLCanvas. Das heißt man kombiniert das GLJPanel
ebenfalls mit einem GLEventListener, welcher die Änderungen auf der
Zeichenfläche bearbeitet. Mit einem FPSAnimator kann man wieder eine feste
Rate einstellen mit der das GLJPanel aktualisiert werden soll.
13
Stefan Omert
Java Bindings for OpenGL
7. Tutorial
In diesem Abschnitt möchte ich die Programmierung mit JOGL etwas näher erläutern.
Ich werde dazu ein einfaches Programm erstellen und Schritt für Schritt den
Quellcode erklären. Für die Entwicklung dieses Programms benutze ich die
Entwicklungsumgebung Eclipse in der Version 3.2 und das aktuelle JOGL-Paket in
der Version 1.1.1-rc6.
7.1 Einfaches Fenster
Ich möchte mit dem öffnen eines einfachen Fensters beginnen. Wie im Punkt 4.3
Einrichten der Entwicklungsumgebung Eclipse beschrieben erstellt man sich
zunächst ein neues Projekt und fügt die beiden Dateien jogl.jar und gluegen-rt.jar
zum Projekt hinzu. Nun erstellt man sich in seinem Projekt eine neue Klasse. Als
Superklasse sollte die Klasse JFrame eingetragen werden und als Schnittstelle
der GLEventListener. Die main-Methode sollte erstellt werden und die abstrakten
Methoden der Schnittstelle sollten auch übernommen werden.
Bild6: Screenshot zum Erstellen einer JOGL-Klasse
14
Stefan Omert
Java Bindings for OpenGL
Es müsste folgender Code entstanden sein.
Um nun ein einfaches leeres Fenster zu erzeugen müssen wir in den Code einen
Konstruktor einfügen.
15
Stefan Omert
Java Bindings for OpenGL
Zunächst werden zwei Datenfelder festgelegt, welche immer die aktuelle Größe
des Fensters enthalten. Dem Konstruktor kann man zum erzeugen des Fensters
die gewünschte Größe übergeben. Der Konstruktor erzeugt uns ein neues Objekt
welches eine Unterklasse von JFrame ist. Dadurch haben wir uns eigentlich schon
ein Fenster erzeugt. Mit der Methode setSize() der Klasse JFrame wird nun die
Größe des Fensters gesetzt. Die Methode setTitle() legt einen Titel des Fensters
fest, welcher in der obersten Leiste des Fensters erscheint. Im nächsten Schritt
erzeugt man sich eine GLCanvas als Zeichenfläche für OpenGL-Befehle. Dieser
fügt man den GLEventListener hinzu, der die Callbackfunktionen von OpenGL
realisiert. Die Zeichenfläche muss natürlich in das Fenster eingefügt werden, dies
geschieht mit der Methode add() von JFrame. Nun fügen wir noch einen
WindowListener ein, der beim Schließen des Fensters das Programm beendet. Im
letzten Schritt müssen wir das Fenster mit der Methode setVisible() noch sichtbar
machen. Die Callbackfunktionen init(), displayChanged(), display() und reshape()
bleiben zunächst leer, da wir ja ein leeres Fenster ohne Objekte wollen. Die mainMethode hat nur die Aufgabe ein Objekt der eigenen Klasse zu erzeugen.
Nun kann man das Programm in Eclipse einfach als Java-Anwendung ausführen.
Bild7: Screenshot zum Ausführen eines JOGL-Programms
16
Stefan Omert
Java Bindings for OpenGL
Anschließend öffnet sich ein einfaches leeres Fenster mit der Überschrift
Mein_Tutorial.
Bild8: Einfaches leeres Fenster mit JOGL erstellt
7.2 Fenster mit RGB-Würfel
In diesem Abschnitt wollen wir unser erstes Objekt auf der Zeichenfläche im
Fenster realisieren. Der Grundaufbau dieses Programms sieht genauso aus wie im
Abschnitt zuvor. Wir müssen uns natürlich wieder ein Fenster mit einer
Zeichenfläche schaffen, wie das funktioniert sollte nun jeder wissen. Der
Konstruktor und die main-Methode können aus dem ersten Beispiel übernommen
werden. Die init() Methode des GLEventListener wird zuerst und nur einmal beim
erzeugen des Fensters aufgerufen.
Der erste Schritt in jeder Callbackfunktion ist es sich ein GL-Objekt zu holen. Das
Interface GL bietet nämlich alle Methoden von OpenGL an. Dann wird in der init()Methode zunächst die Hintergrundfarbe, wie aus OpenGL bekannt, gesetzt. Da es
sich bei unserem RGB-Würfel um ein 3D-Objekt handelt, müssen wir natürlich den
17
Stefan Omert
Java Bindings for OpenGL
Tiefenbuffer aktivieren und eine Tiefenfunktion festlegen. Der Löschwert für den
Tiefenbuffer wird stets auf die größte Tiefe gesetzt. Die reshape()-Methode wird
aufgerufen wenn das Fenster verschoben wird oder die Größe des Fensters
geändert wird, also auch beim Erzeugen des Fensters.
Zunächst werden die Variablen für die Höhe und die Breite des Fensters
aktualisiert. Mit glViewport() wird der Viewport an die Fenstergröße angepasst. Die
Funktion glOrtho() legt das Viewingvolumen fest. Um den Betrachtungspunkt
einstellen zu können, muss man sich erst ein GLU-Objekt erstellen, welches die
OpenGL Utility Bibliothek darstellt. Mit der Methode gluLookAt() dieser Klasse
kann man dann den Betrachtungspunkt einstellen. Um den Würfel als 3D-Objekt
zu erkennen wird der Augpunkt nach links-vorne-oben gelegt. In der display()Methode wird die Hauptarbeit erledigt, nämlich das eigentliche zeichnen des
Objektes.
Der erste Schritt ist es den Colorbuffer und den Depthbuffer mit den in der init()Methode eingestellten Werten vorzuinitialisieren. Danach wird eine Hilfsfunktion
aufgerufen die das Objekt zeichnet. Natürlich könnte man auch den ganzen Code
zum Zeichnen des RGB-Würfels direkt in der display()-Methode unterbringen. Aber
der besseren Übersichtlichkeit wegen habe ich diesen Code ausgelagert. In der
18
Stefan Omert
Java Bindings for OpenGL
Methode objektZeichnen() wird der RGB-Würfel aus sechs Rechtecken aufgebaut.
Aus dieser Methode möchte ich nur einen Codeausschnitt für eines der Rechtecke
zeigen. Die anderen Rechtecke werden genauso erzeugt nur mit entsprechend
anderen Koordinaten und Farben.
Mit den aus OpenGL bekannten Funktionen gl.Begin() und gl.End() kann man
grafische Primitiven erstellen. Der Übergabe Wert GL_POLYGON erlaubt es
Polygone über die Angabe von Vertexen (Koordinaten) zu realisieren. Über
glColor3f() kann man die Farbe der Vertexe einstellen. Mit glVertex3f wird eine
Koordinate festgelegt. Die Farben zwischen den Vertexen werden beim
Shmoothshading, welches als Standard eingestellt ist, interpoliert. Über jeweils vier
Koordinaten kann man dann die sechs Rechtecke erstellen aus denen sich der
RGB-Würfel zusammensetzt. Beim Ausführen dieses Programms müsste sich
dann folgendes Bild ergeben.
Bild9: Fenster mit RGB-Würfel mit JOGL erstellt
19
Stefan Omert
Java Bindings for OpenGL
Es fällt auf das es kein richtiger Würfel ist sondern mehr ein Quader. Dies liegt
daran, dass das Viewingvolumen nicht an die Seitenverhältnisse des Fensters
angepasst ist. Dies baut man am besten in die reshape() Methode ein.
Über eine if-Abfrage findet man zunächst heraus ob das Fenster höher als breit
oder breiter als hoch ist. Im entsprechenden Fall passt man entweder die Höhe
oder die Breite des Viewingvolumen an das Seitenverhältnis des Fensters an.
7.3 Maussteuerung
In diesem Abschnitt möchte ich euch zeigen wie man mit JOGL Mauseingaben im
Fenster verarbeiten kann. Dazu möchte ich den im vorherigen Abschnitt erstellten
RGB-Würfel bei entsprechender Mausbewegung um die X- bzw. Y-Achse rotieren
lassen. Mauseingaben werden wie von Java her bekannt bearbeitet. Dazu werden
zunächst
die
beiden
Interfaces
MouseListener
und
MouseMotionListener
zusätzlich implementiert.
Natürlich muss man durch diesen Schritt alle abstrakten Methoden der Interfaces
implementieren. Die meisten Methoden werden in unserem kleinen Beispiel
allerdings
leer
bleiben.
Die
beiden
Methoden
mousePressed()
und
mouseDragged() werden unsere gewünschte Funktionalität erfüllen, da wir den
Würfel nur mit gedrückter Maustaste bewegen wollen. Die beiden Listener müssen
natürlich wissen wo sie ihre Eingaben her bekommen, deshalb müssen sie sich
beim GLAutoDrawable-Interface anmelden. Diesen Code bringt man am besten in
der init()-Methode unter.
20
Stefan Omert
Java Bindings for OpenGL
In der mousePressed-Methode werden nur die Koordinaten des Mauszeigers
gespeichert sobald eine Taste der Maus betätigt wird.
Die Methode mouseDragged() wird angesprochen wenn die Maus mir gedrückter
Taste bewegt wird. In dieser Methode werden dann ständig die Koordinaten der
Maus eingelesen. Aus der Startposition der Maus und der aktuellen Position
werden dann die entsprechenden Rotationswinkel für den Würfel errechnet. Um
die Rotation anzuzeigen muss am Ende noch die display()-Methode der
Zeichenfläche angesprochen werden. In dieser Methode wird der Würfel dann
entsprechend gedreht und neu in das Fenster gezeichnet.
Wenn man das Programm nun ausführt kann man den Würfel ganz einfach mit der
Maus um seine X- bzw. Y-Achse drehen.
21
Stefan Omert
Java Bindings for OpenGL
Bild10: Fenster mit verdrehtem RGB-Würfel mit JOGL erstellt
7.4 Tastatursteuerung
Dieser Abschnitt befasst sich mit Tastatureingaben und wie man diese unter JOGL
auswerten kann. In diesem Beispiel wollen wir die Tastatureingaben nutzen um
den Shadingmode um zu schalten. Das Drücken der Taste 'f' soll Flatshading
einstellen und die Taste 's' soll Smoothshading einstellen. Die Vorgehensweise ist
ähnlich der im vorherigen Abschnitt besprochenen Maussteuerung. Zunächst wird
noch das Interface KeyListener implementiert.
In der init()-Methode meldet man den KeyListener genauso wie die MouseListener
an.
Die Methode des KeyListeners die wir mit Code versehen müssen ist keyTyped().
22
Stefan Omert
Java Bindings for OpenGL
Diese Methode wird aufgerufen wenn eine Taste gedrückt wird. Durch die switchcase-Anweisung wird bestimmt welche Taste gedrückt wurde, und die Variable
shadeMode wird entsprechend gesetzt. Natürlich muss bei jedem Tastendruck das
Fenster aktualisiert werden, damit das Ergebnis auch am Bildschirm erscheint.
Dies geschieht durch Aufruf der display()-Methode. In dieser Methode wird auch
durch glShadeModel() der in der Variable shadeMode gespeicherte Shadingmodus
eingestellt.
Nun kann durch Drücken der entsprechenden Taste der Shadingmodus im
Programm umgestellt werden.
Bild10: Fenster mit RGB-Würfel mit JOGL erstellt.
Links: Shmoothshading
Rechts: Flatshading
7.5 Animation (kreisende Kugel)
Im letzten Abschnitt meines Tutorials möchte ich eine Kugel um das bisherige
Objekt, den RGB-Würfel, kreisen lassen. Für solche Animationen stellt JOGL zwei
Animatorklassen zur Verfügung. Zum einen der FPSAnimator und zum anderen
der normale Animator. Ich werde hier den FPSAnimator verwenden. Als erstes
erzeugen wir uns im Konstruktor eine Instanz des FPSAnimator.
23
Stefan Omert
Java Bindings for OpenGL
Dem Konstruktor des FPSAnimator wird die Zeichenfläche und die Frames-PerSecond-Rate übergeben. Die nächste Anweisung startet den Animator. Das hat
zur Folge, dass der Animator nun 60mal in der Sekunde die display()-Methode der
Zeichenfläche aufruft. Der Animator läuft in einem seperaten Thread. Wenn das
Fenster geschlossen wird muss man den Animator sicherheitshalber stoppen
bevor man das Programm beendet. Dies geschieht im WindowListener durch die
Methode stop() des Animators. Um nun die kreisende Kugel zu realisieren müssen
in der display()-Methode noch einige Erweiterungen vorgenommen werden.
Die OpenGL Utility Toolkit Library (GLUT) stellt eine Methode zum zeichnen einer
Kugel zur Verfügung. Mit dem glut-Objekt können wir auf diese Methode zugreifen
und so ganz einfach unsere Kugel realisieren. Mit glTranslated() wird die Kugel auf
ihre Umlaufbahn um den Würfel verschoben. Mit glRotated() wird die Kugel um
den entsprechenden Winkel rotiert. Der Rotationswinkel stammt aus der Variable
winkel. Diese Variable wird bei jedem Aufruf der display()-Methode um den selben
Wert erhöht. Somit ist eine gleichmäßige Rotation der Kugel garantiert, da die
diese Methode mit einer festen Rate aufgerufen wird. GlPushMatrix() und
glPopMatrix() sind dafür zuständig das nur die Kugel verschoben und gedreht wird
und nicht auch noch der Würfel. GlPushMatrix() sichert die oberste Matrix auf den
24
Stefan Omert
Java Bindings for OpenGL
Stack und glPopMatrix() holt diese wieder zurück. Das Ergebnis dieser
Erweiterungen im Code ist eine um den RGB-Würfel kreisende Kugel.
Bild11: Fenster mit RGB-Würfel und umkreisender Kugel mit JOGL erstellt
25
Stefan Omert
Java Bindings for OpenGL
8. Schlusswort
Ich hoffe ich konnte mit meiner Ausarbeitung jedem einen kleinen Einblick in JOGL
geben und zeigen, dass es durch dieses Binding sehr einfach ist Java und
OpenGL
zu
vereinen.
Vor
allem
die
Verwendung
von
AWT-
und
Swingkomponenten macht den Einstieg für Javaprogrammierer sehr einfach. Auch
Geschwindigkeitseinbußen im Gegensatz zu OpenGL-Programmen in C sind
kaum vorhanden.
Bei der Einrichtung und der Verwendung von JOGL sind keine nennenswerten
Probleme aufgetreten. Das einzige was am Anfang für Verwirrung sorgte, sind
veraltete JOGL-Beispiele und -Tutorials im Internet, welche veraltete JOGL-Pakete
verwendeten und mit der aktuellen Version nicht mehr kompatibel sind.
Auch wenn man nur geringe Vorkenntnisse in OpenGL und Java hat ist der
Einstieg in Grafikprogrammierung mit JOGL sehr leicht. Im Internet gibt es einige
gute Tutorials zu diesem Thema. Auch auf er Entwicklerseite und in verschiedenen
Foren bekommt man sehr viel Information zu diesem Thema und auch Hilfe bei
der Programmierung.
26
Stefan Omert
Java Bindings for OpenGL
9. Anhang
9.1 Quellen
/JODEV/
JOGL API Project, https://jogl.dev.java.net/
/JOAP/
JOGL API, http://download.java.net/media/jogl/builds/nightly/
javadoc_public/overview-summary.html
/JOIN/
JOGL.info, http://www.jogl.info/
/PRIM/
JOGL Primer, http://sol.cs.hm.edu/rs/jogl-primer/index.html
/WIK1/
Wikipedia Jogl, http://de.wikipedia.org/wiki/Jogl
/WIK2/
Wikipedia Java Standard: OpenGL,
http://de.wikibooks.org/wiki/Java_Standard:_OpenGL
/PJ3D/
Pro Java 6 3D Game Development,
http://fivedots.coe.psu.ac.th/~ad/jg2/index.html
27
Herunterladen