Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Tutorial

OpenGL und FreeBASIC - eine kleine Einführung - Teil 2 - die Primitive

von MitgliedEastler_dartSeite 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 übersetztBedeutung orginal Englisch
GL_POINTSEinfache Punkteindividual points
GL_LINESLinien, immer Paare von 2 Punkten
werden zu einer Linie
pairs of vertices
interpreted as individual
line segments
GL_LINE_STRIPLinien über mehrere Punkte drüber wegseries of connected
line segments
GL_LINE_LOOPwie zuvor, jedoch wird der letzte Punkt
mit dem ersten verbunden=geschlossen
same as above,
with a segment added between last
and first vertices
GL_TRIANGLESimmer drei aufeinanderfolgende
Punkte werden zu einem Dreieck
triples of vertices
interpreted as triangles
GL_TRIANGLE_STRIPListe mit verlinkten Dreieckenlinked strip of triangles
GL_TRIANGLE_FANverlinkte Fan-Liste mit Dreieckenlinked fan of triangles
GL_QUADSimmer vier Punkte werden zu einem Viereckquadruples of vertices
interpreted as four-sided
polygons
GL_QUAD_STRIPListe mit verlinkten Viereckenlinked strip of
quadrilaterals
GL_POLYGONPunkte eines einfachen, convexen Polygonsboundary 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_strip_anzeige

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

gl_line_loop_anzeige

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_Triangles_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:
gl_triangle_strip_anzeige
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.
gl_triangles_strip_anzeige_mit_nr
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:
gl_triangle_fan_anzeige
Auch hier wieder, sieht nicht nach Dreiecken aus, deshalb wieder die Anzeige mit zusätzlich orange Eckpunktnummern und schwarzen Umrahmungslinien an den Dreiecken:
gl_triangle_fan_mit_nummern
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_quads_anzeige

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:
gl_quad_strip_anzeige
Damit man auch versteht, noch mal die Anzeige, jetzt aber mit hinzugefügten schwarzen Rändern an den Vierecken sowie orange Koordinatennummern:
gl_quad_strip_mit_nummern

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:
gl_polygon_mit_nummern
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.

 

Gehe zu Seite Gehe zu Seite  1  2  
Zusätzliche Informationen und Funktionen
  • Das Tutorial wurde am 20.07.2008 von MitgliedEastler_dart angelegt.
  • Die aktuellste Version wurde am 30.09.2008 von MitgliedEastler_dart gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen