Tutorial GLScene

Aus DGL Wiki
Wechseln zu: Navigation, Suche

GlScene Tutorial

Vorwort

GLScene ist eine wirklich geniale Komponentensammlung, um schnell z.B. einen Editor für die eigene Engine zu proggen. Aber schon die Installation ist so komplex, dass einige daran scheitern. Ich habe auch eine Weile (ca. 3 Stunden nur für die Installation) gebraucht. Darum liefere ich hier eine kleine Einführung in GLScene (exklusiv für DelphiGL.com ;-)). Habe ein bisschen dafür gebraucht, weil wieder mal ein paar Lehrer eine „Schreibt-mal-schnell-eine-zweiseitige-Abhandlung-Phase“ hatten. Aber schließlich bin ich doch noch fertig geworden. Diese Anleitung ist für totale Einsteiger - Fortgeschrittene und Profis werden nix Neues erfahren. Da ich kein Freund großer Worte bin, fange ich einfach mal an.


Installation(das Grauen...)

Wurde schon im DGL-Forum diskutiert, ich denke aber, durch die verschiedenen Versionen sowohl von Delphi als auch von GLScene gibt’s hier kein Patentrezept. Ich hab das wahrscheinlich viel zu kompliziert gemacht, aber es funzt wenigstens und das ist ja die Hauptsache! Also hier meine eigene Anleitung:

  • Alle Dateien aus dem Verzeichnis Source von GLScene in den Lib-Ordner von Delphi kopieren.
  • Anschließend aus den Unterordnern des Source – Verzeichnisses (also Base, CGShaders, Designtime, etc) alle Dateien nochmal in das Lib – Verzeichnis kopieren (nicht verschieben!)
  • Die Datei GLScene.inc suchen und in das Delphi-Verzeichnis kopieren (bei mir D:\Programme\Delphi6\ )
  • Delphi starten, die GLScene6.dpk' (oder 4, 5, 7) öffnen und auf Install klicken. Nun müsste GLScene installiert werden und eine Registerkarte bei den Komponenten hinzugefügt werden.

BenBE: Alternativ kann man aber auch einfach die besagten Verzeichnisse unter Tools\Umgebungsoptionen\Bibliothek (Tools\Environment\Library) sowohl zum Bibliptheks- als auch Suchpfad (1. und 4. Editbox, einfach auf die drei Punkte rechts daneben klicken) hinzufügen und anschließend das Package installieren. Funktioniert genauso, ist einfacher und spart vor allem sehr viele Nerven *g* Weiterhin bleibt dadurch der Lib-Ordner von Delphi sauber.

Erste Schritte

Als erstes fügen wir eine Komponente mit dem schönen Namen GLScene (Tutorial GLScene html m2fc1a926.png) ein. Das ist das wichtigste aller Objekte und wird in allen euren GLScene-Programmen vorkommen. Mit einem Doppelklick darauf seht ihr den Grundaufbau eurer Szene:

Tutorial GLScene html 74dd1768.png


Alle Bestandteile eurer Szene werden in GLScene nach Cameras und Scene objects eingeordnet. Um euch einen Überblick über die von GLScene bereitgestellten Objekte zu verschaffen, macht ihr einen Rechtsklick auf Scene objects und geht dann auf Add object. Die meisten von den Einträgen hier erklären sich von selbst und wenn sie es nicht gleich tun, dann nach einigem Ausprobieren.


Anschließend setzen wir noch einen GLSceneViewer (Tutorial GLScene html m27e37d40.png) ins Formular. Standardmäßig ist er nur 100x100 groß, also stellen wir in den Eigenschaften des GLSceneViewers Align auf alClient. Wie der Name schon sagt, ist der GLSceneviewer das Objekt, das die Szene (aus dem Objekt GLScene) auf den Bildschirm bringt.


Nun können wir das Programm einfach mal starten:

Tutorial GLScene html cffa458.png


