CARL VON OSSIETZKY Einführung in JOGL 2.0 Johannes Diemke Übung im Modul OpenGL mit Java Wintersemester 2010/2011 Einführung OpenGL Open Graphics Library Spezifikation für ein plattformunabhängiges API für 2D- und 3D-Computergrafik Ist als Zustandsautomat entworfen Dient als Schnittstelle zwischen Benutzer und Grafikkarte Im professionellen Bereich als 3D-Standard führend Aktuelle Version: 4.1 (26. Juli 2010) Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 2/26 Einführung Java Bindings for OpenGL Ermöglichen Java Programmen die Nutzung der OpenGL API I Wrapperklassen stellen die Schnittstelle bereit I Nutzten das Java Native Interface Der Grafikcode gleicht dem von C/C++ OpenGL Programmen I Einfache Portierung bestehender OpenGL Programme I JOGL lernen ist im Wesentlichen OpenGL lernen Eröffnet neue Einsatzgebiete für Java I Computerspiele, VR, CAD, Simulationen, . . . Versionen Stable Release: Preview Release: Johannes Diemke JOGL 1.1.1 (22. Mai 2008) JOGL 2.0 PRE 20101001 (30. Sept. 2010) OpenGL mit Java WiSe 2010 / 2011 3/26 Einführung Warum JOGL 2.0? JOGL 1.1.1 wurde nur bis OpenGL 2.1 entwickelt Ab OpenGL 3.1 ist ein Großteil der als deprecated eingestuften Funktionalität der fixed function pipeline aus der API entfernt Mit JOGL 2.0 wurden daher Profile als Abstraktion der verschiedenen OpenGL Versionen eingeführt Weiterhin wurde eine geringfügige Refaktorierung der API durchgeführt Programme die OpenGL > 2.1 verwenden wollen benötigen daher JOGL 2.0 Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 4/26 Einführung Installation von JOGL 2.0 1 JOGL 2.0 setzt eine vorhandene Installation des JDK voraus I http://java.sun.com/ 2 Um JOGL 2.0 verwenden zu können, müssen die benötigten Bibliotheken von JogAmp bezogen werden I http://jogamp.com/ 3 Als nächstes muss das Archiv mit den Bibliotheken in ein beliebiges Verzeichnis entpackt werden I Bspw. /home/trigger/lib/jogl-2.0-pre-20101001-linux-i586 I Im Unterverzeichnis ./lib befinden sich die JOGL 2.0 JAR Dateien sowie dazugehörige native Bibliotheken Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 5/26 Einführung Installation von JOGL 2.0 (Forts.) 4 Konfiguration der Eclipse IDE zur Verwendung von JOGL 2.0 I Erstellen der User Library jogl-2.0 für die JOGL Bibliothek Window I Preferences I Java I Build Path I User Libraries I New. . . Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 6/26 Einführung Installation von JOGL 2.0 (Forts.) 4 Konfiguration der Eclipse IDE zur Verwendung von JOGL 2.0 I Erstellen der User Library jogl-2.0 für die JOGL Bibliothek Window I Preferences I Java I Build Path I User Libraries I New. . . Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 7/26 Einführung Installation von JOGL 2.0 (Forts.) 4 Konfiguration der Eclipse IDE zur Verwendung von JOGL 2.0 I Hinzufügen der JOGL 2.0 JARs jogl.all.jar, gluegen-rt.jar, nativewindow.all.jar, newt.all.jar Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 8/26 Einführung Installation von JOGL 2.0 (Forts.) 4 Konfiguration der Eclipse IDE zur Verwendung von JOGL 2.0 I Setzen der Native library location der hinzugefügten JARs Native library location I Edit. . . I External Folder. . . Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 9/26 Einführung Installation von JOGL 2.0 (Forts.) 4 Konfiguration der Eclipse IDE zur Verwendung von JOGL 2.0 I Hinzufügen der jogl-2.0 User Library zu einem bestehenden Projekt Properties I Java Build Path I Libraries I Add Library. . . I User Library Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 10/26 Einführung Installation von JOGL 2.0 (Forts.) 4 Konfiguration der Eclipse IDE zur Verwendung von JOGL 2.0 I Hinzufügen der jogl-2.0 User Library zu einem bestehenden Projekt Properties I Java Build Path I Libraries I Add Library. . . I User Library Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 11/26 Einführung Erstellung einer einfachen JOGL 2.0 Applikation Ziel ist eine Applikation, die ein Fenster öffnet in welches gerendert werden kann Alternative Möglichkeiten OpenGL Zeichenflächen zu erzeugen I GLCanvas (AWT) I GLJPanel (Swing) I GLWindow (NEWT API, Bestandteil von JOGL 2.0) Vorgehen bei Verwendung des AWT 1 2 3 4 5 6 Wahl eines GLProfile Konfiguration der GLCapabilities Erstellen eines GLCanvas Implementieren des GLEventListener Hinzufügen des GLCanvas zu einem AWT Frame Erstellen eines Animator-Threads Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 12/26 Einführung Schritt 1: Wahl eines GLProfile JOGL 2.0 unterstützt verschiedene OpenGL Profile Vor der Entwicklung einer JOGL 2.0 Applikation muss zunächst ein GLProfile gewählt werden Aktuell unterstützte Profile: I GL4bc GL4 GL3bc GL3 GL2 GLES1 GLES2 GL2ES1 GL2ES2 GL2GL3 Johannes Diemke (4.x, mit x ≥ 0, d. h. GL2 plus GL4) (4.x, mit x ≥ 0) (3.x, mit x ≥ 1, d. h. GL2 plus GL3) (3.x, mit x ≥ 1) (1.x bis zu 3.0) (ES 1.x, mit x ≥ 0) (ES 2.x, mit x ≥ 0) (GL2 ∩ ES1) (GL3 ∩ GL2 ∩ ES2) (GL3 ∩ GL2) OpenGL mit Java WiSe 2010 / 2011 13/26 Einführung Schritt 1: Wahl eines GLProfile (Forts.) OpenGL 1.x bis zu 3.0 GLProfile glp = GLProfile.get(GLProfile.GL2); Die statische Methode initSingleton der Klasse GLProfile muss zwingend vor allen anderen Methodenaufrufen aufgerufen werden public class JOGL2Basecode { public static void main(String[] args) { // It is mandatory to call this methods ASAP, before // anything else. GLProfile.initSingleton(); GLProfile glp = GLProfile.get(GLProfile.GL2); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 14/26 Einführung Einschub: GLContext Anschaulich: Beschreibt Eigenschaften einer OpenGL Zeichenfläche I OpenGL Version I Farbformat, OpenGL Zustand, . . . Schritt 2: Konfiguration der GLCapabilities Ein GLCapabilities Objekt beschreibt die gewünschten Fähigkeiten eines GLContext public class JOGL2Basecode { public static void main(String[] args) { GLProfile.initSingleton(); GLProfile glp = GLProfile.getDefault(); // configure context GLCapabilities caps = new GLCapabilities(glp); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 15/26 Einführung Schritt 3: Erstellen eines GLCanvas Ein GLCanvas ist eine mit AWT kompatible OpenGL Zeichenfläche I Erstellt und verwaltet selbstständig seinen GLContext I Implementiert das GLDrawable Interface public class JOGL2Basecode { public static void main(String[] args) { GLProfile.initSingleton(); GLProfile glp = GLProfile.getDefault(); // configure context GLCapabilities caps = new GLCapabilities(glp); // a canvas based on your OpenGL capabilities GLCanvas canvas = new GLCanvas(caps); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 16/26 Einführung Schritt 4: Implementieren des GLEventListener Damit in ein GLDrawable gerendert werden kann, muss das GLEventListener Interface implementiert und angemeldet werden Daraufhin ist es möglich auf Rendering-Events des GLDrawable zu reagieren public class JOGL2Basecode implements GLEventListener { public static void main(String[] args) { GLProfile.initSingleton(); GLProfile glp = GLProfile.getDefault(); GLCapabilities caps = new GLCapabilities(glp); GLCanvas canvas = new GLCanvas(caps); canvas.addGLEventListener(new JOGL2Basecode()); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 17/26 Einführung Schritt 4: Implementieren des GLEventListener (Forts.) Die init-Methode wird nach der Erzeugung des GLContext aufgerufen I Passiert bspw. wenn ein GLCanvas erstellt wird Wird daher häufig zur Initialisierung von OpenGL genutzt I Lichter I ShadeModel I ... public void init(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); // synchronize with the refresh rate of the display (v-sync) gl.setSwapInterval(1); gl.glClearColor(0.3f, 0.3f, 0.3f, 1.0f); gl.glShadeModel(GL2.GL_SMOOTH); gl.glEnable(GL2.GL_DEPTH_TEST); } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 18/26 Einführung Schritt 4: Implementieren des GLEventListener (Forts.) Die display-Methode wird von dem GLDrawable aufgerufen, wenn ein Neuzeichen notwendig wird public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glTranslatef(0.0f, 0.0f, -10.0f); gl.glColor3f(0.65f, 0.85f, 0.65f); gl.glBegin(GL2.GL_QUADS); gl.glVertex3f(-1.0f, -1.0f, 2.0f); gl.glVertex3f(1.0f, -1.0f, 0.0f); gl.glVertex3f(1.0f, 1.0f, 0.0f); gl.glVertex3f(-1.0f, 1.0f, 2.0f); gl.glEnd(); } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 19/26 Einführung Schritt 4: Implementieren des GLEventListener (Forts.) Die reshape-Methode wird von dem GLDrawable nach einem Resize-Event aufgerufen public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL2 gl = drawable.getGL().getGL2(); GLU glu = new GLU(); if (height == 0) { height = 1; } float aspect = (float) width / (float) height; gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(45.0f, aspect, 0.1f, 100.0f); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 20/26 Einführung Schritt 4: Implementieren des GLEventListener (Forts.) Die dispose-Methode wird von dem GLDrawable vor dem Zerstören des GLContext aufgerufen Hier sollen eigentlich OpenGL Ressourcen destruiert werden I Texturen I Shader Programme I ... Benutzt aber niemand public void dispose(GLAutoDrawable drawable) { } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 21/26 Einführung Schritt 5: Hinzufügen des GLCanvas zu einem AWT Frame public static void main(String[] args) { GLProfile.initSingleton(); GLProfile glp = GLProfile.get(GLProfile.GL2); GLCapabilities caps = new GLCapabilities(glp); GLCanvas canvas = new GLCanvas(caps); canvas.addGLEventListener(new JOGL2Basecode()); Frame frame = new Frame("JOGL2Basecode"); frame.add(canvas); frame.setSize(640, 480); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 22/26 Einführung Schritt 6: Erstellen eines Animator-Threads Die display-Methode des GLDrawable wird standardmäßig aufgerufen wenn: I Resize-Events auftreten I Bedeckte Bereiche des Frames wieder sichtbar werden Um die display-Methode wiederholt aufzurufen ist ein Animator-Thread notwendig Frame frame = new Frame("JOGL2Basecode"); frame.add(canvas); frame.setSize(640, 480); final Animator animator = new Animator(canvas); ... frame.setVisible(true); animator.start(); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 23/26 Einführung Schritt 6: Erstellen eines Animator-Threads (Forts.) Animator.stop() ist blockierend und kann im AWT Thread zu Deadlocks führen Daher sollte der Aufruf einem eigenen Thread ausgeführt werden frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { new Thread(new Runnable() { public void run() { animator.stop(); System.exit(0); } }).start(); } }); frame.setVisible(true); animator.start(); Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 24/26 Einführung Das Ergebnis Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 25/26 Literatur Dave Shreiner OpenGL Programming Guide http://www.opengl-redbook.com/ Richard S. Wright, Benjamin Lipchak und Nicholas Haemel OpenGL SuperBibel http://www.starstonesoftware.com/OpenGL/ Randi J. Rost OpenGL Shading Language http://www.3dshaders.com/ Tomas Akenine-Möller, Eric Haines und Naty Hoffman Real-Time Rendering http://www.realtimerendering.com/ Johannes Diemke OpenGL mit Java WiSe 2010 / 2011 26/26