Konstruktion von Szenengraphen
← Hierarchie Ebenen | ● | Szenengraph Implementierung →
Wie implementiert man konkret die Konstruktion und die Traversierung eines Szenengraphen wie z.B. des folgenden?
Konstruktionsprinzip in 10 Schritten:
1) Jeder Knoten eines Szenengraphen ist von einer Basisklasse abgeleitet. Für das glVertex Framework ist das die Basisklasse lgl_Node. Zuanfangs besteht der Szenengraph nur aus einem Zeiger auf den Wurzelknoten. Da der Szenengraph noch keinen Knoten enthält ist der Zeiger der NULL-Zeiger:
2) Einen neuen Knoten erzeugt man dynamisch wie folgt:
Der erste erzeugte Knoten ist typischerweise auch zugleich der Wurzel-Knoten:
3) Jeder Knoten enthält die Methode add(), mit der sich ein weiterer neuer Knoten als Kind hinzufügen lässt:
node->add(child);
4) Transformations-Knoten wie z.B. einen Translations-Knoten (lgl_TranslationNode) oder einen Rotations-Knoten (lgl_RotationNode) fügt man damit wie folgt hinzu:
lgl_Node *child = new lgl_TranslationNode(t);
node->add(child);
double w = ...; // rotation angle
vec3 a = ...; // rotation axis
lgl_Node *grandchild = new lgl_RotationNode(w, a);
child->add(grandchild);
Die add() Methode gibt als Rückgabewert einen Zeiger auf das gerade hinzugefügte Kind zurück. Dadurch lassen sich mehrere Hinzufügungen konkatenieren:
Dies entspricht einer Starrkörper-Transformation (lgl_TransformationNode) mit der Matrix M:
node->add(new lgl_TransformationNode(M));
5) Zeitlich animierte Transformationen wie Rotationen (lgl_RotationAnimationNode) werden analog hinzugefügt:
vec3 a = ...; // rotation axis
... ->add(new lgl_RotationAnimationNode(w, a))-> ...
6) Unter den Transformations-Knoten, die sich jeweils auf ihre Kinder und Kindeskinder auswirken, werden Geometrie-Knoten eingefügt. Diese kapseln jeweils einen VBO (lglVBO *):
... ->add(new lgl_GeometryNode(vbo));
7) Farbe wird mittels eines Farb-Knotens (lgl_ColorNode) hinzugefügt. Diese Farbe wirkt sich auf alle Geometrie-Knoten, die Kinder oder Kindeskinder sind, aus:
8) Kamerapose und Perspektive wird mittel eines Kamera-Knotens (lgl_Camera) der Szene hinzugefügt:
9) Abschließend kann der Szenengraph gerendert werden, indem man an der Wurzel die Methode renderSceneGraph(dt) aufruft mit dt = 1/FPS:
Diese Methode veranlasst einen Tiefenabstieg des gesamten Szenengraphs, wobei alle VBOs der traversierten Geometrie-Knoten mit der jeweils aktuellen Transformation gerendert werden (Depth-First Render Traversal).
10) Wenn der Szenengraph (z.B. bei Programmende) nicht mehr benötigt wird, so gibt man den insgesamt belegten Speicher frei, indem man den Wurzelknoten löscht: