Mit Qt und Coin, einem Klon von Open Inventor, gelingt das Programmieren von interaktiven 3D-Welten wesentlich einfacher als mit OpenGL. Eine Einführung.
Wer 3D-Welten programmieren möchte, denkt meist zuerst an OpenGL[1],[2]. Oft sind aber der von SGI stammende Open Inventor oder das kompatible Coin (siehe Kasten “Open Inventor und Coin”) die bessere Wahl: OpenGL zeichnet (rendert) die Grafiken zwar flott, ist aber kompliziert und zeitaufwändig zu programmieren. Der Aufbau und die Befehle von OpenGL orientieren sich stark an der Grafikhardware. Verglichen mit Open Inventor ist OpenGL auf dem Level einer Assembler-Sprache.
Das objektorientierte Open Inventor Toolkit wurde 1991 von denselben SGI-Mitarbeitern entwickelt, aus deren Feder bereits OpenGL stammt. Open Inventor fasst alle Funktionalitäten von OpenGL in Objekten zusammen. Dies Design vereinfacht besonders das Programmieren mit C++. Open Inventor selbst benutzt OpenGL zum Rendern der Grafik und erbt damit dessen hohe Qualität und Geschwindigkeit.
Das Toolkit ist viel mehr als nur eine Bibliothek, die Klassen zum Erzeugen von 3D-Grafiken bereitstellt. Open Inventor erlaubt es zum Beispiel, 3D-Szenen in so genannten Szenengraphen zu beschreiben und abzuspeichern. Das dafür entwickelte Dateiformat diente 1994 als Vorlage für VRML (Virtual Reality Modeling Language). Mit Open Inventor sind auch Interaktionen mit der Szene möglich. Über den Szenengraphen lassen sich die Objekte identifizieren, somit sind angepasste Reaktionen möglich.
Leider sind Coin und SoQt nicht in allen Linux-Distributionen enthalten (siehe Kasten “Installation”). Beide Pakete enthalten sehr ausführliche Dokumentationen in Englisch.
3D-Grafik inklusive GUI
Größter Unterschied zwischen dem Programmieren mit Open Inventor und Coin ist die Bindung zum GUI-System. Die folgenden Beispiele benutzen über SoQt die Qt-Bibliothek, Motif-Varianten sind auf[9] zu finden. Mit Ausnahme der SoQt-Komponente laufen alle Beispiele auch unter SGIs Open-Source-Variante von Open Inventor, die Namen Coin und Open Inventor werden im Folgenden daher gleichberechtigt benutzt.
Wie in Programmiereinführungen üblich ist das erste Beispiel ein Hello-World-Programm. Es initialisiert einen Viewer (Betrachter) und stellt Text dar. Dieser Text wird dreidimensional angezeigt, der Benutzer kann ihn von beliebigen Positionen aus betrachten. Der Code ist in Listing 1 zu sehen, er steht auf[9] zum Download bereit. Folgender Befehl übersetzt das Programm:
g++ HelloSoQt.cpp -o HelloSoQt -lCoin -lSoQt -I$QTDIR/include
Das Kommando bindet die Coin- und SoQt-Bibliothek ein und gibt mit der Option »-I$QTDIR/include« an, wo die Qt-Headerfiles zu finden sind. Das Ergebnis ist in Abbildung 2 zu sehen.
Virtuelle Welten entdecken und untersuchen
Die Klasse »SoQtExaminerViewer« (Zeile 31) stellt mehrere Funktionen bereit, um verschiedene Ausschnitte der Szene zu betrachten. Mit gedrückter linker Maustaste folgt die Grafik jeder Mausbewegung. Der Betrachter bietet zusätzliche Funktionen über Räder und Knöpfe am Rand des Fensters.
Besonders auffällig sind die drei Räder: Zwei befinden sich in der linken unteren Ecke, ein weiteres Rad ist auf der unteren rechten Seite angebracht. Das rechte Rad, Dolly genannt, ändert die Entfernung des Betrachters von der Szene (Zoom-Effekt). Die beiden linken Räder rotieren die Szene um die x- beziehungsweise y-Achse.
|
Coin |
|---|
|
Hersteller: Systems in Motion Lizenz: LGPL (GPL für Version 2.0 geplant) Stabile Version: Coin 1.0.3, SoQt 1.0.1 Coin Professional: Kommerzielle Lizenz (pro Entwickler und Jahr 2000 US-Dollar), für proprietäre Projekte geeignet Multiplattform: Coin läuft auf Linux, anderen Unix-ähnlichen Systemen und Windows; Voraussetzung sind ein C++-Compiler und eine OpenGL-Bibliothek GUI-Bindings: Derzeit Qt, Gtk+, Motif und Windows; Coin lässt sich aber auch ohne diese Bindings nutzen |
Werkzeuge für Entdecker
Auf der rechten Bildschirmseite über dem Dolly-Rad befinden sich insgesamt sieben Knöpfe:
- Pfeil: Bearbeitungsmodus
- Hand: Interaktiver Modus
- Haus: Kameraposition auf die Defaultposition setzen
- Blaues Haus: Setzt eine Kameraposition (Ansichtswinkel) als
neue Default-Position - Auge: Setzt die gesamte Szene ins Blickfeld
- Lampe: Setzt den Fokus für den Zoomer (Dolly)
- Kasten: Wechselt zwischen verschiedenen Transformationen
All diese Interaktionen bewegen die Kamera und nicht die Szene. Der interaktive Modus ist unmittelbar nach dem Start des Viewers aktiv. Er erlaubt es dem Betrachter, die Kameraposition und so seinen Blickwinkel mit Hilfe der GUI-Räder und der Maus nach seinen Wünschen zu verändern. Weitere Einstellungen lassen sich im Popup-Menü (über einen Rechtsklick) treffen.

