Buchempfehlung
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Mikrocomputertechnik mit Controllern der Atmel AVR-RISC-Familie
Umfassend, aber leicht verständlich führt dieses Buch in die Programmierung von ATMEL AVR Mikrocontrollern ein. [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 2 von 2

Aber eigentlich wollen wir hier erst mal mit Linien arbeiten, auch wenn wir dabei gleich alle Listenarten beschrieben hatten. Linien in der einfachsten Form = GL_LINES. Alles andere brauchen wir jetzt noch nicht.

Koordinatensystem zeichnen

Wie der Titel schon sagt, soll uns OpenGL nun ein Koordinatensystem anzeigen, mit welchem wir uns das ganze 3D-Getue besser veranschaulichen können. Und dieses System wird ausschließlich aus Linien erstellt - das haben wir ja nun ausführlich exerziert.

Im Prinzip sind das 3 Linien, welche jede eine der drei Achsen darstellt. Aber wie in der Schule mit dem 2D-Koordinatensystem, wollen wir die Linien auch in die einzelnen Maßeinheiten unterteilen.

Oh Gott, werden Sie nun denken, so viele Linien, das gibt ja ne ellenlange Liste an Punkten?
Weit gefehlt. So lang wird die Liste gar nicht.
Es stimmt zwar, dass wir auf ein Fenster, welches wir für OpenGL geöffnet haben, keine FreeBasic-Grafikbefehle anwenden können, und es stimmt auch, dass FreeBasic immer nur ein Grafikfenster aufhaben will. Das heißt aber nicht, dass wir überhaupt keine FreeBasic Befehle einsetzen sollen. Wir haben nur keinerlei Möglichkeit, mit FreeBasic (also ohne OpenGL) dem Anwender irgendwelche Texte anzeigen zu lassen.

"Hausinterne" Berechnungen von Positionen oder For-Next-Schleifen sind durchaus möglich. Halt alles, was keine Ausgabe auf den Screen schickt. Sogar die Tastatur kann abgefragt werden - wir haben im Hauptprogramm ja die Schleife laufen, in der auf den Druck auf die Escape-Taste geprüft wird ;-).

Also packen wir die Maßeinheitsunterteilungsstriche in For-Next-Schleifen.

Aber erst einigen wir uns auf die Farbgebung.
Wenn wir einfach die drei Hauptlinien der Achse zeichnen, wissen wir ja nicht, welche die X- / welche die Y- oder welche die Z-Achse darstellt. Und darum verwenden wir für jede Achse eine andere Farbe, aber welche?
Mit einer Eselsbrücke wird das am einfachsten sein.
Die Bezeichnung RGB kann sich bestimmt jeder merken, man ließt sie ja immer wieder irgendwo.
Damit hätten wir eine Farbreihenfolge, die wir uns ganz schnell wieder in Erinnerung holen können.
Für die Achsenreihenfolge steht ja das Alphabet zur Verfügung. Die Achsen nennen wir in Reihenfolge X, Y und Z.
Und das ordnen wir hier einfach einander zu:

AchseFarbe
X-AchseRot
Y-AchseGrün
Z-AchseBlau

Weiterhin wollen wir mit Farbe noch folgendes optisch erkennbar machen.
Und zwar, welches Stück der jeweiligen Achse im Minusbereich der Einheiten liegt, und welches im Plusbereich.
Das bedeutet, dass wir die Maßunterteilungsstriche mit zwei verschiedenen Farben malen, je nachdem, ob der Bereich mit negativen oder mit Positiven Maßangaben zu erreichen ist.
Hier einigen wir uns auf Helles Weiß = positiv, dunkles Schwarz = negativ (welch kreative Eselsbrücke boah).

Tja, und mit der Festlegung, dass diese Unterteilungslinien in anderer Farbe
(schwarz/weiß) als die Achsen selbst (rot/grün/blau) dargestellt werden sollen, laufen wir in ein weiteres Problem.
Die Schnittpunkte der Linien. Die Unterteilungsstriche kreuzen die Achse selbst. Und dabei wird ein Punkt, der durch die Achse selbst z.B. rot ist, mit den weißen oder schwarzen Einteilungsstrichen eben in weiß oder in schwarz angezeigt. Das hatte ich schon probiert, sieht doof aus.

Wir umgehen dieses Problem, indem wir als erstes die Maßeinheiten zeichnen, und danach die eigentliche Achse.

Also ran ans Werk.
Erstellen wir für jede Achse jeweils eine Schleife für die positive Hälfte und für die negative Hälfte. Wir zählen in der Schleife immer um 1.0 weiter, und setzen auf der Achsenlänge dann an diesen "ganzen" Werten ein Kreuzstrich.
Aber bedenken Sie, wir arbeiten unter 3D, an der X-Achse zum Beispiel brauchen wir pro Maßeinheitenpunkt zwei Querstriche, einer der senkrecht läuft (Y-Achse) und einer der in die Tiefe läuft (Z-Achse). Weil später wandern wir durch den Raum und schauen uns das ganze von oben an, dann sähen wir ja nur einen einzelnen Punkt, da der Maßstrich von senkrecht oben gesehen ja nur eben diesen einen Punkt hergibt, die restlichen liegen direkt darunter und sind nicht zu sehen.

Nun setze ich einfach ein bisschen Kenntnis in FreeBasic und in For-Next-Schleifen voraus, gehe also nicht allzu tief ins Detail:

Zum Zählen in der Schleife, brauchen wir eine Zählvariable. Da wir diese nur für das Koordinatensystem verwenden wollen, erzeugen (dimmen) wir diese gleich in unserer SUB. Und da wir dieses Koordinatensystem immer wieder einsetzen wollen, kriegt es auch eine eigene SUB. Des weiteren wollen wir dieses Koordinatensystem später auch an anderen Stellen, als nur auf Punkt 0,0,0 anzeigen, deshalb Reservieren wir in der SUB auch gleich noch ein paar Übergabevariablen. Die Sub nennen wir, wer hätte das gedacht, "Koordinatensystem".

Also, im Hauptteil diese Sub erst mal Deklarieren:

DECLARE SUB Objekt1 () 'steht ja schon drin, darunter schreiben wir:
DECLARE SUB Koordinatensystem(was AS STRING, TxtPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)

In der Schleife im Hauptteil rufen wir noch vor unserer anderen SUB Objekt1 die Sub des Koordinatensystems auf, wobei wir für den Parameter "Para3" den Wert -9 übergeben müssen, die restlichen bleiben leer bzw 0.
Weshalb wir eine -9 für die Z-Achse übergeben, hängt mit den Projektionsdaten von OpenGL zusammen, aber darauf möchte ich erst später eingehen. Wir schreiben im Hauptteil in die Schleife:

   Koordinatensystem("", "", 0, 0, -9)
   Objekt1               'steht ja schon drin

Und ans Ende unseres Listings kommt die SUB selber, wobei wir zu jeder Positionsangabe unsere Sub-Parameter hinzuzählen.
Wenn wir zum Beispiel mit folgendem Listing
FOR Zaehler = 1 TO 3
glVertex3f Zaehler, 0,0
NEXT Zaehler

auf der Z-Achse die Punkte 1,0,0 und 2,0,0 und 3,0,0 ansteuern wollten, aber mit unseren Parametern noch auf alle drei Werte Einfluss nehmen wollen, würden wir so ergänzen:
FOR Zaehler = 1 TO 3
glVertex3f Zaehler+Para1, 0+Para2, 0+Para3
NEXT Zaehler

Das würde nach der Auflösung der For-Next-Schleife :
einen folgenden Programmablauf ergeben:
glVertex3f 1+Para1, 0+Para2, 0+Para3
glVertex3f 2+Para1, 0+Para2, 0+Para3
glVertex3f 3+Para1, 0+Para2, 0+Para3

und mit Einarbeiten der übergebenen Parameter an die SUB (wie in der Hauptschleife oben eingetragen: Koordinatensystem("", "", 0, 0, -9))
glVertex3f 1+0, 0+0, 0+-9
glVertex3f 2+0, 0+0, 0+-9
glVertex3f 3+0, 0+0, 0+-9


