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