Abbildung 1: Die Coin-Bibliothek vermittelt zwischen der Anwendung und OpenGL. SoQt bindet das GUI-Toolkit Qt ein, SoXt setzt alternativ auf Motif.

Abbildung 2: Das Beispielprogramm Hello SoQt zeigt im SoQt-Betrachter einen Schriftzug, den der Anwender aus verschiedenen Richtungen betrachten kann.
Der Szenengraph: Ordnung für 3D-Objekte
Um eine 3D-Szene (3D-Welt) effizient zu verwalten, benutzt Open Inventor einen Szenengraphen (scene graph). Er ist wie ein Baum aufgebaut, über dessen Wurzel alle Objekte der Szene ansprechbar sind. Die Elemente des Szenengraphen sind Knoten mit unterschiedlichen Funktionen. Die Knoten beschreiben jeweils einen Teil der Szene.
Beim Berechnen und Darstellen einer Szene arbeitet sich Open Inventor von der Wurzel zu den Blättern (den untersten Knoten) den Szenengraphen entlang, und zwar von links nach rechts und von oben nach unten. Spezielle Knoten bewirken weitere Änderungen, zum Beispiel Transformationen und Rotationen. Diese Änderungen wirken sich auf alle folgenden Knoten aus. An dieser Stelle zeigt sich die Ähnlichkeit zur Status Machine von OpenGL: Eine Eigenschaft, zum Beispiel die Farbe von 3D-Objekten (Klasse »SoBaseColor«), bleibt so lange aktiv, bis diese Eigenschaft einen neuen Wert erhält.
Der Programmierer bestimmt durch die Anordnung der Objekte im Szenengraphen das Aussehen und Verhalten der Szene. Wichtig ist die Reihenfolge der Effekte. Vertauscht man zum Beispiel eine Rotation (Drehung) und eine Translation (Verschiebung), wird das zu einem anderen Ergebnis führen.
Open Inventor stellt eine Vielzahl von Knotentypen zur Verfügung. Diese Knoten können Oberflächen definieren, Materialien beschreiben oder Beleuchtung und Kameras setzen. Weitere Knoten bieten Schnittstellen für die Interaktion an oder beschreiben unterschiedliche Transformationen.
Knotenkunde: Von Form, Farbe, Material und Licht
Jeder Knoten ist durch eine Klasse realisiert. Der Name einer (Knoten-)Klasse beginnt mit »So«, zum Beispiel »SoMaterial« oder »SoCone«. Wenn eine Szene in eine Datei geschrieben wird, entfallen die »So«-Vorsilben. Die Namen der Knoten entsprechen dann VRML.
Jede Klasse besitzt Felder, die die Eigenschaften der Knoten charakterisieren. Welche Felder ein Knoten bietet ist beispielsweise in der Dokumentation von SGI nachzulesen: Unter[5] sind die “Open Inventor Nodes Quick Reference” und die “Open Inventor C++ Reference” als PDF-Dokumente zu finden (im Suchfeld den Namen des Dokuments eingeben). Coin und dessen Erweiterungen (etwa SoQt) enthalten ihre Dokumentation direkt im Sourcecode. Mit Hilfe von Doxygen lässt sich daraus eine HTML-Übersicht generieren.
Neue Knoten einfügen
Folgendes Beispiel fügt einen neuen Knoten in den Szenengraphen ein:
SoCone *kegel = new SoCone;
hkegel->height.setValue(4);
kegel->parts.setValue("SIDES");
wurzel->addChild(kegel)
Es erzeugt ein Objekt der gewünschten Klasse (hier »SoCone«) und belegt einige Felder. Die Höhe setzt das Beispiel auf »4« fest und es bestimmt, dass die Seitenflächen sichtbar sein sollen. Als Letztes wird dann der Knoten an den Graphen (hier Wurzel genannt) angehängt. Tabelle 1 enthält die wichtigsten Form-Klassen mit deren Feldern. Ein späterer Artikel wird beschreiben, wie man eigene Knoten erzeugt.
Diese Bausteinen lassen sich zu einem komplexen Gebilde zusammensetzen, das beispielsweise einen Stuhl darstellt. Um den Graphen dafür aufzubauen ist es notwendig, die Szene in einzelne Komponenten zu unterteilen. Generell gilt: Je mehr Komponenten eine Szene beschreiben, umso realistischer wirkt das Ergebnis.
|
Tabelle |
|||
|---|---|---|---|
|
Knotenname |
Bedeutung |
Felder |
Standardwert |
|
SoCone |
Kegel |
parts |
ALL (SIDES, BOTTOM) |
|
|
|
bottomRadius height |
1 |
|
|
|
height |
2 |
|
SoCube |
Würfel |
width |
2 |
|
|
|
height |
2 |
|
|
|
depth |
2 |
|
SoCylinder |
Zylinder |
parts |
ALL (SIDES, TOP, BOTTOM) |
|
|
|
radius |
1 |
|
|
|
height |
2 |
|
SoSphere |
Kugel |
radius |
1 |
|
SoText2 |
2D-Text |
string |
leerer String |
|
|
|
spacing |
1 |
|
|
|
justification |
LEFT (RIGHT, CENTER) |
|
SoText3 |
3D-Text |
string |
leerer String |
|
|
|
spacing |
1 |
|
|
|
justification |
LEFT (RIGHT, CENTER) |
|
|
|
parts |
FRONT (SIDES, ALL, BACK) |
|
Open Inventor und |
|---|
|
Seit Version 2.1 (1996) hat SGI die Entwicklung von Open Inventor an TGS[4] übergeben. Diese Firma entwickelt und vertreibt alle neueren Versionen (aktuell: 3.1) als kommerzielles Produkt. SGI entschloss sich im August 2000, ihre letzte eigene Open-Inventor-Version (2.1) für Linux als Open Source zu veröffentlichen[3]. Das norwegische Unternehmen Systems in Motion[6] bietet eine eigene Implementierung, Coin[7] genannt, für Windows, Linux und andere Unix-Systeme an. Coin steht derzeit (Version 1.x) unter der LGPL-Lizenz, für Version 2.0 ist ein Wechsel zur GPL geplant. Mehr Dynamik mit CoinFür diesen Artikel wurde Coin gewählt, es verspricht mehr Dynamik in der Entwicklung als die Variante von SGI. Coin versucht neue Features von Open Inventor 3.x zu implementieren, während SGI nur Open Inventor 2.1 nach Linux portierte. Für Coin sprechen auch die vielen Erweiterungen, die SIM anbietet. Neben der Standardbindung zu Motif bietet es auch Qt, Gtk und Java. Diese Bindungen sind nötig, weil Open Inventor nur die 3D-Szene zeichnet, den Fensterrahmen und die Bindung zum Windowmanager muss der Programmierer selbst bereitstellen. Während OpenGL eine Erweiterung namens GLUT[1] anbietet, um diese Arbeit zu erleichtern, ist Open Inventor auf Motif abgestimmt. Alternativen wie Gtk und Qt sind jedoch einfacher und unter Linux weiter verbreitet als Motif. Qt passt bestens zu Coin, da beide in C++ implementiert sind. |
|
Installation |
|---|
|
Voraussetzung für Coin ist, dass OpenGL und GLUT installiert sind. Die Zeichengeschwindigkeit von Open Inventor hängt zum größten Teil von OpenGL ab. Die verbreitete OpenGL-Bibliothek Mesa führt die 3D-Berechnungen in Software durch, für manche 3D-Grafikkarten stehen aber auch optimierte OpenGL-Treiber zur Verfügung. Der Autor benutzt eine Geforce 2MX und Nvidias Treiber für XFree 4.x. Wenn möglich, sollte die Hardwarebeschleunigung aktiviert werden, da Open Inventor speziell bei Interaktionen sehr viel Rechenleistung benötigt. Der Sourcecode von Coin[8] lässt sich recht einfach selbst übersetzen und installieren. Nach dem Auspacken genügt der übliche Dreisatz: ./configure make make install Die meisten Linux-Distributionen enthalten bereits Qt. Oft wird aber nur die Qt-Bibliothek installiert, ohne die zum Programmieren nötigen Headerdateien. Auch muss die Bibliothek mit OpenGL-Unterstützung übersetzt sein. Unter SuSE 8.1 sind alle Pakete von Qt 3.0.5 zu installieren, die »$QTDIR«-Variable auf »/usr/lib/qt-3.0.5« zu setzen und »$QTDIR/bin« in den Pfad »$PATH« aufzunehmen. Die Quellen von SoQt stehen ebenfalls auf [8] zum Download bereit, das Kompilieren funktioniert wie bei Coin. Nach der Installation von Coin und SoQt sollte Root den Befehl »/sbin/ldconfig« ausführen, um beide Bibliotheken systemweit erreichbar zu machen. |
Einfacher Stuhl als Beispiel eines Szenengraphen
Ein Stuhl lässt sich relativ einfach aufbauen, er besteht nur aus einer Sitzfläche, einer Rückenlehne und vier Beinen. Die Stuhlbeine unterscheiden sich vor allem durch ihre Position. Abbildung 3 zeigt den Szenengraphen für diese Konstruktion, jede Eigenschaft und jede Geometrie ist in einem eigenen Objekt beschrieben. Dank des objektorientierten Ansatzes müssen mehrfach benötigte Objekte nur einmal definiert werden, sie lassen sich mehrfach in den Szenengraphen einsetzen. Im Beispiel werden die Vorder- und Hinterbeine nur einmal erzeugt und an verschiedenen Stellen (nach den notwendigen Transformationen) im Szenengraphen eingesetzt. Das gilt auch für die Farbe der Stuhlbeine. Der Sourcecode des Beispiels ist auf[9] verfügbar, Abbildung 4 zeigt das ausgeführte Programm.
Es ist ratsam, vor dem Programmieren einen Szenengraphen zu planen, da das erneute Verwenden von Objekten viel Speicher spart. Wenn ganze Untergraphen (etwa die Beine im Stuhl-Beispiel) mehrfach eingefügt sind, spart das Speicher und zusätzlich bleiben der Szenengraph und der Sourcecode übersichtlich. Das mag im vorliegenden Beispiel nicht besonders ins Gewicht fallen, in großen Projekten wie Spielen oder CAD-Programmen ist die Menge von Objekten aber von entscheidender Bedeutung.