Ich denke, Sie haben damit verstanden, wie ich mit den Sub-Parametern die Position der Anzeige beeinflusse. Damit ist es ein Leichtes, das Koordinatensystem bei Bedarf auch an einer anderen Position als 0/0/0 anzuzeigen, weil sämtliche Positionsangaben noch die übergebenen Werte mit hinzuzählen.

Mit diesem Wissen, also per For-Next die eigentlichen Positionen erstellen und dann mit hinzuaddieren der Subparameter die Position verschieben, erstellen wir nun unsere Sub Koordinatensystem wie folgt:

'-------------------------
SUB Koordinatensystem(was AS STRING, TxtPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
   DIM AS INTEGER Zaehler
         glBegin GL_LINES:' Ja, wir beginnen mit der Beschreibungsliste für Linien
         'und zwar zuerst die positiven Bereiche jeder Achse
         glColor3f 1.0, 1.0, 1.0        :' Positives Maß = weiße Teilstriche (Rot 1.0, blau 1.0, grün 1.0 = weiß)
         FOR Zaehler = 1 TO 3 :'für die Maßeinheitspositionen 1, 2 und 3 Striche Ziehen
            'X-ACHSE
               'senkrechter Strich (wie Y-Achse)
            glVertex3f  Zaehler+Para1,  0.2+Para2,  0.0+Para3 :' Anfangspunkt auf XAchse-Maßpunkt, 0.2 Einheiten drüber(+Y), Tiefe = 0
            glVertex3f  Zaehler+Para1, -0.2+Para2,  0.0+Para3 :' Endpunkt auf XAchse-Maßpunkt, 0.2 Einheiten drunter(-Y), Tiefe = 0
               'waagerechter Strich (wie Z-Achse)
            glVertex3f  Zaehler+Para1,  0.0+Para2,  0.2+Para3 :' Anfangspunkt auf XAchse-Maßpunkt, 0.2 Einheiten drüber(+Y), Tiefe = 0
            glVertex3f  Zaehler+Para1,  0.0+Para2, -0.2+Para3 :' Endpunkt auf XAchse-Maßpunkt, 0.2 Einheiten drunter(-Y), Tiefe = 0
            'Y-ACHSE
               'Strich wie X-Achse
            glVertex3f  0.2+Para1, Zaehler+Para2,  0.0+Para3 :' Anfangspunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach +X, Tiefe = 0
            glVertex3f -0.2+Para1, Zaehler+Para2,  0.0+Para3 :' Endpunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach -X, Tiefe = 0
               'Strich wie Z-Achse
            glVertex3f  0.0+Para1, Zaehler+Para2,  0.2+Para3 :' Anfangspunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach vorne/+Z, Seite (X) = 0
            glVertex3f  0.0+Para1, Zaehler+Para2, -0.2+Para3 :' Endpunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach hinten/-Z, Seite (X) = 0
            'Z-ACHSE
               'Strich waagerecht (X)
            glVertex3f  0.2+Para1,  0.0+Para2, Zaehler+Para3 :' Anfangspunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach rechts +X, Hoehe = 0
            glVertex3f -0.2+Para1,  0.0+Para2, Zaehler+Para3 :' Endpunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach links -X, Hoehe = 0
               'Strich senkreicht (Y)
            glVertex3f  0.0+Para1,  0.2+Para2,  Zaehler+Para3 :' Anfangspunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach oben +Y, Seite = 0
            glVertex3f  0.0+Para1, -0.2+Para2,  Zaehler+Para3 :' Endpunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach unten -Y, Seite = 0
         NEXT Zaehler
         glColor3f 0.0, 0.0, 0.0        :' Negatives Maß = schwrze Teilstriche (alles auf 0)
         FOR Zaehler = -3 TO -1 :'für die Maßeinheitspositionen -3, -2 und -1 Striche Ziehen
         'X-ACHSE
            'senkrechter Strich (wie Y-Achse)
            glVertex3f  Zaehler+Para1,  0.2+Para2,  0.0+Para3 :' Anfangspunkt auf XAchse-Maßpunkt, 0.2 Einheiten drüber(+Y), Tiefe = 0
            glVertex3f  Zaehler+Para1, -0.2+Para2,  0.0+Para3 :' Endpunkt auf XAchse-Maßpunkt, 0.2 Einheiten drunter(-Y), Tiefe = 0
            'waagerechter Strich (wie Z-Achse)
            glVertex3f  Zaehler+Para1,  0.0+Para2,  0.2+Para3 :' Anfangspunkt auf XAchse-Maßpunkt, 0.2 Einheiten drüber(+Y), Tiefe = 0
            glVertex3f  Zaehler+Para1,  0.0+Para2, -0.2+Para3 :' Endpunkt auf XAchse-Maßpunkt, 0.2 Einheiten drunter(-Y), Tiefe = 0
            'Y-ACHSE
               'Strich wie X-Achse
            glVertex3f  0.2+Para1, Zaehler+Para2,  0.0+Para3 :' Anfangspunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach +X, Tiefe = 0
            glVertex3f -0.2+Para1, Zaehler+Para2,  0.0+Para3 :' Endpunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach -X, Tiefe = 0
               'Strich wie Z-Achse
            glVertex3f  0.0+Para1, Zaehler+Para2,  0.2+Para3 :' Anfangspunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach vorne/+Z, Seite (X) = 0
            glVertex3f  0.0+Para1, Zaehler+Para2, -0.2+Para3 :' Endpunkt auf YAchse-Maßpunkt, 0.2 Einheiten nach hinten/-Z, Seite (X) = 0
            'Z-ACHSE
               'Strich waagerecht (X)
            glVertex3f  0.2+Para1,  0.0+Para2, Zaehler+Para3 :' Anfangspunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach rechts +X, Hoehe = 0
            glVertex3f -0.2+Para1,  0.0+Para2, Zaehler+Para3 :' Endpunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach links -X, Hoehe = 0
               'Strich senkreicht (Y)
            glVertex3f  0.0+Para1,  0.2+Para2,  Zaehler+Para3 :' Anfangspunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach oben +Y, Seite = 0
            glVertex3f  0.0+Para1, -0.2+Para2,  Zaehler+Para3 :' Endpunkt auf ZAchse-Maßpunkt, 0.2 Einheiten nach unten -Y, Seite = 0
         NEXT Zaehler
         'UND NUN DIE DREI ACHSEN SELBST:
         'X-ACHSE
         glColor3f 1.0, 0.0, 0.0        :' Xachse = rot
         glVertex3f  -3.0+Para1, 0+Para2, 0+Para3
         glVertex3f  +3.0+Para1, 0+Para2, 0+Para3
         'Y-ACHSE
         glColor3f 0.0, 1.0, 0.0        :' Yachse = grün
         glVertex3f  0+Para1, -3.0+Para2, 0+Para3
         glVertex3f  0+Para1, +3.0+Para2, 0+Para3
         'Z-ACHSE
         glColor3f 0.0, 0.0, 1.0        :' Zachse = blau
         glVertex3f  0+Para1, 0+Para2, -3.0+Para3
         glVertex3f  0+Para1, 0+Para2, +3.0+Para3
      glEnd
END SUB

Wenn Sie das jetzt kompilieren, erhalten Sie folgendes Bild:
3D-Koordinatensystem_von_standardsichtpunkt
Ups, das sieht ja komisch aus, werden Sie sagen.
Man sieht die X-Achse (rot) und Y-Achse (grün) prima, aber was ist mit 3D? die dritte Achse, die Z-Achse?
Keine Panik, sie ist da.
Sehen Sie in der Mitte des Bildes das weiße Kreuz, welches die X- und Y-Achsen überdeckt? das ist unser Z-Achse.
Nur zeigt OpenGL alles vom Standpunkt 0/0/0 mit Sichtrichtung auf entlang der negativen Z-Achse an. Und deshalb sehen wir hier nur einen Schnitt durch die Z-Achse, mit einer der weißen Maßeinheitsunterteilungen.

Also, was haben wir erreicht?
Wir kennen nun alle "Primitiven", ob Linien, Dreiecke, Vielecke, wir wissen was das ist.
Und OpenGL malt uns ein schönes 3D-Koordinatensystem, nur, man sollte es auch von einem anderen Standpunkt aus anschauen können. Und genau das machen wir im nächsten Kapitel.

 

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