Tutorial
OpenGL und FreeBASIC - eine kleine Einführung - Teil 2 - die Primitive
von Eastler_dart | Seite 1 von 2 |
OPEN-GL Tutorial TEIL II - Die Primitiven und das Koordinatensystem
Einleitung
Na, werter Leser, haben Sie sich die Denkweise in 3D etwas einverleibt?
Sie haben doch nicht etwa das erste Tutorial noch gar nicht gelesen? Dann aber schleunigst nachholen. Wir bauen hier auf das dort Erarbeitete auf!
Beschreibungslistenarten - die Primitiven
Wie bereits angekündigt, wollen wir hier aus den Punkten mal Linien und Flächen machen. Wie schon besprochen, müssen auch diese Linien und die Flächen per 3D-Koordinaten in einer glBegin-glEnd-Liste an OpenGL übergeben werden.
Da taucht bestimmt bei Ihnen die Frage auf, "was für Listen kann man denn so alles an OpenGL übergeben?".
Dazu hab ich hier eine Tabelle vorbereitet, die Ihre Frage beantwortet:
Variablenname hinter glBegin | Bedeutung frei übersetzt | Bedeutung orginal Englisch |
---|---|---|
GL_POINTS | Einfache Punkte | individual points |
GL_LINES | Linien, immer Paare von 2 Punkten werden zu einer Linie | pairs of vertices interpreted as individual line segments |
GL_LINE_STRIP | Linien über mehrere Punkte drüber weg | series of connected line segments |
GL_LINE_LOOP | wie zuvor, jedoch wird der letzte Punkt mit dem ersten verbunden=geschlossen | same as above, with a segment added between last and first vertices |
GL_TRIANGLES | immer drei aufeinanderfolgende Punkte werden zu einem Dreieck | triples of vertices interpreted as triangles |
GL_TRIANGLE_STRIP | Liste mit verlinkten Dreiecken | linked strip of triangles |
GL_TRIANGLE_FAN | verlinkte Fan-Liste mit Dreiecken | linked fan of triangles |
GL_QUADS | immer vier Punkte werden zu einem Viereck | quadruples of vertices interpreted as four-sided polygons |
GL_QUAD_STRIP | Liste mit verlinkten Vierecken | linked strip of quadrilaterals |
GL_POLYGON | Punkte eines einfachen, convexen Polygons | boundary of a simple, convex polygon |
Oha, hier stehen nur Punkte, drei Arten von Linien, drei Arten von Dreiecken, zwei Arten von Vierecken und ein Polygon. Mehr nicht.
Aha, aus diesem bisschen Grundmaterial werden also Figuren geformt.
So ist es. Wenn in einem Game eine superfein ausgearbeitete Figur, mit fast echt wirkenden Gesichtszügen und Mimik, über Ihren Bildschirm rennt, dann sind das immer Punkte, Linien, Dreiecke, Vierecke oder Polygone.
Klar, ggf. auch eine Mischung aus diesen im Grunde 6 Möglichkeiten.
Hier jede Möglichkeit im einzelnen:
GL_POINTS = Punkte
das hatten wir ja im letzten Kapitel, für jede angegebene 3D-Position wird ein Punkt erzeugt
GL_LINES = einfache Linien
Aus der Liste mit 3D-Positionen werden immer die nächsten zwei Positionen entnommen, und eine gerade Linie zwischen diesen beiden erstellt.
Sind weitere 2 3D-Positionen in der Liste vorhanden, wird auch mit diesen beiden eine neue, mit der vorigen nicht in Zusammenhang stehende Linie erzeugt.
Um das bildlich dazustellen, verwenden wir folgendes Listing, welches anstelle unserer 3 Punkte aus dem letzten Kapitel in der Sub Objekt1 einzutragen ist.:
SUB Objekt1()
glBegin GL_LINES
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 2.0, -6.0 :' der dritte Punkt
glVertex3f -0.5, 1.0, -6.0 :' der vierte Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
glVertex3f 1.5, 2.0, -6.0 :' der siebente Punkt
glVertex3f 1.5, 1.0, -6.0 :' der achte Punkt
glEND
END SUB
Damit wird folgendes Bild auf dem Monitor angezeigt, wobei ich zum besseren Verständnis in das angezeigten Bild noch in oranger Farbe die Nummern der Punkte eingefügt habe:
GL_LINE_STRIP = verbundene Linien
Mit einer glBegin-glEnd-Liste wird eine einzige Linie erzeugt.
Die Linie verläuft über alle 3D-Koordinaten, sodass sie je nach Lage der Koordinaten an jeder Adresse abknickt, um in Richtung nächste Adresse weiter zu laufen.
Um uns dies bildlich darzustellen, verwenden wir das Listing mit den GL_LINES, ändern nur den Typ der Liste auf GL_LINES_STRIP ab:
SUB Objekt1()
glBegin GL_LINE_STRIP '<<<<nur hier was zu ändern ;-)
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 2.0, -6.0 :' der dritte Punkt
glVertex3f -0.5, 1.0, -6.0 :' der vierte Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
glVertex3f 1.5, 2.0, -6.0 :' der siebente Punkt
glVertex3f 1.5, 1.0, -6.0 :' der achte Punkt
glEND
END SUB
Aus diesem Listing ergibt sich folgendes Bild, in dem wiederum manuell in orange die Nummern der Punkte mit drin stehen:
GL_LINE_LOOP = zu einer Schleife verbundene Linen
Mit GL_LINE_LOOP wird genau das gleich gemacht, wie bei GL_LINE_STRIP, jedoch wird zusätzlich noch der erste angegebene 3D-Punkt mit dem Letzen mit einer Linie verbunden - Damit gibt es keine Enden der Linie
mehr, diese beiden werden ja auch miteinander verbunden.
Mit den 3D-Koordinaten, welche wir für GL_LINES und GL_LINES_STRIP verwendet hatten, sieht das Ganze als GL_LINE_LOOP so aus (auch hier in orange nachträglich Punktnummern dazugeschrieben):
SUB Objekt1()
glBegin GL_LINE_LOOP '<<<<nur hier was zu ändern ;-)
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 2.0, -6.0 :' der dritte Punkt
glVertex3f -0.5, 1.0, -6.0 :' der vierte Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
glVertex3f 1.5, 2.0, -6.0 :' der siebente Punkt
glVertex3f 1.5, 1.0, -6.0 :' der achte Punkt
glEND
END SUB
Das ist zwar interessant, aber kriegt man auch farbige Flächen hin?
Ja klar, zu den Punkten und Linien gibt es ja noch die Dreiecke, Rechtecke und Vielecke, welche wie folgt funktionieren:
GL_TRIANGLES = einzelne Dreiecke
Bei GL_TRIANGLES-Listen werden immer die nächsten 3 3DKoordinaten genommen, und daraus ein Dreieck erstellt, dass die 3 Koordinaten die Ecken des Dreiecks beschreiben, erklärt sich ja von selbst.
Sind in der Liste noch weitere 3 Koordinaten, so wird mit diesen ein zweites Dreieck erstellt, usw.
Geben Sie z.B. 15 Koordinaten in der Liste an, werden 5 Dreiecke gezeichnet.
Um auf die Beispiele der Linien aufzubauen zu können, müssen wir darin die letzten beiden Koordinaten rauslöschen, mit 8 Punkten können keine Dreiecke gezeichnet werden, das sind 2 zuviel oder 1 zu wenig - mit 6 Punkten geht es und mit 9 Punkten ginge es auch.
Somit ergibt sich ein Listing als Beispiel für GL_TRIANGLES:
SUB Objekt1()
glBegin GL_TRIANGLES '<<<<hier was zu ändern ;-)
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 2.0, -6.0 :' der dritte Punkt
glVertex3f -0.5, 1.0, -6.0 :' der vierte Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
'<<<<<<hier sind es jetzt zwei Zeilen weniger
glEND
END SUB
das ergibt folgende Anzeige:
GL_TRIANGLE_STRIP = zusammenhängende Dreiecke
Mit GL_TRIANGLE_STRIP werden auch mehrere Dreiecke aus den in der Liste vorhandenen Koordinaten erstellt.
Klar, mit den ersten 3 Koordinaten in der Liste, wird einfach ein Dreieck wie zuvor erstellt. Jedoch werden danach die letzten beiden Koordinaten dieses bereits erstellten Dreieckes zusammen mit der als Nächstes in der Liste folgenden Koordinate zu einem zweiten Dreieck geformt. Das bedeutet, mit 4 Koordinaten werden 2 Dreiecke. Das geht dann auch immer so weiter, ist noch mal eine Koordinate in der Liste, bildet diese zusammen mit den letzten zwei Koordinaten des zuvor aus der Liste erstellten Dreiecks ein
weiteres Dreieck.
Mit folgendem Listing, wird das beispielhaft demonstriert, wir verwenden wieder die 8 Koordinaten aus den Lines-Beispielen:
SUB Objekt1()
glBegin GL_TRIANGLE_STRIP '<<<<nur hier was zu ändern ;-)
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 2.0, -6.0 :' der dritte Punkt
glVertex3f -0.5, 1.0, -6.0 :' der vierte Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
glVertex3f 1.5, 2.0, -6.0 :' der siebente Punkt
glVertex3f 1.5, 1.0, -6.0 :' der achte Punkt
glEND
END SUB
Das ganze sieht dann in der Bildschirmausgabe aus, wie ein gelbes Rechteck:
Um zu verstehen, was da ab geht, hab ich in die Bildschirmausgabe wie gehabt die Eckpunktnummern in orange hinzugefügt und zusätzlich die eigentlich angezeigten Dreiecke mit schwarzen Linien umrandet dargestellt.
Sie sehen, man kann aus Dreiecken durchaus auch Rechtecke oder andere Formen erstellen. Das ist übrigens ein Performance-Tip. Formen, die man direkt aus Dreiecken zusammenschustert, werden am allerschnellsten dargestellt!
GL_TRIANGLE_FAN = Dreiecke wie Propeller/Rotoren
Mit GL_TRIANGLE_FAN werden wieder die ersten drei Koordinaten in der Liste als Dreieck angezeigt. Hier "merkt sich" Open GL jedoch die erste Koordinate der Liste und die letzte Ecke des zuletzt aus der Liste gezeichneten Dreiecks.
Diese beiden "gemerkten" Positionen zusammen mit der Nächsten in der Liste ergeben das nächste Dreieck.
Das klingt als Text erst mal verwirrend, aber unser folgendes Listing macht gleich klar, für was das gut sein soll:
SUB Objekt1()
glBegin GL_TRIANGLE_FAN
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f 0.0, 0.0, -6.0 :' der erste Punkt
glVertex3f 0.5, 1.5, -6.0 :' der zweite Punkt
glVertex3f 1.5, 0.5, -6.0 :' der dritte Punkt
glVertex3f 1.5, -0.5, -6.0 :' der vierte Punkt
glVertex3f 0.5, -1.5, -6.0 :' der fünfte Punkt
glVertex3f -0.5, -1.5, -6.0 :' der sechste Punkt
glVertex3f -1.5, -0.5, -6.0 :' der siebente Punkt
glVertex3f -1.5, 0.5, -6.0 :' der achte Punkt
glVertex3f -0.5, 1.5, -6.0 :' der neunte Punkt
glVertex3f 0.5, 1.5, -6.0 :' der zehnte Punkt(=wie zweiter)
glEND
END SUB
Die Anzeige sieht dann so aus:
Auch hier wieder, sieht nicht nach Dreiecken aus, deshalb wieder die Anzeige mit zusätzlich orange Eckpunktnummern und schwarzen Umrahmungslinien an den Dreiecken:
Interessant, nicht wahr? Wenn man hier die Anzahl der Unterteilungen am äußeren Rand erhöht, also schlichtweg mit mehr Dreiecken dieses "rund" erstellt, wird das ganze zu einem Kreis ;-).
GL_QUADS = Vierecke
bei GL_QUADS verhält es sich wie bei GL_TRIANGLES, nur dass es um Vierecke geht. Also immer vier Punkte ergeben ein Viereck. Mit unseren 8 Koordinaten aus dem LINESbeispiel würde das jedoch erst mal schief gehen. Denn in dem Lines-Beispiel haben wir die Reihenfolge der acht Punkte so gelegt, dass sie
dort optisch Sinn machen.
Hier jedoch müssen wir die Reihenfolge ändern, da bei Quads die Punkte "im Kreis rum" um das Viereck anzugeben sind. Also die Koordinaten sind identisch zum Lines-Beispiel, jedoch in der Reihenfolge der Auflistung mussten wir anpassen:
SUB Objekt1()
glBegin GL_QUADS
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 1.0, -6.0 :' der dritte (vierte) Punkt
glVertex3f -0.5, 2.0, -6.0 :' der vierte (dritte) Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
glVertex3f 1.5, 1.0, -6.0 :' der siebente(achte) Punkt
glVertex3f 1.5, 2.0, -6.0 :' der achte(siebente) Punkt
glEND
END SUB
Hier die Bildschirmanzeige, da sie bereits deutlich darstellt, was passiert, hier gleich mit dazugefügten, orange Koordinatennummern.
GL_QUAD_STRIP = zusammenhängende Rechtecke
bei GL_QUAD_STRIP läuft es wieder fast genau gleich, wie bei GL_TRIANGLE_STRIP.
Aus den ersten vier Koordinaten wird ein Rechteck gebildet, dabei "merkt" sich OpenGL dann die letzten zwei Koordinaten, fügt die nächsten zwei aus der Beschreibungsliste dazu und erzeugt daraus dann ein zweites, neues Rechteck.
Das wird solange weiter exerziert, bis keine zwei Koordinaten mehr in der Beschreibungsliste stehen.
Auch hier wieder ein Beispiel, wieder mit den 8 Koordinaten, die wir bisher schon oft in den anderen Beispielen verwendet haben, also diejenige Version, bei der wir keine Reihenfolge geändert haben:
SUB Objekt1()
glBegin GL_QUAD_STRIP
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f -1.5, 2.0, -6.0 :' der erste Punkt
glVertex3f -1.5, 1.0, -6.0 :' der zweite Punkt
glVertex3f -0.5, 2.0, -6.0 :' der dritte Punkt
glVertex3f -0.5, 1.0, -6.0 :' der vierte Punkt
glVertex3f 0.5, 2.0, -6.0 :' der fünfte Punkt
glVertex3f 0.5, 1.0, -6.0 :' der sechste Punkt
glVertex3f 1.5, 2.0, -6.0 :' der siebente Punkt
glVertex3f 1.5, 1.0, -6.0 :' der achte Punkt
glEND
END SUB
Bei der Anzeige wieder ein Effekt, das alle Quads als ein einziges Rechteck angezeigt werden:
Damit man auch versteht, noch mal die Anzeige, jetzt aber mit hinzugefügten schwarzen Rändern an den Vierecken sowie orange Koordinatennummern:
GL_POLYGON = Vieleck
mit dieser Beschreibungslistenart können Gebilde erstellt werden, welche mehr als vier Ecken haben. Für Anfänger ist dieses Grundelement(Primitive) das beliebteste, weil man gleich mal viele, eigentlich schwierige Formen damit erstellen kann. Jedoch ist dieses Element zugleich auch das langsamste Objekt dieser Primitivenliste. OpenGL zerlegt solche Vielecke zuerst in Dreiecke, wo der Zeitverlust entsteht.
Alle Formen, welche man mit Polygonen erstellt, lassen sich auch über mehrere Dreiecke erstellen, das ist dann das gleiche Ergebnis, aber bedeutend schneller im Programmablauf!
Auch hier ein Beispiel, sinniger Weise nehmen wir die Koordinaten aus dem Beispiel von GL_TRIANGLE_FAN und lassen nur den ersten Parameter = 0/0 weg:
SUB Objekt1()
glBegin GL_POLYGON
glColor3f 1.0,1.0,0.0 :' Zeichenfarbe auf gelb
glVertex3f 0.5, 1.5, -6.0 :' der zweite Punkt
glVertex3f 1.5, 0.5, -6.0 :' der dritte Punkt
glVertex3f 1.5, -0.5, -6.0 :' der vierte Punkt
glVertex3f 0.5, -1.5, -6.0 :' der fünfte Punkt
glVertex3f -0.5, -1.5, -6.0 :' der sechste Punkt
glVertex3f -1.5, -0.5, -6.0 :' der siebente Punkt
glVertex3f -1.5, 0.5, -6.0 :' der achte Punkt
glVertex3f -0.5, 1.5, -6.0 :' der neunte Punkt
glVertex3f 0.5, 1.5, -6.0 :' der zehnte Punkt(=wie zweiter)
glEND
END SUB
Das ergibt die selbe Anzeige, wie bei GL_TRIANGLE_FAN, jedoch sind bei GL_POLYGON hier keine unterteilende Dreiecke vorhanden.
Hier die Anzeige mit den Eckpunktnummern in orange nachträglich dazu gefügt:
Wie schon gesagt, falls Sie dieses Gebilde erzeugen wollen, verwenden Sie mit dem erarbeiteten Wissen lieber die Listenart GL_TRIANGLE_FAN, damit wird dieses Gebilde weitaus schneller angezeigt.
So, das war es mit der Übersicht über die Primitiven. Wenn Sie also irgendwelche Modelle erstellen wollen, mit einigen oder allen dieser hier beschriebenen "einfachen" Formen müssen Sie das machen, es gibt keine anderen.
Zusätzliche Informationen und Funktionen | |||||||
---|---|---|---|---|---|---|---|
|
|