Teil 1 - Institut für Visualisierung und Interaktive Systeme

Transcription

Teil 1 - Institut für Visualisierung und Interaktive Systeme
Bildsynthese
Vorlesung im SS 2004
Thomas Ertl
Institut für Visualisierung und Interaktive Systeme (VIS)
Universität Stuttgart
[email protected]
http://www.vis.uni-stuttgart.de
Telefon: 0711/7816-331, Raum: 1.445
Sprechstunde: Do: 11-12 und n.V.
1
Organisatorisches
• Vorlesung
Thomas Ertl
Dienstag 14.00 - 15.30
V38.02
Mittwoch 9.45 - 11.15
V38.02
i.a. 4 Stunden pro Woche,
bitte Ankündigungen auf Web-Seite beachten
fällt aus am 4.5., 5.5. 18.5., 19.5., 29.6. und 30.6.
• Übungen: Dirc Rose, Guido Reina
Montag 14.00 – 14.45
0.447
wöchentliche Aufgaben: Theorie und Praxis
erstes Aufgabenblatt 21.4. dann immer Mittwochs
Abgabe am Mittwoch darauf, Besprechung am Montag
erste Übung: Montag 26.4., keine Übung am 3.5.
• Aktuelle Infos, Folien, Material und Übungsblätter
wwwvis/ger/teaching/lecture/ss04/bs
2
Lehrangebot VIS
Grundlagen
der MMK,
GUIs, 2D- u.
3D-Graphik
Grundlagen der
interaktiven
Systeme
WS
3V+1Ü
Bildsynthese
BS
SS
3V+1Ü
Modellierung &
Animation (MA)
WS
3V+1Ü
Visualisierung
VIS
SS
3V+1Ü
Rechnerunterstützes Lehren &
Lernen
WS
3V+1Ü
Spezielle
Visualisierungstechniken
WS
2V
Vertiefungsvorlesungen
Prüfung Vertiefungslinie:
Graphik
Visualisierung
+ Kompaktkurse und SoPras
+ Fachpraktikum VIS für Informatiker
+ Studienprojekte für Softwaretechniker
+ Seminare und Hauptseminare
+ Studien- und Diplomarbeiten
3
Interaktive Systeme für
Sensorisch Behinderte
(SS)
Software-Ergonomie
(WS)
OO-GUI (WS)
Hyperdokumente (SS)
Mensch-MaschineKommunikation
• 2 beliebige 4SWS
Vorlesungen aus
unterschiedlichen Säulen
• Grundlagenvorlesung
bevorzugt als
- Info I (INF) bzw. Hauptfach
(SWT) schriftlich
- Wahlbereich (INF) bzw.
Ergänzung (SWT) mündlich
Übersicht
• Aus Grundlagenvorlesung (GIS) bekannt:
– 2D Rastergraphik
Farben, Transparenz, Scan-Konvertierung, Clipping, ...
– Einführung in die 3D Graphik
Transformations-Pipeline, Verdeckung, Beleuchtung, ...
4
Übersicht
• Bildsynthese (BS) – Rendering
– Interaktives Rendering (i.A. lokale Beleuchtung)
• OpenGL – Konzepte und Wiederholung
• Texturen und andere Mapping-Verfahren
• Schatten und andere Tricks
• Szenengraph APIs und Graphikhardware
– Physikalisch basiertes Rendering (i.A. globale Beleuchtung)
• Radiometrischen Größen, Radiance-Gleichung
• Monte-Carlo-Verfahren, Raytracing
• Radiosity
– Nicht-Photorealistische Darstellungstechniken (NPR)
• Künstlerische Darstellungen
• Illustrationen/Visualisierung
5
Photorealismus vs. Interaktivität
• Realistische Bilder („wie Photos“)
nur durch physikalische Simulation von
– Lichterzeugung und Lichtausbreitung
– Wechselwirkung Licht mit Materie (Reflexion, Streuung)
– Bilderstellung (Aufnahme und Wahrnehmung)
i.A. sehr aufwändig (d.h. meist nicht interaktiv)
• Interaktive Graphik meist nicht sehr realistisch
– mit programmierbarer Graphikhardware oft physikalische
Simulation in interaktiven Raten möglich
• Versuch einer Annäherung meist mit Tricks
z.B. in Spielen
6
Beispiel
© blue moon
rendering
7
Beispiel
8
© blue moon
rendering
Beispiel
9
© O. Deussen
Beispiel
10
© University of
Utah
Beispiel
© University of
Utah
11
Beispiel
12
© University of
Utah
Beispiel
© University of
Utah
13
Graphik-APIs (low level, immediate mode)
OpenGL
DirectX
•
Portabel (Unixe, Linux,
Windows, MacOS, ...)
Kontinuität
•
Nur Windows
•
Client-Server (mit X11)
Eingeschränktes RessourceManagement (Verbessert ab
neusten OGL Versionen)
Langsamere Anpassung an
neue Hardwaremerkmale
GPU-abhängige Extensions
und GPU-unabhängige
Programmierung
•
•
Strukturelle Änderungen bei
Versionswechseln
Kein Client-Server-Konzept
Umfangreiches RessourcenManagement (Vertex-Ströme,
Texturen, Programme, ...)
Schnellere Reaktion auf
Hardwareentwicklungen
GPU-unabhängige
Programmierung
•
•
•
•
•
14
•
•
OpenGL – Weitere Merkmale
•
•
•
•
Orthogonales, intuitives Design
Prozedurale Schnittstelle
Spezifikation nicht Pixel-genau
Erweiterungen erlauben Zugriff auf spezielle
Hardware-Features
– z.Z. 230 Extensions beim ARB registriert
– Nvidias Extension Spec 500+ Seiten
– Treibende Kräfte bei Funktionalitätserweiterungen:
3DLabs, Nvidia und ATI (nicht länger SGI)
15
OpenGL – Historie und Entwicklung
• 1983 - 1992: SGI Graphics Library (GL)
– nahezu proprietär (Portierung durch Dritte auf IBM, Sun,...)
– 3D Rendering + Eingabeereignisse, Fenster, Menüs, Text, ...
– Konkurrenz durch „Standards“: GKS-3D, PHIGS PLUS
• OpenGL www.opengl.org
– Definiert durch Architecture Review Board (ARB)
SGI, IBM, Compaq, Intel, Microsoft, HP, Sun,
Evans&Sutherland, nVidia, ATI, Apple, 3Dlabs,
– Hardware-unabhängiges 3D-Rendering API
– Fenstersystem-neutral (keine Events, Fenster, Menüs, ...)
– keine Funktionalitätsuntermengen möglich
– 2000: Open Source (Beispielimplementierung)
– 2001: OpenGL 1.3 (Multi-Texturen, Cube Maps)
– 2002: OpenGL 1.4 (Vertex Shader)
– 2003: OpenGL 1.5 (Fragment Shader, Buffer Objects, GLSL)
16
OpenGL - Konzepte
• Implementiert Graphik-Pipeline
• Geometrische Primitive:
Punkte, Linien, Polygone
• Bild-Primitive
Images und Bitmaps
• Zustandsmaschine
Farbe, Materialien, Lichtquellen, ...
• Low-level und Immediate Mode API
keine höheren Modellierungs- und
Animationskonzepte, kein Szenengraph
• True Color, Phong-Lighting, Gouraud-Shading,
Texturen, Mip-Mapping, Alpha-Blending, Z-Buffer,
Stencil-Buffer, Accumulation-Buffer, ...
17
OpenGL Bibliotheken
• Core OpenGL (200+ Funktionen)
z.B. glClear(GL_COLOR_BUFFER_BIT)
• GLU OpenGL Utility Library
z.B. gluLookAt, gluSphere, gluNurbs
• GLX Interface Lib zum X-Window-System
z.B. glXChooseVisual, glXSwapBuffers
• WGL Microsoft Windows – AGL MacOS
z.B. wglCreateContext
• GLUT: OpenGL Utility Toolkit
– Plattform-neutrale Schnittstelle zum Fenstersystem
– kein offizieller OpenGL-Bestandteil
18
APIs um OpenGL
application program
OpenGL Motif
widget or similar
GLUT
GLX, AGL
or WGL
GLU
GL
X, Win32, Mac O/S
software and/or hardware
19
OpenGL und X11
application program
GLX: GL über X
(Protokollerweiterung)
xlib
GLX
OpenGL
X-Protokoll
direct rendering
context:
lokaler X11Bypass
OpenGLServer-Extension
X-Server
dispatcher
X11-Renderer
GL-Renderer
software and/or hardware
20
GLUT: Grundlagen
• Struktur einer GLUT-Anwendung
– initialisiere, konfiguriere und öffne Fenster mit Render-Kontext
– initialisiere OpenGL-State
– registriere Callback-Funktionen
• Zeichnen:
glutDisplayFunc(display)
• Fenstergröße ändern: glutReshapeFunc (resize)
• Animation/Simulation: glutIdleFunc(idle)
• Benutzereingaben:
glutKeyboardFunc(keyboard)
• Mausereignisse:
glutMouseFunc(mouse)
– warte in Ereignisschleife (Event processing loop)
• Header-Dateien
• #include <GL/gl.h>
• #include <GL/glu.h>
• #include <GL/glut.h>
21
GLUT: Beispiel
void main( int argc, char** argv )
{
int mode = GLUT_RGB|GLUT_DOUBLE;
glutInit(&argc, argv);
glutInitDisplayMode( mode );
glutCreateWindow( argv[0] );
init();
glutDisplayFunc( display );
glutReshapeFunc( resize );
glutKeyboardFunc( keyboard );
glutMouseFunc( mouse );
glutIdleFunc( idle );
glutMainLoop();
}
22
GLUT: Beispiel cont.
void init( void )
{
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClearDepth( 1.0 );
glEnable( GL_LIGHT0 );
glEnable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
}
void keyboard( char key, int x, int y )
{
switch( key ) {
case ‘q’ : case ‘Q’ :
exit( EXIT_SUCCESS );
break;
case ‘r’ : case ‘R’ :
rotate = GL_TRUE;
break;
}
}
23
GLUT: Beispiel cont.
void display( void )
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_TRIANGLE_STRIP);
glVertex3fv( v[0] );
glVertex3fv( v[1] );
glVertex3fv( v[2] );
glVertex3fv( v[3] );
glEnd();
glutSwapBuffers();
}
void resize( int w, int h )
{
glViewport( 0, 0, (GLsizei) w, (GLsizei) h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 65.0, (GLfloat) w/h, 1.0, 100.0);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0.0, 0.0, 5.0,
0.0, 0.0, 0.0,
0.0,
1.0,
0.0
);
24
}
OpenGL-Pipeline (nach Kurt Akeley)
25
OpenGL-Pipeline
Polynomial
Evaluator
CPU
Display
List
Per Vertex
Operations &
Primitive
Assembly
Rasterization
Texture
Memory
Pixel
Operations
26
Fragment: Pixel mit Attributen
• Bildschirm-Koordinaten (x,y)
• Tiefe (z)
• Farbe (RGBA)
• Textur-Koordinaten (u,v)
Per Fragment
Operations
Frame
Buffer
OpenGL: Geometrische Primitive
Alle geometrischen Primitive werden durch
Vertizes (in homogenen Koordinaten) definiert
GL_LINES
GL_LINE_STRIP
GL_POINTS
GL_LINE_LOOP
GL_POLYGON
GL_TRIANGLES
GL_QUADS
GL_QUAD_STRIP
GL_TRIANGLE_FAN
GL_TRIANGLE_STRIP
27
glVertex Vielfalt
glVertex3fv( v )
Number of
components
2 - (x,y)
3 - (x,y,z)
4 - (x,y,z,w)
28
Data Type
b
ub
s
us
i
ui
f
d
-
byte
unsigned
short
unsigned
int
unsigned
float
double
byte
short
int
Vector
omit “v” for
scalar form
glVertex2f( x, y )
Primitive und Vertex-Attribute
• Wie werden die Vertizes verbunden?
glBegin( primType ); ...; glEnd();
• Wie werden Primitive gerendert?
– Vertex-Attribute
glColor*(); glNormal*(); glTexCoord();
– Globaler Zustand
glPointSize(size); glLineStipple(rep, pattern);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
GLfloat red, greed, blue;
Glfloat coords[3];
glBegin( primType );
for ( i = 0; i < nVerts; ++i ) {
glColor3f( red, green, blue );
glVertex3fv( coords );
}
glEnd();
29
Transformationen: Kamera-Analogie
•
•
•
•
Modellierung: bewege und skaliere Modell
Blickpunkt: Position und Orientierung der Kamera
Projektion: Zoom-Objektiv einstellen
Viewport: Ausschnittsvergrößerung
Sichtvolumen
Kamera
Stativ
30
Modell
Transformationen: Pipeline
eye
object
v
e
r
t
e
x
Modelview
Matrix
Modelview
clip
Projection
Matrix
normalized
device
Perspective
Division
window
Viewport
Transform
Projection
Modelview
z
z
z
z
z
z
Matrix-Stacks:
• Modelview
• Projection
• Texture
Weitere Berechnungen in der
Geometriestufe:
• material -> color
• shade model (flat)
• polygon rendering mode
• polygon culling
• clipping
31
Transformationsmatrizen
• Wähle Matrix-Stack
glMatrixMode(GL_MODELVIEW or GL_PROJECTION)
• Lade oder multipliziere Matrix (von rechts – post mult.)
glLoadMatrix(), glMultMatrix()
• Verwalte Stack
glLoadIdentity(),glPushMatrix(), glPopMatrix()
• Spezielle Modelview-Transformationen
glRotate(), glTranslate(), glScale()
32
Transformationen: Projektion
• Spezielle Projektionen
glFrustum(left,right,bottom,top,zNear,zFar)
gluPerspective(fovy,aspect,zNear,zFar)
glOrtho(left,right,bottom,top,zNear,zFar)
• glFrustum erlaubt nicht-symmetrische Sichtpyramiden
33
Transformationen: Viewing und Modeling
• Kamera-Bewegung (nach vorne) ist äquivalent zu
Bewegung aller Objekte in Richtung Kamera
• Viewing-Transformation äquivalent zu mehreren
Modellierungstransformationen
glTranslatef( 0.0, 0.0, -5.0 );
gluLookAt( 0.0,0.0,5.0, 0.0,0.0,0.0, 0.0,1.0,0.0);
34
Zusammengesetzte Transformationen
• Globale Sicht
– platziere Objekte relativ zu Ursprung der Weltkoordinaten
– Reihenfolge im Code rückwärts (pre-multiply!)
• Lokale Sicht
– Bewege lokale Koordinatensystem der Objekte
– Reihenfolge im Code vorwärts (post-multiply!)
glTranslate(0,0,-5)
glRotate(-90,0,1,0)
drawobject (in Modellkoord)
global
lokal
-z
x
35
global
lokal
Hierarchische Modellierung
Verwende Push/Pop auf Modelview-Matrix-Stack
draw_wheel_and_bolts()
{
long i;
draw_wheel();
for(i=0;i<5;i++){
glPushMatrix();
glRotatef(72.0*i,0.0,0.0,1.0);
glTranslatef(3.0,0.0,0.0);
draw_bolt();
glPopMatrix();
}
}
36
draw_body_and_wheel_and_bolts()
{
draw_car_body();
glPushMatrix();
glTranslatef(40,0,30);
/*move to first wheel position*/
draw_wheel_and_bolts();
glPopMatrix();
glPushMatrix();
glTranslatef(40,0,-30);
/*move to 2nd wheel position*/
draw_wheel_and_bolts();
glPopMatrix();
... /*draw last two wheels*/
}
Rücktransformation
• Transformationseigenschaften aus Zustand (State)
glGetIntegerv( GL_VIEWPORT, GLint viewport[4])
glGetDoublev ( GL_MODELVIEW_MATRIX,
GLdouble mvmatrix[16] )
glGetDoublev ( GL_PROJECTION_MATRIX,
GLdouble projmatrix[16])
• Rücktransformation aus Fensterkoordinaten
gluUnProject (GLdouble winx, winy, winz,
mvmatrix[16], projmatrix[16],
GLint viewport[4],
GLdouble *objx, *objy, *objz )
37
Stereo
•
•
•
•
38
Double-Buffer für linkes und rechtes Auge
Augenabstand (interocular distance)
Fusionsabstand (auf dem Schirm)
Verwende glFrustrum() mit realen Koordinaten
Stereo cont.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); /* the default matrix */
glPushMatrix();
glDrawBuffer(GL_BACK_LEFT)
gluLookAt(-IOD/2.0, 0.0, EYE_BACK,
0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
<viewing transforms>
<modeling transforms>
draw();
glPopMatrix();
glPushMatrix();
glDrawBuffer(GL_BACK_RIGHT);
gluLookAt(IOD/2.0, 0.0, EYE_BACK,
0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
<viewing transforms>
<modeling transforms>
draw();
glPopMatrix();
39
Bilder - größer als der Framebuffer
• Bilder hoher Auflösung (z.B. 5000 x 4000)
• Tiled Displays (Wände mit mehreren Projektoren)
• Aufteilung in NDC
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glScalef(xScale, yScale);
glTranslatef(xOffset,yOffset,0.f);
setProjection();
40
Interactive Mural (Stanford)
41
Interactive Mural (Stanford)
42
Clip-Ebenen
• Mindestens 6 weitere Clip-Ebenen möglich
(zusätzlich zum View Frustum Clipping)
• Spezifiziere Koeffizienten der Ebene
Ax + By + Cz + D = 0
glEnable(GL_CLIP_PLANEi)
glClipPlane(GL_CLIP_PLANEi, GLdouble* coeff)
• Zeichne nur, wenn
−1
( A B C D )M ( x e
Modelview-Matrix
ye
ze
w e )T ≥ 0
Augkoordinaten
43
Polygon-Aspekte
• Polygone haben Vorder- und Rückseiten
vorne: Vertizes laufen entgegen Uhrzeigersinn
evtl. umgekehrt, aber konsistent!
• Vorder- und Rückseiten unterschiedlich zeichnen
glPolygonMode(GL_FRONT, GL_FILL)
glPolygonMode(GL_BACK, GL_LINE)
• Rückseiten können auch entfernt werden
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
• Innere Kanten bei Outlines evtl. vermeiden
glEdgeFlag(GL_FALSE)
44
Polygon-Aspekte cont.
•
•
•
•
Zerteile allgemeine Polygone in Tris und Quads
Verwende TriStrips, TriFans, QuadStrips
Vermeide nichtebene Polygone und Quads
Vermeide T-Vertizes
– führt zu Löchern und Shading-Fehlern
– füge Kante ein
• Spezialbehandlung von Polygonen,
die sich in derselben Ebene überlagern
z.B. Bild an der Wand (surface decals)
– Führt zu Rundungsproblemen (z-Fighting)
glPolygonOffset(factor, unit)
glEnable(GL_POLYGON_OFFSET_FILL)
z-Werte erhalten Offset (nach hinten)
typische Werte factor = 1, unit = 1
45
Attribute
• Zustandsvariablen für Darstellungsmodi
verschiedener Primitive
– POINT_SIZE, POINT_SMOOTH
– LINE_WIDTH, LINE_STIPPLE_PATTERN, ...
– POLYGON_MODE, POLYGONE_STIPPLE, ...
• gruppiert mit anderen State-Bits in Attribute Groups
– line, polygon, texture, fog, transform, viewport, ....
• Diese werden effizient gesichert und restauriert mit
– glPushAttrib() und glPopAttrib()
Attribute Stacks werden auf dem Server gehalten
• Client-Attribute (z.B. vertex array, pixel store):
– glPushClientAttrib()und glPopClientAttrib()
46
Normalen
• Vertex-Normalen bestimmen über
– gewichtete Mittelung über Normalen angrenzender Flächen
– Normalen für ein Dreieck über Vektorprodukt
• Skalierungen und Scherungen können
Normalisierung zerstören
ermögliche automatische Normalisierung:
glEnable(GL_NORMALIZE)bzw. GL_RESCALE_NORMAL
• Scharfe Kanten brauchen mehrere Normalen
47
Beleuchtung und Schattierung
• Zwei Arten die Farbe eines Vertex zu bestimmen
– Vertex-Attribut glColor()
– Materialfarbe + Beleuchtung
– Evtl. gekoppelt durch glColorMaterial
• Umschalten mit glEnable(GL_LIGHTING)
RGBA-Color
Lighting
Shading
flat/smooth
Color
Clamping
Texture
• Schattierung ohne Beleuchtung:
Scanline-Interpolation der Vertex-Farben
z.B. Bildverarbeitung: zeichne Pixel als Quad
48
Phong-Beleuchtung
⎛ xL ⎞
⎜ ⎟
⎜ y L ⎟ Lichtquellen⎜z ⎟
Position
⎜ L⎟
Farbe
⎜w ⎟
⎝ L⎠
Vertex P
⎛x⎞
⎜ ⎟
⎜y⎟
⎜z⎟
⎜ ⎟
⎜w ⎟
⎝ ⎠
M⋅P
ambient
diffus
spekular
Attenuation
Modelview
Transformation
Matrix M
⎛ nx ⎞
⎜ ⎟
⎜ ny ⎟
⎜n ⎟
⎝ z⎠
(M )
−1 T
Vertex
Farbe
⋅N
Material- globales
farben ambientes
Licht
Normale N
49
Phong-Beleuchtung cont.
•
•
diffus (Lambert’sches Gesetz)
cos(θ) = N * L
spekular (Highlight)
cos(σ) = R * V (Phong)
cos(σ’) = N * H (Blinn-Phong)
N σ’ H
L
50
θ
σ V
R
H=
L+V
L+V
Phong-Beleuchtung erweitert
I = OEλ + Iaλ ⋅ Oaλ
(
+ ∑ f i ⋅ spot i Iai λ ⋅ Oaλ + max (N • L i ,0 ) ⋅ Idi λ ⋅ Od λ
i
+ max (N • H i ,0 ) ⋅ Isi λ ⋅ Osλ
n
fi =
1
,
kc + kl d + kq d 2
)
spot i = max (V • D,0 )
spot exp
• Abschwächung
• Spotlight
• Globales ambientes Licht
51
OpenGL-Beleuchtung
• Licht einschalten
glEnable( GL_LIGHTING )
glEnable( GL_LIGHTn )
• Lichtquellen-Eigenschaften
GL_AMBIENT
GL_DIFFUSE
GL_SPECULAR
GL_POSITION
glLightf{v}( light, property, value ) GL_SPOT_*
GL_*_ATTENUATION
• Material-Eigenschaften
GL_AMBIENT
glMaterialfv( face, property, value ) GL_DIFFUSE
• Lichtquellen-Arten
GL_SPECULAR
GL_SHININESS
– Spotlight: Vorzugsrichtung
GL_EMISSION
– Lokal (Point Light): strahlt in alle Richtungen
– im Unendlichen (Directional Light; gerichtet): w=0 in Position
• Evtl. beide Seiten beleuchten
glEnable( GL_LIGHT_MODEL_TWO_SIDE)
• Primary/Secondary Color für Textur-Highlights
52
OpenGL-Beleuchtung cont.
• Lichtquellen-Position durch Modelview-Matrix
– statisch in der Szene
– bewegt mit einem Objekt
– bewegt mit dem Viewport
• Optimierungen
– unendlich weiter Betrachter
glEnable(GL_LIGHT_MODEL_LOCAL_VIEWER)
–
–
–
–
–
gerichtet schneller als Punktlicht schneller als Spotlight
wenige Lichtquellen
wenn beidseitig, dann gleiches Material vorne und hinten
vermeide Vertex Color
Ändern einer Materialeigenschaft für viele Vertizes durch
Verwendung von glColor() :
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
53
Optimierung der Geometrieverarbeitung
• Vermeide häufige Zustandsänderung (State Changes)
– gruppiere gleiche Materialien
– Szenengraph API tun dies automatisch
– Sichere Attribute in Gruppen auf dem Stack
glPushAttrib(), glPopAttrib()
• Vermeide häufige Funktionsaufrufe
–
–
–
–
große Geometrien zwischen glBegin/glEnd
evtl. glBegin/glEnd außerhalb der Objektdefinition
weniger glVertex()Tristrips und Quadstrips
Vertex-Arrays: erlauben Direct Memory Access (DMA)
Push model
Memory
CPU
Pull model
Memory
CPU
push
Graphics HW
pointer
54
Graphics HW
fast DMA
Vertex Arrays
• Aktivieren der Array-Speicherung von
Vertex,Normal,Color,Index,Texture_Coord,Edge_Flag
glEnableClientState(GL_NORMAL_ARRAY);
• Erzeugen der Arrays
glColorPointer (3, GL_FLOAT, 0, colors);
• Zugriff auf einzelne Elemente
glArrayElement (2);
• Zeichne viele Elemente und ganze Arrays
glDrawElements(GL_QUADS, 24,
GL_UNSIGNED_BYTE, allIndices);
glDrawArrays(GL_LINES, 0, n);
• Noch Cache-effizienter: Interleaved Arrays
Attribute und Koordinaten für einen Vertex zusammenpacken
55
R
G
B X
Y
Z
R
G
B X
Y
Z
R
G
B X
Y
Z
Vertex Arrays cont.
static GLfloat data [][6] = {
{ 1.0, 0.5, 0.0,
/* color 0 */
0.0, 5.0, 0.0 }, /* vertex coord 0 */
{ 0.0, 0.3, 1.0,
/* color 1 */
5.0, 5.0, 0.0 }, /* vertex coord 1 */
{ 0.3, 0.5, 0.3
/* color 2 */
5.0, 0.0, 1.0 }
/* vertex coord 2 */
};
glInterleavedArrays(GL_C3F_V3F, 0, data);
• Packe Texturkoord., Farben, Normalen, Koord.
mit GL_T2F_C4F_N3F_V3F
• Vertex Arrays werden im Client alloziert!
– Ausnutzen von lokalem Graphikspeicher mit
Display Listen oder Buffer Objects
56
Evaluatoren
• Rendering von Bezier-Kurven und –Flächen
definiert durch Kontrollpunkte
• Evaluatoren generieren Vertizes für stückweise
lineare Approximation (Linienzug, Quad-Mesh)
GLfloat ctrlpoints[4][3] = {
{ -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0},
{2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}};
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4,
&ctrlpoints[0][0]);
glEnable(GL_MAP1_VERTEX_3);
glBegin(GL_LINE_STRIP);
for (i = 0; i < 31; i++)
glEvalCoord1f((GLfloat) i/30.0);
glEnd();
57
Evaluatoren cont.
• Bezier Patches und uniforme Auswertung
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, &ctrlpoints[0][0][0]);
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2,
0, 1, 4, 2, &texpts[0][0][0]);
glEnable(GL_MAP2_TEXTURE_COORD_2);
glEnable(GL_MAP2_VERTEX_3);
glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
.....
glEvalMesh2(GL_FILL, 0, 20, 0, 20);
58
Display-Listen
Steigerung der Rendering-Geschwindigkeit
• durch Vorverarbeitung
– Matrixinvertierung, Materialkombinationen
– interne Datenformate (z.B. Images, Texturen)
• für Client-Server-Betrieb
– Caching von GL-Befehlen im Server (evtl. in Hardware)
– weniger Netzwerklast
• Display-Listen
– nur GL-Befehle und evaluierte Parameter im Server
– können mit anderem State aufgerufen werden
– gemeinsam benutzt von mehreren Graphik-Kontexten
• Aber
– kein Abspeichern/Einlesen
– kein Editieren
59
Display-Listen cont.
• Erzeugen einer Display-Liste
GLuint id;
void init( void )
{id = glGenLists( 1 );
glNewList( id, GL_COMPILE );
glBegin(GL_POLYGON);
for ( i=0; i<100; i++ )
glVertex2f(sin(i*2*PI/100),cos(i*2*PI/100));
glEnd();
glEndList();
}
• Aufrufen einer Display-Liste
void display( void )
{
glCallList( id );
}
60
Hierarchische Display-Listen
glNewList( CAR, GL_COMPILE );
glCallList( CHASSIS );
glTranslatef( … );
glCallList( WHEEL );
glTranslatef( … );
glCallList( WHEEL );
…
glEndList();
• „Editieren“ von CAR durch Neudefinition von WHEEL
• Eigenschaften von Display-Listen:
– Ausführung im aktuellen Kontext
– Zustandsänderungen (State Changes) bleiben erhalten
– Kapselung von Zustandsänderungen durch
Push/Pop Matrix/Attributes
61
Geometrie im Graphikkartenspeicher
• Display Lists gut für statische Geometrie
– ändert sich nicht pro Frame
– wird von Szenengraph-APIs generiert
– „Retained Mode“
• Für dynamische Geometrie: Vertex Buffer Objects
– VBOs erlauben die Abbildung von Vertex Arrays in
Memory Buffer auf der Graphikkarte (OpenGL 1.5)
– via AGP Memory
– Zugriff über API
oder Mapping
– ersetzt
ATI_vertex_
array_object
NV_vertex_
array_range
62
Speicherobjekte auf der Graphikkarte
• Verallgemeinertes Konzept für Buffer in Hardware
– Vertex Buffer (VBO)
– Pixel Buffer (PBO)
– Texture Objects
• Ermöglicht
– Render-to-Texture
– Render-to-Vertex_Array
• Noch nicht standardisiert verfügbar
– z.B. ATI Überbuffer
63
Bitmaps
• Rechteckiger 2D Bereich mit 1 Bit Tiefe
• Zeichne mit aktueller Farbe an Rasterposition und
verschiebe Rasterposition
GLubyte rasters[24] = {
0xc0, 0x00, 0xc0, 0x00,
0xc0, 0x00, 0xc0, 0x00,
0xc0, 0x00, 0xff, 0x00,
0xff, 0x00, 0xc0, 0x00,
0xc0, 0x00, 0xc0, 0x00,
0xff, 0xc0, 0xff, 0xc0};
glColor3f (1.0, 1.0, 1.0);
glRasterPos2i (20, 20);
glBitmap (10, 12, 0.0, 0.0, 11.0, 0.0, rasters);
glBitmap (width, height, xorig, yorig,
64
xmove, ymove, bitmap);
Text-Darstellung (Font Rendering)
• Speichere jedes Zeichen als Bitmap in einer
separaten Display-Liste
fontOffset = glGenLists (128);
for (i = 0,j = ‘A’; i < 26; i++,j++) {
glNewList(fontOffset + j, GL_COMPILE);
glBitmap(8, 13, 0.0, 2.0, 10.0, 0.0, letters[i]);
glEndList();}
void printString(char *s){
glPushAttrib (GL_LIST_BIT);
glListBase(fontOffset);
glCallLists(strlen(s), GL_UNSIGNED_BYTE,
(GLubyte *) s);
glPopAttrib ();}
• Verwende Zeichensätze des Fenstersystems
65
glXUseFonts()
Images
• Zeiche Bild an Rasterposition
glDrawPixels(width, height, format, type,
image)
• Bild aus Framebuffer-Position x,y lesen:
glReadPixels(x, y, width, height, format,
type, image)
• Typen
GL_UNSIGNED_BYTE, GL_SHORT, GL_FLOAT,
GL_UNSIGNED_BYTE_3_3_2,
GL_UNSIGNED_INT_2_10_10_10_REV, ...
• Formate
GL_RGBA, GL_RBG, GL_RED, GL_ALPHA,
GL_LUMINANCE_ALPHA, GL_DEPTH_COMPONENT,
GL_ABGR_EXT,...
66
Pixel-Pipeline
glBitmap(), glDrawPixels()
CPU
Pixel
Storage
Modes
Pixel-Transfer
Operations
(and Pixel Map)
Rasterization
(including
Pixel Zoom)
Per Fragment
Operations
Frame
Buffer
glTex*Image();
Texture
Memory
glReadPixels(), glCopyPixels()
glCopyTex*Image();
• Kopiere Bild im Framebuffer von x,y –Position an
Rasterposition
glCopyPixels(x, y, width, height, buffer)
• Vergrößere, verkleinere, reflektiere Bild
glPixelZoom(xfactor, yfactor)
67
Storage Modes – Transfer Modes
• Vielfältige Pack/Unpack Modi
glPixelStore(name, param);
GL_UNPACK_SWAP_BYTES,
GL_PACK_LSB_FIRST,
GL_PACK_SKIP_ROWS,
GL_PACK_ALIGNMENT
• Vielfältige Transfer Modi
glPixelTransfer(name, param);
GL_MAP_COLOR, GL_RED_SCALE, GL_ALPHA_BIAS, ..
• Farbtabellen
glPixelMap(map, map_size, values);
GL_PIXEL_MAP_I_TO_R, GL_PIXEL_MAP_A_TO_A, ...
68
Pixel Write
69
Imaging Subset
• Optionale Erweiterung von OpenGL 1.2
–
–
–
–
–
Flexible Farbtabellen
1D- und 2D-Faltung (Convolution)
Histogramm und Min/Max-Funktionen
Farbabbildung mit Farbmatrix (Color Matrix)
Erweiterte Blending-Operationen
• Verfügbar, wenn
glGetString(GL_EXTENSIONS)
liefert ARB_imaging
• Effiziente Farbtabellen
• Weitere Farbtabellen nach
Farbmatrix und Faltung
• In programmierbarer Hardware teilweise
durch Fragment Program/Shader ersetzt
70
Scale & Bias
Pixel Mapping
Color Table
Convolution
Image Transf
Color Matrix
Histogram
Min/Max
Farbmatrix
• 4x4 Matrix-Stack für Farbverarbeitung
glMatrixMode(GL_COLOR)
• beliebige affine Kombination von RGBA
• weiterer Scale/Bias bringt Werte wieder in [0,1]
• z.B. Luminanz-Berechnung
Rw = 0.3086, Gw= 0.6094,
Bw = 0.0820
• RGB – CMY Konvertierung
• Per-Pixel-Beleuchtung
Skalarprodukte bei Phong
– Normale pro Pixel in Textur
(Normal Map)
– Berechne diffuse Beleuchtung
pro Pixel (scale/bias)
71
⎛ Lx
⎜
L • N = ⎜ Lx
⎜L
⎝ x
Farbmatrix: Anwendungen
• Kombination mehrerer Farbkanäle
• Bsp. RGB -> Luminanz
72
Ly
Ly
Ly
Lz ⎞⎛ N x ⎞
⎟⎜ ⎟
Lz ⎟⎜ N y ⎟
Lz ⎟⎠⎜⎝ N z ⎟⎠
Farbmatrix: Anwendungen cont.
• Nicht-lineare Modifikation einzelner Farbkanäle
Hue-Quantisierung
Hue-Verstärkung
Hue-Negierung
73
Faltung
• Faltung von 1D- und 2D-Bildern mit Filter-Kernel
• 1D kontinuierlich und diskret
• 2D diskret
• Separierbare Filter
74
Filterung
75
Filter-Kernel
• Horizontale Kanten
• Bildglättung
• Hochpass
• Laplace
76
Faltung, Histogram, Min/Max
• Faltung (Convolution)
– lade Kernel als Image (z.B. 7x7 RGBA)
– spezifiziere Scale/Bias und Rand-Verhalten
– beeinflusst jeden Pixel-Transfer (Texturen), wenn
eingeschaltet
• Histogram, Min/Max
–
–
–
–
zähle Anzahl von Farbkomponenten
sortiert in Bins
QueryCounters liefert Verteilung als 1D Bild zurück
ähnlich mit Min/Max
• Unterstützung in Hardware oft nur auf SGI
77
Faltung: Anwendung
• Kontrastverstärkung auf Schnittbildern
78
OpenGL-Puffer
• Framebuffer besteht aus
–
–
–
–
Color Buffer (flexible Aufteilung)
Depth Buffer (z-Puffer)
Stencil Buffer (Stanz-Maske, State-Machine)
Accumulation Buffer (Multipass-Rendering)
• Anfordern
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE
| GLUT_DEPTH | GLUT_STENCIL)
• Evtl. Anschalten
glEnable(GL_DEPTH_TEST)
• Löschen (teuere Operation - evtl. vermeiden!)
glClearColor(0,0,0,1); glClearDepth(1.0);
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT | ...)
79
Stereo/Double Buffering
• Auswählen des Buffers
while(GL_TRUE){
glDrawBuffer(GL_LEFT_BUFFER);
gluLookAt(LeftEye);
drawscence();
glDrawBuffer(GL_RIGHT_BUFFER);
gluLookAt(RightEye);
drawscence();
glXSwapBuffers()
}
Back
• Quadbuffer
Front
80
Left
Right
Maskieren von Buffern
• Sperre einzelne Buffer bzw. Bit-Planes gegen
Schreiben (Überschreiben)
• z.B. Bewegung vor komplexen Hintergrund
Render Background (mit Z-Buffer)
Save Background (glReadPixels)
glDepthMask(GL_FALSE) z-Buffer read-only
while()
Load Background (glDrawPixels)
Render Foreground
81
Fragment-Verarbeitung
Depth
Depth
Test
Test
82
Scissor
Scissor
Test
Test
Blending
Blending
Alpha
Alpha
Test
Test
Dithering
Dithering
Stencil
Stencil
Test
Test
Logical
Logical
Operations
Operations
Framebuffer
Fragment
• Tests und Verarbeitungsstufen für Fragmente auf
dem Weg zum Framebuffer
Blending
• Kombination von Fragmenten (source) mit Pixeln im
Framebuffer (destination) in Abhängigkeit von
Transparenz
• Spezifiziere Blending-Faktoren für Source und
Destination (Sr, Sg, Sb, Sa) (Dr, Dg, Db, Da)
GL_ZERO, GL_ONE,
GL_SRC_ALPHA
(As, As, As, As)
GL_ONE_MINUS_SRC_ALPHA
(1, 1, 1, 1)-(As, As, As, As)
• Einschalten und Blending-Funktion
glEnable(GL_BLEND)
glBlendFunc(sfactor, dfactor)
• Berechnet wird
(RsSr+RdDr, GsSg+GdDg, BsSb+BdDb, AsSa+AdDa)
83
Blending cont.
• Typische Anwendung
semitransparentes Objekt über opakes
glBlendFunc (GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA)
• Nicht alle Systeme haben einen Alpha-Buffer!
• Spezielle Blend Functions
GL_CONSTANT_COLOR, GL_ONE_MINUS_CONST_ALPHA
konstante Farbe bzw. Transparenz
• Blend Equation
glBlendFunc (GL_FUNC_ADD) (default)
– GL_FUNC_SUBTRACT
Differenzbilder
– GL_FUNC_MIN, GL_FUNC_MAX
Minimum/Maximum aller Werte
z.B. Maximum Intensity Projection (MIP) in der Medizin
z.B. morphologische Filter
84
Scissor-Test
• Fragmente außerhalb eines Rechtecks werden
entfernt
glScissor( x, y, width, height )
• Aktualisierung kleiner Fensterbereiche
z.B. Löschen mit glClear()
• Wenn kein Objektraum-Clipping möglich,
z.B. bei nichtlinearen Projektionen
85
Alpha-Test
• Weise Fragmente aufgrund ihres Alpha-Wertes
zurück
glAlphaFunc( func, value )
glAlphaFunc( GL_LESS, 1.0 ) alle nicht-opaken
glEnable( GL_ALPHA_TEST )
• Setze in Bildern (Texturen)
Hintergrund auf transparent
(Billboards – drehen sich mit)
• Rendering von Szenen mit
transparenten Polygonen
Korrekt: zuerst alle opaken, dann alle
semitransparenten sortiert von hinten nach vorne
86
Sortierung transparenter Polygone
• Opake Kugel und
transparenter blauer Kegel
Kugel vor Kegel:
Kein Blau sollte
durchscheinen
Kugel hinter Kegel:
Bläulicher Überlapp
Kugel hinter Kegel:
Depth-Test verhindert
Blending
87
Transparente Objekte ohne Tiefensortierung
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
while (TRUE){
glEnable(GL_BLEND);
glAlphaFunc(GL_EQUAL, 1.0);
drawscence(); nur opake Objekte
glEnable(GL_BLEND);
glAlphaFunc(GL_LESS, 1.0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDepthMask(GL_FALSE);
drawscence(); blende transparente Objekte
glDepthMask(GL_TRUE);}
•
88
Transparente Polygone verschwinden hinter opaken, aber
ändern nicht den z-Buffer
d.h. mehrere überlappende transparente Polygone werden
nicht korrekt dargestellt
Optimierung der Transparenz-Sortierung
• Verwende kommuntatives Blending
– glBlendFunc(GL_DST_COLOR, GL_ZERO)
– glBlendFunc(GL_ONE, GL_ONE)
• Verwende Face Culling
– zeichne zuerst die Rück-, dann die Frontseiten
– funktioniert für geschlossene, konvexe,
nicht überlappende Objekte
• Depth Test ausschalten
– Rückseiten werden nicht von Frontseiten verdeckt
– für geschlossene, konvexe Objekte einer Farbe ist die
Reihenfolge egal
89
Screendoor Transparency
• Muster simuliert Semitransparenz
• Verwende Polygon-Stipple
(Bitmap) mit Anteil der Einsen
entsprechend der Opazität
• Unterschiedliche Muster für
unterschiedliche Objekte
90
Maskieren mit Alpha Compositing
• Kombiniere 2 Bilder durch drittes Alpha-Bild (Matte)
– Zeichne erstes Bild in Framebuffer
– Zeichne Maske in Alphabuffer
– Blende zweites Bild mit
glBlendFunc(GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA)
91
Stencil-Test und Stencil-Buffer
• Weiterer Puffer (z.B. 8 Bit pro Pixel)
als einfache Zustandsmaschine
• Stencil-Wert entscheidet, ob Fragment gezeichnet
wird (z.B. Vergleich mit Referenzwert)
• Typische Anwendung: Rendering
in nicht rechteckige bzw. nicht
achsenparallele Bereiche
92
Stencil Dissolves
93
Stencil-Test und Tiefentest
if (fragment.alpha alphafunc refalpha)
if (buffer.stencil stencilfunc refstencil)
if (fragment.depth depthfunc buffer.depth)
foreach colorbuffer
buffer.color = fragment.color;
buffer.depth = fragment.depth;
buffer.stencil = zpass();
else
buffer.stencil = zfail();
else
buffer.stencil = fail();
94
Stencil-Test cont.
• Stencil-Test festlegen
glStencilFunc(stencilfunc, refstencil, mask)
vergleiche mit Referenzwert in maskierten Bits
GL_ALWAYS, GL_NEVER, GL_LESS, GL_EQUAL, ...
• Änderungen im Stencil-Buffer je nach Tiefentest
glStencilOp( fail, zfail, zpass )
mögliche Funktionen:
GL_KEEP, GL_ZERO, GL_INCR, GL_INVERT, ...
• Zeichne Maske in Stencil-Buffer
glStencilFunc( GL_ALWAYS, 0x1, 0x1 );
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);
• Zeichne Objekte, wo Stencil ungleich 1
glStencilFunc( GL_NOT_EQUAL, 0x1, 0x1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
95
Stencil: Beispiel
• Trennung in zwei Bildbereiche
glClearStencil(0x0);
glClear(GL_STENCIL_BUFFER_BIT);
glStencilFunc(GL_ALWAYS,1,1);
glStencilOP(GL_REPLACE, ...);
glColorMask(GL_FALSE);
draw_window_polygon();
glColorMask(GL_TRUE);
glStencilFunc(GL_EQUAL,1,1);
glStencilOp(GL_KEEP, ...)
draw_outside_scene();
glStencilFunc(GL_NOTEQUAL,1,1);
draw_dashboard();
96
Verdeckte Linien mit Stencil-Buffer
• Drahtgitter-Darstellung eines Modells
mit verdeckten Linien (wire frame)
• Naiv
– Zeichne Polygone nur mit Rand
– Zeichne Polygone gefüllt mit Hintergrundfarbe
• Problem: Füllen überschreibt die Randlinien
– unterschiedliche Rasterisierung von Linien und Polygonen
– z-Fighting: Linien und Polygone in derselben Tiefe
• Lösung
für jedes Polygon
– Zeichne Linien und markiere im Stencil-Buffer
– Füllen nur bei leerem Stencil (im Inneren)
– Löschen des Stencil-Buffers durch nochmaliges Zeichnen
der Linien mit INVERT
97
Silhouetten-Kanten mit Stencil-Buffer
• Farbe und Tiefe aus, Stencil an mit 1
• Zeichne Objekt nach links, rechts, oben, unten
um ein Pixel verschoben
• Farbe und Tiefe an, Stencil an auf 0
• Zeichne Objekt an Originalposition
• Stencil-Test gleich 1
• Zeichne Rechteck in Silhouetten-Farbe
98
Maskieren mit Stencil-Buffer
• Schreibe Maske in Stencil-Buffer, z.B. als AlphaKanal-Bild mit Alpha-Test
• Zeichne 2 Bilder jeweils
bei Stencil = 1 oder bei Stencil=0
99
Accumulation-Buffer
• Zwischenspeicher zur Kombination mehrerer
Rendering-Schritte (Multipass-Verfahren)
• Optische Analogie: Mehrfachbeleuchtung
• Meist höhere Genauigkeit als Color-Buffer
(z.B. 12 Bit pro Kanal, negative Werte, Gleitkomma)
• Meistens (immer?) ohne Hardware-Unterstützung
• Zugriff über glAccum(op, value)
100
– GL_LOAD
buffer.accum = value*buffer.color
– GL_ACCUM
buffer.accum = buffer.accum + value*buffer.color
– GL_RETURN
buffer.color = value*buffer.accum
– GL_ADD/GL_MULT
buffer.accum = value +/* buffer.accum
Accumulation-Buffer: Antialiasing
• Zeichne Szene mehrmals mit leicht verschobenem
Blickpunkt (weniger als 1 Pixel) (Jitter)
• Mische Bilder
glAccum(GL_ACCUM, 1.0/n)
• Zeige Ergebnis des
Supersamplings
glAccum(GL_RETURN, 1.0)
• Wähle Zufallsblickpunkte aus
Jitter-Box
101
Accumulation-Buffer: Tiefenunschärfe
• Depth-of-Field
– Verzittern des Viewing Frustums
– Scharfe Ebene (focal plane) fixiert
– n Bilder zufällig verschoben
Back Plane
Focal Plane
Front Plane
eye pos1 eye pos2
102
Accumulation-Buffer: Bewegungsunschärfe
• Motion Blur
– zeitliches Zittern
– allmähliches
Ausblenden
glAccum(GL_MULT,
factor)
103
Chromakeying
• Ersetze in einem Bild (C1) alle Pixel einer Farbe
(oder eines Farbbereichs) durch entsprechende
Pixel eines anderen Bildes (C2)
• Beispiel: Wetterkarte im Fernsehstudio
• Konkret: Berechne Maskenbild mit
Transparenzwerten, die der Luminanz der
Farbdifferenz zur Referenzfarbe (Ckey) entsprechen
• Teilschritte
– berechne Ergebnis: |C1 – Ckey| im Framebuffer
– konvertiere Betrag der Abweichung von der Referenzfarbe zu
einem Luminanzbild mit Maske im Alpha-Kanal durch Kopieren
auf sich selbst mit Farbmatrix
– Blende Bild 2 in Bild 1 gemäß Transparenz
104
Chromakeying cont.
Key-Farbe
• Zeichne Rechteck mit Key-Farbe
• Kopiere in den Accu, skaliere
dabei mit –1
• Zeichne erstes Bild und addiere
zu Accu
• Kopiere Accu in Framebuffer,
dabei Clamping zu [0,1]
• Blende Accu (skaliert mit –1) in
den FB mit GL_ADD
Betrag der Differenz
105
Chromakeying cont.
106
OpenGL-Picking
• Picking:
Identifizierung graphischer 3D-Objekte „in der
Nähe“ der Cursor-Position
• Alle anderen Eingabeereignisse werden durch das
Fenstersystem bzw. GUI-Toolkit abgehandelt
• Keine direkte Rückrechnung Pixel->Objekt möglich
• Weiterer Rendering-Durchlauf nötig
for all objects
if projection of object is
near cursor position
then add to hit list
return all hits sorted from front to back
• Szenengraph-APIs (retained mode) brauchen nur
spezielle Traversierung (ohne OpenGL)
107
OpenGL-Picking cont.
• OpenGL-Anwendungen müssen die komplette
Szene ohne Ausgabe regenerieren
• Spezieller Selektionsmodus (neben GL_RENDER)
glRenderMode(GL_SELECT)
• Hits werden durch Clipping an einem kleinen
Viewing Frustum entdeckt, trivial reject – no hit!
gluPickMatrix(x, y, width, height, viewport)
108
OpenGL-Picking cont.
• Allokiere Selection-Buffer
glSelectBuffer(size, buffer)
• Zeichne Szene im Selektionsmodus (keine Ausgabe)
• Nach dem Rückschalten in Render-Modus
hit_n = glRenderMode(GL_RENDER)
hit_n Primitive schneiden Sichtvolumen
• Hit Records im Selection-Buffer enthalten:
– Anzahl der Namen im Pfad auf dem Stack
– zmin/zmax aller Hit-Primitive
– Namenspfad auf dem Stack
• Namen sind Integer-IDs, mit einem lokalen
Gültigkeitsbereich auf einem Namens-Stack
hierarchische Modelle haben Pfad-Namen
2. car, 3. wheel, 1. bolt
z.B. 3 zmin zmax 2 3 1
109
Picking: Programm-Rahmen
glutMouseFunc( pickMe );
void pickMe( int button, int state, int x, int y )
{
GLuint nameBuffer[256];
GLint hits;
GLint myViewport[4];
if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN) return;
glGetIntegerv( GL_VIEWPORT, myViewport );
glSelectBuffer( 256, nameBuffer );
glRenderMode( GL_SELECT );
glInitNames();
glMatrixMode( GL_PROJECTION );
glPushMatrix(); glLoadIdentity();
gluPickMatrix( (GLdouble) x, (GLdouble)
(myViewport[3]-y), 5.0, 5.0, myViewport );
glPushName( 1 );
/*
draw something */
glLoadName( 2 );
/*
draw something else … continue … */
glMatrixMode( GL_PROJECTION );
glPopMatrix();
hits = glRenderMode( GL_RENDER );
/*
process nameBuffer */
110 }
Picking: Effizienz
• OpenGL-Picking kann langsam sein
– verwende grobe Geometrie für Picking z.B. Bounding-Box
– verwende Bounding-Box-Info für Picking ohne OpenGL
– verwende Szenengraph-API
• OpenGL Picking kann nicht eindeutig sein
– nur Vertizes – Bilder über RasterPos
– wg. nicht eindeutiger Ausdehnung in der Tiefe!
– verwende z.B. Picking im Backbuffer
• Ermögliche Standard-Selektionsmechanismen
–
–
–
–
–
Einzel-Pick mit linker Maustaste
zusätzliches Objekt selektieren mit Shift + linke Maustaste
Sweep-Pick im Rubberband-Rechteck
Feedback der selektierten Objekte (Highlight)
Deselektion bei leerem Pick
111
Picking im Backbuffer
• Weise jedem Objekt eine eindeutige ID zu
• Kodiere ID in Vertex-Farbe glColor*ub()
(z.B. 16 Mio. Objekte bei 24 Bit RGB)
• Rendere ohne Beleuchtung und Shading in
Backbuffer
• Lese Framebuffer-Wert an der Cursor-Position
• Evtl. hierarchische IDs und Multipass-Rendering
Pfadnamen-Kodierung (4-4-6-10 Bits)
• Kein Swapbuffer, da Falschfarben
• Nur eine Objekt-ID zurück
112
Highlighting
• Hervorheben ausgewählter Objekte durch Ändern
von visuellen Attributen (Farbe, Wireframe, ...)
• Neuzeichnen der gesamten Szene evtl. teuer
speziell bei Locate-Highlight (mouse-over)
• Zeichne Objekt in Overlay-Ebenen (selten
vorhanden)
• Zeichne Objekt in Color-Buffer mit
Tiefentest auf GL_EQUAL
• XOR des MSB in jedem Farbkanal für starke
Farbänderung mit GL_COLOR-LOGIC_OP
• Manipulation des Objekts im Vordergrund
lade Farb- und Tiefenpuffer der Restszene
113
Feedback-Modus
• Wie in Selection-Modus keine Graphikausgabe
• Ausgabe der transformierten und beleuchteten
Geometriedaten (keine Rasterisierung)
– Vertex-Koordinaten im Window-Koordinatensystem
– Farben und Texturkoordinaten je Vertex auf Wunsch
• Marker (glPassThrough) erleichtern Auffinden
• Verwendung
glFeedbackBuffer( size, type, buffer )
glRenderMode( GL_FEEDBACK )
• Typische Anwendung:
– Postscript-Ausgabe
– Debugging
114