7.4 Tesselierung von Polygonen - DFKI
7.4 Tesselierung von Polygonen - DFKI
7.4 Tesselierung von Polygonen - DFKI
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Anwendungsgebiet<br />
- OpenGL kann direkt nur einfache konvexe Polygone anzeigen<br />
- Polygone sind einfach, wenn<br />
- sie selbstdurchdringungsfrei sind<br />
- sie keine doppelten Ecken enthalten<br />
- an einer Ecke genau zwei Kanten aufeinander treffen<br />
- Polygone mit<br />
- Selbstdurchdringungen<br />
- Löchern<br />
- und nicht-konvexe Polygone<br />
müssen zur Darstellung in einfache konvexe Polygone zerlegt<br />
werden<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-1
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Nutzung der GLU Bibliothek<br />
- GLU bietet (ab Version 1.2) Routinen, die beliebige Polygone<br />
tesselieren und Kombinationen aus<br />
- Dreiecken,<br />
- Dreiecksnetzen,<br />
- Triangle Fans,<br />
- Triangle Strips und<br />
- Linien<br />
zurück geben<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-2
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Vorgehen<br />
- Erzeugung eines Tesselation Objekts<br />
- Definition und Registrierung <strong>von</strong> Callback-Funktionen, welche die<br />
eigentliche <strong>Tesselierung</strong> durchführen (z.B. die Behandlung <strong>von</strong><br />
Selbstdurchdringungen)<br />
- Definition <strong>von</strong> <strong>Tesselierung</strong>s-Eigenschaften (z.B. der Umlaufrichtung<br />
<strong>von</strong> Polygon-Rändern, um Löcher zu entdecken)<br />
- Erstellung und Darstellung der tesselierten Polygone durch<br />
Spezifikation der Konturen der Polygone<br />
- Löschen des <strong>Tesselierung</strong>s-Objekts nach Abschluß aller<br />
<strong>Tesselierung</strong>s-Operationen<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-3
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Verwaltung <strong>von</strong> Tesselator-Objekten<br />
- Ein Tesselator-Objekt kann zur <strong>Tesselierung</strong> aller Polygone in einer<br />
Szene verwendet werden<br />
- Das Objekt verwaltet die zur <strong>Tesselierung</strong> verwendeten Daten wie<br />
Ecken, Kanten und Callback-Funktionen<br />
- Erstellung eines Tesselator-Objekts:<br />
GLUtesselator* gluNewTess(void);<br />
gibt einen Zeiger auf das neu erstellte Objekt bzw. einen Nullpointer<br />
im Fehlerfall zurück<br />
- Löschen eines Tesselator-Objekts:<br />
void gluDeleteTess(GLUtesselator* qobj);<br />
löscht das Tesselator-Objekt und gibt den genutzten<br />
Speicherbereich frei<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-4
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
§7 Erweiterte Zeichenfunktionen<br />
Callback-Routinen bei der <strong>Tesselierung</strong><br />
- Beim Auftreten der Ereignisse<br />
- Beginn und Ende eines Polygons / einer Kontur<br />
- Spezifikation eines Edge Flags<br />
- Spezifikation einer Ecke<br />
- Selbstdurchdringung eines Polygons<br />
- Fehler<br />
während der <strong>Tesselierung</strong> werden entsprechende Callbacks zur<br />
Behandlung der Ereignisse aufgerufen<br />
- Nach der Definition der Callbacks werden die zu tesselierenden<br />
Polygone mittels eigener GLU-Routinen beschrieben<br />
- Nach vollständiger Beschreibung der Polygone startet die<br />
<strong>Tesselierung</strong> durch Aufruf der entsprechenden Callbacks<br />
- Nicht definierte Callbacks werden nicht aufgerufen, dabei geht evtl.<br />
Information der Ursprungs-Polygone verloren<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-5
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Registrierung <strong>von</strong> Tesselator-Callbacks<br />
void gluTessCallback(GLUtesselator* tess,<br />
GLenum type, void (*fn)());<br />
- Registriert die mit dem Funktionspointer übergebene Funktion als<br />
Callback für den übergebenen Typ type<br />
- Wird als Funktionszeiger ein Nullpointer übergeben, wird der<br />
Callback gelöscht<br />
- Durch erneuten Aufruf der Registrierungs-Funktion kann ein<br />
Callback überschrieben werden<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-6
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Callback-Funktion beim Beginn eines darzustellenden Polygons<br />
- Typ des Callbacks:<br />
GLU_TESS_BEGIN<br />
- Signatur:<br />
void begin(GLenum type);<br />
- Beispiel-Code:<br />
void CALLBACK beginCallback(GLenum which){<br />
glBegin(which);<br />
}<br />
- Mögliche Parameter für which:<br />
GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, GL_TRIANGLES,<br />
GL_LINE_LOOP<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-7
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Beginn eines darzustellenden Polygons mit weiteren Daten<br />
- Typ des Callbacks:<br />
GLU_TESS_BEGIN_DATA<br />
- Signatur:<br />
void begin(GLenum type, void* user_data);<br />
- Der Anwender kann (wie bei jedem anderen Callback auch)<br />
spezifische Daten mit übergeben, die in der Callback-Funktion dann<br />
verarbeitet werden.<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-8
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Callback-Funktion beim Ende eines darzustellenden Polygons<br />
- Typ des Callbacks:<br />
GLU_TESS_END bzw. GLU_TESS_END_DATA<br />
- Signatur:<br />
void end(void); bzw. void end(void* user_data);<br />
- Beispiel-Code:<br />
void CALLBACK endCallback(void){<br />
glEnd();<br />
}<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-9
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Callback-Funktion beim Auftreten einer Ecke<br />
- Typ des Callbacks:<br />
GLU_TESS_VERTEX bzw. GLU_TESS_VERTEX_DATA<br />
- Signatur:<br />
void vertex(void* vertex_data); bzw.<br />
void vertex(void* vertex_data, void* user_data);<br />
- Beispiel-Code:<br />
void CALLBACK vertexCallback(GLvoid *vertex){<br />
const GLdouble *pointer;<br />
}<br />
pointer = (GLdouble *) vertex;<br />
glVertex3dv(vertex);<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-10
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Callback-Funktion zur Behandlung <strong>von</strong> Edge-Flags<br />
- Edge Flags spezifizieren, ob eine Kante eines Polygons als<br />
Randkante dargestellt werden soll oder als innere Kante nicht<br />
gezeichnet wird<br />
- Typ des Callbacks:<br />
GLU_TESS_EDGE_FLAG bzw. GLU_TESS_EDGE_FLAG_DATA<br />
- Signatur:<br />
void edgeFlag(GLboolean flag); bzw.<br />
void edgeFlag(GLboolean flag, void* user_data);<br />
- Beispiel-Code:<br />
void CALLBACK edgeFlagCallback(GLboolean flag){<br />
glEdgeFlag(flag);<br />
}<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-11
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Callback-Funktion zur Fehlerbehandlung<br />
- Typ des Callbacks:<br />
GLU_TESS_ERROR bzw. GLU_TESS_ERROR_DATA<br />
- Signatur:<br />
void error(GLenum errno); bzw.<br />
void error(GLenum errno, void* user_data);<br />
- Beispiel-Code:<br />
void CALLBACK errorCallback(GLenum errorCode){<br />
const GLubyte *estr;<br />
}<br />
estring = gluErrorString(errorCode);<br />
fprintf(stderr,"Tessellation Error: %s\n",estr);<br />
exit(0);<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-12
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Callback-Funktion beim Auftreten <strong>von</strong> Selbstdurchdringungen<br />
- Wird aufgerufen, wenn eine neue Ecke eingefügt wird<br />
- Typ des Callbacks:<br />
GLU_TESS_COMBINE bzw. GLU_TESS_COMBINE_DATA<br />
- Signatur:<br />
void combine(GLdouble coords[3], // Neuer Punkt<br />
void* vertex_data[4],<br />
GLfloat weight[4],<br />
void** outData); bzw.<br />
void combine(GLdouble coords[3],<br />
void* vertex_data[4],<br />
GLfloat weight[4],<br />
void** outData,<br />
void* user_data);<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-13
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Polygon-Definition<br />
- Zu tesselierende Polygone können aus mehreren Konturen bestehen<br />
- Die Spezifikation erfolgt analog zur Spezifikation normaler Polygone<br />
void gluTessBeginPolygon(GLUtesselator* tessobj,<br />
void* user_data);<br />
void gluTessEndPolygon(GLUtesselator* tessobj);<br />
- Beim Beginn der Spezifikation eines Polygons können<br />
anwendungsspezifische Daten übergeben werden, die beim Aufruf<br />
der jeweiligen GLU_TESS_*_DATA Callbacks jeweils mit übergeben<br />
werden.<br />
- Der <strong>Tesselierung</strong>s-Algorithmus startet zum Ende der Polygon-<br />
Definition und ruft die registrierten Callback-Funktionen (mit evtl.<br />
definierten <strong>Tesselierung</strong>s-Eigenschaften) auf.<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-14
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Anwendungsspezifische Daten<br />
- Mittels des user_data Pointers bei der Polygon-Definition können<br />
anwendungsspezifische Daten übergeben werden, die sich auf das<br />
ganze Polygon beziehen<br />
- Sie werden an die jeweiligen GLU_TESS_*_DATA Callbacks<br />
übergeben, sofern diese definiert sind<br />
- Wird für einen Callback sowohl die GLU_TESS_* und die<br />
GLU_TESS_*_DATA Version registriert, so wird nur die zweite<br />
Version verwendet und die erste ignoriert<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-15
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Kontur-Definition<br />
- Eine Kontur definiert eine geschlossene Kontur eines Polygons (z.B.<br />
den äußeren Rand oder den Rand eines Lochs)<br />
- Anfang und Ende einer Kontur werden analog zu einem Polygon<br />
definiert<br />
void gluTessBeginContour(GLUtesselator* tessobj);<br />
void gluTessEndContour(GLUtesselator* tessobj);<br />
- Zwischen diesen beiden Aufrufen werden die Ecken des<br />
darzustellenden Polygons definiert.<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-16
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Ecken-Definition<br />
void gluTessVertex(GLUtesselator* tessobj,<br />
GLdouble coords[3], void* vertex_data);<br />
- Definiert die Koordinaten und weitere Daten einer Ecke<br />
-vertex_data wird an den entsprechenden GLU_TESS_VERTEX<br />
oder GLU_TESS_VERTEX_DATA Callback weitergereicht<br />
- Vorsicht! Die Signatur dieses Callback bietet keine Möglichkeit auf die<br />
Koordinaten zuzugreifen!<br />
- Die Koordinaten werden nur bei folgender Vertex-Callback-Registrierung<br />
verwendet:<br />
gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv);<br />
-vertex_data sollte also ebenso die Koordinaten der Ecke<br />
enthalten, daneben sind Normalen- oder Farb-Daten sinnvoll<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-17
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Beispielprogramm<br />
- tess_simple.c<br />
(Siehe Website)<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-18
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
<strong>Tesselierung</strong>s-Eigenschaften<br />
- Beeinflussen den <strong>Tesselierung</strong>s-Algorithmus<br />
void gluTessProperty(GLUtesselator* tessobj,<br />
GLenum property, GLdouble value);<br />
- Mögliche Eigenschaften<br />
GLU_TESS_BOUNDARY_ONLY<br />
mögliche Werte: GL_TRUE und GL_FALSE<br />
zeichnet nur den Umriss der Konturen, keine ausgefüllten Polygone<br />
GLU_TESS_TOLERANCE<br />
maximale Distanz, die zwei Punkte auseinander liegen können, um zu<br />
einem zusammengefasst werden zu können. Defaultwert: 0.0<br />
GLU_TESS_WINDING_RULE<br />
beschreibt Regeln, nach denen das Innere und Äußere eines Polygons<br />
bestimmt wird<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-19
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Winding Numbers and Winding Rules<br />
- Winding Number<br />
- Anzahl der Umläufe der Kontur um einen Punkt<br />
- Umläufe im Gegenuhrzeigersinn zählen positiv<br />
- Umläufe im Uhrzeigersinn negativ<br />
- Winding Rule<br />
- Regel, nach der in Abhängigkeit <strong>von</strong> der Winding Number das Innere<br />
eines Polygons bestimmt wird<br />
- Mögliche Regeln:<br />
GLU_TESS_WINDING_ODD (Default)<br />
GLU_TESS_WINDING_NONZERO<br />
GLU_TESS_WINDING_POSITIVE<br />
GLU_TESS_WINDING_NEGATIVE<br />
GLU_TESS_WINDING_ABS_GEQ_TWO<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-20
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Beispielprogramm<br />
- tesswind.c<br />
(Siehe Website)<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-21
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Einsatz <strong>von</strong> Winding Rules in der Constructive Solid Geometry<br />
- Voraussetzung:<br />
- Orientierung der Polygone so, dass Winding Number der Außenseite 0<br />
und der Innenseite 1 ist<br />
- Kann durch Vorverarbeitungsschritt erreicht werden:<br />
<strong>Tesselierung</strong> mit der Eigenschaft GLU_TESS_BOUNDARY_ONLY<br />
- Durch Einsatz <strong>von</strong> zwei Tesselator-Objekten können in den Callback-<br />
Funktionen des ersten die Eingabe-Polygone für den zweiten erzeugt<br />
werden<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-22
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Realisierung der CSG-Operationen:<br />
- Vereinigung<br />
- Tesselierte Darstellung eines Polygons, das alle zu vereinigenden<br />
Konturen enthält<br />
- <strong>Tesselierung</strong> mit der Winding Rule GLU_TESS_WINDING_NONZERO oder<br />
GLU_TESS_WINDING_POSITIVE ergibt das gewünschte Polygon<br />
- Schnitt<br />
- Funktioniert nur für jeweils zwei Konturen mittels<br />
GLU_TESS_WINDING_ABS_GEQ_TWO<br />
- Differenz<br />
- Zeichnen des zweiten Operanden in umgekehrter Reihenfolge der<br />
Ecken mit Winding Rule GLU_TESS_WINDING_POSITIVE<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-23
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Abfrage <strong>von</strong> <strong>Tesselierung</strong>s-Eigenschaften<br />
void gluGetTessProperty(GLUtesselator* tessobj,<br />
GLenum property, GLdouble* value);<br />
- Die Werte der möglichen Eigenschaften<br />
GLU_TESS_BOUNDARY_ONLY,<br />
GLU_TESS_TOLERANCE, oder<br />
GLU_TESS_WINDING_RULE<br />
werden im Parameter value zurückgegeben<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-24
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Definition des Drehsinns mittels Normalen<br />
void gluTessNormal(GLUtesselator* tessobj,<br />
GLdouble x, GLdouble y, GLdouble z);<br />
- Die Polygone werden auf die durch die Normale definierte Ebene<br />
projiziert<br />
- Dreiecke werden im Gegenuhrzeigersinn im Bezug zur Normalen<br />
angeordnet<br />
- Beschleunigt den <strong>Tesselierung</strong>svorgang<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-25
§7 Erweiterte Zeichenfunktionen<br />
<strong>7.4</strong> <strong>Tesselierung</strong> <strong>von</strong> <strong>Polygonen</strong><br />
Beispielprogramm<br />
-tess.c<br />
(Siehe Website)<br />
Visualisierung mit C++ / OpenGL - SS 2006<br />
§7-26