Juhu! Es lässt sich [hoffentlich] compilieren (bei einem OpenGL-Init ohne GLScene käme das, bei mir jedenfalls, fast einem Wunder gleich ;-)). Aber was sehen unsere entzündeten Augen da? Das Formular ist ja ganz leer! Nun, anscheinend ist die Initialisierung doch nicht so einfach. Es fehlt noch eine Kamera, die, mit dem GLSceneviewer verknüpft, unsere Szene anzeigt. Wer gut aufgepasst hat, sieht wahrscheinlich gleich, was zu tun ist (Den anderen gibt`s was auf die Finger!). Mit einem Doppelklick auf Tutorial GLScene html m2fc1a926.png öffnen wir das „Inhaltsverzeichnis“ unserer Szene. Es folgt ein Rechtsklick auf Cameras und dann auf Add Camera. Schon ist die Kamera in unserer Szene implementiert. Jetzt muss unserem GLSceneviewer nur noch gesagt werden, über welche Kamera er die Szene darstellen soll, denn bei größeren Programmen gibt es oft mehrere Kameras. Dazu klicken wir auf den GlSceneviewer und stellen in den Eigenschaften Camera auf GLCamera1 ein. Nach einem weiteren Compilieren stellen wir fest, dass sich immer noch nichts tut. Das liegt daran, dass sich ja noch nichts in der Szene befindet, was darzustellen wäre. Deshalb fügen wir jetzt einfach per Scene objects -> Add object -> Basic geometry > Sphere im GlScene – Dialog eine Kugel ein. Dann fehlt nur noch, dass wir die Camera ein wenig verschieben, da sie sich standardmäßig mitten in der Kugel an dem Punkt 0|0|0 befindet. Also stellen wir die Eigenschaft Position von der Camera ein wenig anders ein. Zu guter letzt definieren wir unsere Kugel als Zielobjekt (TargetObject), auf das die Kamera gerichtet sein soll. Das Ergebnis:

Tutorial GLScene html m151172de.png


Demotivierend, nicht? Naja, wenigstens ist was Rundes da. Das kommt daher, dass wir noch keine Lichtquelle definiert haben. Inzwischen dürfte der Weg aber klar sein: GLScene1 -> Scene objects -> Rechtsklick -> Add object -> LightSource. Dann verschieben wir noch schnell die Lichtquelle, wie immer mit einer kleinen Veränderung der Positionseigenschaft. Und schon haben wir unsere erste Szene fertig:

Tutorial GLScene html 17961123.png


Immer noch sehr schlicht, aber man muss natürlich den Arbeitsaufwand mit dem eines normalen Inits vergleichen, um jetzt darüber zu urteilen.


Wer durch unsere bisherigen (optischen) Ergebnisse etwas demotiviert wurde, dem verordne ich dringend mal einen Besuch im GLScene - Ordner Demos/bench/... !


Zusätzliches

Natürlich gibt es noch weitere Features, von denen ich hier mal ein paar aufzählen möchte:


Alles, was die Szene indirekt kosmetisch beeinflusst, ist bei der Eigenschaft Buffer des GLSceneViewers zu finden:

Tutorial GLScene html m549c3f82.png


Die meisten dürften sich selbst erklären. Da dies aber ein Tutorial für Anfänger sein soll, mal eine kleine Aufzählung:


AntiAliasing: Wird verwendet, um pixelige Stufen zu vermeiden. Man hat hier mehrere Stufen zur Auswahl, die jeweilige Unterstützung hängt von der Grafikkarte und ihren Treibern ab.


Tutorial GLScene html m3d75de8.png
Das umrahmte Bild zeigt eine „antialiasierte“ (grausam, dieses Wort, nicht?) Kugel. AntiAliasing hat aber den Nachteil, dass es den PC zum Teil enorm verlangsamen kann, sofern man nicht eine Grafikkarte von ATI ab einer Radeon 9500 Pro besitzt.


BackgroundColor: Legt, wie könnte es anders sein, die Hintergrundfarbe des GLSceneViewers fest.


ColorDepth: Hier kann man, wie bei den Desktop-Eigenschaften die Farbtiefe der Darstellung anpassen. Standard sind, glaube ich, 32 Bit (cddefault)


ContextOptions: Hier können Veränderungen am Rendering-Kontext vorgenommen werden, wie z.B. der StencilBuffer aktiviert werden etc...


DepthPrecision: Hat mehr oder weniger die gleiche Funktion wie ColorDepth.


FaceCulling: Zeichnet nur die Vorderseiten von Objekten und bringt so mehr Frames. (Dazu gibt’s ein DGL – Tutorial)


FogEnable: Aktiviert Nebel.


FogEnvironment: Die Optionen des Nebels:


FogColor: Hmm.. *scharf nachdenk* ach ja, Farbe des Nebels ;-)


FogDistance: Legt fest, ob sich der Nebel kreis- oder würfelförmig um den Betrachter ausbreiten soll.


FogEnd: Bestimmt die Entfernung zum Betrachter, ab der nichts mehr zu sehen ist.


FogLinear: Dazu gibt’s schon ein Tutorial (von Lithander).


FogStart: Gegenpart zu FogEnd und legt den Abstand zum Betrachter fest, ab dem der Nebel beginnt.


Lighting: Aktiviert/Deaktiviert alle Lichtquellen.


ShadeModel: Wie schön rund sollen z.B. Kugeln werden?


Als nächstes möchte ich mit euch noch einige Optionen der Objekte selbst durchgehen:


Bottom (bei Kugeln): Hier kann man bestimmen, ob und wie die Kugel „beschnitten“ werden soll (mir ist hier nix Besseres eingefallen), am besten einfach mal Werte wie -20 eingeben.


Material: Mit einem Klick auf ... öffnet man den Material Editor:
Tutorial GLScene html m7dc9f971.png


Das hier ist mal das Texturfenster. Hier kann man ein Bild als Textur laden. Anschließend hat man einige Optionen zur Verfügung, am besten probiert ihr einfach mal ein bisschen rum, um die verschiedenen Effekte zu genießen. Wichtig ist nur, dass das Häkchen bei Disabled entfernt ist, da sonst keine Textur dargestellt wird (wird immer wieder gern vergessen). Ansonsten gibt’s halt noch die Register Front und Back, deren Optionen sich auch selbst erklären dürften. Um einfach die Farbe des Objekts zu verändern, geht man meist auf Front -> Diffuse.


PitchAngle, RollAngle, TurnAngle: die Drehung des Objekts in um die Z-(PitchAngle), die X-(RollAngle) und die Y-Achse (TurnAngle)


Slices und Stacks (bei Kugeln): Gibt an, aus wie vielen Teilen die Kugeln gemacht werden soll, sprich die „Rundheit“ (wo wird uns dieses Deutsch noch hinführen?)


Stop (auch bei Kugeln): Eigentlich wie Bottom, nur wird die Kugel durch eine Senkrechte Ebene „beschnitten“ (ich geb`s auf)


