31.12.2013 Aufrufe

7.4 Tesselierung von Polygonen - DFKI

7.4 Tesselierung von Polygonen - DFKI

7.4 Tesselierung von Polygonen - DFKI

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!