OpenGL for Java OpenGL for Java Prof. Dr. V. Stahl Ziele Bewegte Simulationen grafisch darstellen können (effizient, realistisch, dreidimensional) Grundfunktionen von OpenGL beherrschen Mathematische Voraussetzungen für Computer Grafik verstehen OpenGL for Java Prof. Dr. V. Stahl Wozu OpenGL? Computer Grafik Echtzeit 3D Grafik sehr rechenintensiv Einfache, leicht parallelisierbare Algorithmen (wenig Code, wenige Kontrollstrukturen) Viele wichtige Anwendungen geeignet für Spezialhardware (Grafikkarte) Weiterer Vorteil durch Grafik Karte: Weniger Hauptspeicherzugriffe, indem grafische Objekte direkt auf der Grafikkarte gespeichert werden. OpenGL: High level Software API für Grafik Hardware OpenGL for Java Prof. Dr. V. Stahl Was ist OpenGL? Spezifikation einer Software Schnittstelle zur Grafik Hardware (API) System- und Programmiersprachen unabhängig ca. 250 Befehle … und was nicht? GUI Programmierung, Sound, Netzwerk, usw… OpenGL for Java Prof. Dr. V. Stahl Wie funktioniert‘s? Benutzerprogramm: Aufruf von OpenGL API Funktionen Position, Form und Farbe von 3D Objekten (Würfel, Kugel, …) Position und Farbe von Lichtquellen Oberflächenbeschaffenheit (Textur) von Objekten Position und Blickrichtung der Kamera OpenGL Koordinatensystem Transformationen (Drehung, Verschiebung…) Projektion der 3D Szene auf ein 2D Bild Farbverlauf auf Flächen (Licht/Schatten) Sichtbare/verdeckte Flächen Transformation von Texturen OpenGL for Java Prof. Dr. V. Stahl Geschichte von OpenGL 1982 SGI beginnt mit der Entwicklung für High End Grafik Workstations 1992 OpenGL Version 1.0 Seit 1992 Open GL Architecture Review Board (ARB) Mitglieder: Compaq, ATI, nVidia, HP, IBM, Apple, Microsoft, … Heute: OpenGL Version 2.0 Grafikkarten Wettbewerb, Erweiterungen OpenGL for Java Prof. Dr. V. Stahl Zusätzliche Bibliotheken GLU (OpenGL Utilities) Einfache Funktionen zum Zeichnen komplexerer Objekte (Kugeln, Zylinder, Scheibe, …) Gekrümmte Flächen: NURBS Viele nützliche Hilfsfunktionen GLUT (OpenGL Utility Toolkit) Torus, Tetrahedron, Octahedron, … Text Plattformunabhängige GUI Funktionen (Fenster, Maus, Tastatur) Für GUI Funktionen verwenden wir Java! OpenGL for Java Prof. Dr. V. Stahl Zusätzliche Bibliotheken Anwendungsprogramm GLUT GLU WGL/GLX/AGL OpenGL Systemunabhängig Window System Grafik Hardware Systemabhängig OpenGL for Java Prof. Dr. V. Stahl Anwendungsprogramm GL4Java JNI GLUT GLU WGL/GLX/AGL OpenGL Systemunabhängig Window System Grafik Hardware Systemabhängig OpenGL for Java Prof. Dr. V. Stahl Triangle Das erste OpenGL Programm Starter.java Fenster erzeugen (JFrame) Zeichenfläche (Canvas3D) erzeugen und anzeigen Canvas3D.java Abgeleitet von GLAnimCanvas (GL4Java Klasse) preInit, init: Initialisierung display: Wird aufgerufen, um Bildschirm neu zu zeichnen reshape: Wird aufgerufen, wenn Fenstergröße geändert wird. OpenGL for Java Prof. Dr. V. Stahl Starter.java import javax.swing.*; import java.awt.*; class Starter { public static void main(String[] args) { // Erzeugen des OpenGL Canvas Canvas3D canvas3D = new Canvas3D(640,480); // Erzeugen des Anwendungsfensters JFrame frame = new JFrame("Triangles for Java"); // OpenGL Canvas dem Frame hinzufügen Container pane = frame.getContentPane(); pane.add(canvas3D); // Frame Grösse setzen und anzeigen frame.setSize(640,480); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } } OpenGL for Java Prof. Dr. V. Stahl Canvas3D.java import gl4java.awt.GLCanvas; class Canvas3D extends GLAnimCanvas { // Konstruktor für Gl4Java Klasse GLCanvas public Canvas3D(int w, int h) { super(w, h); } // Globale OpenGL Optionen (z.B. double buffering) setzen public void preInit() { … } // Einmaliges Initialisieren (z.B. Farbe zum Löschen) public void init() { … } // Wird aufgerufen, wenn Bildschirm neu gezeichnet werden muss public void display() { … } // Wird aufgerufen, wenn Fenstergröße geändert wird public void reshape(int width, int height) { … } } OpenGL for Java Prof. Dr. V. Stahl TriangleView reshape(int width, int height) Bildschirmbereich auf den gezeichnet werden soll in Pixel glViewport( 0,0,width,height ); Matrix, die 3D nach 2D Projektion macht Perspektivische Projektion 60 Grad Blickwinkel, Clipping Abstand 2 bis 4 glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective(60, 1.0, 2.0, 4.0); // Matrix, die Zeichenkoordinatensystem positioniert glMatrixMode( GL_MODELVIEW ); OpenGL for Java Prof. Dr. V. Stahl display Löschen was zuvor gemalt wurde glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Farbe rot einstellen glColor3f(1.0f,0.0f,0.0f); Zeichenkoordinatensystem 3 Einheiten nach hinten setzen glLoadIdentity(); glTranslatef(0.0f, 0.0f, -3.0f); Dreieck durch Eckpunkte zeichnen glBegin(GL_TRIANGLES); glVertex3f(-1.0f, -1.0f, 0.0f); // links unten glVertex3f( 1.0f, -1.0f, 0.0f); // rechts unten glVertex3f( 0.0f, 1.0f, 0.0f); // mitte oben glEnd(); OpenGL for Java Prof. Dr. V. Stahl init Interpolation wenn Eckpunkte unterschiedliche Farbe haben glShadeModel(GL_FLAT); Hintergrundfarbe Weiss glClearColor(1.0f, 1.0f, 1.0f, 0.0f); preinit Double Buffering (flüssiger bei bewegter Grafik) super.doubleBuffer = true; Für Stereo Brillen super.stereoView = false; OpenGL for Java Prof. Dr. V. Stahl TriangleInterpolation Schattierungsmodell auf GL_SMOOTH setzen Jedem Eckpunkt des Dreiecks eine andere Farbe geben gl.glBegin(GL_TRIANGLES); gl.glColor3f(1.0f,0.0f,0.0f); rot gl.glVertex3f(-1.0f, -1.0f, 0.0f); links unten gl.glColor3f(0.0f,1.0f,0.0f); grün gl.glVertex3f( 1.0f, -1.0f, 0.0f); rechts unten gl.glColor3f(0.0f,0.0f,1.0f); blau gl.glVertex3f( 0.0f, 1.0f, 0.0f); mitte oben gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl TriangleRotation, TriangleRotationView Dreieck um 20 Grad um z-Achse nach links drehen gl.glRotatef( 20.0f, 0.0f, 0.0f, 1.0f ); z-Achse OpenGL for Java Prof. Dr. V. Stahl Matrizen in OpenGL Model View Matrix glMatrixMode(GL_MODELVIEW); Legt Position und Orientierung des Koordinatensystems fest, in das als nächstes gezeichnet wird. glRotate(), glTranslate(), … 3D nach 2D Projektions Matrix glMatrixMode(GL_PROJECTION); Bestimmt, wie eine 3D Szene auf ein 2D Bild projiziert wird. - Orthogonalprojektion: glOrtho() - Perspektivische Projektion: gluPerspective(), glFrustum() Wird i.a. nur einmal gesetzt und nicht mehr geändert. OpenGL for Java Prof. Dr. V. Stahl Koordinatensystem Transformationen in OpenGL glVertex(x,y,z) Objektkoordinaten Multiplikation mit Model View Matrix glRotate(),glTranslate() Kamerakoordinaten Multiplikation mit Projektions Matrix gluPerspective() 2D Koordinaten Skalieren, Verschieben glViewPort() Bildschirmkoordinaten (Pixel) OpenGL for Java Prof. Dr. V. Stahl Etwas Mathematik… Transformationen (Translation, Rotation, Projektion) Koordinatensysteme Homogene Koordinaten OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_TRIANGLES); 4 gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); Punkt Punkt Punkt Punkt usw. 1 2 3 4 2 1 5 6 3 gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_POINTS); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 1 2 3 gl.glEnd(); Größe der Punkte gl.glPointSize(float size) OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_LINES); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 1 2 4 3 gl.glEnd(); Liniendicke gl.glLineWidth(float size) OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_LINE_STRIP); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 1 2 4 3 gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_LINE_LOOP); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 1 2 4 3 gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_TRIANGLE_STRIP); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 1 2 3 4 gl.glEnd(); OpenGL for Java 5 Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_TRIANGLE_FAN); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 5 4 1 2 3 gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_QUADS); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 4 1 1 2 3 4 3 2 7 5 6 8 gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_QUAD_STRIP); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt Punkt Punkt Punkt … 1 2 3 4 1 4 2 5 3 6 gl.glEnd(); OpenGL for Java Prof. Dr. V. Stahl OpenGL Primitive gl.glBegin(GL_POLYGON); gl.glVertex(…); gl.glVertex(…); gl.glVertex(…); usw. Punkt 1 Punkt 2 Punkt 3 … 1 5 2 4 3 gl.glEnd(); 4 1 Ränder dürfen sich nicht schneiden, sonst ist unklar was innen und außen ist! 2 3 Die Eckpunkte müssen alle in einer Ebene liegen, sonst ist unklar welche Fläche gemalt werden soll! Polygone müssen konvex sein! OpenGL for Java 5 4 1 5 2 Prof. Dr. V. Stahl 3 Polygone GL_TRIANGLES, GL_QUADS, GL_POLYGON Def. Vorderseite: Reihenfolge der Eckpunkte gegen Uhrzeigersinn 3 3 1 2 2 1 Rückseite Vorderseite 4 3 1 2 1 2 4 3 OpenGL for Java Prof. Dr. V. Stahl Polygone Polygone gefüllt, als Linien oder nur die Eckpunkte zeichnen gl.glPolygonMode( GL_FRONT, GL_POINT ) GL_BACK GL_LINE GL_FRONT_AND_BACK GL_FILL Nur Vorderseite/Rückseite zeichnen Effizienz Verdeckte Flächen bei geschlossenen Körpern gl.glEnable(GL_CULL_FACE) gl.glCullFace( GL_FRONT ) GL_BACK GL_FRONT_AND_BACK OpenGL for Java Prof. Dr. V. Stahl Bewegte Grafik In der init Methode Geschwindigkeit (Bilder pro Sekunde) super.setAnimateFps(60.0); // 60 Aufrufe von display() pro Sekunde Starten und anhalten super.start(); super.stop(); OpenGL for Java Prof. Dr. V. Stahl TriangleAnimation, TriangleAnimationView Bewegte Grafik Rotierendes Dreieck um seine (lokale) y-Achse Vorderseite ausgefüllt, Rückseite Linien OpenGL for Java Prof. Dr. V. Stahl Cube, CubeLight 3D Grafik Problem: Kein „richtiger“ 3D Eindruck wenn Flächen ausgefüllt sind! Lösung: Licht und Schatten Lichtquellen (Position, Richtung, Farbe, Ausbreitung, …) Oberflächen (Normalenvektor, Reflektionseigenschaften, Farbe, …) OpenGL for Java Prof. Dr. V. Stahl Mehr Mathematik… Licht Reflektion Normalenvektoren OpenGL for Java Prof. Dr. V. Stahl CubeLightView Diffuse Reflektion… ohne Glanz mit Glanz OpenGL for Java Prof. Dr. V. Stahl Normalenvektoren gl.glBegin(GL_QUADS); // Vorderseite gl.glNormal3f( 0.0f, 0.0f, gl.glVertex3f(-1.0f,-1.0f, gl.glVertex3f( 1.0f,-1.0f, gl.glVertex3f( 1.0f, 1.0f, gl.glVertex3f(-1.0f, 1.0f, 1.0f); 1.0f); 1.0f); 1.0f); 1.0f); // Rechte Seite gl.glNormal3f( 1.0f, 0.0f, 0.0f); gl.glVertex3f( 1.0f,-1.0f, 1.0f); gl.glVertex3f( 1.0f,-1.0f,-1.0f); gl.glVertex3f( 1.0f, 1.0f,-1.0f); gl.glVertex3f( 1.0f, 1.0f, 1.0f); // usw… gl.glEnd() OpenGL for Java Prof. Dr. V. Stahl Normalenvektoren gl.glNormal3f( 0.0f, 0.0f, 1.0f); Aktuellen Normalenvektor setzen. Dieser bleibt so lange gültig, bis ein neuer Normalenvektor gesetzt wird Möglich: An jedem Eckpunkt ein anderer „Normalenvektor“. Anwendung: Gekrümmte Flächen, die aus vielen Einzelpolygonen bestehen. Lichtverlauf an den Kanten dann glatter („smooth shading“). OpenGL for Java Prof. Dr. V. Stahl Licht // Licht aktivieren gl.glEnable(GL_LIGHTING); Ab jetzt Farbberechnung nur noch mit Licht und Oberflächen! Aufrufe von glColor werden ignoriert! // Einzelne Lichtquellen einschalten (maximal 8) gl.glEnable(GL_LIGHT0); gl.glEnable(GL_LIGHT1); gl.glEnable(GL_LIGHT2); OpenGL for Java Prof. Dr. V. Stahl Licht // Position der i-ten Lichtquelle // Unendlich weit in z-Richtung, daher parallele Strahlen float[] position = { 0.0f, 0.0f, 1.0f, 0.0f }; gl.glLightfv( i, GL_POSITION, position ); // Farbe der i-ten Lichtquelle (RGBA) float[] color = { 1.0f, 1.0f, 1.0f, 1.0f } gl.glLightfv( i, GL_DIFFUSE, color); GL_AMBIENT GL_SPECULAR OpenGL for Java Prof. Dr. V. Stahl Licht (S ) t h ig l t po // Richtung der Lichtstrahlen float[] direction = { 0.0f, 0.0f, -1.0f } gl.glLightfv( i, GL_SPOT_DIRECTION, direction ); // Öffnungswinkel der Lichtstrahlen gl.glLightf( i, GL_SPOT_CUTOFF, angle); // Exponentielles Abfallen von der Mitte zum Rand gl.glLightf( i, GL_SPOT_Exponent, exp); position angle direction OpenGL for Java Prof. Dr. V. Stahl Material // Reflektionseigenschaften (RGBA) float[] color = { 1.0f, 0.0f, 0.0f, 1.0 } gl.glMaterialfv( GL_FRONT, GL_DIFFUSE, color ); GL_BACK GL_AMBIENT GL_FRONT_AND_BACK GL_SPECULAR GL_AMBIENT_AND_DIFFUSE GL_EMISSION // Glanz (für specular reflection) gl.glMaterialf( GL_FRONT, GL_SHININESS, factor); GL_BACK GL_FRONT_AND_BACK OpenGL for Java Prof. Dr. V. Stahl CubeSpot Material Weißen, rotierenden Würfel mit einem roten und einem blauen Spotlight anstrahlen. Die Lichtquellen drehen sich nicht mit! Was passiert wenn man backface culling abschaltet? Würde ein nicht-konvexes Objekt richtig dargestellt? OpenGL for Java Prof. Dr. V. Stahl CubeTexture Texturen Idee: Bild auf die Oberflächen von Objekten kleben 1 0 0 Texturbild 1 Polygon Jedem Eckpunkt des Polygons einen Punkt der Textur zuordnen. Texturkoordinaten: glTexCoord2f() Farbwerte innerhalb des Polygons durch Interpolation. OpenGL for Java Prof. Dr. V. Stahl Texturen import gl4java.utils.textures.PngTextureLoader; // Texturbild lesen (Abmessungen müssen 2er Potenz sein!) PngTextureLoader texload = new PngTextureLoader(gl, glu); texload.readTexture("textures/ambrosil.png"); // Textur in Speicher auf Grafik Karte laden glTexImage2D( GL_TEXTURE_2D, 01, GL_RGB, texload.getImageWidth(), texload.getImageHeight(), 02, GL_RGB, GL_UNSIGNED_BYTE, texload.getTexture() ); 1 Mip Maps 2 Rand // Interpolation glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); GL_TEXTURE_MIN_FILTER GL_NEAREST OpenGL for Java Prof. Dr. V. Stahl Texturen CubeIntersect Zwei rotierende Marmorwürfel nebeneinander zeichnen so dass sie sich überschneiden. Jeder Würfel dreht sich um eine Achse durch seinen Mittelpunkt! Würfel zeichnen in eigene Methode kapseln und zweimal aufrufen. Momentane Matrix auf Stapel speichern bzw. zurück holen: glPushMatrix, glPopMatrix Hidden Surface Problem: gl.glEnable(GL_DEPTH_TEST); z-Puffer Algorithmus Warum reicht backface culling nicht mehr aus? OpenGL for Java Prof. Dr. V. Stahl GLU Quadrics Kugel, Zylinder, Scheibe // Quadric erzeugen bzw. löschen long quad = glu.gluNewQuadric(); glu.gluDeleteQuadric( quad ); // Kugel glu.gluSphere( quad, radius, kuchenstücke, stapel ); // Zylinder glu.gluCylinder( quad, radius_unten, radius_oben, höhe, kuchenstücke, stapel ); // Scheibe glu.gluDisk( quad, radius_innen, radius_außen, kuchenstücke, ringe ); OpenGL for Java Prof. Dr. V. Stahl Quadric GLU Quadrics // Darstellung glu.gluQuadricDrawStyle( quad, GLU_FILL ); GLU_POINT GLU_LINE GLU_SHILOUETTE // Normalenvektoren automatisch erzeugen glu.gluQuadricNormals( quad, GLU_SMOOTH ); GLU_FLAT GLU_NONE // Texturkoordinaten automatisch erzeugen glu.gluQuadricTexture( quad, GL_TRUE ); GL_FALSE OpenGL for Java Prof. Dr. V. Stahl EarthMoon GLU Quadrics Flat shading statt smooth shading bei der Berechnung der Normalenvektoren Mond um Erde kreisen lassen (moon.png) Texturen in init-Methode laden und auf Grafikkarte speichern // Platz für ID’s für 2 Texturobjekte int[] textures = new int[2]; // Texturobjekte erzeugen, ID’s in textures speichern gl.glGenTextures(2, textures); // i-te Textur zur aktuellen Textur machen gl.glBindTexture(GL_TEXTURE_2D, textures[i]); OpenGL for Java Prof. Dr. V. Stahl Positionierung der Kamera glu.gluLookAt ( double eyex, double eyey, double eyez, // Punktvektor double atx, double aty, double atz, // Punktvektor double upx, double upy, double upz // Richtungsvektor ); eye up at OpenGL for Java Prof. Dr. V. Stahl Positionierung der Kamera glu.gluLookAt ( double eyex, double eyey, double eyez, // Punktvektor double atx, double aty, double atz, // Punktvektor double upx, double upy, double upz // Richtungsvektor ); In „Wirklichkeit“ wird die gesamte Szene bewegt! Die Kamera steht nach wie vor im Koordinatenursprung und schaut in negative z-Richtung. Multiplikation der Model View Matrix mit einer entsprechenden Matrix von links. (Transformation bzgl. Ursprungskoordinatensystem!) Daher: gluLookAt gleich nach glLoadIdentity aufrufen! OpenGL for Java Prof. Dr. V. Stahl Positionierung der Kamera Kamera mit Cursor Tasten in x- und y-Richtung bewegen. Kamera soll dabei immer gerade aus in negative z-Richtung schauen. import java.awt.event.KeyEvent; import java.awt.event.KeyListener; // Klasse Canvas3D ist Key Listener class Canvas3D extends GLAnimCanvas implements KeyListener // Im Konstruktor von Canvas3D addKeyListener(this); // Callback public void public void public void Funktionen keyTyped(KeyEvent e){} keyReleased(KeyEvent e){} keyPressed(KeyEvent e) { … } OpenGL for Java Prof. Dr. V. Stahl LookAt, LookAtView OpenGL for Java Prof. Dr. V. Stahl Pick Picking & Selection Ziel: 3D Objekte mit der Maus anklicken Problem: Verdeckungen (welches Objekt wurde angeklickt?) Umrechnen von Mauskoordinaten in Weltkoordinaten Vorgehen: Bild intern neu zeichnen, allerdings nur einen ca. 4x4 Pixel Ausschnitt um die aktuelle Mausposition. Mitprotokollieren welches Objekt in welcher Tiefe gemalt wurde. Ergebnisliste (Objekte mit Tiefeninformation) auswerten. OpenGL for Java Prof. Dr. V. Stahl Picking & Selection Ausschnitt um die aktuelle Mausposition (x,y) zeichnen. Dazu PickMatrix links an Projektionsmatrix multiplizieren // Projektionsmatrix neu berechnen gl.glLoadIdentity(); glu.gluPickMatrix(x,height-y, 4, 4, viewport); glu.gluPerspective(60, 1.0,2.0,4.0); Liste initialisieren, in der die getroffenen Objekte gespeichert werden. Render Mode auf GL_SELECT setzen. int[] nameBuffer = new int[100]; gl.glSelectBuffer(100,nameBuffer); gl.glRenderMode(GL_SELECT); gl.glInitNames(); gl.glPushName(0); OpenGL for Java Prof. Dr. V. Stahl Picking & Selection Bild intern neu zeichnen. Objekte durch Zahlen benennen, z.B. gl.glLoadName(42); gl.glRectf(-1.0,1.0,-1.0,1.0); Auf Render Mode GL_RENDER zurückschalten. int hits = gl.glRenderMode(GL_RENDER); Für jedes getroffene Objekt enthält nameBuffer nun vier Zahlen: 1 minimale und maximale Tiefe des getroffenen Ausschnitts Objektname, der während des Zeichnens mit glLoadName gesetzt wurde OpenGL for Java Prof. Dr. V. Stahl Picking & Selection Projektionsmatrix muss danach wieder hergestellt werden! Angeklicktes Objekt ist dasjenige mit geringster Tiefe (nameBuffer durchsuchen!) Tiefeninformation ist unsigned int. Gibt‘s in Java aber nicht! int 230 OpenGL for Java unsigned int Prof. Dr. V. Stahl Picking & Selection Erde- Mond System erweitern so dass die Planeten angeklickt werden können. Angeklickter Planet soll stehen bleiben und sich beim nächsten Klick weiterbewegen. OpenGL for Java Prof. Dr. V. Stahl