Buchempfehlung
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
Windows-Programmierung. Das Entwicklerhandbuch zur WIN32-API
"Der" Petzold, das über 1000 Seiten starke Standardwerk zum Win32-API - besonders nützlich u. a. bei der GUI-Programmierung in FreeBASIC! [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 4 - Rotieren

von MitgliedEastler_dartSeite 4 von 4

aufräumen

Jetzt ist es an der Zeit, ein bißchen aufzuräumen. Das angezeigte Koordinatensystem ist ja gut uns schön, bestimmt jetzt und auch später hilfreich, aber um die 3D-Welt zu genießen, wirkt es eher etwas störend.

Also versuchen wir mal, dem Anwender die Wahl zu lassen, ob er das Koordinatensystem sehen will:
Schlichtweg ein Flag für An und Aus (Variable 0 oder 1) setzen, in der Tastaturabfrage dieses Flag/Var bei Drücken der Taste "K" hin- und herschalten und in der Anzeigeroutine eine IF-Then-Auswertung machen, ob das Flag an(1) oder aus(0) ist.

Für das Flag eine Variable innerhalb der SUB Koordinatensystem dimmen:

SUB Koordinatensystem(was AS STRING, .......
   DIM AS INTEGER Zaehler  :'steht ja schon drin
   STATIC AS INTEGER AnzeigeSchalter:'<--------------------

Die ganze Sub "Koordinatensystem" hat zwar die Übergabe der Variable WAS, wertet diese aber noch nicht aus. Somit die Sub per SELECT CASE in verschiedene Funktionen aufteilen, das was bisher drin ist, kommt in den CaseFall "Anzeigen".
Und dieser Case-Fall "Anzeigen" prüft zuerst, ob in AnzeigeSchalter der Wert 1 (eingeschalten) drin ist.
Ein zweiter Select-Case-Fall wird angelegt, der auf die Übergabe des Strings "AnAus" gestartet wird, und die Variable AnzeigeSchalter je nach dem, was drin steht, auf 0 oder 1 setzt.
Damit sieht die SUB Koordinatensystem jetzt so aus:

SUB Koordinatensystem(was AS STRING, TxtPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
   DIM AS INTEGER Zaehler
   STATIC AS INTEGER AnzeigeSchalter
   SELECT CASE UCASE(was)
      CASE "ANAUS"
         IF AnzeigeSchalter = 0 THEN AnzeigeSchalter = 1 ELSE AnzeigeSchalter = 0
      CASE "ANZEIGEN"
        IF AnzeigeSchalter = 1 THEN
         glBegin GL_LINES:' Ja, wir beginnen mit der Beschreibungsliste fuer 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 6 :'fuer 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 = -6 TO -1 :'fuer 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  -6.0+Para1, 0+Para2, 0+Para3
         glVertex3f  +6.0+Para1, 0+Para2, 0+Para3
         'Y-ACHSE
         glColor3f 0.0, 1.0, 0.0        :' Yachse = grün
         glVertex3f  0+Para1, -6.0+Para2, 0+Para3
         glVertex3f  0+Para1, +6.0+Para2, 0+Para3
         'Z-ACHSE
         glColor3f 0.0, 0.0, 1.0        :' Zachse = blau
         glVertex3f  0+Para1, 0+Para2, -6.0+Para3
         glVertex3f  0+Para1, 0+Para2, +6.0+Para3
         glEnd
       END IF
   END SELECT
END SUB

Jetzt muß natürlich der Aufruf in der Hauptschleife geändert werden, da die Sub den Parameter "Anzeigen" im Aufruf in der ersten Variable braucht:

    glPushMatrix :'<----------------------------------
    Koordinatensystem("Anzeigen", "", 0, 0, 0) :' den Stringwert "Anzeigen" übergeben
    glPopMatrix :'<----------------------------------

Und in der Tastaturabfrage den CASE-Fall "K" oder "k" anlegen,
innerhalb dessen der Schalter AN/AUS umgeschalten wird.

   'ProgrammSchleife
   '---------------------------
   'JE NACH TASTENDRUCK DEN ENTSPRECHENDEN POSITIONSWERT VERÄNDERN
   SELECT CASE Tastendruck
   .
   .
      CASE "K", "K"
         Koordinatensystem("AnAus", "", 0, 0, 0) :' Schalter umstellen, falls An ist, auf Aus, sonst auf An

Damit können wir mittels der K-Taste das Anzeigen des Koordinatensystems An- und Ausschalten.

Aber etwas Anderes fällt mir bei der Tastatur noch auf: Sicher, wir haben die Cursortasten so belegt, wie wir die Funktionen erarbeitet hatten. Aber für ein bequemes Bewegen, liegt das ganze ein bißchen verdreht.
Eigentlich geh ich davon aus, das das Drücken der Cursortasten die Bewegung hervorruft. Und die normalerweise übliche Bewegung ist Vor, Zurück, Links-Dreh und Rechts-Dreh. Bei uns ist das grad umgekehrt entstanden.
Diese "normalen" Bewegungen müssen durch zusätztiches Dazudrücken der STRG- bzw. CTRL-Tasten ausgelöst werden.
Schlage vor, wir drehen das um:
Also Curor hoch/runter = in /gegen Sichtrichtung wandern.
Cursor links/rechts = drehen um Achse nach links/rechts.
CTRL+Links/Rechts = seitlich links/rechts laufen.
Bleibt für Höher/Wachsen Niedriger/KleinerWerden nur noch Ctrl- bzw. Strg+Hoch/Runter.
mit diesen Änderungen sieht die Tastaturabfrage so aus:

   SELECT CASE Tastendruck
      CASE "K", "K"
         Koordinatensystem("AnAus", "", 0, 0, 0) :' Schalter umstellen, falls An ist, auf Aus, sonst auf An
      CASE TCtrlrechts                :'Falls die Tasten "Cursor nach rechts" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         XRichtg = XRichtg - COS((WeltDrehY * Pi) / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg - SIN((WeltDrehY * Pi) / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TCtrllinks                 :'Falls die Tasten "Cursor nach rechts" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         XRichtg = XRichtg + COS((WeltDrehY * Pi) / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg + SIN((WeltDrehY * Pi) / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TCtrlzurueck               :'Falls die Tasten "Cursor unten" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         YRichtg = YRichtg + 0.04 :'HOCH und Runter bleibt unberührt von der Y-Drehung
      CASE TCtrlvor                   :'Falls die Tasten "Cursor hoch" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         YRichtg = YRichtg - 0.04 :'HOCH und Runter bleibt unberührt von der Y-Drehung
      CASE TZurueck                   :'Falls die Taste "Cursor runter" gedrückt wurde
         XRichtg = XRichtg + COS((WeltDrehY-90) * Pi / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg + SIN((WeltDrehY-90) * Pi / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TVor                       :'Falls die Taste "Cursor hoch" gedrückt wurde
         XRichtg = XRichtg + COS((WeltDrehY+90) * Pi / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg + SIN((WeltDrehY+90) * Pi / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TLinks                      :'Falls die Taste "Cursor links" gedrückt wurde
         WeltDrehY = WeltDrehY - 1
      CASE TRechts                     :'Falls die Taste "Cursor rechts" gedrückt wurde
         WeltDrehY = WeltDrehY + 1
      CASE "x"
         PyraXDrehw=PyraXDrehw+1
      CASE "x"
         PyraXDrehw=PyraXDrehw-1
      CASE "y"
         PyraYDrehw=PyraYDrehw+12
      CASE "y"
         PyraYDrehw=PyraYDrehw-12
      CASE "z"
         PyraZDrehw=PyraZDrehw+1
      CASE "z"
         PyraZDrehw=PyraZDrehw-1
      CASE "i", "i"                       :'<------------------------
         ConNr = FREEFILE                 :'nächste freie Dateinummer für öffnen von FreeBasic holen und in ConNr merken
         open "con" FOR OUTPUT AS #ConNr  :'und nun die Konsole als Datei unter Nr ConNr öffnen
            PRINT #ConNr, "PyraXDrehw:" & format(PyraXDrehw,"0.00") & "  PyraYDrehw:" & format(PyraYDrehw,"0.00") & "  PyraZDrehw:" & format(PyraZDrehw,"0.00")
            PRINT #ConNr, "XRichtg:" & format(XRichtg,"0.00") & "  YRichtg:" & format(YRichtg,"0.00") & "  ZRichtg:" & format(ZRichtg,"0.00")
         CLOSE #ConNr
   END SELECT

So, nun bewegen wir uns/die Kamera so, wie man sich das vorstellt. Wir können mit "K" das Koordinatensystem ein- und ausblenden, mit "i" werden für uns wichtige Positions- und Drehwerte im Konsolenfenster angezeigt.
Mit den Cursortasten laufen wir in Sichtrichtung, drehen uns nach links oder rechts, zusammen mit den Ctrl- oder Strg-Tasten laufen wir nach links oder rechts, werden größer oder kleiner.

Zusätzlich haben wir eine Objektroutine für Pyramiden drin, welche wir mit den X-, Y- und Z-Tasten hin und her drehen können.

film_endstand.gif

Damit haben wir nun ein verbessertes Grundgerüst, um per SUBs mit OpenGL Objekte zu erstellen, um anschießend diese in einer kleinen 3D-Welt anzeigen zu lassen und in dieser Welt umher zu laufen.

Mal sehen, im nächsten Kapitel werd ich wohl das Texturieren, "also Bilder auf die Flächen kleben" grob umreißen.

Hier nochmal das komplette Listing:

'REM Tutorial 4 - OpenGL-Tutorial von Eastler
'-------------------------
'DIMs
'-------------------------
DIM SHARED AS STRING Tastendruck
DIM SHARED AS STRING Tlinks, Trechts, Tvor, Tzurueck, TCtrlVor, TCtrlZurueck, TCtrlLinks, TCtrlRechts
Tlinks       = CHR(255) & CHR( 75)  :' beim Drücken der Taste CursorLinks gibt die Tastatur CHR(255) & CHR( 75) zurück
Trechts      = CHR(255) & CHR( 77)  :' CursorRechts
Tvor         = CHR(255) & CHR( 72)  :' CursorHoch
Tzurueck     = CHR(255) & CHR( 80)  :' CursorRunter
TCtrlVor     = CHR(255) & CHR(141)  :'Ctrl oder STRG zusammen mit CursorHoch
TCtrlZurueck = CHR(255) & CHR(145)  :'Ctrl oder STRG zusammen mit CursorRunter
TCtrlLinks   = CHR(255) & CHR(115)  :'<--------CURSOR NACH LINKS-Variable mit Wert belegen
TCtrlRechts  = CHR(255) & CHR(116)  :'<--------CURSOR NACH RECHTS-Variable mit Wert belegenDIM AS SINGLE XRichtg, YRichtg, ZRichtg
DIM AS SINGLE XRichtg, YRichtg, ZRichtg
DIM AS SINGLE PyraXDrehw, PyraYDrehw, PyraZDrehw :'<------------------------ für Pyramide per Tasten drehen
DIM AS SINGLE WeltDrehX, WeltDrehY, WeltDrehZ
DIM AS INTEGER ConNr                :' Dateinummerspeicher beim Consolefenster öffnen
DIM SHARED AS DOUBLE Pi
Pi = 3.14159265358979323846
'-------------------------
'Includes
'-------------------------
#include "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glu.bi"
#include once "vbcompat.bi" '<--------------um Zahlen per "format()" formatieren zu können

'-------------------------
'Declarationen
'-------------------------
'-------------------------
'Declarationen
'-------------------------
DECLARE SUB Koordinatensystem(was AS STRING, TxtPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
DECLARE SUB Objekt1()
DECLARE SUB BewegtePunkte()
DECLARE SUB Schachbrettboden(was AS STRING, StrPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
DECLARE SUB Pyramide (was AS STRING, StrPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)

'-------------------------
' das Fenster öffnen
'-------------------------
screen 19, 16, , 2

'-------------------------
' Open-GL Init
'-------------------------
glViewport 0, 0, 800, 600                      ' den Current Viewport auf eine Ausgangsposition setzen
glMatrixMode GL_PROJECTION                     ' Den Matrix-Modus Projection wählen
glLoadIdentity                                 ' Diesen Modus auf Anfangswerte setzen
gluPerspective 45.0, 800.0/600.0, 0.1, 100.0   ' Grundeinstellungen des Anezeigefensters festlegen
glMatrixMode GL_MODELVIEW                      ' Auf den Matrix-Modus Modelview schalten
glLoadIdentity                                 ' und auch diesen auf Anfangswerte setzen
glClearColor 0.5, 0.5, 0.50, 0.0               ' Setze Farbe für löschen auf Mittelgrau
glClearDepth 1.0                               ' Depth-Buffer Löschen erlauben
glEnable GL_DEPTH_TEST                         ' den Tiefentest GL_DEPTH_TEST einschalten
glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT  'Tiefen- und Farbpufferbits löschen
'---------------------------
'HAUPTTEIL
'---------------------------
Schachbrettboden("SetzKantenLaenge", "", 0.5,  0,    0)
Schachbrettboden("SetzQuadsZahl",    "", 24,   24,   0)     :'6 Einheiten +und- = 12Einheiten Koordiantensystem, bei 0.5 Quadgröße 24 Stück
Schachbrettboden("SetzFarbe1",       "", 0,    0,    0.5)   :'erste Farbe dunkleres blau
Schachbrettboden("SetzFarbe2",       "", 0.25, 0.25, 0.25)  :'erste Farbe dunkles grau
Schachbrettboden("SetzStartPos",     "", -6,   -6,   -1)     :'ganz vorne ganz links beginnen, Boden auf Hoehe(3.Para)-1 verlegen(Y)

Pyramide("SetzLaengen" , "", 1, 1,  1)
Pyramide("SetzFarbe1"  , "", 1, 0, 0)
Pyramide("SetzFarbe2"  , "", 0, 1, 0)
Pyramide("SetzFarbe3"  , "", 0, 0, 1)
Pyramide("SetzFarbe4"  , "", 1, 1, 0)
Pyramide("SetzFarbe5"  , "", 1, 0, 1)

DO UNTIL Tastendruck = CHR(27)                         :'die Schleife solange immer wiederholen, bis in der Variablen Tastendruck die Esc-Taste (chr(27) steht
   Tastendruck = INKEY                                 :'Jeder Tastendruck wird sofort in die Variable Tastendruck gespeichert
   '---------------------------
   'ProgrammSchleife
   '---------------------------

   'JE NACH TASTENDRUCK DEN ENTSPRECHENDEN POSITIONSWERT VERÄNDERN
   SELECT CASE Tastendruck
      CASE "K", "K"
         Koordinatensystem("AnAus", "", 0, 0, 0) :' Schalter umstellen, falls An ist, auf Aus, sonst auf An
      CASE TCtrlrechts                :'Falls die Tasten "Cursor nach rechts" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         XRichtg = XRichtg - COS((WeltDrehY * Pi) / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg - SIN((WeltDrehY * Pi) / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TCtrllinks                 :'Falls die Tasten "Cursor nach rechts" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         XRichtg = XRichtg + COS((WeltDrehY * Pi) / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg + SIN((WeltDrehY * Pi) / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TCtrlzurueck               :'Falls die Tasten "Cursor unten" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         YRichtg = YRichtg + 0.04 :'HOCH und Runter bleibt unberührt von der Y-Drehung
      CASE TCtrlvor                   :'Falls die Tasten "Cursor hoch" zuammen mit Strg- bzw. Ctrl gedrückt wurde
         YRichtg = YRichtg - 0.04 :'HOCH und Runter bleibt unberührt von der Y-Drehung
      CASE TZurueck                   :'Falls die Taste "Cursor runter" gedrückt wurde
         XRichtg = XRichtg + COS((WeltDrehY-90) * Pi / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg + SIN((WeltDrehY-90) * Pi / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TVor                       :'Falls die Taste "Cursor hoch" gedrückt wurde
         XRichtg = XRichtg + COS((WeltDrehY+90) * Pi / 180) * 0.04 :' Den X-Pos-Wert anpassen
         ZRichtg = ZRichtg + SIN((WeltDrehY+90) * Pi / 180) * 0.04 :' Den Y-Pos-Wert anpassen
      CASE TLinks                      :'Falls die Taste "Cursor links" gedrückt wurde
         WeltDrehY = WeltDrehY - 1
      CASE TRechts                     :'Falls die Taste "Cursor rechts" gedrückt wurde
         WeltDrehY = WeltDrehY + 1
      CASE "x"
         PyraXDrehw=PyraXDrehw+1
      CASE "x"
         PyraXDrehw=PyraXDrehw-1
      CASE "y"
         PyraYDrehw=PyraYDrehw+12
      CASE "y"
         PyraYDrehw=PyraYDrehw-12
      CASE "z"
         PyraZDrehw=PyraZDrehw+1
      CASE "z"
         PyraZDrehw=PyraZDrehw-1
      CASE "i", "i"                       :'<------------------------
         ConNr = FREEFILE                 :'nächste freie Dateinummer für öffnen von FreeBasic holen und in ConNr merken
         open "con" FOR OUTPUT AS #ConNr  :'und nun die Konsole als Datei unter Nr ConNr öffnen
            PRINT #ConNr, "PyraXDrehw:" & format(PyraXDrehw,"0.00") & "  PyraYDrehw:" & format(PyraYDrehw,"0.00") & "  PyraZDrehw:" & format(PyraZDrehw,"0.00")
            PRINT #ConNr, "XRichtg:" & format(XRichtg,"0.00") & "  YRichtg:" & format(YRichtg,"0.00") & "  ZRichtg:" & format(ZRichtg,"0.00")
         CLOSE #ConNr
   END SELECT   'PRÜFEN, DASS DIE POSITIONSWERTE IN ALLEN DREI RICHTUNGEN ZWISCHEN -3 und +3 BLEIBEN
   IF XRichtg >  6 THEN XRichtg =  6           :'falls zu weit rechts, bei  6 festnageln
   IF XRichtg < -6 THEN XRichtg = -6           :'falls zu weit links,  bei -6 festnageln
   IF YRichtg >  6 THEN YRichtg =  6           :'falls zu weit hoch,   bei  6festnageln
   IF YRichtg < -6 THEN YRichtg = -6           :'falls zu weit runter, bei -6 festnageln
   IF ZRichtg >  5 THEN ZRichtg =  5           :'falls zu weit zurück, bei 10 festnageln
   IF ZRichtg < -10 THEN ZRichtg = -10           :'falls zu weit vor,    bei -6 festnageln
   glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT  :'bisherig erstellte Objekte löschen, unsere 3D-Welt wieder von Neuem an erstellen
   glPushMatrix                                        :'aktuelle Position + Drehgrade sichern (2.Zettel mit gleicher Pos auf PositionsSTACK)
    glRotatef WeltDrehY, 0, 1, 0                       :'Rotationsbefehl der Kamera, um Y ist zu drehen
    glTranslatef XRichtg, YRichtg, ZRichtg             :'Verschiebung der Kamera, auf neue Werte einstellen

    '-------------------------
    'AB HIER OBJEKTE ERSTELLEN
    '-------------------------
    glPointSize(5)                             :' Punktgröße auf 5 = deutlich groß
    glColor3f 1.0,0.0,0.0                      :' Anzeigefarbe auf ROT setzen
'    Objekt1()                                  :' Sub Objekt1 aufrufen, in der zwei Punkte an der grad aktuellen Pos erstellt werden
    Koordinatensystem("Anzeigen", "", 0, 0, 0) :' den Stringwert "Anzeigen" übergeben
    Schachbrettboden("BeschreibungsListeBoden", "", 0, 0, 0):' SchachbrettBoden in der 3D-Welt erstellen
    glPushMatrix                                                             :'akt.Position und Drehgrade sichern
    Pyramide("BeschreibungsListe"  , "", PyraXDrehw, PyraYDrehw, PyraZDrehw) :'die erste Pyramide
    glPopMatrix                                                              :'auf gesichterte Position und Drehgrade zurücksetzen
    glTranslatef -2, 0, 0                                                    :'hier der Verschiebebefehl, damit die 2.Pyramide woanderst steht
    Pyramide("BeschreibungsListe"  , "", PyraXDrehw, PyraYDrehw, PyraZDrehw) :'und eine zweite Pyramide

    '-----------------
    'OBJEKTE ERSTELLEN
    '-----------------
    flip                                               :'liebes OpenGL, zeig alles, was in der Schleife für dich vornedran steht, auf Monitor an
   '---------------------------
   'Ende der Schleife
   '---------------------------
   glPopMatrix                                         :' Aufgabe erledigt, den zweiten Zettel mit der geänderten Pos wegschmeißen, dann ist Alte Pos wieder aktuelle Pos
LOOP

END

'-------------------------
SUB BewegtePunkte()
   STATIC AS SINGLE Seite, Hoehe, Tiefe  'Static, damit die Vars beim nächsten Aufruf der Schleife immer noch den Wert haben
   Seite=Seite + 0.01
   IF Seite > 3 THEN Seite = -3     :'damit halten wir den Wert von Seite zwischen -3 und +3
   glTranslatef Seite, 0, -6        :'wir Positionieren die Anzeige fest auf -6 der Z-Achse = im Kamerabereich und beweglich auf der X-Achse
   Objekt1()
END SUB
'-------------------------
SUB Objekt1()
  glBegin GL_POINTS        'Beschreibungsliste für Punkte beginnen
     glVertex3f   1,  1, 0 'einen Punkt auf 1/1/0
     glVertex3f  -1, -1, 0 'noch einen Punkt, dieser auf -1/-1/0
  glEnd                    'Ende der Beschreibungsliste (hier für Punkte)
END SUB
'--------------------------------
SUB Koordinatensystem(was AS STRING, TxtPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
   DIM AS INTEGER Zaehler
   STATIC AS INTEGER AnzeigeSchalter
   SELECT CASE UCASE(was)
      CASE "AnAus"
         IF AnzeigeSchalter = 0 THEN AnzeigeSchalter = 1 ELSE AnzeigeSchalter = 0
      CASE "Anzeigen"
        IF AnzeigeSchalter = 1 THEN
         glBegin GL_LINES:' Ja, wir beginnen mit der Beschreibungsliste fuer 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 6 :'fuer 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 = -6 TO -1 :'fuer 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  -6.0+Para1, 0+Para2, 0+Para3
         glVertex3f  +6.0+Para1, 0+Para2, 0+Para3
         'Y-ACHSE
         glColor3f 0.0, 1.0, 0.0        :' Yachse = grün
         glVertex3f  0+Para1, -6.0+Para2, 0+Para3
         glVertex3f  0+Para1, +6.0+Para2, 0+Para3
         'Z-ACHSE
         glColor3f 0.0, 0.0, 1.0        :' Zachse = blau
         glVertex3f  0+Para1, 0+Para2, -6.0+Para3
         glVertex3f  0+Para1, 0+Para2, +6.0+Para3
         glEnd
       END IF
   END SELECT
END SUB
'-------------------------
SUB Schachbrettboden(was AS STRING, StrPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
   STATIC AS SINGLE QuadKantenLaenge, QuadsQuer, QuadsTief
   STATIC AS SINGLE Farbe1Rot, Farbe1Gruen, Farbe1Blau
   STATIC AS SINGLE Farbe2Rot, Farbe2Gruen, Farbe2Blau
   STATIC AS SINGLE StartPosX, StartPosZ, BodenHoehe
   STATIC AS INTEGER ZaehlerX, ZaehlerZ                   :'ForNext-Zählvars, ggf. rekursiver aufruf dieser Sub, drum STATIC
   SELECT CASE UCASE(was)
      CASE "SetzKantenLaenge"
         'Aufruf hierfür in Para1 die Länge der Kanten der Quadrate
         QuadKantenLaenge = Para1
      CASE "SetzQuadsZahl"
         'Aufruf hierfür in Para1 die Anzahl von Quads quer,
         'in Para2 die Anzahl in der Tiefenrichtung
         QuadsQuer = Para1
         QuadsTief = Para2
      CASE "SetzFarbe1"
         'in Para1 Para2 Para2 die Rot Grün und Blauwerte der ersten Quadratfarbe
         Farbe1Rot   = Para1
         Farbe1Gruen = Para2
         Farbe1Blau  = Para3
      CASE "SetzFarbe2"
         'in Para1 Para2 Para2 die Rot Grün und Blauwerte der ersten Quadratfarbe
         Farbe2Rot   = Para1
         Farbe2Gruen = Para2
         Farbe2Blau  = Para3
      CASE "SetzStartPos"
         'in Para1 Para2 Para2 die X und Z Position, von wo begonnen wird,
         'die vielen Quadrate zu erstellen
         StartPosX   = Para1
         StartPosZ   = Para2
         BodenHoehe  = Para3
      CASE "BeschreibungsListeBoden"
         'Hier erstellen wir die FOR-NEXT-SCHLEIFEN,
         'welche die OpenGL-Beschreibungsliste
         'zum Anzeigen des Bodens erstellen
         glBegin GL_QUADS
            FOR ZaehlerX = 1 TO QuadsQuer     :'Laufnr des grad zu zeichnenden Quads auf der X-Achse
               FOR ZaehlerZ = 1 TO QuadsTief  :'Laufnr des grad zu zeichnenden Quads auf der Z-Achse
                  'Die Farbe festlegen
                  IF ((ZaehlerX+ZaehlerZ)\2)*2=(ZaehlerX+ZaehlerZ) THEN
                     'Wenn die Summe von ZahlerX+ZaehlerY gerade ist Farbe1 nehmen
                     glColor3f Farbe1Rot, Farbe1Gruen, Farbe1Blau
                  ELSE
                     'Wenn die Summe von ZahlerX+ZaehlerY UNgerade ist Farbe2 nehmen
                     glColor3f Farbe2Rot, Farbe2Gruen, Farbe2Blau
                  END IF
                  'Die Eckpunkte der Quadrate benennen wir in der Reihenfolge GEGEN DEN UHRZEIGERSINN, von oben draufschauend
                  glVertex3f StartPosX+(ZaehlerX-1)*QuadKantenLaenge,  BodenHoehe,  StartPosZ+(ZaehlerZ-1)*QuadKantenLaenge
                  glVertex3f StartPosX+ ZaehlerX   *QuadKantenLaenge,  BodenHoehe,  StartPosZ+(ZaehlerZ-1)*QuadKantenLaenge
                  glVertex3f StartPosX+ ZaehlerX   *QuadKantenLaenge,  BodenHoehe,  StartPosZ+ ZaehlerZ   *QuadKantenLaenge
                  glVertex3f StartPosX+(ZaehlerX-1)*QuadKantenLaenge,  BodenHoehe,  StartPosZ+ ZaehlerZ   *QuadKantenLaenge
               NEXT ZaehlerZ
            NEXT ZaehlerX
         glEnd
      CASE ELSE
         'Hier kommen alle SUB-Aufrufe an, welche als
         'was-Parameter einen Eintrag haben, der hier
         'nicht ausgewertet wurde.
         'Tippfehler vom Programmierer????
   END SELECT
END SUB
'-------------------------
SUB Pyramide(was AS STRING, StrPara AS STRING, Para1 AS SINGLE, Para2 AS SINGLE, Para3 AS SINGLE)
   'Pyramide erstellen, Grundfläche/Quadrat = auf Höhe 0, seitlich mittig auf X- und Z-Achse Positioniert
   'Grundflächengroesse = XLaenge x ZLaenge, Höhe Pyramide = ZLaenge
   STATIC AS SINGLE XLaenge, YLaenge, ZLaenge
   STATIC AS SINGLE Farbe1Rot, Farbe1Gruen, Farbe1Blau
   STATIC AS SINGLE Farbe2Rot, Farbe2Gruen, Farbe2Blau
   STATIC AS SINGLE Farbe3Rot, Farbe3Gruen, Farbe3Blau
   STATIC AS SINGLE Farbe4Rot, Farbe4Gruen, Farbe4Blau
   STATIC AS SINGLE Farbe5Rot, Farbe5Gruen, Farbe5Blau
   STATIC AS INTEGER ZaehlerX, ZaehlerZ                   :'ForNext-Zählvars, ggf. rekursiver aufruf dieser Sub, drum STATIC
   SELECT CASE UCASE(was)
      CASE "SetzLaengen"  : XLaenge   = Para1 : YLaenge     = Para2 : ZLaenge     = Para3
      CASE "SetzFarbe1"   : Farbe1Rot = Para1 : Farbe1Gruen = Para2 : Farbe1Blau  = Para3 :'ein Dreieck
      CASE "SetzFarbe2"   : Farbe2Rot = Para1 : Farbe2Gruen = Para2 : Farbe2Blau  = Para3 :'ein Dreieck
      CASE "SetzFarbe3"   : Farbe3Rot = Para1 : Farbe3Gruen = Para2 : Farbe3Blau  = Para3 :'ein Dreieck
      CASE "SetzFarbe4"   : Farbe4Rot = Para1 : Farbe4Gruen = Para2 : Farbe4Blau  = Para3 :'ein Dreieck
      CASE "SetzFarbe5"   : Farbe5Rot = Para1 : Farbe5Gruen = Para2 : Farbe5Blau  = Para3 :'der Boden/Quadrat
      CASE "BeschreibungsListe"
         glrotatef Para1, 1, 0, 0    :'<----------- um X-Achse drehen
         glrotatef Para2, 0, 1, 0    :'<----------- um Y-Achse drehen
         glrotatef Para3, 0, 0, 1    :'<----------- um Z-Achse drehen
         'die OpenGL-Beschreibungsliste zum Anzeigen der Pyramide erstellen
         glBegin GL_QUADS
            'der Boden der Pyramide als Quadrat, auf Höhe 0(Y-Achse),
            'seitliche Ausrichtungen = Quadratmitte = X-Achsenmitte und Z-Achsenmitte
            'damit Zentriert sitzt, für 1.Punkt einfach halbe Kantenlänge von 0 Abziehen, für 2. dazuaddieren
            'Reihenfolge Eckpunktangabe gegen Uhrzeigersinn VON UNTEN her gesehen (unten=Außenseite später)
            glColor3f  Farbe5Rot        , Farbe5Gruen      , Farbe5Blau
            glVertex3f 0-(XLaenge/2)    , 0  , 0+(ZLaenge/2)
            glVertex3f 0-(XLaenge/2)    , 0  , 0-(ZLaenge/2)
            glVertex3f 0+(XLaenge/2)    , 0  , 0-(ZLaenge/2)
            glVertex3f 0+(XLaenge/2)    , 0  , 0+(ZLaenge/2)
         glEnd
         glBegin GL_TRIANGLES
            '   Dreieckseite 1 =an Kante 1.+2.Quadratpunkt
            glColor3f  Farbe1Rot        , Farbe1Gruen      , Farbe1Blau
            glVertex3f 0-(XLaenge/2)    , 0       , 0-(ZLaenge/2)
            glVertex3f 0-(XLaenge/2)    , 0       , 0+(ZLaenge/2)
            glVertex3f 0                , YLaenge , 0
            '   Dreieckseite 2 =an Kante 2.+3.Quadratpunkt
            glColor3f  Farbe2Rot        , Farbe2Gruen      , Farbe2Blau
            glVertex3f 0+(XLaenge/2)    , 0  , 0-(ZLaenge/2)
            glVertex3f 0-(XLaenge/2)    , 0  , 0-(ZLaenge/2)
            glVertex3f 0                , YLaenge , 0
            '   Dreieckseite 3 =an Kante 3.+4.Quadratpunkt
            glColor3f  Farbe3Rot        , Farbe3Gruen      , Farbe3Blau
            glVertex3f 0+(XLaenge/2)    , 0  , 0+(ZLaenge/2)
            glVertex3f 0+(XLaenge/2)    , 0  , 0-(ZLaenge/2)
            glVertex3f 0                , YLaenge , 0
            '   Dreieckseite 4 =an Kante 3.+1.Quadratpunkt
            glColor3f  Farbe4Rot        , Farbe4Gruen      , Farbe4Blau
            glVertex3f 0-(XLaenge/2)    , 0  , 0+(ZLaenge/2)
            glVertex3f 0+(XLaenge/2)    , 0  , 0+(ZLaenge/2)
            glVertex3f 0                , YLaenge , 0
         glEnd
      CASE ELSE
         'Hier kommen alle SUB-Aufrufe an, welche als
         'was-Parameter einen Eintrag haben, der hier
         'nicht ausgewertet wurde.
         'Tippfehler vom Programmierer????
   END SELECT
END SUB

 

Gehe zu Seite Gehe zu Seite  1  2  3  4  
Zusätzliche Informationen und Funktionen
  • Das Tutorial wurde am 17.08.2008 von MitgliedEastler_dart angelegt.
  • Die aktuellste Version wurde am 22.07.2012 von MitgliedAffemitwaffel gespeichert.
  Bearbeiten Bearbeiten  

  Versionen Versionen