Abbildung 3: Der Szenengraph teilt den Stuhl in seine Bestandteile: Sitz, Vorder- und Hinterbeine sowie Lehne. Die linken und rechten Beine unterscheiden sich nur durch ihre Position.
Dokumentation
Wer sich für Open Inventor interessiert und nicht bis zum nächsten Artikel warten möchte, findet viele interessante Quellen online. Die ausführlichste Dokumentation stammt von SGI[5]. Der “Inventor Mentor” ist die Bibel für alle Open-Inventor-Programmierer. Er beschreibt alle Features, etwa das Setzen von Licht- und Kamerapositionen, das Erzeugen von komplexen Geometrien, die Animation einer Szene sowie das Programmieren von Interaktionen.
Neben dem Inventor Mentor bietet SGI auch das “Open Inventor C++ Reference Manual” zum Download an, das alle Klassen der SGI-Version von Open Inventor beschreibt. Die Erweiterungen von Coin sind dabei leider nicht enthalten. Wer mehr über Coin wissen will, kann auf die mitgelieferte HTML-Dokumentation zurückgreifen.
Fazit und Ausblick
Mit Coin und SoQt lassen sich recht einfach interaktive dreidimensionale Grafiken programmieren, ohne die (L)GPL-Welt verlassen zu müssen. Der Aufwand ist, besonders im Vergleich zu OpenGL, sehr gering – trotzdem überzeugen die Ergebnisse. Für das Rendering greift Open Inventor schließlich auf das performante OpenGL zurück.
Die hier vorgestellten Möglichkeiten zeigen nur einen Ausschnitt der Fähigkeiten von Open Inventor. Der nächste Artikel wird erklären, wie der Programmierer mehr Interaktion durch Menü- und Mausaktionen erlaubt. (fjl)
|
Infos |
|---|
|
[1] Thomas G. E. Ruge, “Hello 3D-World”: Linux-Magazin 04/01, S. 134 [2] Thomas G. E. Ruge und Pablo Gussmann, “Punkte, Linien, Polygone”: Linux-Magazin 06/01, S. 102 [3] Open-Source-Variante von Open Inventor: [http://oss.sgi.com/projects/inventor/] [4] TGS: [http://www.tgs.com] [5] Technische Dokumentation von SGI: [http://techpubs.sgi.com/library] [6] Systems in Motion: [http://www.sim.no/] [7] Coin: [http://www.coin3d.org] [8] Sourcecode von Coin und SoQt: [ftp://ftp.coin3d.org/pub/coin/src/] [9] Dateien zum Artikel: [ftp://ftp.linux-magazin.de/pub/listings/magazin/2003/02/3d/] |
|
Der |
|---|
|
Dr. Stephan Siemen arbeitet als wissenschaftlicher Mitarbeiter an der Essex University (UK). Dort entwickelt er Software zur 3D-Darstellung von Wettersystemen und unterrichtet Studenten in Computergrafik und Programmierung. Auf [http://prswww.essex.ac.uk/stephan/3D/] bietet er weitere Informationen zum Thema. |