ShowAxes: Zeigt die Achsen an (ist eine meiner Lieblingsoptionen!)


Visible: Ist wohl selbsterklärend ;)


Der „Cadencer“

Tutorial GLScene html m1130af53.png

Wenn man mit GLScene arbeitet, wird man zwangsläufig irgendwann mal mit dem Cadencer zu tun haben. Er ist nämlich das Wichtigste für Animationen und entspricht dem OnIdle aus der VCL. Im einzigen Ereignis des Cadencers, OnProgress, kann man dann z.B. Bewegungen nach dem Prinzip

Objekt.Position = Objekt.Position + Objekt.Geschwindigkeit

durchführen.

Der Cadencer ermöglicht es aber auch, frameunabhägige Bewegungen durchzuführen:

Objekt.Position = Objekt.Position + Objekt.Geschwindigkeit * Deltatime


Objekte erzeugen, während das Programm läuft

Wenn man z.B. einen Editor programmiert, wird man Objekte während des Renderns komplett neu erzeugen müssen.


Alle Objekte der Szene sind sogenannte GLCustomSceneObjects. Also definieren wir in einer Variablen-Sektion eine Variable nach dem Schema:

Objekt: TGLCustomSceneObject;

Um dann also ein Objekt zu erzeugen, müssen wir entscheiden, ob es ein sogenanntes Rootobject oder Childobject werden soll. Rootobjekte befinden sich in der Objekthierarchie ganz oben, Childobjekte sind immer einem Rootobjekt untergeordnet. Das zeige ich am besten mal mit folgendem Bild:

Tutorial GLScene html m325f1590.png


Der praktische Unterschied der beiden Arten ist, dass Rootobjekte automatisch an die Position 0|0|0 gesetzt werden. Childobjekte werden im Gegensatz dazu zwar auch an der Position 0|0|0 erstellt, jedoch relativ zu ihrem Rootobjekt. Das heißt, wenn man z.B. ein Rootobjekt an die Position 1|2|4 stellt, dann wird ein Childobjekt, das dann erstellt wird, auch an die Position 1|2|4 gebracht. Das ist ein bisschen kompliziert, am besten probiert ihr das einfach mal aus.

Nun aber zum praktischen Teil:

  • Ein Rootobjekt erstellen
     RootObjekt := GLScene.Objects.AddNewChild(TGLCube);
         |                                       |
     TGLCustomSceneObject             Typ des neuen Objekts
  • Ein Childobjekt erstellen
     ChildObjekt :=         RootObjekt.AddNewChild(TGLFrustrum);
        |                       |                           |
     TGLCustomSceneObject Das Rootobjekt des Childobjekts   Typ des neuen Objekts


Nachwort

Das war’s erstmal. Ich hoffe, dass ich euch einen kleinen Überblick über die Materie habe geben können. Wie immer könnt ihr eure Fragen, eventuelle Fehler oder Ideen für ein weiterführendes Tutorial im Forum posten. Über Feedback würde ich mich natürlich auch sehr freuen!


Euer

La_Boda



Vorhergehendes Tutorial:
-
Nächstes Tutorial:
-

Schreibt was ihr zu diesem Tutorial denkt ins Feedbackforum von DelphiGL.com.
Lob, Verbesserungsvorschläge, Hinweise und Tutorialwünsche sind stets willkommen.