96

Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Embed Size (px)

DESCRIPTION

My bachelor thesis about graphic programming with the open source 3d engine Ogre3D.Meine Bachelor-Arbeit über Grafikprogrammierung mit der freien 3D-Engine Ogre3D.

Citation preview

Page 1: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Bachelorarbeit zum Thema

�Untersuchung des Funktionsumfanges und der

Leistungsfähigkeit der Gra�k-Engine OGRE3D�

zur Erlangung des akademischen Grades

Bachelor of Science

vorgelegt dem

Fachbereich Informatik, Mathematik und Naturwissenschaften der

Hochschule für Technik, Wirtschaft und Kultur Leipzig

von

Lars Bilke

24. Oktober 2006

Betreuer: Prof. Dr.-Ing. habil. Dieter Vyhnal

Page 2: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Eidesstattliche Erklärung

Hiermit versichere ich, die vorliegende Arbeit selbstständig und unter ausschlieÿlicherVerwendung der angegebenen Literatur und Hilfsmittel erstellt zu haben.

Die Arbeit wurde bisher in gleicher oder ähnlicher Form keiner anderen Prüfungsbehördevorgelegt und auch nicht verö�entlicht.

Markranstädt, den 24. Oktober 2006

2

Page 3: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Inhaltsverzeichnis

Abbildungsverzeichnis 6

1 Einführung 7

1.1 Einführung 3D-Engines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.1.1 Begri�sklärung 3D-Engine . . . . . . . . . . . . . . . . . . . . . . 81.1.2 Begri�serklärung Hardware-Abstraktion . . . . . . . . . . . . . . 81.1.3 Geschichtliches . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81.1.4 Unterschiede zwischen freien und kommerziellen 3D-Engines . . . 9

1.2 Freie 3D-Engines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.2.1 Irrlicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101.2.2 Nebula Device 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111.2.3 Panda3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.2.4 Vergleichende Betrachtungen zu OGRE 3D . . . . . . . . . . . . . 13

1.3 Kommerzielle 3D-Engines . . . . . . . . . . . . . . . . . . . . . . . . . . 151.3.1 Torque Game Engine . . . . . . . . . . . . . . . . . . . . . . . . . 151.3.2 CryEngine 1/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161.3.3 Unreal-Engine 2/3 . . . . . . . . . . . . . . . . . . . . . . . . . . 171.3.4 Source-Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

2 Leistungsumfang von OGRE 3D 20

2.1 Generelle Leistungsmerkmale . . . . . . . . . . . . . . . . . . . . . . . . 202.2 Unterstützte Plattformen und 3D-APIs . . . . . . . . . . . . . . . . . . . 202.3 Material- und Shader-Unterstützung . . . . . . . . . . . . . . . . . . . . 212.4 3D-Geometrien . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212.5 Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.6 Szenenverwaltung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.7 Speziale�ekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222.8 Weitere Leistungsmerkmale . . . . . . . . . . . . . . . . . . . . . . . . . 23

3 Einführung in die OGRE 3D-Programmierung 24

3.1 Kernobjekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243.1.1 Root-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253.1.2 RenderSytem-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . 253.1.3 SceneManager-Objekt . . . . . . . . . . . . . . . . . . . . . . . . 263.1.4 ResourceManager-Objekt . . . . . . . . . . . . . . . . . . . . . . . 27

3

Page 4: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3.1.5 Mesh-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273.1.6 Entity-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283.1.7 SceneNode-Objekt . . . . . . . . . . . . . . . . . . . . . . . . . . 293.1.8 Materials . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293.1.9 Overlays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

3.2 Einrichten einer Entwicklungsumgebung und Erstellen eines OGRE 3D-Projekts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

3.3 Eine �Hello World�-Anwendung . . . . . . . . . . . . . . . . . . . . . . . 323.4 FrameListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373.5 Ein interaktives Beispiel: Kamera- und Charaktersteuerung . . . . . . . . 39

3.5.1 Kamerasteuerung . . . . . . . . . . . . . . . . . . . . . . . . . . . 393.5.2 Charaktersteuerung . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4 Das OGRE 3D-Skriptsystem 44

4.1 Material-Skripte und Shader . . . . . . . . . . . . . . . . . . . . . . . . . 444.1.1 Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 444.1.2 Passes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454.1.3 Shader in OGRE 3D . . . . . . . . . . . . . . . . . . . . . . . . . 474.1.4 Ein einfacher Beispielshader . . . . . . . . . . . . . . . . . . . . . 49

4.2 Compositor-Skripte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524.2.1 Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534.2.2 Target Pass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534.2.3 Compositor Pass . . . . . . . . . . . . . . . . . . . . . . . . . . . 544.2.4 Ein einfacher Beispiel-Kompositor . . . . . . . . . . . . . . . . . . 54

4.3 Particle-Skripte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554.3.1 Partikelemitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . 564.3.2 Partikela�ektoren . . . . . . . . . . . . . . . . . . . . . . . . . . . 574.3.3 Ein einfaches Beispiel-Partikelskript . . . . . . . . . . . . . . . . . 58

4.4 Overlay-Skripte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594.4.1 Elemente zu Overlays hinzufügen . . . . . . . . . . . . . . . . . . 604.4.2 Standard-Overlay-Elemente . . . . . . . . . . . . . . . . . . . . . 604.4.3 Font De�nition-Skripte . . . . . . . . . . . . . . . . . . . . . . . . 61

5 Schatten in OGRE 3D 63

5.1 Allgemeines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635.1.1 Schatten in OGRE 3D aktivieren . . . . . . . . . . . . . . . . . . 635.1.2 Modulative Schatten . . . . . . . . . . . . . . . . . . . . . . . . . 645.1.3 Additive Light Masking . . . . . . . . . . . . . . . . . . . . . . . 64

5.2 Stencil-Schatten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 645.2.1 Das �HelloWorld�-Beispiel mit Stencil-Schatten . . . . . . . . . . . 65

5.3 Textur-basierte Schatten . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

6 Animation in OGRE 3D 67

6.1 Skeletale Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

4

Page 5: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

6.2 Vertex-Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696.2.1 Morph-Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . 696.2.2 Pose-Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696.2.3 Kombination von skeletaler und Vertex-Animation . . . . . . . . . 71

6.3 Szenenknoten-Animation . . . . . . . . . . . . . . . . . . . . . . . . . . . 716.4 Animation von numerischen Werten . . . . . . . . . . . . . . . . . . . . . 72

7 OGRE 3D-Tools und Exporter 73

7.1 XML-Konverter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737.2 MeshUpgrader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 747.3 MeshViewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 757.4 ParticleEditor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767.5 Mesh-Exporter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76

7.5.1 3ds Max-Exporter . . . . . . . . . . . . . . . . . . . . . . . . . . . 777.5.2 Blender-Exporter . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

7.6 oFusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777.7 RenderMonkey-Shader Exporter . . . . . . . . . . . . . . . . . . . . . . . 79

8 Ausblick 81

A Quellcode 82

A.1 HelloWorld-Quellcode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82A.2 Eine interaktive Anwendung-Quellcode . . . . . . . . . . . . . . . . . . . 85A.3 Compositor: Weichzeichner-Materialskript . . . . . . . . . . . . . . . . . 90A.4 Compositor: Weichzeichner-Pixelshader . . . . . . . . . . . . . . . . . . . 91A.5 Beispielshader: Vertexshader . . . . . . . . . . . . . . . . . . . . . . . . . 92A.6 Beispielshader: Pixelshader . . . . . . . . . . . . . . . . . . . . . . . . . . 93

B Inhalt der Begleit-CD 94

Literaturverzeichnis 95

5

Page 6: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Abbildungsverzeichnis

1.1 Die Komponenten einer Spiel-Engine (in Anlehnung an [Mot03], Seite 495) 101.2 Screenshot von dem noch nicht verö�entlichten Nebula Device Spiel Dra-

kensang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121.3 Disney�s Toontown Online . . . . . . . . . . . . . . . . . . . . . . . . . . 131.4 Freie Engines im Vergleich . . . . . . . . . . . . . . . . . . . . . . . . . . 141.5 Marble Blast Ultra auf der XBox 360 . . . . . . . . . . . . . . . . . . . . 151.6 Screenshot aus einer Crysis-Demonstration . . . . . . . . . . . . . . . . . 161.7 Normal Mapping in der Unreal Engine 3 . . . . . . . . . . . . . . . . . . 171.8 Lebensecht wirkende Charaktere im Spiel Half-Life 2 . . . . . . . . . . . 19

3.1 Die OGRE-Kernobjekte und ihre Beziehungen untereinander (in Anleh-nung an [The06b]) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

3.2 Das HelloWorld-Renderfenster . . . . . . . . . . . . . . . . . . . . . . . . 373.3 Das Renderfenster der interaktiven Anwendung . . . . . . . . . . . . . . 43

4.1 Der PerVertex-Lighting Beispielshader . . . . . . . . . . . . . . . . . . . 524.2 Ein einfacher Weichzeichner . . . . . . . . . . . . . . . . . . . . . . . . . 554.3 Ein einfaches Partikelsystem . . . . . . . . . . . . . . . . . . . . . . . . . 59

5.1 Das HelloWorld-Beispiel mit Stencil-Schatten . . . . . . . . . . . . . . . 655.2 Textur-basierte Schatten in OGRE . . . . . . . . . . . . . . . . . . . . . 66

6.1 Gesichtsanimation mit Pose-Animation . . . . . . . . . . . . . . . . . . . 70

7.1 Auswirkung der Detailreduktion des XML-Konverters auf die Texturpro-jektion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74

7.2 Der OGRE MeshViewer . . . . . . . . . . . . . . . . . . . . . . . . . . . 757.3 Der OGRE ParticleEditor . . . . . . . . . . . . . . . . . . . . . . . . . . 767.4 Die OGRE-Renderansicht innerhalb von 3ds Max . . . . . . . . . . . . . 787.5 Ein Bump-Mapping Shader in RenderMonkey von ATI Technologies . . . 797.6 Ein einfacher Specular Lighting Shader mit einer Holztextur . . . . . . . 80

6

Page 7: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

1 Einführung

Die Entwicklung der Computergra�k, insbesondere der Echtzeit-3D-Gra�k, hat in letz-ter Zeit eine rasante Entwicklung erlebt. In den letzten 5 Jahren hat sich die Gra�k-Rechenleistung, gemessen in Pixeln pro Sekunde, alle 6 Monate verdoppelt, das ent-spricht einem Faktor von etwa 1000! [Fer04]Aber nicht nur die Leistungsfähigkeit sondern auch die Qualität und die Flexibilität derGra�kprogrammierung haben sich deutlich verbessert. Die ersten Gra�kbeschleunigerwurden durch völlig frei programmierbare Gra�kprozessoren ersetzt, die es ermöglichen,Gra�kalgorithmen und -e�ekte, die bisher Nicht-Echtzeit-Systemen vorbehalten waren,nun auch in Echtzeit zu benutzen. Interaktive Anwendungen in Echtzeit kommen quali-tativ immer näher an vorberechnete Animationssequenzen oder auch computergenerierteSpiel�lme heran.Die Frage ist, wie kann man die Fähigkeiten heutiger Computer mitsamt ihren Gra�k-prozessoren am e�ektivsten nutzen?Gra�k-APIs1 wie Direct3D oder OpenGL bieten einen einfachen Einstieg in die Gra-�kprogrammierung und direkten Zugri� auf die Hardware. Sie bieten aber bei weitemkein Grundgerüst für eine komplexe Anwendung, denn diese benötigt Dinge wie Unter-stützung verschiedener Plattformen, Ressourcen- und Szenenverwaltung, Sichtbarkeits-algorithmen, eine Möglichkeit zum Austausch von Daten mit anderen Anwendungen, dieInhalte für die Engine erstellen usw.Die frei erhältliche 3D-Gra�kengine OGRE 3D2 bietet all die Funktionalität, die manbraucht, um komplexe 3D-Gra�k zum Leben zu erwecken und bietet alle Funktionali-täten, um die Möglichkeiten moderner Gra�kprozessoren für seine Anwendung zu nut-zen.

Diese Arbeit beleuchtet den Funktionsumfang und die Leistungsfähigkeit der Gra�k-Engine OGRE 3D, im folgenden nur mit OGRE bezeichnet. Nach einem Vergleich mitweiteren 3D-Engines, sowohl freien als auch kommerziellen, und der Au�istung der Leis-tungsmerkmale von OGRE erfolgt eine Einführung in die Programmierung mit OGRE.Darauf folgend werden wichtige Bereiche der Engine, wie z.B. das Materialsystem undAnimationen, näher beleuchtet und mit Beispielen verständlicht. Abschlieÿend werdeneinige Werkzeuge betrachtet, die direkt mit OGRE arbeiten oder Daten mit der Engineaustauschen können.

1API - Application Programming Interface, dt.: Schnittstelle zur Anwendungsprogrammierung2OGRE - Object-Oriented Rendering Engine

7

Page 8: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

1.1 Einführung 3D-Engines

1.1.1 Begri�sklärung 3D-Engine

Eine 3D-Engine3 ist ein Kernbestandteil von Computerspielen oder anderen interaktivenAnwendungen mit in Echtzeit berechneten Gra�ken. Synonyme sind z.B. Gra�k-Engine,Rendering-Engine oder fälschlicherweise Spiel-Engine, deren Begri� eigentlich eine höhe-re Funktionalität (z.B. Physik und Kollisionserkennung, Sound, Scripting und KünstlicheIntelligenz) als der der 3D-Engines assoziiert. 3D-Engines kümmern sich um die Darstel-lung möglichst realitätsnaher 3D-Gra�k. Sie verfügen meist über einen Szenengraphen,der eine objektorientierte Repräsentation der 3D-Welt darstellt, das Design der Anwen-dung vereinfacht und die Gra�kberechnungen von komplexen 3D-Welten optimiert.

1.1.2 Begri�serklärung Hardware-Abstraktion

Eine Hardware-Abstraktionsschicht4 ist eine in Software implementierte Abstraktions-schicht zwischen der physischen Hardware und der Software, die auf dem System läuft.Diese Schicht versteckt die Unterschiede von verschiedener Hardware (z.B. von ver-schiedenen Gra�kkarten) vor dem Anwendungsprogrammierer, der mit einem einheit-lichen Befehlssatz möglichst jede verfügbare Hardware ansprechen will. 3D-Engines set-zen meistens auf Gra�k-APIs wie Direct3D oder OpenGL auf, die eine Schnittstelle zurGra�khardware zur Verfügung stellen und die Hardware-Abstraktionsschicht direkt an-sprechen. Das OGRE-Rendersystem benutzt entweder Direct3D (eine gute Einführungist in [Sch03] zu �nden) oder OpenGL. Ein gewisses Grundverständnis dieser Gra�k-APIs ist sehr vorteilhaft für die Arbeit mit OGRE, weshalb hier auf die jeweiligen In-ternetseiten http://www.microsoft.com/directx/ und http://www.opengl.org ver-wiesen wird.

1.1.3 Geschichtliches

Der Begri� 3D-Engine erschien erstmals Mitte der 90er Jahre im Zusammenhang mit3D-Spielen. Sogenannte �First-Person Shooter�5 (FPS) wie �Doom� oder �Quake� von�id Software� waren die ersten sehr populären 3D-Spiele. Um nicht alles von Grund aufneuzuprogrammieren, lizenzierten Spieleentwickler die Kernkomponenten der Software

3wörtlich: 3D-Motor oder Gra�kmotor4HAL - engl.: Hardware Abstraction Layer5Ballerspiele, die aus der Ich-Perspektive gespielt werden

8

Page 9: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

und entwickelten dazu eigene Gra�ken, Charaktere und Welten, also Spielinhalte6.Spätere Spiele wie �Quake III� oder �Unreal� wurden bereits mit dem Hintergedankenentwickelt, die 3D-Engine später an weitere Entwicklungsstudios verkaufen zu können,was zur Folge hatte, dass die Engine und die Inhalte separat entwickelt wurden. DieLizenzierung der 3D-Engines wurde eine weitere Einnahmequelle für Spieleentwickler.Jedoch beinhalten die lizenzierten Engines meist weitere Funktionalitäten auÿer derGra�kerzeugung, denn es handelt sich meistens um komplette Spiel-Engines. Auÿerdemmachen wiederverwendbare Engines die Programmierung von Spielfortsetzungen leichterund kostene�ektiver.

Auch vor 1990 gab es schon so etwas wie Spiel- oder Gra�k-Engines wie z.B. LucasArts� �SCUMM�-System und Incentive Software�s �Freescape�-Engine. Im Gegensatzzu modernen Engines wurden diese Systeme nie von anderen Entwicklern lizenziert.[Wik06], Suchbegri� �game engine�

1.1.4 Unterschiede zwischen freien und kommerziellen3D-Engines

Der gröÿte Unterschied von freien und kommerziellen 3D-Engines ist die Verfügbar-keit und Stabilität von Werkzeugen, die Inhalte nahtlos aus DCC 7-Anwendungen indie Engine importieren, möglichst Echtzeit-Feedback bieten und die Benutzung auchvon Nichtprogrammierern bewältigt werden kann. Kommerzielle Engines bieten meistein reichhaltiges Angebot solcher Werkzeuge. Im Gegensatz zu den freien Engines, diemeist nur die Engine an sich bieten. Weitere Werkzeuge werden meist aus Eigenini-tiative einzelner Enthusiasten heraus programmiert mit teilweise durchaus beachtlichenErgebnissen. Trotzdem erreichen diese Werkzeuge meist nie den Funktionsumfang undvorallem die Stabilität kommerzieller Produkte. Beim Importieren von Inhalten ist beieiner freien Engine meist mehr Handarbeit zu verrichten.

Zu den meisten kommerziellen Engines werden keine o�ziellen Angaben zum Preis fürdie Lizenzierung gemacht. Entwickeler, die die Engines benutzen, verp�ichten sich ineinem NDA8 darüber keine Auskunft zu geben. Man geht aber davon aus, dass High-End Engines wie z.B. die Unreal Engine 3 (siehe auch Kapitel 1.3.3 auf Seite 17) füretwa 500.000 Dollar zu lizenzieren sind und somit wirklich nur für einige sehr groÿeEnwticklungsstudios mit einem Budget von mehreren Millionen Dollar pro Spiel in Fragekommen. Deshalb gibt es für Hobby- und kleinere Entwickler oder für den universitärenBereich nur die Alternative der freien Engines. Die einzige kommerzielle Engine, diepreislich auch für diese Zielgruppe in Frage kommt, ist die Torque Game Engine (siehe

6engl.: game assets7DCC - digital content creation, dt.: Erzeugung digitaler Inhalte8NDA - Non-Disclosure-Agreement, dt.: Vertraulichkeitsvereinbarung

9

Page 10: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

auch Kapitel 1.3.1 auf Seite 15) mit einem Preis von 100 US$ pro Arbeitsplatz.

Die hier vorgestellten kommerziellen Engines sind eigentlich komplette Spiele-Engines,d.h. sie bieten neben der Darstellung von Gra�k weitere Funktionen an, die man fürSpiele und interaktive Anwendungen benötigt. Dazu zählen z.B. Sound-, Netzwerk- undPhysik-Fuktionalität und Systeme für künstliche Intelligenz sowie entsprechende Werk-zeuge für diese Bereiche. Abbildung 1.1 auf Seite 10 verdeutlicht die Komponenten einerSpiel-Engine und deren Interaktion untereinander. Auf den folgenden Seiten werden nurdie Renderfunktionalitäten der Engines verglichen.

Abbildung 1.1: Die Komponenten einer Spiel-Engine (in Anlehnung an [Mot03], Seite495)

1.2 Freie 3D-Engines

1.2.1 Irrlicht

Irrlicht ist eine Multiplattform OpenSource 3D-Engine, die in C++ geschrieben wur-de aber auch für .NET Sprachen erhältlich ist9. Sie benutzt entweder OpenGL oder

9kostenlos erhältlich unter: http://irrlicht.sourceforge.net/

10

Page 11: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

die DirectX-API. Irrlicht unterstützt PerVertex-10 und PerPixel-Lighting11, Lightmap-ping12, Bump- und Normal-Mapping13 sowohl durch die Fixed-Function-Pipeline14 alsauch durch Shader 15 bis Shadermodell 3.0 in HLSL16 und GLSL17. Ein hierarchicherSzenenmanager ermöglicht die Verwaltung der Szene in Octrees18 als auch durch Oc-clusion Culling19. 3D-Modelle können aus diversen 3D-Modelling-Anwendungen wie 3dsMax, Blender, Milkshape und Maya importiert werden. Die Animation von 3D-Modellenerfolgt über Morphing und skeletale Animation (siehe Kapitel 6 auf Seite 67). Die Enginestellt auÿerdem ein Lua-Scripting-Interface bereit. [Dev06]

irrEdit ist ein frei erhältlicher Szeneneditor für Irrlicht, der sich allerdings noch in derEntwicklung be�ndet und bisher erst in Version 0.4 vorliegt20.

Für Irrlicht sind zahlreiche Tutorials und eine gute Dokumentation verfügbar, die denEinstieg in die Irrlicht-Programmierung sehr erleichtert. Auÿerdem beschäftigt sich einerege Community mit Irrlicht.

Kommerzielle Projekte, die mit Irrlicht realisiert wurden, sind nicht bekannt. [Dev06]und [Irr06]

1.2.2 Nebula Device 2

Nebula Device 2 ist eine OpenSource 3D-Engine in C++ von Radon Labs21 aus Berlin.Sie ist eine moderne Engine, die ihre komplette Rendering-Pipeline durch Shader reali-siert und dafür DirectX verwendet. Bisher kann man sie nur unter Windows verwenden,Portierungen nach Linux und Max OSX sind in Planung. Sie besitzt Skriptinterfaces fürPython, Lua und Ruby.

Es gibt verschiedene Szenenmanager für unterschiedliche Anforderungen wie Portale,Octrees und Occlusion Culling. 3D-Modelle können aus dem Wavefront und dem Lega-

10Lichtberechnungen werden pro Vertex durchgeführt und die Ergebnisse werden zwischen zwei Vertizesinterpoliert

11Lichtberechnungen werden für jeden Pixel einzeln durchgeführt was realistischere Ergebnisse alsPerVertex-Lighting ermöglicht

12Lichtberechnungen werden vorberechnet und direkt in Texturen geschrieben. Dies ermöglicht nurstatische Beleuchtung

13Hinzufügen von Ober�ächendetails durch spezielle Texturen14bisherige, nicht-programmierbare Funktionen der Gra�kkarte15programmierbare Prozessoren auf modernen Gra�kkarten16HLSL - High Level Shading Language, Programmiersprache für Shader von Microsoft17GLSL - OpenGL Shading Language, Programmiersprache für Shader, für Informationen siehe [Ros04]18Algorithmus zur Aufteilung des Raumes in immer kleiner werdende Würfel19Algorithmus, um verdeckte Bereiche der Szene von der Gra�kberechnung auszuschlieÿen20erhältlich unter: http://irredit.irrlicht3d.org/21erhältlich unter: http://www.radonlabs.de

11

Page 12: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

cy n3d-Format importiert werden. Exporter für Maya und 3ds Max sind kommerziellerhältlich. Die Engine unterstützt Keyframe- und skeletale Animation, Morphing undAnimationsüberblendung. Das Rendering erfolgt über Shader bis Shadermodell 3.0. Par-tikelsysteme werden ebenfalls unterstützt.

Abbildung 1.2: Screenshot von dem nochnicht verö�entlichten Nebu-la Device Spiel Drakensang

Die Engine wurde bereits in vielen kom-merziellen Produkten wie z.B. verschie-denen Lernspielen des Cornelsen Verlags(z.B. �Task Force Biologie�), in �ProjectNomads� und in �Verliebt in Berlin� ein-gesetzt. Das Rollenspiel �Drakensang� be-�ndet sich momentan bei Radon Labs inEntwicklung (siehe Abbildung 1.2 auf Sei-te 12). [Dev06] und [Rad06]

1.2.3 Panda3D

Panda3D22 ist eine 3D-Engine für SGI,Linux, Sun und Windows. Sie wurde ur-sprünglich von Walt Disney ImagineeringVR Studio für das Online-Multiplayerspiel�Toontown Online� (siehe Abbildung 1.3auf Seite 13) entwickelt. Die Engine ist in

C++ geschrieben und verfügt über ein Python Skriptinterface. Panda3D ist jetzt alsOpen Source Software unter http://www.panda3d.org verfügbar.

Das Rendering erfolgt wahlweise über OpenGL oder DirectX. Ein Python Kommando-zeilenfenster ermöglicht die Änderung von Python Skripten während der Ausführungder Panda3D-Anwendung. 3D-Modelle können aus 3ds Max und Maya in das Panda3D-eigene Egg-Format exportiert werden. Die Szeneninhalte werden über einen Szenengra-phen verwaltet und mit einem Szeneneditor platziert. Die Engine unterstützt Vertexbe-leuchtung, animierte Texturen, Partikelsysteme und Nebel oder Shader in Cg23. Anima-tionen erfolgen durch inverse Kinematik oder skeletale Animation. Auÿerdem beinhaltetdie Engine ein einfaches Physik- und Künstliche Intelligenz-System.

Bisher kam die Engine nur in Toontown und in verschiedenen studentischen Projektendes Carnegie Mellon Entertainment Technology Center in Pittsburgh, USA zum Einsatz.Das liegt vielleicht daran, dass die Engine mit der vorhanden Dokumentation nur in Py-thon programmiert werden kann und somit der Quellcode immer ö�entlich sichtbar und

22Panda - Platform Agnostic Networked Display Architecture23Programmmiersprache für Shader von NVidia

12

Page 13: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

veränderbar bleibt. Dies schlieÿt die Engine zur Verwendung in kommerziellen Projektenpraktisch aus. Es ist zwar möglich die Engine direkt in C++ zu programmieren, jedochgibt es dafür keine Dokumentation und Tutorials. [Dev06] und [Pan06]

1.2.4 Vergleichende Betrachtungen zu OGRE 3D

Abbildung 1.3: Disney�s Toontown Online

Abschlieÿend kann man sagen, dass al-le hier vorgestellten freien Engines einenähnlich Funktionsumfang haben und auchin mittlerweile stabilen Versionen ver-fügbar sind. Eine vergleichende Tabelleder Leistungsmerkmalen der Engines istauf Seite 14 zu �nden. OGRE verfügtim Gegensatz zu den anderen Enginesüber ein leistungsfähiges Post-Processing-Framework. Die damit erreichten E�ekte,wie z.b. HDRR und Tiefenunschärfe, wer-den in kommenden 3D-Anwendungen im-mer wichtiger. Auÿerdem ermöglicht OG-RE die komplette Ausnutzung der FixedFunction Pipeline sowie Unterstützung für

alle Shadermodelle und -programmiersprachen. Die anderen betrachteten Engines bietenin dieser Hinsicht nicht alle Leistungsmerkmale, die OGRE bietet.Zum ausschlaggebenden Kriterium für ORGRE 3D als Betrachtungsobjekt dieser Ar-beit ist für mich aber die sehr lebendige Community, mit ihren stets gefüllten Forenund Wikis, geworden. Die Archive bieten in vielen Fällen bereits die benötigten Ant-worten auf aufkommende Fragen und wenn nicht, dann werden diese meist in Stundenvon den kompetenten Betreuern der Foren, oft sogar vom OGRE-Schöpfer Steve Stree-ting persönlich, beantwortet. OGRE bietet dem Einsteiger in die 3D-Programmier eindurchdachtes und klares Klassensystem und einen leichten Einstieg durch zahlreiche Tu-torials. Irrlicht wird dem Neuling ebenfalls durch zahlreiche Tutorials nahegebracht. DieNebula Device 2 Engine ist durch ihr komplett auf Shader ausgerichtetes Rendersystemeher nicht für Einsteiger zu empfehlen und die Panda3D Engine hängt der technischenEntwicklung etwas hinterher und es gibt nur wenige Tutorials.Desweiteren wurde OGRE dieses Jahr erstmalig durch den Google Summer of Codeunterstützt, einer Initiative von Google zur Weiterentwicklung ausgezeichneter OpenSource Software. Die Engine hält der technischen Entwicklung von Computersystem mitund wurde bereits in den Spielen �Ankh� vom deutschen Entwickler Deck13, das im Rah-men des Deutschen Entwicklerpreis zum besten deutschen Spiel 2005 gekürt wurde, und�Paci�c Storm� von Buka Entertainment aus Russland auf die Nutzung in komplexen,kommerziellen Projekten getestet.

13

Page 14: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Die Engine ist unter der LGPL24 lizensiert. Dies ermöglicht die freie Verwendung derEngine sowohl in OpenSource als auch in kommerziellen Projekten. Im Gegensatz zurGPL25 müssen Projekte nicht als OpenSource verö�entlicht werden, sondern können,soweit die Engine nicht verändert wurde, in einer eigenen Lizenz erscheinen.

Abbildung 1.4: Freie Engines im Vergleich

24LGPL - Lesser General Public License25GPL - General Public License

14

Page 15: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

1.3 Kommerzielle 3D-Engines

1.3.1 Torque Game Engine

Die Torque Game Engine26 oder TGE ist eine modi�zierte Version von einer Spiel-Engine, die ursprünglich von Dynamix für das Spiel �Tribes 2� entwickelt wurde. Jetztist die Torque Engine für unabhängige oder professionelle Spieleentwickler von GarageGames linzenzierbar.Die �Torgue Indie License� kostet pro Programmierer moderate 100 US$ solange derProgrammier in einer Firma mit weniger als 250.000 US$ Umsatz jährlich angestellt ist.Die alternative kommerzielle Lizenz kostet 495 US$ pro Programmierer. Diese Preis-politik ermöglicht es auch kleinen Entwicklungsstudios eine leistungsfähige Engine zubenutzen.

Abbildung 1.5: Marble Blast Ultra auf derXBox 360

Auÿer 3D-Gra�k beinhaltet die Engi-ne auch Netzwerkunterstützung, Scrip-ting, einen Welteditor und Benutzer-schnittstellenerzeugung. Die Engine lässtsich unter Windows, Macintosh und Li-nux verwenden. Die Engine unterstütztLandschafts-Rendering mit mehreren Tex-turen (Multi-Texturing), volumetrischerNebel, Umgebungs-Mapping (Environ-ment Mapping), Vertex-Lighting und dasLaden von 3D-Modellen im .DTS- und.DIF-Format. .DTS-Modelle können überskeletale oder über Morph-Animation ani-miert werden. Auÿerdem kann stufenloszwischen mehreren Animation überblen-det werden. .DIF-Modelle werden für die

statische Szenengeometrie benutzt, da sie nicht dynamisch beleuchtet werden können.

Die Torque Engine enthält mehrere Werkzeuge zur Inhalteerstellung, wie einen GUI-Editor, einen Welteneditor zum Platzieren von Objekten und Modi�zieren von Szenen-eigenschaften, einen Generator zur Erzeugung von Höhentexturen als Grundlage fürGelände, einen Geländetextureditor, einen Editor zur Modi�zierung der Geländeformund einen Modelleditor.

Hauptkritikpunkt der Engine ist die unzureichende Dokumentation. Garage Games hatdieses Problem erkannt und unter http://tdn.garagegames.com das Torque Developer

26erhältlich unter http://www.garagegames.com

15

Page 16: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Network ins Leben gerufen, in der Ho�nung, dass die Benutzer der Engine über dasWiki-System eine vollständigere Dokumentation erscha�en.

Die Torque Engine kann über die Torque Shader Engine zur Unterstützung von mo-dernen Shadern erweitert werden. Jedoch wird nur das Shadermodell 2.0 unterstützt.Es gibt mehrere Starter Kits, die die Entwicklung bestimmter Spieletypen erleichternsollen, wie z.B. das �Racing Starter Kit� für Rennspiele.

Bekanntestes Spiel, das die Torque Engine nutzt, ist �Marble Blast Ultra� welches fürden PC als auch für die XBox verfügbar ist (siehe Abbildung 1.5 auf Seite 15).

GarageGames hat bereits mit Torque X die nächste Version der Engine angekündigt.Torque X baut auf dem neuen XNA Framework 27 von Microsoft auf, eines Frameworkszur Entwicklung von Spielen und anderen interaktiven Anwendungen. Torque X kannmit dem neuen XNA Game Studio Express28, welches auf der frei erhältlichen Entwick-lungsumgebung Visual C# Express29 aufsetzt, benutzt werden, um mit dem gleichenProgrammcode Anwendungen sowohl für den PC mit Windows XP als auch für Micro-softs Spielekonsole XBox 360 zu entwickeln. [Dev06] und [Gar06]

1.3.2 CryEngine 1/2

Abbildung 1.6: Screenshot aus einer Crysis-Demonstration

Die CryEngine ist eine Spiel-Engine dieim Spiel �Far Cry� von Crytek30 benutztwurde. Ursprünglich wurde die Engine füreine Technologie-Demonstration für NVi-dia geschrieben.

Die CryEngine2 ist eine neue in derEntwicklung be�ndliche Spiel-Engine, diestark auf der CryEngine basiert und fürden kommenden Crytek-Titel �Crysis� ge-nutzt wird. Bisher gab es in der Ö�entlich-keit nur eine beeindruckende technischeDemonstration zu sehen31. Die Demo zeig-te fortgeschrittene Technologien wie z.B.

dynamisches indirektes Licht (Dynamic Ambient Lighting), weiche Schatten, Tiefen-

27Informationen und kostenloser Download unter: http://msdn.microsoft.com/directx/xna/28kostenlos erhältlich unter http://msdn.com/directx/XNA/gse/29erhältlich unter http://msdn.microsoft.com/vstudio/express/visualcsharp/30eher spärliche Informationen zur Engine unter: http://www.crytek.com31erhältlich unter http://www.youtube.com/watch?v=MqSOZGCcFYU

16

Page 17: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

sowie Bewegungsunschärfe und extrem detaillierte 3D-Modelle. Erste persönliche Ein-drucke der Engine von einer Multiplayer-Demonstration auf der Games Convention 2006in Leipzig belegen die Möglichkeit dieser Technologien in Echtzeit (siehe Abbildung 1.6auf Seite 16). [Dev06]

1.3.3 Unreal-Engine 2/3

(a) HochaufgelöstesModell bestehend aus2 Mio. Dreiecken

(b) NiedrigaufgelöstesModell bestehend ausca. 5000 Dreiecken

(c) Endergebniss in der Engine: niedrigaufge-löstes Modell mit Normal Map

Abbildung 1.7: Normal Mapping in der Un-real Engine 3

Die Unreal-Engine32 ist eine der popu-lärsten Spiele-Engines und sie kam in derersten Version 1998 mit dem gleichnami-gen Spiel heraus und wird von Epic Ga-mes entwickelt. Die Engine unterscheidetsich zu den meisten anderen Engines dar-in, dass man mit der Lizenz nicht nurdie Engine sondern gleich ein komplettesSpiel mit Quellcode und allen Inhalten er-wirbt. Das hat den Vorteil dass man sehrschnell einen eigenen Prototyp entwickelnkann, aber den Nachteil, dass je mehr sichdas zu entwickelnde Spiel von einem klas-sischen First Person Shooter (FPS) un-terscheidet, desto schwieriger es wird dieEngine den eigenen Bedürfnissen anzu-passen. Die Unreal-Engine kann über dieUnrealScript-Skriptsprache gesteuert wer-den.

Die Unreal-Engine 2 baut auf Direct3D8 und OpenGL 1.x auf und unterstütztbereits Shadermodell 1. Sie scha�t naht-lose Übergänge zwischen Indoor-BSP33-Szenen, statischen und dynamischen Mo-dellen und Outdoor-Szenen. Sie unter-stützt skeletale Animation und Gesichtsa-nimation inkklusive Lippensynchronisati-on.Die Engine hebt sich durch ihr reichhal-tiges Angebot an funktionsstarken Werk-zeugen hervor. So bieten der Level-Editor

32nähere Informationen unter: http://www.unrealtechnology.com33BSP - Binary Space Partition, Algorithmus zur Aufteilung des Raumes in eine baumartige Struktur

17

Page 18: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

UnrealED alles um einen Spiellevel zu erstellen, inklusive der Festlegung der Spiellogiküber Skripte. Es gibt weitere Editoren für Partikelsysteme, Benutzerinterfaces, Zwischen-sequenzen in Spielgra�k (sogenannte cutscenes) und für Modellanimationen. UnrealEDist z.B. in dem Spiel Unreal Tournament 2004 enthalten und ermöglicht es, neue Kartenfür das Spiel zu erstellen.Die Version 2.5 erweitert die Engine um Direct3D 9 und OpenGL 2.x Unterstützung.Somit werden auch moderne Gra�ktechnologien wie HDRR34, Normal und Bump Map-ping, weiche Schatten und Per Pixel Lighting möglich. Nun werden auch Microsoft�sXBox, 64-Bit Windows und Linux von der Engine unterstützt.

Die Unreal-Engine 3 be�ndet sich noch in der Entwicklung und wird für PCs, Micro-soft�s XBox 360 und Sony�s Playstation 3 erältlich sein. Die Engine läuft mit Direct3D9 und 1035 und OpenGL 2.x. Sie unterstützt Shadermodell 2, 3 und 4 inklusive der neu-en Geometry Shader 36 und verfügt über eine komplette 64- oder 128-Bit High DynamicRange Rendering (HDRR) - Pipeline.Die Editoren werden weiterhin in ihrer Funktionalität ausgebaut. UnrealCascade ermög-licht das Editieren komplexer Partikelsystem, mit UnrealPhAT editiert man die Skeletteund physikalischen Eigenschaften der 3D-Modelle, AnimTree erlaubt das Editieren undMischen mehrerer einzelner Animationen zu komplexen Bewegungen, ein visueller Ma-terialeditor erlaubt die Erstellung komplexer Materialien ohne direkt Shader program-mieren zu müssen und UnrealED, der leistungsstarke Level-Editor, der alle anderenWerkzeugen in einer Ober�äche vereint.Die Engine verfügt über ein Werkzeug zur automatischen Erstellung von Normal Maps.Dabei wird aus einem extrem hoch aufgelösten (bis 8 Mio. Dreiecke) Modell eines Cha-rakters eine hochaufgelöste Normal Map (2048 x 2048 Pixel) erstellt und in der Enginemit einem niedrig aufgelösten (bis 12000 Dreiecke) Mesh gerendert (siehe Abbildung 1.7auf Seite 17). [Wik06], Suchbegri� �unreal engine� und [Unr06]

34HDRR - High Dynamic Range Rendering, Licht wird mit einer höheren Werteumfang berechnet, wasz.B. Überstrahle�ekte ermöglicht

35Direct3D 10 wird erst mit der Verö�entlichung von Windows Vista anfang 2007 erhältlich sein36neue Stufe im Renderingprozess, zwischen Vertex- und Pixel-Shader angeordnet, ermöglicht er z.B.

die prozedurale Erzeugung von 3D-Geometrie direkt auf der Gra�kkarte

18

Page 19: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

1.3.4 Source-Engine

Die Source Engine wurde bis 2005 von Valve Software für das Spiel �Half-Life 2� entwi-ckelt. Sie läuft unter Direct3D 9 und unterstützt HLSL bis Shadermodell 2.0, ist aber biszu Direct3D 6 abwärtskompatibel mit älterer Gra�khardware. Zu den Leistungsmerkma-len zählen weiterhin Bump und Environment Mapping, dynamische Lichter, projektiveSchatten und vorberechnete Light Maps, HDR-Beleuchtung, Wasser mit Brechungse�ek-ten und komplexe Partikelsysteme. Valve hebt besonders die Charakteranimationsmög-lichkeiten der Engine hervor. So werden Charaktere über ein skeletales System animiert.Im Gesichtsbereich kommt ein simuliertes Muskelsystem zum Einsatz, das die Charakterelebensnaher erscheinen lassen soll (siehe Abbildung 1.8 auf Seite 19). Auch die Lippender Charaktere können zumindest grob auf mehrere Sprachen synchronisiert werden.

Abbildung 1.8: Lebensecht wirkende Cha-raktere im Spiel Half-Life 2

Die Engine ist in C++ geschrieben undist nur für den PC erhältlich. Sie ist überDLLs modular aufgebaut. Zu den um-fangreichen Werkzeugen zählt der ValveHammer Editor, der ähnlich dem Unreal-ED eine komplette Umgebung zur Er-stellung von Spielszenen mit sofortigenoptischen Feedback zur Verfügung stellt.Der Half-Life Model Viewer erlaubt dieBetrachtung und Bearbeitung einzelner3D-Modelle. Über den Faceposer werdensämtliche Gesichtsanimationen der Cha-raktere erstellt. Auÿerdem verfügt die En-gine über Exporter für 3ds Max, Maya undSoftimage XSI. [Val06]

19

Page 20: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

2 Leistungsumfang von OGRE 3D

OGRE ist eine szenenorientierte, �exible in C++ geschriebene 3D-Engine ,die eine ein-fache und intuitive Möglichkeit zur Nutzung moderner Gra�khardware zur Verfügungstellt. Die Klassenbibliothek abstrahiert alle Details der darunterliegenden Systembiblio-theken wie Direct3D oder OpenGL und ist damit wirklich plattformunabhängig.

2.1 Generelle Leistungsmerkmale

• OGRE ist komplett objekt-orientiert gestaltet und bietet eine einfache Schnittstellezum Rendering von dreidimensionalen Szenen unabhängig von der verwendetenGra�k-API-Implementierung.

• Eine �exible Plugin-Architektur ermöglicht die Erweiterung der Engine ohne er-neute Kompilierung.

• Konsistentes Design und Dokumentation aller Klassen.

• Unterstützung von ZIP-Archiven.

2.2 Unterstützte Plattformen und 3D-APIs

• Als 3D-APIs werden OpenGL und Direct3D unterstützt.

• Windows-, Linux- und MACOSX-Unterstützung, experimentelle PocketPC1 (Win-dows Mobile) Unterstützung.

• Kann unter Windows mithilfe von Visual C++2 (Visual C++ 6 bis OGRE Version1.0.7, Visual Studio 2003 und 2005 ab OGRE Version 1.2) und Code::Blocks erstelltwerden.

• Kann unter Linux und MAC OSX mithilfe von gcc 3+3 erstellt werden.

1Informationen zur Implementierung unter: http://www.ogre3d.org/phpBB2/viewtopic.php?t=15938&highlight=

2Visual C++ Express ist kostenlos erhältlich unter: http://msdn.microsoft.com/vstudio/express/visualc/

3erhältlich unter: http://gcc.gnu.org/releases.html

20

Page 21: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

2.3 Material- und Shader-Unterstützung

• Eine mächtige Material-Skriptsprache ermöglicht die Ausarbeitung und Speiche-rung von Materialde�nitionen auÿerhalb der eigentlichen Anwendung in Skriptda-teien.

• Unterstützung aller Funktionen der Fixed Function Pipeline wie z.B. Multitexture-Rendering (mehrere Texturen werden ineinandergeblendet und auf eine 3D-Geometriegerendert), Multipass-Blending (z.B. für durchsichtige Ober�ächen), Texturkoor-dinatengenerierung und -modi�kation und Nebele�ekte für ältere Gra�khardware.

• Moderne Vertex- und Pixel-Shader, entweder in Assembler oder in Hochsprachenwie HLSL, Cg und GLSL geschrieben, werden unterstützt.

• Multipass Rendering sorgt z.B. für die Beleuchtung eines Objekts mit mehrerenLichtquellen.

• Mehrere Techniken pro Materialde�niton erlauben verschiedene Implementationenvon E�ekten für verschieden leistungsfähige Gra�kkarten. OGRE erkennt welcheTechnik verwendet werden kann und benutzt die Beste.

• Gleiches gilt für Material-LODs4: Mit zunehmender Entfernung der Objekte zumBetrachter kann ein weniger rechenintensives Material benutzt werden, um diePerformance zu steigern.

• Texturen können in folgenden Formaten geladen werden: PNG, JPEG, TGA, BMPund DDS, wobei auch ungewöhnliche Texturformen wie volumetrische und kubi-sche (z.B. für Umgebungs-Mapping) sowie komprimierte (DXT/S3TC) Texturenunterstützt werden.

• Texturen können in Echtzeit zur Verfügung gestellt werden, z.b. für Live-Video-Streams.

• Mip-Mapping sorgt dafür, dass weit entfernte Objekte eine verkleinerte Versionder ursprünglichen Textur verwenden. Dabei werden die einzelnen Mip-Maps au-tomatisch von OGRE erzeugt sollten sie nicht bereits in der Texturdatei vorhandensein.

2.4 3D-Geometrien

• Mehrere Exporter für 3D-Modelling-Anwendungen, wie z.B. 3DS Max, Maya, Blen-der und Milkshape3D, exportieren in das OGRE-eigene Mesh-Format .mesh (sieheKapitel 7.5, Seite 76).

• Manuell oder automatisch erzeugte Mesh-LODs sorgen für eine erhöhte Perfor-mance.

4LOD - Level of Detail, dt.: Detailgrad

21

Page 22: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

2.5 Animation

• Skeletale Animation mit gewichtsgesteurter Überblendung mehrerer Animationen.Knochengewichte können manuell eingestellt werden und Knochen auch manuellanimiert werden. Kon�gurierbare Interpolationsmethoden ermöglichen die Wahlzwischen genauer und langsamer und ungenauerer aber schnellerer Interpolation.

• Morph-Animation zur linearen Überblendung zweier Formen.

• Pose-Animation erlaubt die Überblendung mehrerer Formen mit steuerbaren Ge-wichten über die Zeit hinweg für z.B. Gesichtsanimationen.

• Generische Animationsspuren ermöglichen die Animation jedes Parameters überdie Zeit hinweg.

2.6 Szenenverwaltung

• Das integrierte Szenenmanagement ist sehr �exibel gestaltet und nicht an einenbestimmten Szenentyp gebunden. Man kann vorde�nierte Klassen benutzen, wiez.B. BSP oder Octree, oder eigene Unterklassen schreiben, um volle Kontrolleüber die Szenenverwaltung zu bekommen und diese an die spezielle Anwendunganpassen.

• Ein hierarchischer Szenengraph verwaltet alle szenenrelevanten Objekte und sorgtfür eine inhaltliche wie räumliche Beziehung der Objekte untereinander.

Für weitergehende Information zur Szenenverwaltung von interaktiven Anwendungen imAllgemeinen siehe [Eri05].

2.7 Speziale�ekte

• Das Compositor-System erlaubt die einfache Verwendung von Post-ProcessingE�ekten, wie z.B. Bewegungsunschärfe und verschiedene Filtere�ekte über eineSkriptsprache ähnlich den Materialskripten.

• Ein skriptbasiertes Partikelsystem ermöglicht Partikelemitter und -a�ektoren.

• Unterstützung von Himmelsboxen (6 Texturen bilden die Umgebung der Szene),Himmelsebenen und Himmelshalbkugeln (jeweils eine Textur) zur Ausgestaltungder Szene.

• Billboards5 als Platzhalter für zweidimensionale Sprites, z.B. für weit entfernteBäume oder Wolken.

5Rechtecke, die immer dem Betrachter zugewandt sind und auf die eine Textur mit Alpha-Kanalprojiziert wird

22

Page 23: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

• Transparente Objekte werden automatisch verwaltet. Man muss sich nicht um dieRenderreihenfolge kümmern.

• Verschiedene Schatten-Render-Methoden wie modulative, additive, stencil- undtexturbasierte Schatten werden unterstützt und werden wenn möglich direkt aufder Gra�khardware berechnet.

2.8 Weitere Leistungsmerkmale

• Einheitliches Ressourcen- und Speichermanagement.

• Ein Debugger für den Speichermanager hilft beim Finden von Speicherlöchern.

• Sogenannte Controller erlauben die Verbindung bestimmter Parameter unterein-ander.

• Der ReferenceAppLayer stellt ein Beispiel zur Verfügung, wie man OGRE mit an-deren Bibliotheken, wie z.B. ODE6 für Kollisionserkennung und Physik, verbindet.

• TrueType Fonts können zur Ausgabe auf dem Bildschirm genutzt werden.

• Die 2D-GUI7 CEGUI (�Crazy Edies GUI�) ist bereits in OGRE integriert undbietet Buttons, Listen Editierboxen, Scrollbalken usw.

[The06b] und [Dev06]

6ODE - Open Dynamics Engine7GUI - Graphical User Interface, dt.: gra�sche Benutzerschnittstelle

23

Page 24: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3 Einführung in die OGRE

3D-Programmierung

3.1 Kernobjekte

Die in Abbildung 3.1 auf Seite 24 dargestellten Objekte bilden die Basis für jede OGRE-Anwendung:

Abbildung 3.1: Die OGRE-Kernobjekte und ihre Beziehungen untereinander (in Anleh-nung an [The06b])

24

Page 25: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3.1.1 Root-Objekt

Das Root-Objekt stellt den Einstiegspunkt in das OGRE-System dar. Dieses Objektmuss als allererstes OGRE-Objekt erstellt werden und als letztes zerstört werden.

Über das Root-Objekt lässt sich das Rendersystem kon�gurieren. Die Methode show-

ConfigDialog() prüft alle Renderoptionen, wie verfügbare Renderer (OpenGL oder Di-rectX), Au�ösungen, Farbtiefen, Vollbildschirm- und Antialiasing-Optionen. Auÿerdemspeichert die Methode die vorgenommenen Einstellungen in einer Kon�gurationsdateizur späteren Initialisierung des Render-Systems.

Das Root-Objekt stellt Zugri� zu wichtigen Objekten des OGRE-Systems, wie demSzenen-, dem Mesh- und Texturmanager, bereit.

Die Anwendung betritt durch den Aufruf der Root-Objekt-Methode startRendering()die Renderschleife, die nur durch die Schlieÿung aller Renderfenser oder durch eine ex-plizite angeforderte Beendigung der Anwendung aus einem FrameListener (siehe Kapitel3.4 auf Seite 37) heraus beendet werden kann.

3.1.2 RenderSytem-Objekt

Das RenderSystem-Objekt ist eine abstrakte Klasse, die das Interface zur darunter-liegenden Render-API de�niert. Es ist für das Senden der Renderoperationen an dieverwendete API und für das Setzen aller Renderoptionen verantwortlich. Die Klasse istabstrakt, weil die komplette Implementation spezi�sch für die jeweilige Render-API ist.Es gibt API-spezi�sche Unterklassen für jede Render-API, z.B. D3DRenderSystem fürDirect3D. Nachdem das System durch Root::initialise() initialisiert wurde, ist dasRenderSystem-Objekt für die gewählte Render-API über die Root::getRenderSystem()-Methode verfügbar.

Normalerweise ist es nicht nötig direkt auf das RenderSystem-Objekt zuzugreifen. Al-les was zum Rendern von Objekten und dem Einstellen der Renderoptionen benötigtwird, ist über den Szenenmanager sowie über Materialien und anderen szenenorientier-ten Klassen verfügbar. Der Szenenmanager sorgt dafür, dass die benötigte Methoden desRenderSystem-Objekt zum richtigen Zeitpunkt aufgerufen werden.Man benötigt das RenderSystem-Objekt jedoch um mehrere separate Renderfenster zuerstellen oder um andere fortgeschrittene Möglichkeiten des Rendersystems zu nutzen.

25

Page 26: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3.1.3 SceneManager-Objekt

Neben dem Root-Objekt ist das SceneManager -Objekt der wichtigste Teil des OGRE-Systems für den Anwendungsprogrammierer. Der Szenenmanager kennt die Inhalte derSzene, die gerendert werden sollen. Er ist verantwortlich für die Organisation der Inhalte,wie Kameras, bewegliche Objekte (Entities, siehe Kapitel 3.1.5 auf Seite 28), Lichtquellenund Materialien (Ober�ächeneigenschaften von Objekten) sowie für das Verwalten derWeltgeometrie, die eine statische Geometrie zur Repräsentation der unbeweglichen Teileder Szene darstellt.

Es ist nicht nötig, in der Anwendung Listen von Objektverweisen zu führen. Der Sze-nenmanager führt alle erstellten Objekte durch zugewiesene eindeutige Namen. DerZugang zu Objekten geschieht durch verschiedene SceneManager-Methoden wie z.B.getCamera() und getEntity(), und dem eindeutigen Namen.

Der Szenenmanager sendet die Szene an das RenderSystem-Objekt wenn die Szene ge-rendert werden soll.

Die meiste Interaktion mit dem Szenenmanager geschieht während der Erstellung derSzene. SceneManager-Methodenaufrufe sorgen dafür, dass sich die Szene mit Inhaltenfüllt. Es werden 3D-Geometrien geladen, mit Materialien versehen, in der Szene platziertsowie Kameras und Lichtquellen de�niert. Die spätere (dynamische) Veränderung derSzene wird über FrameListener-Objekte (siehe Kapitel 3.4 auf Seite 37) vollzogen.

Weil verschiedene Szenentypen (z.B. Outdoor / Indoor) verschiedenen Algorithmen be-nötigen, um zu entscheiden, welche Objekte zum Rendern an das Rendersytem gesendetwerden, um eine möglichst gute Performance zu erzielen, gibt es mehrere Unterklassender SceneManager-Klasse. Der Standard-Szenenmanger rendert eine Szene ohne Organi-sation der Objekte und man sollte keine gute Performance bei groÿen Szenen mit vielenObjekten erwarten. Spezialisierungen der SceneManager-Klasse werden für bestimmteSzenentypen gescha�en, um die Szenenorganisation für diesen Typ zu optimieren undeine gute Performance zu erzielen. Zum Beispiel optimiert der BspSceneManager dasRendern von groÿen Indoor-Levels basierend auf Binary Space Partition Trees.

Die OGRE-Anwendung muss nicht wissen welche Unterklassen verfügbar sind. Die An-wendung ruft nur Root::createSceneManager() mit dem Typ der Szene als Parameterauf (z.B. ST_GENERIC, ST_INTERIOR) und das OGRE-System nutzt automatischdie beste verfügbare SceneManager-Unterklasse oder den Standard-Szenemanager wennkeine Spezialisierung verfügbar ist. Dies ermöglicht es erst später einen optimierten Sze-nenmanager zu erstellen.

26

Page 27: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3.1.4 ResourceManager-Objekt

Die ResourceManager -Klasse ist eine Basisklasse weitere Klassen, die zum Verwalten vonRessourcen benutzt werden. Ressourcen sind Daten, die geladen werden müssen wie z.B.Texturen und 3D-Geometrien (Meshes). Es gibt Unterklassen von der ResourceManager-Klasse, um jeden Ressourcentyp zu verwalten, wie z.B. den TextureManager um Textu-ren zu laden und den MeshManager um 3D-Geometrien zu laden.

Ressourcemanager sorgen dafür, dass Ressourcen nur einmal geladen werden und verwal-ten die benötigten Speicherbereiche. Auÿerdem werden die angeforderten Ressourcen inmehreren zuvor spezi�zierten Verzeichnissen oder komprimierten Archiven (zip-Dateien)gesucht.

Normalerweise interagiert man nicht direkt mit den Ressourcenmanagern. Ressourcen-manager werden von anderen OGRE-Teilen aufgerufen wenn sie benötigt werden. Wennman z.B. eine Textur einem Material hinzufügen will, wird der TextureManager auto-matisch aufgerufen. Man kann aber auch direkt Ressourcen über die Ressourcenmanagervorladen, um einen späteren Festplattenzugri� innerhalb der Rendering-Schleife zu ver-meiden.

Man muss jedoch den Ressourcenmanager direkt aufrufen, um ihm mitzuteilen wo ernach Ressourcen suchen soll. Dies geschieht über addSearchPath() und addArchive().Dadurch werden aber nur die Suchverzeichnisse und -archive des speziellen Ressourcen-manager gesetzt, z.B. hat es nur Auswirkung auf das Laden von Texturen wenn man dieMethoden des TextureManagers aufruft. Alternativ kann man die statische MethodeResourceManager::addCommonSearchPath() oder ResourceManager::addCommonAr-

chive() aufrufen, um alle Ressourcenmanager auf die Verzeichnisse und Archive zu-greifen zu lassen.

3.1.5 Mesh-Objekt

Ein Mesh-Objekt repräsentiert die 3D-Geometrie eines Modells und ist normalerwei-se relativ klein gegenüber der Weltgeometrie. Mesh-Objekte repräsentieren beweglicheObjekte und werden nicht zur Repräsentation der Weltgeometrie genutzt.

Mesh-Objekte sind eine Art von Ressourcen und werden durch den MeshManager Res-sourcenmanager verwaltet. Sie werden normalerweise aus dem OGRE-spezi�schen �.mesh�-Format geladen. Mesh-Dateien werden meist aus 3D-Modelling-Anwendungen wie z.B.3ds Max (siehe Kapitel 7.5.1 auf Seite 77) exportiert.

Man kann Mesh-Objekte auch manuell erzeugen, indem man die MeshManager::create-

27

Page 28: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Manual()-Methode aufruft. Auÿerdem gibt es Methoden, um z.B. Ebenen generisch zuerzeugen (siehe Kapitel 5.2.1 auf Seite 65).

Mesh-Objekte bilden die Basis für individuelle bewegliche Objekt in der Szene, wel-che Entities (siehe Kapitel 3.1.5 auf Seite 28) genannt werden. Mesh-Objekte könnenauÿerdem über skeletale Animation (siehe Kapitel 5.3 auf Seite 67) animiert werden.

Mesh-Objekte setzen sich aus einem oder mehreren SubMesh-Objekten zusammen. Jedesrepräsentiert einen Teil des Meshes, der ein individuelles Material benutzt. Wenn einMesh nur ein Material benutzt, so sollte es auch nur aus einem SubMesh bestehen.

3.1.6 Entity-Objekt

Ein Entity ist eine Instanz eines beweglichen Objektes in der Szene. Es kann alles Mög-liche darstellen. Es wird nur die Annahme gemacht, dass es keine feste Position in derSzene hat.

Entities basieren auf 3D-Geometrien, die durch das Mesh-Objekt repräsentiert werden.Mehrere Entities können auf dem selben Mesh-Objekt basieren, wenn man mehrere Ko-pien eines Meshes in der Szene darstellen will. Auch hier wird wieder die Mesh-Ressourcenur einmal geladen auch wenn mehrere Entities mit dem Mesh-Objekt assoziiert sind.

Man erzeugt ein Entity durch den Aufruf der SceneManager::createEntity()-Methode.Man gibt dem Entity einen eindeutigen Namen und spezi�ziert das zugrunde liegen-de Mesh-Objekt. Der Szenenmanager sorgt dafür, dass das Mesh durch Aufrufen desMeshManager-Ressourcenmanager geladen wird.

Entities sind nicht Bestandteil der Szene solange sie nicht an einem Szenenknoten (Sce-neNode, siehe Kapitel 3.1.6 auf Seite 29) angehängt werden. Durch das Anhängen anSzenenknoten werden komplexe hierarchische Beziehungen zwischen den Positionen undOrientierungen von Entities ermöglicht. Man verändert die Positionen von Knoten, umindirekt die Positionen der Entities zu verändern.

Zu einem Mesh können auÿerdem mehrere Materialien (siehe Kapitel 3.1.7 auf Seite29) de�niert sein. So ist es möglich, verschiedenen Teilen des Meshes auch verschiedeneMaterialien zuzuordnen. Jedes von einem Mesh erzeugte Entity benutzt automatisch dievorgegebenen Materialien. Man kann dies aber für jedes Entity individuell ändern, ummehrere Entities mit verschiedenen Materialien aber basierend auf demselben Mesh zuerzeugen.

Wenn ein Entity basierend auf einem Mesh erzeugt wird, so ist es aus einem oder mehre-ren SubEntity-Objekten zusammengesetzt, wobei jedes zu einem SubMesh-Objekt korre-

28

Page 29: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

spondiert. Man greift auf das SubEntity über die Entity::getSubEntity()-Methode zu.Jetzt kann man über den Aufruf von setMaterialName() das Material des SubEntity-Objektes ändern. Dadurch kann man Entities basierend auf ein und demselben Meshindividuell gestalten.

3.1.7 SceneNode-Objekt

Die Szene wird durch den Szenenmanager in einer baumbasierten Struktur verwal-tet. Jeder Knoten entspricht einem SceneNode-Objekt. Der Wurzelknoten wird überSceneManager::getRootSceneNode() bereitgestellt. An jeden Knoten können weite-re Knoten als Kindknoten über SceneNode::createChildSceneNode() angefügt wer-den.

An jeden Knoten können Entities oder andere szenenrelevante Objekte wie Kameras oderLichtquellen angefügt werden. Szenenknoten haben eine Position, eine Skalierung undeine Orientierung in der Szene. Ändert man z.B. die Position eines Knotens so ändertsich auch die Position der Kindknoten relativ zum aktuellen Knoten. Dies beein�usstnatürlich auch die Position der angefügten Entities.

3.1.8 Materials

Das Material -Objekt kontrolliert, wie Objekte in der Szene gerendert werden. Es spezi-�ziert, welche Ober�ächen-Eigenschaften Objekte haben, wie z.B. di�use Farbe, Glanz-farbe, Glanzstärke, wie viele Texturschichten vorhanden sind, welche Bilder als Texturendienen und wie sie miteinander kombiniert werden, welche Speziale�ekte hinzukommen,z.B. Umgebungsabbildung (Environment Mapping), wie die Texturen ge�ltert werdenusw.

Materialien können entweder durch den Programmierer im Quellcode durch Aufrufen vonSceneManager::createMaterial() und Einstellen der verschiedenen Parameter erzeugtwerden oder durch das Spezi�zieren eines Skriptes welches erst zur Laufzeit geladen wird(siehe Kapitel 4.1 auf Seite 44). Der groÿe Vorteil von Skripten liegt in der nicht mehrnotwendigen Neukompilierung des Quellcodes bei Änderung eines Skripts, da es ja erstzur Laufzeit geladen wird. So erhält man ein schnelles Feedback auf Änderungen derMaterialskripts und auch Nicht-Programmierer können Ein�uss auf das Aussehen derSzenenobjekte nehmen, da die Materialskripts leicht lesbar und verständlich sind.

Alles was die Erscheinung und das Rendern eines Objektes mit Ausnahme der Formbetri�t wird in einem Material de�niert.

29

Page 30: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Der Szenenmanager verwaltet die Hauptliste aller in einer Szene verfügbaren Materialien.Zur Liste können Materialien durch den Aufruf von SceneManager::createMaterial

oder durch das Laden eines Meshes (was zur Folge hat, das auch die zugehörigen Ma-terialien geladen werden) hinzugefügt werden. Die Eigenschaften von neuen Materialienwerden auf die von OGRE de�nierten Standardeigenschaften gesetzt oder durch dasjeweilige Materialskript festgelegt.

3.1.9 Overlays

Overlays sind 2- oder 3-dimensionale Elemente, die über die normale Szene gerendertwerden, um Benutzerinterfaces, Menüs oder Statistiken anzuzeigen. 2D-Elemente werdenfür eben genannte Objekte und 3D-Elemente werden z.B. für Cockpits oder andere 3D-Objekte genutzt, die über die normalen Szene gerendert werden.

Man kann Overlays entweder über SceneManager::createOverlay() erzeugen oderman de�niert sie in einem Overlayskript. Wobei letzteres wegen der schnellen Anpassungund Veränderung ohne Neukompilierung praktikabler ist. Auch Overlayskripts werdenerst zur Laufzeit geladen. Overlays werden mit ihrer show()-Methode zur Anzeige ge-bracht. Man kann auch mehrere Overlays gleichzeitig zeigen, wobei ihre Sichtbarkeits-reihenfolge über die Methode Overlay::setZOrder() gesetzt wird.

Die OverlayElement-Klasse abstrahiert die Details von 2D-Elementen, die zu Overlayshinzugefügt werden. Alle Elemente die zu Overlays hinzugefügt werden können, werdenvon dieser Klasse abgeleitet. Die OverlayElement-Klasse verfügt über grundlegende Ei-genschaften wie z.B. Gröÿe, Position, Materialname usw. Eigene Unterklassen könnendie Funktionalität der OverlayElement-Klasse erweitern und spezialisieren.

Eine wichtige Unterklasse von OverlayElement ist OverlayContainer. Ein OverlayContai-ner ist dasselbe wie ein OverlayElement, nur dass er wiederum andere OverlayElement-Klassen enthält und sie zu logischen Gruppen verbindet.

Wenn man ein 2D Element als ein Overlay erzeugen will, ruft man OverlayManager::-

createOverlayElement() auf. Der Typ des zu erzeugenden Elements wird durch einezu übergebende Zeichenkette de�niert. So erzeugt der Aufruf Overlay::Manager::get-Singleton().createOverlayElement(�Panel�, �new2DPanel�) eine �ache rechtecki-ge Fläche mit dem eindeutigen Namen �new2DPanel�, die weitere Overlay-Elementebeinhalten kann.

Um einen Container (wie z.B. das Panel) zu einem Overlay hinzuzufügen, ruft manOverlay::add2D() auf. Wenn man Kind-Elemente zu einem Container hinzufügen will,ruft man OverlayContainer::addChild() auf. Kind-Elemente können OverlayElements

30

Page 31: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

oder OverlayContainer sein. Die Position eines Kind-Elements ist relativ zur linken obe-ren Ecke seines Eltern-Elements.

[The06a] und [The06b]

3.2 Einrichten einer Entwicklungsumgebung und

Erstellen eines OGRE 3D-Projekts

In diesem Abschnitt wird die Einrichtung und die Kompilierung eines OGRE-Projektsinnerhalb der Visual Studio Entwicklungsumgebung von Microsoft erläutert. Die Pro-jekteinrichtung erfolgt in anderen Entwicklungsumgebungen ähnlich.

Eine im Funktionsumfang reduzierte aber kostenlose Version von Microsoft Visual Studiomit dem Namen Visual C++ Express steht kostenlos auf der Microsoft Homepage zumDownload1. Diese Version ist für die Entwicklung mit OGRE bereits geeignet. WeilVisual C++ Express auf die Erstellung von .net-Anwendungen ausgelegt ist benötigtman zusätzlich das Win32-SDK2, denn OGRE-Anwendungen laufen nicht innerhalb der.net-Runtime sondern sind klassische Win32-Anwendungen.

Man installiert Visual C++ und das Win32-SDK. Das Win32-SDK muss in die Ent-wicklungsumgebung integriert werden. Man wählt dazu im Visual C++ den Menüpunkt�Extras/Optionen� aus und markiert im linken Fensterbereich �Projekte und Projekt-mappen/VC++ Verzeichnisse�. Unter �Verzeichnisse anzeigen für� selektiert man denPunkt �Includedateien� und fügt über das entsprechende Symbol das Verzeichnis �<Pfadzum Win32-SDK>/Include� hinzu. Anschlieÿend trägt man bei �Ausführbare Dateien�das Verzeichnis �<Pfad zum Win32-SDK>/bin� und bei �Bibliotheksdateien� das Ver-zeichnis �<Pfad zum Win32-SDK>/lib� ein.Jetzt ö�net man die Datei �corewin_express.vsprops� im Verzeichnis �<Pfad zu Vi-sual C++>/VC/VCProjectDefaults� und tauscht die Zeile �AdditionalDependencies=kernel32.lib� gegen �AdditionalDependencies=kernel32.lib user32.lib

gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib

oleaut32.lib uuid.lib� aus. Anschlieÿen löscht man in der Datei �AppSettings.htm�die Kommentare in den Zeilen 441 bis 444.

Für die kommerzielle Version Visual Studio sind die obengenannten Schritte nicht nö-tig.

1http://www.microsoft.com/germany/msdn/vstudio/express/default.mspx2erhältlich unter: http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5\&displaylang=en

31

Page 32: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Nun lädt man das OGRE-SDK herunter 3 und installiert es. Um die Installation zu prü-fen, ö�net man in Visual C++ die Projektmappe �Samples_vc8� aus dem Ordner �<Pfadzum OGRE-SDK>/samples�. Dieses Projekt enthält einige OGRE-Beispielprogramme.Klickt man nun im Menü auf �Erstellen/Projektmappe erstellen� erzeugt Visual C++alle Beispiele und legt sie unter �<Pfad zum OGRE-SDK>/bin/debug� ab.

Ein eigenes OGRE-Projekt erstellt man indem man über �Projekt/Neu� und �NeueWin32-Anwendung� ein neues Projekt erzeugt. Man muss dem Projekt noch die OGRE-Verzeichnisse bekannt geben. Dazu fügt man in den �Projekteigenschaften� unter �Kon�-gurationseigenschaften� bei �C++/Allgemein� dem Punkt �Zusätzliche Include-Verzeich-nisse� den Eintrag �<Pfad zum OGRE-SDK>/include� hinzu. Genau so ergänzt manunter �Linker/Allgemein� die �Zusätzliche Bibliotheksverzeichnisse� um �<Pfad zumOGRE-SDK>/lib�, sowie unter �Linker/Eingabe� die �Zusätzliche Abhängigkeiten� umden Eintrag �OgreMain_d.lib�. Abschlieÿend muss man noch sicherstellen, dass das er-stellte Programm die Dateien aus dem Verzeichnis �<Pfad zum OGRE-SDK>/bin/debug�beziehungsweise �<Pfad zum OGRE-SDK>/bin/release� �ndet oder man kopiert die Da-teien aus diesen Verzeichnissen in die entsprechenden Verzeichnisse der eben erstelltenAnwendung. [Sch06]

3.3 Eine �Hello World�-Anwendung

Folgende exemplarische HelloWorld-Anwendung initialisiert das OGRE-Rendersystem,lädt ein Mesh mitsamt den zugehörigen Materialien und Texturen und de�niert einenBetrachter der Szene (Kamera) und eine Lichtquelle.

Man erstellt ein neues OGRE-Projekt gemäÿ den Schritten in Kapitel 3.1.9 auf Seite 31.Zuerst bindet man die OGRE-Engine über einen #include-Befehl ein:

#include <Ogre.h>

Es werden auÿerdem weitere Header für den Fehlerdialog, für EventListener und KeyE-vents benötigt. Eine ausführliche Erklärung dieser erfolgt später.

#include <OgreErrorDialog.h>#include <OgreEventListener.h>#include <OgreKeyEvent.h>

Das Benutzen des OGRE-Namensraumes, indem alle OGRE-Klassen enthalten sind,erspart viel Tipparbeit, denn sonst müsste vor jede OGRE-Klasse das Prä�x �Ogre::�

vorangestellt werden.

using namespace Ogre;

3erhältlich unter http://www.ogre3d.org

32

Page 33: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Innerhalb der main()-Funktion wird der Programmcode in einen �try/catch�-Block aus-geführt. Der Code im �catch�-Block erzeugt im Fehlerfall ein Fenster (createErrorDia-log()), das die Fehlermeldung (ermittelt über getFullDescription()) anzeigt und vom�PlattformManager� erzeugt wird, der alle betriebssystemabhängigen Elemente, wie z.B.das eben erzeugte Dialogfenster, kapselt. Als allererstes erzeugt man im �try�-Block einRoot-Objekt:

Root* mRoot = new Root("Plugins.cfg", "Ogre.cfg", "ogre.log");

Dieses Objekt stellt den Kern des OGRE-Systems dar und ist Ausgangspunkt für allesweitere (siehe Kapitel 3.1, Seite 24). Das erste Argument gibt den Pfad zu einer Kon-�gurationsdatei an, die OGRE mitteilt welche Plugins genutzt werden sollen. Pluginssind z.B. das DirectX- und auch das OpenGL-Rendersystem und verschiedene Szenen-manager. Eine beispielhafte �Plugin.cfg�-Datei sieht folgendermaÿen aus:

# Define plugin folderPluginFolder =.

# Define pluginsPlugin=RenderSystem_Direct3D9Plugin=RenderSystem_GLPlugin=Plugin_ParticleFXPlugin=Plugin_BSPSceneManagerPlugin=Plugin_OctreeSceneManagerPlugin=Plugin_CgProgramManager

Die �ogre.log�-Datei dient zum Protokollieren von OGRE-Ausgaben und Fehlermeldun-gen. In der Datei �Ogre.cfg� werden die Einstellungen OGRE-Kon�gurationsdialogesgespeichert. Diesen Dialog präsentiert man dem Benutzer mit:

mRoot ->showConfigDialog ();

Nun erstellt man ein Fenster, in das die Engine zeichnet:

RenderWindow* mWindow = mRoot ->initialise(true , "HelloWorld");

Um nun ein 3D-Modell mitsamt Materialde�nitionen und Texturen in der OGRE-Anwen-dung nutzen zu können, muss man den �ResourceManager� verwenden, der sich umsämtliche externen Daten kümmert. Um dem Ressourcenmanager ein Verzeichnis mitexternen Daten bekanntzugeben, benutzt man folgenden Funktionsaufruf:

ResourceGroupManager :: getSingleton (). addResourceLocation("<Pfad zum OGRE -SDK >\\ media \\ materials \\ scripts","FileSystem");

Der zweite Parameter �FileSystem� gibt an, dass es sich beim ersten Parameter um einVerzeichnis handelt. Alternativ kann man auch externe Daten wie 3D-Modelle, Materia-lien und Texturen in ZIP-Archive packen. Dann würde der zweite Parameter �Zip� sein.

33

Page 34: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Man muss noch 3 weitere Pfade für dieses Beispiel angeben, siehe dazu den Quellcode aufSeite 82. Nachdem dem Ressourcenmanager alle Verzeichnisse bekanntgegeben wurden,initialisiert man den Datenbestand mit:

ResourceGroupManager :: getSingleton (). initialiseAllResourceGroups ();

Um nun 3D-Modelle im Raum zu platzieren benötigt man einen Szenenmanager, dersich um alle szenenrelevanten Objekte kümmert:

SceneManager* mSceneManager = mRoot ->createSceneManager(ST_GENERIC );

Jetzt erzeugt man ausgehend von einem dem OGRE-SDK beiliegenden Mesh ein kon-kretes Objekt, das man in der Szene platzieren kann:

Entity* mOgreEntity = mSceneManager ->createEntity("OgreEntity1","ogrehead.mesh");

Mit dieser Zeile wurde ein Entity mit dem eindeutigen Namen �OgreEntity1� aus derMesh-Datei �ogrehead.mesh� erzeugt. Man kann über den Namen jederzeit einen Ver-weis auf das entsprechende OGRE-Objekt bekommen, z.B. über mSceneManager->get-MovableObject(<Name>). Um die Darstellung des Objekts mit der passenden Texturkümmert sich OGRE automatisch, wenn die �.mesh�-Datei den zugehörigen Materialna-men enthält und der Ressourcenmanager diesen bereits in einer eingelesenen Material-datei entdeckt hat und ihm auch alle benötigten Texturen zur Verfügung stehen. Bisherist das Entity aber noch nicht sichtbar. Es muss erst an einen Szenenknoten gehängtwerden. Dazu erzeugt man ein SceneNode-Objekt mit einem eindeutigen Namen undeiner Position in der Szene und verbindet anschlieÿend den Szenenknoten und das zuvorerstellte Entity:

SceneNode* mOgreSceneNode = mSceneManager ->getRootSceneNode ()->createChildSceneNode("Ogre1Node", Vector3 (0,0,0));

mOgreSceneNode ->attachObject(mOgreEntity );

Der neue Szenenknoten ist ein Kindknoten des bereits existierenden Wurzelknotens(�RootSceneNode�). Neue Szenenknoten können entweder an den Wurzelknoten oderan bestehende Szenenknoten anghängt werden um hierarchische Beziehungen der Kno-ten zu erzeugen. Jetzt be�ndet sich das Objekt zwar in der Szene aber es ist aufgrundeiner fehlenden Beleuchtung noch unsichtbar. Das Hintergrundlicht (�AmbientLight�)setzt man auf einen geringen Grauwert:

mSceneManager ->setAmbientLight(ColourValue (0.1 ,0.1 ,0.1 ,1));

Und man erzeugt ein Licht mit der Position (-80, 80, 200) und dem Namen �Light1�:

Light* mLight = mSceneManager ->createLight("Light1");mLight ->setPosition (-80, 80, 200);

34

Page 35: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Es fehlt nur noch eine Kamera, die die Szene aufnimmt:

Camera* mCamera = mSceneManager ->createCamera("Camera1");

Man stellt sie an der Position (40, 40, 100) auf und lässt sie auf den Koordinatenursprungschauen:

mCamera ->setPosition(Vector3 (40 ,40 ,100));mCamera ->lookAt (0,0,0);

Das vom Standpunkt der Kamera aus erzeugte Bild muss nun in einem �Viewport� zurAnzeige gebracht werden:

Viewport* mViewport = mWindow ->addViewport(mCamera );

Welcher normalerweise das gesamte Fenster ausfüllt:

mCamera ->setAspectRatio(Real(mViewport ->getActualWidth ()) /Real(mViewport ->getActualHeight ()));

Um die Anwendung auf Tastendruck beenden zu können, benötigt man noch die selbst-geschriebene Klasse Keyboard:

Keyboard* mKeyboard = new Keyboard ();

Diese Klasse vereint die Interfaces sogenannter FrameListener (siehe auch Kapitel 3.4auf Seite 37 und KeyListener, deren Methoden wie z.B. FrameListener::frameEnded()werden nach jedem gezeichneten Bild oder KeyListener::keyClicked bei jeder ge-drückten Taste aufgerufen. Die Klasse muss beim Root-Objekt registriert werden:

mRoot ->addFrameListener(mKeyboard );

Auÿerdem muss ein EventProcessor initialisiert werden, der die Ereignisse von gedrück-ten Tasten an die Keyboard-Klasse weiterleitet:

EventProcessor* mEventProcessor = new EventProcessor ();mEventProcessor ->addKeyListener(mKeyboard );mEventProcessor ->initialise(mWindow );mEventProcessor ->startProcessingEvents

Zum Abschluss startet man die OGRE-Renderschleife mit:

mRoot ->startRendering ();

Im Anschluss erfolgt die De�nition der Keyboard-Klasse. Sie wird von den OGRE-Klassen FrameListener und KeyListener abgeleitet:

35

Page 36: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

class Keyboard : public KeyListener , public FrameListener{// Öffentliche Methodenpublic:

Keyboard ();virtual void keyClicked(KeyEvent* e);virtual void keyPressed(KeyEvent* e);virtual void keyReleased(KeyEvent* e);virtual void frameEnded(const FrameEvent& evt);

// private Variablenprivate:

bool EscWasPressed; // wurde ESC -Taste gedrückt}

Der Konstruktor setzt die private Variable auf false:

Keyboard :: Keyboard () : mEscWasPressed(false) {}

Die KeyClicked()-Methode wird bei jedem Tastendruck aufgerufen:

void Keyboard :: keyClicked(KeyEvent* e){

// Falls ESC -Taste gedrückt wurdeif(e->getKey () == KC_ESCAPE{

// Setze Variable auf truemEscWasPressed = true;

// Ereignis wurde verarbeitete->consume ();

}}

In den beiden anderen Keyboard-Methoden geschieht nichts. Sie müssen aber überschrie-ben werden:

void Keyboard :: keyPressed(KeyEvent* e) {}void Keyboard :: keyReleased(KeyEvent* e) {}

In der frameEnded()-Methode wird nach jedem Frame überprüft, ob die mEscWasPressed-Variable gesetzt wurde. Wenn ja, dann liefert die Methode false zurück und das Pro-gramm wird automatisch beendet.

bool Keyboard :: frameEnded(const FrameEvent& evt){

return !mEscWasPressed;}

36

Page 37: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Abbildung 3.2: Das HelloWorld-Renderfenster

Man sollte nun nach dem Starten des Programms und der Wahl der OGRE-Optionenim Kon�gurationsdialog ein Renderfenster ähnlich der Abbildung 3.2 auf Seite 37 sehen.Der vollständige Quellcode ist auf Seite 82 zu �nden. [Sch06]

3.4 FrameListener

In der bisherigen �HelloWorld�-Anwendung konnte man bisher nur einmal zu Beginnder Anwendung Ein�uss auf die Szene nehmen. Nachdem Root::startRendering()

aufgerufen wurde, be�ndet sich die Anwendung in der Renderschleife. FrameListenerimplementieren ein Interface, das die Methoden frameStarted() und frameEnded()

zur Verfügung stellt. Die OGRE-Renderschleife sieht läuft folgendermaÿen ab:

• Das Root-Objekt ruft die frameStarted()-Methode aller registrierten FrameLis-tener auf

• Das Root-Objekt rendert das aktuelle Bild

• Das Root-Objekt ruft die frameEnded()-Methode aller registrierten FrameListenerauf

Die Schleife läuft solange, bis entweder eine frameStarted()- oder eine frameEnded()-Methode false zurückgibt (z.B. als Reaktion auf einen Tastendruck). Die beiden Me-thoden sind in der Klasse FrameListener virtuell, d.h. man muss immer eigene Klas-sen davon ableiten, die eine konkrete Implementierung für diese Methoden enthalten.Konkrete FrameListener müssen über Root::addFrameListener() beim Root-Objektregistriert werden. Folgender Quellcodeausschnitt zeigt einen konkreten FrameListener,dem ein Verweis auf eine Animation als Konstruktorparameter übergeben wird und der

37

Page 38: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

am Anfang jedes Bildes den Fortschritt der Animation um die seit dem letzten Aufrufvon frameStarted() vergangene Zeitspanne erhöht (siehe auch Kapitel 5.3 Animationin OGRE 3D auf Seite 67):

class AnimListener: public FrameListener{protected:public:

// Der Konstruktor mit Verweis auf eine AnimationAnimListener(AnimationState* animState){

mAnimState = animState;}

bool frameStarted(const FrameEvent& evt){

// Vergangene Zeit seit dem letzten Bild addierenmAnimState ->addTime(evt.timeSinceLastFrame );

}

protected:// Der Verweis auf die AnimationAnimationState* mAnimState;

};

Man könnte dasselbe Verhalten auch in frameEnded() implementieren. Auÿerdem ist esdem Anwendungsentwickler überlassen, einen groÿen FrameListener zu schreiben oderdie Funktionalität auf mehrere kleinere FrameListener aufzuteilen. Zu beachten ist da-bei nur, dass man nicht vorhersagen kann, in welcher Reihenfolge OGRE die einzelnenFrameListener aufruft.

Im Programm muss nun eine konkrete FrameListener-Instanz erzeugt und beim Root-Objekt registriert werden:

// Zeiger auf eine Animation , muss noch initialisiert werdenAnimationState* animState;...

// Aufrufen des Konstruktors mit der Animation als ParameterAnimListener* animListener = new AnimListener(animState );

// Registrieren des FrameListenersmRoot ->addFrameListener(animListener );

Die Klasse ExampleFrameListener bietet bereits eine beispielhafte Implementation ei-nes FrameListeners und realisiert die Steuerung der Kamera über Maus- und Tastaturein-gaben. Die Klasse ist in der Datei <Pfad zum OGRE-SDK>/samples/include/Example-FrameListener.h de�niert.

38

Page 39: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3.5 Ein interaktives Beispiel: Kamera- und

Charaktersteuerung

Dieses Beispiel erweitert die HelloWorld-Anwendung um eine interaktive Kamerasteue-rung und um eine interaktive Steuerung eines Charakters über die Tastatur. Die Tas-tatureingaben werden dabei gepu�ert verarbeitet, d.h. sobald eine Taste gedrückt wird,wird über einen KeyListener automatisch ein KeyListener::keyPressed-Ereignis aus-gelöst. Sobald die Taste losgelassen wird, wird ein KeyListener::keyReleased-Ereignisausgelöst. Diese Methode hat gegenüber ungepu�erter Eingabe den Vorteil, dass nichtin jedem Bild der komplette momentane Status der Tastatur abgefragt werden muss,sondern nur auf einzelne Ereignisse reagiert werden muss.

Die Verschiebung der Kamera erfolgt über die Pfeiltasten und die Drehung über dieTasten W, A, S und D. Der Charakter wird über die Pfeiltasten auf dem Nummernblockbewegt.

3.5.1 Kamerasteuerung

Zur Kamerasteuerung werden einige neue Variablen benötigt, die am Anfang der Quell-codedatei als globale Variablen deklariert werden:

SceneNode* mCameraNode; // Szenenknoten der KameraVector3 mTranslateVector = Vector3 ::ZERO; // VerschiebungsvektorRadian mRotX = Radian (0); // Rotation um die X-AchseRadian mRotY = Radian (0); // Rotation um die Y-Achseconst Real mMoveScale = 150; // Geschw. der Bewegungconst Degree mRotScale = Degree (60); // Geschw. der Rotation

Innerhalb der main()-Methode wird die Kamera an einen Szenenknoten angefügt und aufdie Startposition (40, 40, 100) gesetzt. Abschlieÿend wird die Kamerablickrichtungauf den Koordinatenursprung gesetzt:

Camera* mCamera = mSceneManager ->createCamera("Camera1");mCamera ->setNearClipDistance (5);

// Erstellen eines Szenenknotens für die KameramCameraNode = mSceneManager ->getRootSceneNode ()->

createChildSceneNode("CameraNode", Vector3(0, 0, 0));

// Kamera anhängenmCameraNode ->attachObject(mCamera );

// Auf Startposition setzenmCameraNode ->translate (40, 40, 100);

39

Page 40: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

// Blickrichtung auf KoordinatenursprungmCameraNode ->setDirection(-mCameraNode ->getPosition ());

Die Tastaturabfrage wird in der Methode Keyboard::keyPressed() durchgeführt. Da-bei wird immer geprüft, welche Taste gedrückt wurde und dementsprechend eine Kompo-nente des Vektors mTranslateVector um den in mMoveScale de�nierten Betrag erhöhtoder verringert wird:

void Keyboard :: keyPressed(KeyEvent* e){

// vor und zurückif (e->getKey () == KC_UP)

mTranslateVector.z -= mMoveScale;if (e->getKey () == KC_DOWN)

mTranslateVector.z += mMoveScale;

// links und rechtsif (e->getKey () == KC_LEFT)

mTranslateVector.x -= mMoveScale;if (e->getKey () == KC_RIGHT)

mTranslateVector.x += mMoveScale;

// hoch und runterif (e->getKey () == KC_PGUP)

mTranslateVector.y += mMoveScale;if (e->getKey () == KC_PGDOWN)

mTranslateVector.y -= mMoveScale;

// Rotation um X-Achseif (e->getKey () == KC_A)

mRotX += mRotScale;if (e->getKey () == KC_D)

mRotX -= mRotScale;

// Rotation um Y-Achseif (e->getKey () == KC_W)

mRotY -= mRotScale;if (e->getKey () == KC_S)

mRotY += mRotScale;}

Auÿerdem muss die Veränderung des Bewegungsvektors und der Rotationsvariablenbeim Loslassen der entsprechenden Taste rückgängig gemacht werden um die Bewegungwieder zu stoppen. Dies geschieht in der Methode Keyboard::keyReleased() einfachdurch Vertauschen der Vorzeichen bei der Zusweisung der Werte:

void Keyboard :: keyReleased(KeyEvent* e){

// vorzurückif (e->getKey () == KC_UP)

40

Page 41: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

mTranslateVector.z += mMoveScale;if (e->getKey () == KC_DOWN)

mTranslateVector.z -= mMoveScale;

// Für die anderen Richtungen analog...

// rotxif (e->getKey () == KC_W)

mRotY += mRotScale;if (e->getKey () == KC_S)

mRotY -= mRotScale;

...}

Abschlieÿend wird der Kameraszenenknoten und damit auch die Kamera entsprechendverschoben. Dies geschieht einmal pro Bild in der Keyboard::frameStarted()-Methode.Zuerst wird die Rotation um die X- und Y-Achse zugewiesen:

bool Keyboard :: frameStarted(const FrameEvent& evt){

mCameraNode ->yaw(mRotX * evt.timeSinceLastFrame );mCameraNode ->pitch(mRotY * evt.timeSinceLastFrame );

Nun wird die Kamera entsprechend ihrer Blickrichtung um den aus mTranslateVectorbekannten Betrag verschoben, wobei die ganze Verschiebung durch die vergangene Zeitseit dem letzten Bild (evt.timeSinceLastFrame) skaliert wird:

mCameraNode ->translate(mCameraNode ->getOrientation () *mTranslateVector * evt.timeSinceLastFrame );

return true;}

3.5.2 Charaktersteuerung

Zur Steuerung des Charakters werden ebenfalls einige globale Variablen benötigt:

SceneNode* mOgreSceneNode; // Der Charakter -SzenenknotenAnimationState* mAnimWalk; // Die Lauf -AnimationAnimationState* mAnimIdle; // Die Warte -AnimationVector3 mRobotTranslate = Vector3 ::ZERO; // VerschiebungsvektorRadian mRobotRot = Radian (0); // Rotationsvariable

In der main()-Methode wird nun statt dem Ogre-Kopf der Roboter-Charakter aus derDatei robot.mesh geladen:

41

Page 42: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Entity* mOgreEntity = mSceneManager ->createEntity("OgreEntity1","robot.mesh");

Es werden die beiden Animationen in die jeweiligen Variablen geladen:mAnimWalk = mOgreEntity ->getAnimationState("Walk");mAnimIdle = mOgreEntity ->getAnimationState("Idle");

Die beiden Animationen sollen als Schleife durchlaufen werden und die Warte-Animationwird aktiviert:mAnimWalk ->setLoop(true);mAnimIdle ->setLoop(true);mAnimIdle ->setEnabled(true);

Die Steuerung des Roboters wird in der keyPressed()-Methode ähnlich der Kamera-steuerung realisiert. Zusätzlich wird bei jedem Tastendruck jeweils die Warte-Animationdeaktiviert und die Lauf-Animation aktiviert:if(e->getKey ()== KC_NUMPAD8)

{// Verschiebungsvektor setzenmRobotTranslate.x += mMoveScale / 4;

// Warte -Animation deaktivierenmAnimIdle ->setEnabled(false );

// Lauf -Animation aktivierenmAnimWalk ->setEnabled(true);

}if(e->getKey ()== KC_NUMPAD2){

mRobotTranslate.x -= mMoveScale / 4;mAnimIdle ->setEnabled(false );mAnimWalk ->setEnabled(true);

}if(e->getKey ()== KC_NUMPAD4){

mRobotRot += mRotScale;mAnimIdle ->setEnabled(false );mAnimWalk ->setEnabled(true);

}if(e->getKey ()== KC_NUMPAD6){

mRobotRot -= mRotScale;mAnimIdle ->setEnabled(false );mAnimWalk ->setEnabled(true);

}

Beim Loslassen der Taste müssen die Änderungen am Verschiebungsvektor und an derRotationsvariablen zurückgesetzt werden und jeweils wieder die Lauf-Animation deak-

42

Page 43: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

tiviert und die Warte-Animation aktiviert werden:

if(e->getKey ()== KC_NUMPAD8){

mRobotTranslate.x -= mMoveScale / 4;mAnimIdle ->setEnabled(true);mAnimWalk ->setEnabled(false );

}

...

if(e->getKey ()== KC_NUMPAD6){

mRobotRot += mRotScale;mAnimIdle ->setEnabled(true);mAnimWalk ->setEnabled(false );

}

Jetzt muss man nur noch in der frameStarted()-Methode die Animationen um diejeweils seit dem letzten Bild vergangene Zeit weiterlaufen lassen und den Roboter dengemachten Eingaben entsprechend rotieren und bewegen:

// Animation updatenmAnimIdle ->addTime(evt.timeSinceLastFrame );mAnimWalk ->addTime(evt.timeSinceLastFrame );

// Roboter rotierenmOgreSceneNode ->yaw(mRobotRot * evt.timeSinceLastFrame );

// Roboter verschiebenmOgreSceneNode ->translate(mOgreSceneNode ->getOrientation () *

mRobotTranslate * evt.timeSinceLastFrame );

Als Ergebnis erhält man eine interaktive Anwendung mit Kamera- und Charaktersteue-rung wie in Abbildung 3.3 auf Seite 43 zu sehen ist. Der komplette Quellcode ist inAnhang A.2 auf Seite 85 zu �nden.

Abbildung 3.3: Das Renderfenster der interaktiven Anwendung

43

Page 44: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4 Das OGRE 3D-Skriptsystem

Im heutigen Anwendungsentwicklungsprozess teilt sich das Entwicklungsteam meist inProgrammierer und Artists (3D-Modellierer, Textur-Ersteller usw.) auf. Das OGRE-Skriptsystem ermöglicht es, Anwendungsinhalte ohne Neukompilation zu verändern undbietet eine einfache Schnittstelle, um auch Nichtprogrammierern Ein�uss auf die An-wendung zu nehmen. Die Funktionalität, die durch Skripte bediet werden, können auchdurch Methodenaufrufe fest im Quelltext programmiert werden, aber dies sollte eher dieAusnahme sein. Alle OGRE-Skripte werden bei der Programminitialisierung geladen.

4.1 Material-Skripte und Shader

Materialskripte sind die wohl mächtigsten OGRE-Skripte, bestimmen sie doch die kom-plette Darstellung der zu rendernden Objekte. Die Skripte werden in einem C++ ähnli-chen Pseudoformat geschrieben. Es können mehrere Materialien in einem Skript de�niertwerden jedoch müssen alle Skripte einen global eindeutigen Namen haben. Materialienkönnen von anderen bereits de�nierten Materialien mit dem Doppelpunkt : kopiertwerden. Dabei überschreibt man im neuen Material nur die veränderten Eigenschaften(ähnelt der Vererbung in C++). Jedes Material enthällt mindestens eine Technique,welche wiederum mindestens einen Pass enthält.

4.1.1 Techniques

Eine Technique stellt eine Möglichkeit zur Verfügung ein Objekt zu rendern. Eine einfa-che Materialde�niton enthält also nur eine Technique. Da die heutige Gra�kkarten sichstark in ihrer Leistungsfähigkeit unterscheiden, kann man das nur tun, wenn man sicherist, dass sich das Material von allen Gra�kkarten auch darstellen lässt. Aufgrund des-sen ist es ratsam, weitere Techniques mit einfacheren Anforderungen an die Hardwarein einem Material zu de�nieren. OGRE wählt dann automatisch die beste Technique,die von der Hardware unterstützt wird. Auÿerdem kann man Techniques eine Distanzzuweisen, sodass weiter entfernte Objekte mit einfacheren Techniques gerendert werden,um eine bessere Performance zu erzielen.

44

Page 45: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Techniques können über die Eigenschaft scheme einem Renderschema zugeordnet wer-den. Durch die De�nition von z.B. den 3 Schemas �Hoch�, �Mittel� und �Niedrig� kannman die Anwendung schnell an die vorhandene Hardware anpassen. Wobei bei der Ein-stellung �Hoch� alle Objekte mit den bestmöglichen Techniques gerendert werden (, diemit der Eigenschaft scheme Hoch de�niert sind) und bei �Niedrig� auf weniger perfor-mancehungrige Techniques zurückgegri�en wird.Die Eigenschaft lod_index weist eine Technique einer Entfernung zu, die im Materi-al über die Eigenschaft lod_distance de�niert wurde. Dies ermöglicht eine wenigerrechenintensive Technique für weiter enfternte Objekte.

4.1.2 Passes

Ein Pass ist ein Renderdurchlauf für ein Objekt mit festgelegten Rendereinstellungen.Eine Technique kann bis zu 16 Passes beinhalten. Je mehr Passes, desto aufwendiger wirddie Berechnung. Passes enthalten Attribute, Textureinheiten und eventuell Verweise aufVertex- und Pixelshader (siehe Kapitel 4.1.3 auf Seite 47).

Hier folgt eine auszugsweise Beschreibung der möglichen Attribute in einem Pass. Fürausführliche Informationen siehe [The06b].

Allgemeine Attribute

Das Attribut scene_blend legt fest, wie der Pass mit bereits gerenderten Inhalten derSzene überblendet wird.Über depth_check bestimmt man, ob der Tiefenbu�er1 vor dem Rendern überprüft wird.depth_write bestimmt, ob das aktuelle Objekt in den Tiefenbu�er schreibt. Overlay-Elemente, wie z.B. Menüs oder Buttons, sollten nicht in den Tiefenbu�er schreiben.cull_hardware bestimmt, ob die Hardware Flächen aufgrund der Anordnung ihrer Ver-tizes vom Rendering ausschlieÿt. Sind die Vertizes von der Kamera aus gesehen imUhrzeigersinn angeordnet und ist das Atribut auf clockwise gesetzt, so werden sie vomRendering ausgeschlossen. Ist das Attribut auf none gesetzt, so werden die Flächen vonbeiden Seiten gezeichnet, was z.B. bei durchsichtigen Objekten sinnvoll ist. Das Attri-but polygon_mode bestimmt, wie das Objekt gerendert wird. solid rendert das Objektnormal, wireframe rendert nur die Auÿenlinien der Flächen (als Drahtgitter) und point

rendert nur die Punkte des Polygons.Das Attribut iteration bestimmt, ob der Pass mehrfach gerendert werden soll. Auÿer-dem kann mit dem Setzen des Attributes auf once_per_light der Pass für jedes Lichtdurchlaufen werden.

1Der Tiefenbu�er (auch Z-Bu�er genannt) enthält die Tiefeninformation bereits gerenderter Objekte.Liegt das aktuelle Objekt hinter einem bereits gezeichneten wird es nicht gerendert.

45

Page 46: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Attribute für die Fixed-Function Pipeline

Folgende Attribute haben nur Auswirkungen auf das Renderergebniss solange die Fixed-Function Pipeline von OGRE benutzt wird. Bei Verwendung Shadern haben diese keineAuswirkungen.

Die Attribute ambient2, diffuse3, specular4 und emissive5 beschreiben die entspre-chenden Farben des Materials.Über das Attribut lighting aktiviert und deaktiviert die dynamische Beleuchtung.Über shading legt man auÿerdem fest, ob das Objekt flat-6, gouraud-7 oder phong-8schattiert wird.

Textureinheiten

Das Attribut texture bestimmt über einen Dateinamen, welche Textur verwendet wirdund um welchen Texturtyp es sich dabei handelt. Unterstützte Typen sind 1d (eine Tex-tur, die nur einen Pixel hoch ist, nützlich in Shadern, wenn man eine aufwendige Funk-tion vor der Laufzeit in eine Textur kodiert, eine sogenannte Look-Up Tabelle), 2d (einenormale Textur), 3d (eine Volumentextur, also mehrere 2D-Texturen, die über dreidi-mensionale Texturkoordinaten in Shadern adressiert werden, z.B. nützlich für animierteTexturen) und cubic(zusammengesetzte Textur aus 6 zweidimensialen Texturen, die aufdie Innenseiten eines Würfels projiziert werden, wird z.B. für Umgebungs-Mapping ver-wendet).tex_adress_mode steuert wie die Textur wiederholt wird. Mögliche Werte sind wrap

(Textur wird wiederholt), clamp (Ende der Textur wird �breitgezogen�), mirror (Texturwird an den Rändern gespiegelt) und border (Textur wird an den Ränder auf eine mittex_border_colour de�nierte Farbe gesetzt).Wie eine Textur aus bestimmten Betrachtungswinkeln und beim Übergang zweier MIP-Stufen ge�ltert wird, bestimmt das Attribut filtering. Mögliche Werte in qualitativaufsteigender Reihenfolge sind none(es wird keine Filterung vorgenommen und auchkein MIP-Mapping angewendet), bilinear(Textur wird über einen 2x2-Filter interpo-liert und es wird eine MIP-Stufe ausgewählt, aber nicht zwischen zwei Stufen überblen-det), trilinear(wie bilinear, nur das hier zwei MIP-Stufen überblendet werden) und

2Die ambiente Farbe bestimmt die Grundfarbe des Objekts ohne Beleuchtung.3Die di�use Farbe bestimmt die Farbe des Objekts, die durch einfallendes Licht re�ektiert wird.4Die spekulare Farbe bestimmt die Glanzfarbe des Objekts.5Die emissive Farbe bestimmt die Farbe mit der das Objekt unabhängig von Lichtquellen oder am-bienten Farbeinstellungen gezeichnet wird.

6Jede Objekt�äche wird mit einer Farbe gezeichnet. Diese wird nicht interpoliert.7Die Farbe jedes Vertex wird linear über die Fläche interpoliert.8Die Vertexnormalen werden über die Fläche interpoliert und somit die Farbe pro Pixel berechnet.Dies ergibt ein realistischeres Ergebniss bei höherem Berechnungsaufwand.

46

Page 47: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

anisotropic(wie trilinear, nur das hier der wirkliche Anstieg der Fläche zur Filterungherangezogen wird und nicht nur ein einfacher 2x2-Filter verwendet wird).Für weitere Attribute, insbesondere zum Animieren der Texturen, siehe [The06b].

4.1.3 Shader in OGRE 3D

Ein Shader ist ein kleines Programm, um die �nalen Ober�ächeneigenschaften eines 3D-Modells oder Bildes zu berechnen. Aufgrund ihrer Natur sind sie sehr gut für paralleleBerechnung geeignet. Mehrere parallele Prozessoren auf aktuellen Gra�kkarten berech-nen somit mehrere Dreiecke und die resultierenden Pixel gleichzeitig. Shader sind inspeziellen Programmiersprachen geschrieben und ersetzen grundlegende Funktionen dertraditionellen Fixed-Function-Pipeline wie z.B. Transformationen, Beleuchtung und Tex-turoperationen. Dabei gibt es auf der Gra�kkarte mehrere Vertex-Einheiten, die Vertex-Shader (wird für jedes Vertex des zu rendernden Objekts einmal ausgeführt) und mehrerePixel-Einheiten, die Pixel-Shader (wird für jedes auf dem Bildschirm sichtbare Pixel ein-mal ausgeführt.OGRE bietet volle Unterstützung für Vertex- und Pixelshader bis zum aktuellen Sha-dermodell 3.0. Somit sind alle modernen Beleuchtungs-(z.B. PerPixel-Lighting, Bump-,Normal- und Parallax Mapping) und Materialsimulationen(z.B. Wasser- und Glasmate-rialien) und E�ekte (z.B. High Dynamic Range Rendering, Nebel und Tiefenunschärfe)in OGRE möglich. Die Shader können in Assembler, DirectX9 HLSL, OpenGL GLSLoder in Cg vorliegen.

Deklarieren von Shadern

Shader müssen erst in einem Skript deklariert werden, bevor sie von einem Materi-al benutzt werden können. Dies kann entweder in dem entsprechenden Materialskriptdirekt oder in einer .program-Datei geschehen. Die Deklaration umfasst einen eindeu-tigen Namen, den Dateinamen des Shaderquellcodes und für welches Shadermodell derShader kompiliert werden soll. Folgendes Beispiel deklariert einen HLSL Vertexshadermit dem Namen �PerPixelLighting.Vertex_Shader�, der aus der Datei �PerPixelLight-ning.Vertex_Shader.source� geladen und für das Shadermodell 2.0 kompiliert wird:

vertex_program PerPixelLighting.Vertex_Shader hlsl{

source PerPixelLightning.Vertex_Shader.sourcetarget vs_2_0entry_point vs_main

default_params{

param_named_auto lightPosition light_position_object_space 0

47

Page 48: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

param_named_auto eyePosition camera_position_object_spaceparam_named_auto worldViewProj worldviewproj_matrixparam_named shininess float 10

}}

Der optionale default_params-Abschnitt de�niert Defaultwerte für an den Shader zuübergebende Parameter. Diese können dann später im Materialskript überschrieben wer-den. Diese Vorgehensweise hält die Materialde�nition schlanker, so werden sich z.B. ver-schiedenen Variationen eines Materials, das den obengenannten Shader benutzt, nur indem Parameter shininess unterscheiden.

Shader in einem Material-Pass verwenden

Innerhalb eines Passes in einem Materialskript kann man Vertex- und Pixelshader, diezuvor in einem Skript deklariert wurden, referenzieren:

vertex_program_ref PerPixelLighting.Vertex_Shader{

param_named_auto worldViewProj worldviewproj_matrixparam_named shininess float 20

}

Hier wird der Vertexshader �PerPixelLighting.Vertex_Shader� aufgerufen und zwei Pa-rameter übergeben, die eventuelle Defaultparameter überschreiben. Parameter könnenüber einen Namen (param_named) oder über einen Index (param_indexed übergebenwerden. Wobei der Index sich auf die Reihenfolge der Variablendeklaration innerhalb desShaders bezieht und in 4-Element-Blöcken angeordnet ist. Wenn man z.B. eine �oat4-Variable an Index 0 deklariert hat, so be�ndet sich die nächste �oat4-Variable an Index 1,wenn man eine 4x4-Matrix an Index 0 deklariert hat, so be�ndet sich die nächste Variablean Index 4 usw. Die Übergabe mit Namen ist also einfacher zu benutzen. Es gibt eine Rei-he von Variablen, die OGRE zu Verfügung stellt und automatisch aktualisiert. Dazu zäh-len z.B. verschiedenen Transformationsmatrizen (z.B. world_matrix, view_matrix,

projection_matrix usw.), Lichtquelleneigenschaften (z.B. light_position, light_-

direction, light_diffuse_colour usw.), Kameraeigenschaften (z.B. camera_po-

sition) und Variablen, die sich über die Zeit verändern, um Animationen zu reali-sieren.Die Übergabe der Lichtquellenposition an den Shader in die Variable mit Namen �light-Pos� geschieht folgendermaÿen:

param_named_auto lightPos light_position 0

Dasselbe nur als Übergabe mit Index:

param_indexed_auto 0 light_position 0

48

Page 49: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Die abschlieÿende 0 gibt an, dass die Position der dem Objekt nächsten Lichtquelleübergeben wird. Höhere Werte beziehen sich dann auf weiter entfernte Lichtquellen.

Shader und Schatten

Wenn man Schatten benutzt, kann es zu einigen Schwierigkeiten in Kombination mitVertexshadern kommen, da diese die Geometrie des Objekts verändern können, dasOGRE-Schattensystem aber keinen Zugri� auf diese Veränderungen hat.

Wenn man Stencil-Schatten benutzt, so sollte man nur skeletale Animation einsetzen,denn jede andere Geometriedeformation hat keine Auswirkung auf den berechnetenSchatten. Man kann dann nur akzeptieren, dass der Schatten nicht korrekt zur geren-derten Geometrie passt oder auf Schattenberechnung ganz verzichten (es sei denn, manrealisiert die Schattenberechnung ebenfalls in einem Shader, was aber ein sehr komplexesGebiet ist).

Wenn man Textur-Schatten benutzt, sind Geometriedeformationen kein Problem.

4.1.4 Ein einfacher Beispielshader

Im folgenden Beispiel wird ein einfacher Shader erarbeitet, der ein 3D-Modell durchdi�uses Licht einer Punktlichtquelle beleuchtet und das Ergebnis mit einer Textur ver-sieht. Der Shader wird in HLSL für das Shadermodell 2.0 geschrieben. Da die Licht-berechnung im Vertexshader geschieht spricht man auch von PerVertex-Lighting. Dasgenauere PerPixel-Lighting würde es erfordern, dass die Lichtberechnungen im Pixels-hader ausgeführt werden, was aber zu einer schlechteren Performance führt.

Der Vertex-Shader

Zuerst de�niert man, welche Informationen des zu rendernden Objektes dem Shader alsEingabe dienen. Für den Beispielshader benötigen wir die Position, die Normale und dieTexturkoordinate des aktuellen Vertex;

struct VS_INPUT{

float4 Pos: POSITION;float3 Normal: NORMAL;float2 Txr: TEXCOORD0;

};

49

Page 50: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Die Ausgabe des Vertexshaders ist zugleich Eingabe des Pixelshaders und umfasst die(transformierte) Position, die Texturkoordinaten und die berechnete Lichtintensität:

struct VS_OUTPUT{

float4 Pos: POSITION;float2 Txr: TEXCOORD0;float4 Color: COLOR0;

};

Auÿerdem müssen folgende Variablen deklariert werden, deren Werte von der Anwen-dung (in diesem Falle das OGRE-System) bereitgestellt werden müssen:

float4x4 matViewProjection; // Transformationsmatrixfloat4 viewPosition; // Die Position des Betrachtersfloat4 LightAmbient; // Das ambiente Lichtfloat4 LightPos; // Position der Lichtquellefloat4 LightColor; // Farbe der Lichtquelle

Für die Lichtberechnung wird der Übersichtlichkeit wegen eine Funktion de�niert, dieaus der Vertex-Position und -Normalen und der Lichtposition und -farbe die Intensitätdes re�ektierten Lichtes auf dem 3D-Modell berechnet:

float4 Light_PointDiffuse(float3 VertPos , float3 VertNorm ,float3 LightPos , float4 LightColor)

{// Berechne die Richtung aus der das Licht auf den Vertex trifft und// normalisiere diesen Vektorfloat3 LightDir = normalize(LightPos - VertPos );

// Berechne die Lichtintensität bezüglich des Winkels zwischen// der Lichtrichtung und der Vertex -Normalen über das Punktproduktfloat AngleAttn = dot(VertNorm , LightDir );

// Da dieser Wert negativ werden kann , muss er auf den Wertebereich// [0, 1] beschnitten werdenAngleAttn = clamp(0, 1, AngleAttn );

// Berechne finale Beleuchtungsintensitätreturn LightColor * AngleAttn;

}

Nun folgt der eigentliche Vertexshader-Code:

VS_OUTPUT vs_main(VS_INPUT In){

VS_OUTPUT Out;

// Berechne die in den Bildschirmraum projizierte Position des VertexOut.Pos = mul(matViewProjection , In.Pos);

50

Page 51: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

// Leite Texturkoordinaten unverändert weiterOut.Txr = In.Txr;

// Das ambiente Licht definiert den Grundanteil der Lichtintensitätfloat4 Color = LightAmbient;

// Berechne Lichtintensität durch die zuvor definierte FunktionColor += Light_PointDiffuse(In.Pos , In.Normal ,

LightPos , LightColor );

// Gib berechnete Farbe an den Pixelshader weiterOut.Color = Color;

return Out;}

Der Pixel-Shader

Der Pixelshader benötigt als Eingabe nur die Texturkoordinaten und die berechneteLichtintensität. Da ein Vertex eher selten genau einem Pixel auf dem Bildschirm ent-spricht, werden die berechneten Werten zwischen verschiedenen Vertizes interpoliert.

struct PS_INPUT{

float2 Txr: TEXCOORD0;float4 Color: COLOR0;

};

Als Variable wird nur noch eine Textur benötigt:

sampler Texture0;

Der Pixelshader hat folgenden einfachen Aufbau:

float4 ps_main(PS_INPUT In){

// Die endgültige Farbe des aktuellen Pixels ergibt sich aus// der interpolierten Lichtintensität , die im Vertexshader// berechnet wurde multipliziert mit dem Farbwert der Texturfloat4 finalColor = In.Color * tex2D(Texture0 , In.Txr);

// Die berechnete Farbe wird ausgegebenreturn finalColor;

}

Die Abbildung 4.1 auf Seite 52 zeigt den Shader in RenderMonkey von ATI (siehe auchKapitel 7.7 auf Seite 79). Der komplette zusammenhängende Quellcode ist in Listing

51

Page 52: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Abbildung 4.1: Der PerVertex-Lighting Beispielshader

A.5 auf Seite 92 zu �nden. Für weitere Informationen zur Shaderprogrammierung siehe[SL04], [Ros04], [Fer04] und [Eng05].

4.2 Compositor-Skripte

Compositor-Skripte bieten eine einfache Möglichkeit PostProcessing-E�ekte wie z.B.Bewegungs- und Tiefenunschärfe oder High Dynamic Range Rendering zu realisieren.Auch hier können die Skripte verändert werden, ohne dass die Anwendung neu kompi-liert werden muss. Im Quelltext muss nur ein Compositor einem Viewport zugewiesenund aktiviert werden:

CompositorManager :: getSingleton (). addCompositor(viewport ,compositorName );

CompositorManager :: getSingleton (). setCompositorEnabled(viewport ,compositorName , enabledOrDisabled );

Um einen PostProcessing-E�ekt zu erzeugen, wird erst die gesamte Szene in eine Texturgerendert. Diese wird über einen Pixelshader auf einen Viereck gerendert, das den gan-zen Bildschirm umfasst. Das Ergebniss dieses Vorganges kann entweder das endgültigeauf dem Bildschirm erscheinende Bild oder aber wieder eine Zwischentextur sein, diedurch weitere Compositor-Passes bearbeitet wird.Mehrere Compositors können in einem sogenannten �CompositorChain� hintereinanderangeordnet werden, d.h. der nächste Compositor erhält als Eingabe die Ausgabe des vor-herigen Compositors. Diese Kette wird automatisch von OGRE angelegt und die Reihen-folge richtet sich nach der Reihenfolge der CompositorManager::getSingleton().add-Compositor()-Aufrufe. Die Hauptkomponenten von einem Compositor sind Techniques,Target Passes und Passes. Das Skript ist wieder in einem Pseudo-C++-Dialekt geschrie-ben und jeder Compositor muss einen global eindeutigen Namen zugewiesen bekom-men.

52

Page 53: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4.2.1 Techniques

Eine Compositor-Technique ist ähnlich wie eine Material-Technique, eine Beschreibung,um einen gewünschten E�ekt zu erzielen. Ein Compositor-Skript kann mehr als eineTechnique beinhalten, um eine Ausweich-Technique für ältere Hardware bereitzustellen.Techniques können die Elemente texture, target und target_output beinhalten. Wo-bei texture eine Textur de�niert, die in einem target_pass verwendet wird. Sie wirdüber einen Namen, Höhe und Breite und ein Pixel-Format de�niert:

texture RenderTarget1 512 512 PF_A8R8G8B8texture RenderTarget2 target_width target_height PF_FLOAT32_RGB

Die erstere Zeile de�niert ein RenderTarget, das 512 mal 512 Pixel groÿ ist und bei demjeder Pixel aus jeweils 8 Bit für Alpha-, Rot-, Grün- und Blauwert zusammengesetzt ist.Die zweite Zeile gibt ein RenderTarget an, das so groÿ wie das Renderfenster ist und beidem die Pixel in einem speziellen Flieÿkommaformat gespeichert sind, welches z.B. fürHDR-Rendering benötigt wird.

4.2.2 Target Pass

Ein Target Pass ist ein Renderdurchlauf, der entweder in eine Render-Textur oder die�nale Ausgabe rendert. Das Element target <Name> rendert in eine Textur, währenddas Element target_output <Name> die �nale Ausgabe erzeugt. Die Inhalte beiderElemente sind gleich. Der Compositor kann jedoch nur ein target_output-Elementaber mehrere target-Elemente haben. Folgende Attribute können in diesen Elementenvorkommen:Über input wird den�niert, ob die Textur vor dem Rendering mit Inhalt gefüllt wird.Der Wert previous sorgt dafür, dass die Textur mit der Original-Renderszene, falls esder erste Compositor in der Kette ist, oder mit der Ausgabe des vorherigen Compositorsgefüllt wird. Der Wert none belässt die Textur unbefüllt, so dass diese vollständig durchden aktuellen Pass gefüllt werden muss.Das Attribut only_initial on sorgt dafür, dass dieser Pass nur einmal bei Aktivierendes Compositors gerendert wird. Dies ist nützlich, wenn dieser Pass nur statische Inhalteenthält.Das Attribut material_scheme teilt diesen Pass ähnlich dem gleichlautenden Attributin Materialskripten einer Qualitätseinstellung zu.

53

Page 54: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4.2.3 Compositor Pass

Ein Compositor Pass ist ein in einem Target Pass durchgeführtes Rendering. Es gibtfolgende Pass-Typen:

• clear: Dieser Pass setzt den Inhalt eines Bu�ers einer Zieltextur auf einen be-stimmten festen Wert. Dies könnte z.B. den Farbbu�er auf eine bestimmte Farbeoder den Tiefenbu�er auf einen bestimmten Wert setzen.

• stencil: Dieser Pass kon�guriert den Stencilbu�er und die zugehörigen Stencil-funktionen für nachfolgende Passes.

• render_scene: Dieser Pass rendert die komplette Szene in eine Textur.

• render_quad: Dies rendert ein bildschirmumfassendes Viereck durch ein de�niertesMaterialskript in eine Textur. Das eigentliche PostProcessing wird durch diesenPass gerendert.

Das Attribut material bestimmt das Material für einen render_quad-Pass. Man be-nutzt Pixelshader in diesemMaterial um PostProcessing-E�ekte zu rendern und übergibtTexturen an das Material über das Attribut input. Für weitere Informationen zu denBu�er- und Stenciloperationen siehe [The06b].

4.2.4 Ein einfacher Beispiel-Kompositor

Folgendes Beispiel zeigt den Aufbau eines PostProcessing-E�ekts, das einen Weichzeich-ner zweimal über die gerenderte Szene laufen lässt (siehe Abbildung 4.2 auf Seite 55):

compositor SimpleBlur{

technique{

texture rt target_width target_height PF_R8G8B8texture rt2 target_width target_height PF_R8G8B8

target rt { input previous }

target rt2{

input none

pass render_quad{

material ScreenSpace.SimpleBlurinput 0 rt

}}

54

Page 55: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

target_output{

input none

pass render_quad{

material ScreenSpace.SimpleBlurinput 0 rt2

}}

}}

(a) Ausgangsbild (b) Endergbniss nach 2 Durchläufen des Weich-zeichner-Kompositors

Abbildung 4.2: Ein einfacher Weichzeichner

Für das zugehörige Materialskript und den Pixelshader siehe Listing A.3 auf Seite 90.

4.3 Particle-Skripte

Particle-Skripte de�nieren Partikelsystem-Vorlagen, die im Quellcode mehrfach instan-tiiert werden können. Jedes Partikelsystem setzt sich aus allgemeinen Eigenschaftenund ein oder mehreren Partikelemittern und optionalen Partikela�ektoren zusammen.

55

Page 56: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Nachfolgend werden einige ausgewählte Eigenschaften erläutert (für eine vollständigeEigenschaftenliste siehe [The06b]):

• quota - Setzt die maximale Anzahl an Partikeln. Wenn dieses Limit erreicht wird,so werden für eine Weile keinen neuen Partikel emittiert bis einige zerstört wurden(weil sie z.B. ihre Lebensdauer überschritten haben).

• material - Legt das Material für alle Partikel des Systems fest. Jedoch kann jedesPartikel sein Aussehen über sein Farbattribut ändern.

• particle_width und particle_height - Bestimmt die Breite und Höhe einesPartikels in Weltkoordinaten.

• cull_each - Ist standardmäÿig auf false gesetzt, so dass das Partikelsystem überseinen umgebenden Hüllquader9 auf Sichtbarkeit geprüft wird. Dies ist vorteilhaftbei kleinen lokalen Partikelsystemen. Bei Systemen, die jedoch einen groÿen Be-reich abdecken, kann es zu einer besseren Performance führen, wenn jedes Partikelauf Sichtbarkeit geprüft wird.

• local_space - Normalerweise bewegen sich Partikel nachdem sie emittiert wur-den unabhängig vom Emitter im Weltkoordinatensystem. Sollen sich die Partikeljedoch in Abhängigkeit zum Emitter bewegen (im lokalen Raum des Emitters) sowird diese Eigenschaft auf true gesetzt.

• billboard_type - Partikel werden über sogenannte Billboards gerendert. Das sindRechtecke, die aus 2 Dreiecken bestehen, die rotiert werden, um in eine bestimmmteRichtung zu zeigen. Normalerweise sind diese Rechtecke direkt der Kamera zuge-wandt (Parameter point). Dies ist für kugelförmige Partikel, wie z.B. Lichte�ekte,gut geeignet. Bei andere E�ekte, wie z.B. Laserfeuer, erzielt man bessere Ergebnis-se mit Partikeln, die in eine eigene Richtung zeigen (Parameter oriented_self).Der Parameter oriented_common richtet die Partikel an einem gegebenen Vektor(Eigenschaft common_direction) aus.

4.3.1 Partikelemitter

Partikelemitter erzeugen Partikel in einem durch den Partikelemittertyp bestimmtenRaum und in zufälliger Verteilung. OGRE unterstützt die Typen Point, Box, Cylinder,Ellipsoid, HollowEllipsoid und Ring. Nachfolgend werden einige ausgewählte Eigen-schaften von Emittern erläutert (für eine vollständige Eigenschaftenliste siehe [The06b]):

• angle - Bestimmt den maximalen Winkel in Grad, indem die Partikel abweichendzur Emitter-Richtung erzeugt werden.

• colour - Bestimmt eine Farbe, in der alle Partikel gerendert werden.

9engl.: bounding box

56

Page 57: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

• colour_range_start und colour_range_end - Legt einen Farbbereich fest, in-nerhalb dessen Partikel zufällig gefärbt werden.

• direction - Legt die Richtung des Emitters relativ zu seinem Szenenknoten fest.

• emission_rate - De�niert, wie viele Partikel pro Sekunde emittiert werden.

• position - Bestimmt die Position des Emitters relativ zu seinem Szenenknoten.

• velocity - Legt eine feste Geschwindigkeit für alle emittierten Partikel fest.

• time_to_live - De�niert eine Anzahl von Sekunden, die der Partikel �lebt� bevorer zerstört wird.

• duration - De�niert eine Anzahl von Sekunden, die der Emitter aktiv ist. Standardist hier 0 für unbegrenzte Aktivität.

• repeat_delay - Falls eine duration ungleich 0 angegeben wurde, de�niert dieserWert die Zeitdauer in Sekunden bis der Emitter wieder aktiv wird.

Die Eigenschaften velocity, time_to_live, duration und repeat_delay können al-ternativ über _min- und _max-Zusätze in einem bestimmten Bereich variiert werden.

4.3.2 Partikela�ektoren

A�ektoren nehmen auf verschiedene Weise Ein�uss auf ein Partikelsystem. Es gibt fol-gende A�ektoren in OGRE:

• LinearForce - Dieser A�ektor addiert eine lineare Kraft, wie z.B. Wind und Gra-vitation, zu allen Partikeln. Er wird de�niert durch einen force_vector und obdie Kraft addiert oder der Durchschnitt zwischen Kraft und dem Bewegungsvektorgebildet wird (force_application average|add).

• Scaler - Skaliert Partikel um einen bestimmten Wert (rate).

• Rotator - Rotiert die Partikel, indem die Partikeltextur rotiert wird. Wird durchAnfangs- und Endrotationsgrade (rotation_range_start und rotation_range_-end) und durch Rotationsgeschwindigkeiten (rotation_speed_range_start undrotation_speed_range_end) de�niert.

• ColourFader - Dieser A�ektor verändert die Farbe eines Partikels um einen be-stimmten Wert pro Sekunde.

Für weitere A�ekoren siehe [The06b].

57

Page 58: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4.3.3 Ein einfaches Beispiel-Partikelskript

Folgendes Particle-Skript de�niert das in Abbildung 4.3 auf Seite 59 gezeigte Partikel-system:

PurpleFountain{

// Grundeinstellungenmaterial Examples/Flare2particle_width 20particle_height 20cull_each falsequota 10000billboard_type oriented_self

// Der Partikelemitteremitter Point{

angle 15emission_rate 75time_to_live 3direction 0 1 0velocity_min 250velocity_max 300colour_range_start 1 0 0colour_range_end 0 0 1

}

// Gravitationaffector LinearForce{

force_vector 0 -100 0force_application add

}

// Ein Farb -Faderaffector ColourFader{

red -0.25green -0.25blue -0.25

}}

Für die Erstellung von Particle-Skripten emp�ehlt sich der ParticleEditor (siehe Kapitel7.4 auf Seite 76), der sofortiges optisches Feedback liefert und intuitiv zu bedienen ist.

58

Page 59: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4.4 Overlay-Skripte

Overlays werden nach allen anderen Objekten gerendert und verdecken damit darun-terliegende Bereiche. Sie eignen sich für Menüs und Buttons oder sonstigen relevantenAnzeigen wie z.B. einer Punkteanzeige oder eines Raumschi�-Cockpits in Spielen. Mankann Overlays direkt im Quellcode de�nieren oder in einem .overlay-Skript, welches dieOverlay-De�ntion in einer Pseudo-C++-Sprache enthält.

Overlay-Skripte enthalten die De�nition von einem oder mehreren Overlays, die globaleindeutige Namen haben müssen. Jedes Overlay besteht aus der Eigenschaft zorder

und ein oder mehreren Elementen. zorder bestimmt die Reihenfolge, in der die Overlaysgerendert werden. Ein Overlay mit höherem Wert überdeckt ein Overlay mit niedrigeremWert.

Abbildung 4.3: Ein einfaches Partikelsystem

59

Page 60: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4.4.1 Elemente zu Overlays hinzufügen

Ein Overlay kann Elemente (ein 2D-Element, das keine weiteren Kindelemente hat)und Container (enthält selber wieder Elemente und Container) beinhalten. Ein Elementoder Container setzt sich aus einem Typen und einem eindeutigen Namen zusammen. InOGRE vorde�nierte Typen sind Panel, BorderPanel, TextArea und TextBox. Elementeoder Container können folgende Eigenschaften enthalten:

• metrics_mode - Bestimmt, wie nachfolgende Positions- und Gröÿenangaben inter-pretiert werden: pixel für absolute Angaben oder relative für relative Angaben.

• horz_align - Ordnet das Element in der Horizontalen an. Mögliche Werte sindleft, center und right.

• vert_align - Ordnet das Element in der Vertikalen an. Mögliche Werte sind top,center und bottom.

• left - Setzt den horizontalen Ursprung des Elements relativ zu einem eventuellenEltern-Element.

• top - Setzt den vertikalen Ursprung des Elements relativ zu einem eventuellenEltern-Element.

• width - Setzt die Breite des Elements proportional zur Bildschirmgröÿe. 0.25 ent-spricht z.B. einem Viertel der Bildschirmbreite.

• height - Setzt die Höhe des Elements proportional zur Bildschirmgröÿe.

• material - Bestimmt das Material, mit welchem das Element gerendert wird.

• caption - Setzt die Überschrift des Elements.

• rotation - Bestimmt, ob das Element gedreht werden soll. Erst folgt die Winkel-angabe, danach die Angabe der Rotationsachse als Vektor. So dreht rotation 30

0 0 1 das Element 30 Grad um die x-Achse.

4.4.2 Standard-Overlay-Elemente

• Panel - Eine rechteckiger Bereich mit einem Hintergrundmaterial, der weitere Ele-mente enthalten kann

• BorderPanel - Wie Panel, nur das ein separates Material für einen Begrenzungs-rahmen gesetzt werden kann

• TextArea - Wird genutzt, um Text zu rendern

• TextBox - Wie TextArea, nur das man Text eingeben kann

Folgender Code zeigt eine beispielhafte Overlay-De�ntion:

60

Page 61: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

// Der Name des OverlaysOverlays/BeispielOverlay{

zorder 200

// erzeugen eines Panelscontainer Panel(OverlayElements/TestPanel){

// in der Mitte zentrieren und nach oben verschiebenleft 0.25top 0width 0.5height 0.1

// Material , mit der das Panel gerendert wirdmaterial Materials/TestPanelMaterial

// Ein weiteres Panel innerhalb des aktuellen Panelscontainer Panel(OverlayElements/WeiteresPanel){

left 0top 0width 0.1height 0.1material Materials/WeiteresPanelMaterial

}}

}

4.4.3 Font De�nition-Skripte

OGRE benutzt texturbasierte Schriftarten, um z.B. den Text in einem Overlay-Elementzu rendern. Schriftarten werden in .fontdef-Dateien de�niert. Man kann eine Schrift-art aus einem TrueType-Font erzeugen lassen oder eine Schriftart-Textur bereitstellen,die alle vorkommenden Zeichen in einer Textur unterbringt und für jedes Zeichen eineTexturkoordinate gespeichert wird.

Eine existierende Schriftart-Textur verwenden

Diese Font-De�ntion ist vom Typ type image und die Eigenschaft source <Dateiname>

legt die Schriftart-Textur fest. Danach folgt eine Reihe von Zeichende�nitionen in derfolgenden Form: glyph <Zeichen> <u1> <v1> <u2> <v2>, wobei die vier Koordinatendas Rechteck beschreiben, in dem sich das Zeichen in der angegebenen Textur be�ndet.

61

Page 62: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Solche Koordinaten von Hand zu erzeugen ist sehr zeitaufwendig. Ein gutes Werkzeug fürdie Generierung der Texturen als auch der Koordinaten ist der BitmapFontBuilder10.

Eine Schriftart-Textur generieren

Diese Art der Font-De�nition ist vom Typ type truetype und hier legt die Eigen-schaft source <Dateiname> die zugrundeliegende TrueType-Schriftart fest. Die Eigen-schaft size legt die Gröÿe der Zeichen in der generierten Textur fest und die Eigen-schaft resolution bestimmt die endgültige Gröÿe der Zeichen, wenn sie gerendert wer-den. Folgendes Skript erzeugt eine Schriftart mit dem Namen Schriftart1 aus der DateiSchrift1.ttf, die nun von Overlay-Elementen zur Textausgabe genutzt werden kann:

Schriftart1{

type truetypesource Schrift1.ttfsize 16resolution 96

}

10erhältlich unter: http://www.lmnopc.com/bitmapfontbuilder/

62

Page 63: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

5 Schatten in OGRE 3D

5.1 Allgemeines

Schatten stellen eines der anspruchvollsten Gebiete der 3D-Programmierung dar. Es gibtsehr verschiedene Ansätze zur Schattenberechnung, jedoch ist keiner perfekt und sie ha-ben alle ihre spezi�schen Vor- und Nachteile. Trotzdem sind Schatten für die Glaub-würdigkeit der dargestellten Szene wichtig, weil sie räumliche Beziehungen zwischen denObjekten verdeutlichen. OGRE stellt mehrere Schattenimplementationen bereit.

5.1.1 Schatten in OGRE 3D aktivieren

Schatten sind standardmäÿig deaktiviert. Man aktiviert sie mit dem Aufruf der Scene-Manager::setShadowTechnique()-Methode und der gewünschten Schattenart als Pa-rameter:

mSceneMgr ->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE );

Weitere Schattenarten sind SHADOWTYPE_STENCIL_MODULATIVE, SHADOWTYPE_TEXTURE_-MODULATIVE und SHADOWTYPE_TEXTURE_ADDITIVE. Die Schattenart muss vor dem Ladender 3D-Modelle gesetzt werden, da Modelle nun anders geladen werden. Auÿerdem be-nötigt man mindestens eine Lichtquelle. Nicht jede Lichtquellenart wird von jeder Schat-tenart unterstützt. Falls eine Lichtquelle keinen Schatten werfen soll, muss diese überLight::setCastShadows(false) von der Schattenberechnung ausgeschlossen werden.Auch Objekte müssen, falls gewünscht, von der Berechnung über SceneNode::setCast-Shadows(false) ausgeschlossen werden. Aus Performance-Gründen kann die Entfer-nung, bis zu der Schatten berechnet werden, über SceneManager::setShadowFar-

Distance() gesetzt werden. Auÿerdem können bestimmte Materialien über den Ma-terialparameter receive_shadows false vom Empfang von Schatten ausgeschlossenwerden. Dies ist z.B. nützlich bei selbstleuchtenden oder transparenten Materialien.

63

Page 64: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

5.1.2 Modulative Schatten

Modulative Schatten dunkeln im Schatten liegende Bereiche einer zuvor mit voller Lichtin-tensität gerenderten Szene mit einer fest eingestellten Farbe ab. Erst wird die Szene mitallen Schatten erhaltenden und werfenden Objekten gerendert. Danach dunkelt ein mo-dulativer Rendering-Durchlauf pro Lichtquelle die im Schatten liegenden Bereiche ab.Zum Schluss werden alle Objekte gerendert, die keine Schatten erhalten sollen. DiesesSchattenmodell ist nicht sehr wirklichkeitsnah, da es bei mehreren Lichtquellen zu unna-türlich dunklen Schatten kommen kann. Jedoch sind modulative Schatten mit statischenin Texturen vorberechneten Schatten kompatibel.

5.1.3 Additive Light Masking

Beim Additive Light Masking wird die Szene in mehreren Durchläufen gerendert. Dabeistellt jeder Durchlauf die Lichtberechnung einer Lichtquelle dar. Im Schatten liegendeBereiche werden dabei ausmaskiert. Jeder Durchlauf addiert seine Berechnungsergebnis-se zum vorigen Durchlauf. Diese Technik führt zu sehr realistischen Ergebnissen aber zuLasten der Performance aufgrund mehrerer Render-Durchläufe.

5.2 Stencil-Schatten

Stencil-Schatten werden durch Schatten-Volumen-Berechnung erzeugt. Das Schattenvo-lumen wird durch folgenden Algorithmus berechnet:

• Finde alle Kanten, die zur Silhouette des Schatten werfenden Objektes gehören

• Expandiere alle gefundenen Kanten in entgegengesetzter Richtung zur Lichtquelle

• Schlieÿe das erzeugte Volumen mit einer Front- und einer Rück�äche

Die Szene wird nun in drei Schritten gerendert (modulativer Schatten):

• Rendere die Szene als wenn sie komplett beleuchtet wäre

• Konstruiere mithilfe der Tiefeninformation der Szene eine Maske innerhalb desStencil-Bu�ers, die Löcher in den Bereichen hat, die nicht innerhalb des Schatten-Volumens liegen

• Rendere die Szene einmal pro Licht mithilfe der Stencil-Bu�er-Maske, um die imSchatten liegenden Bereiche abzudunkeln

64

Page 65: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

5.2.1 Das �HelloWorld�-Beispiel mit Stencil-Schatten

Nun wird das HelloWorld-Beispiel aus Kapitel 3.2 auf Seite 32 um Stencil-Schattenbe-rechnung erweitert. Dabei soll der OGRE-Kopf einen Schatten auf eine darunterliegendeEbene werfen. Um Stencil-Schatten in OGRE zu benutzen, muss zunächst die Schatten-art über folgenden Funktionsaufruf gesetzt werde:

mSceneManager ->setShadowTechnique(SHADOWTYPE_STENCIL_MODULATIVE );

Dieser Methodenaufruf muss vor dem Laden jeglicher 3D-Modelle geschehen. Da dieSchattenfarbe standardmäÿig auf Schwarz gesetzt ist, kann man den Schattenwurf etwasabschwächen:

mSceneManager ->setShadowColour(ColourValue (0.5, 0.5, 0.5));

Nun wird die Ebene de�niert, auf die der Schatten fällt:

// Ein Ebenen -Mesh generisch über den MeshManager erstellenMeshManager :: getSingleton (). createPlane("plane.mesh", "Custom",

Plane(Vector3 ::UNIT_Z , Vector3 ::ZERO), 250, 250, 10, 10);

// Ein Entity aus dem Ebenen -Mesh erstellenEntity* mGround = mSceneManager ->createEntity("GroundEntity",

"plane.mesh");

// Material für die Ebene setzenmGround ->setMaterialName("Examples/Rocky");

// Neuen Szenenknoten erstellen und Ebene anhängenSceneNode* mGroundNode = mSceneManager ->getRootSceneNode ()

->createChildSceneNode ();mGroundNode ->attachObject(mGround );

Abbildung 5.1: Das HelloWorld-Beispiel mit Stencil-Schatten

65

Page 66: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

// Ebene ausrichten und etwas nach unten verschiebenmGroundNode ->setOrientation(Quaternion(Radian(-Math:: HALF_PI),

Vector3 :: UNIT_X ));mGroundNode ->translate(0, -50, 0);

Hier wird ein Ebenen-Mesh (�plane.mesh�) generisch über den MeshManager. erstellt.Danach kann man wie gewohnt ein Entity mit dem Mesh laden. Das Ergebniss ist inAbbildung 5.1 auf Seite 65 zu sehen.

5.3 Textur-basierte Schatten

Textur-basierte Schatten werden berechnet, indem getestet wird, ob ein Objekt von derLichtquelle aus gesehen sichtbar ist. Dieser Test geschieht durch einen Vergleich derTiefe des Objekts (von der Lichtquelle aus gesehen) mit einer Tiefentextur. Die Tiefen-textur wird erstellt, indem die Szene von der Lichtquelle aus gerendert wird, dabei abernicht der Farbwert, sondern die Tiefeninformation gespeichert wird. Das Ergebniss istdie sogenannte Schatten-Map. Diese Technik ist ungenauer als die Stencil-Technik, aberin vielen Fällen performanter. Auÿerdem können die Schatten-Maps weiter bearbeitetwerden, um z.B. weiche Schatten zu erzeugen (dabei werden mehrere Schatten-Mapsin unterschiedlichen Au�ösungen berechnet und daraus ein �nale Schatten-Map durchÜberblendung berechnet), was mit Stencil-Schatten nicht möglich ist. Ein wichtiger Fak-tor für die Genauigkeit der Schatten ist die Au�ösung der Schatten-Map (Abbildung 5.2auf Seite 66 zeigt die Auswirkung der Au�ösung der Schatten-Map auf das Renderer-gebniss in der Beispielanwendung aus dem Kapitel 5.2). Je kleiner die Schatten-Mapdesto ungenauer und weicher werden die Schatten. In OGRE wird diese Schattenartfolgenderweise aktiviert:

mSceneManager ->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE );

(a) Schatten-Map mit einer Au�ösungvon 1024 x 1024 Pixeln

(b) Schatten-Map mit einer Au�ösungvon 128 x 128 Pixeln

Abbildung 5.2: Textur-basierte Schatten in OGRE

66

Page 67: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

6 Animation in OGRE 3D

6.1 Skeletale Animation

Unter skeletaler Animation versteht man die Deformation von 3D-Modellen mithilfe ei-ner skeletalen Struktur (auch Bones, dt. Knochen, genannt). Dabei werden die Knochendes Modells animiert, was zur Folge hat, dass auch die entsprechend zugewiesenen Verti-zes bewegt werden. Jeder Vertex wird einem oder mehreren Knochen in einer bestimmtenWichtung zugewiesen. Die skeletale Struktur wird bei der Erstellung des 3D-Modells ineinem 3D-Modelling-Programm, wie z.b. 3ds Max oder Maya, festgelegt und über einenExporter in das OGRE-.mesh- und -.skeleton-Format exportiert (siehe Kapitel 7.5 aufSeite 76). Die Animationen werden in der .skeleton-Datei gespeichert, die automatischmit geladen wird, wenn eine .mesh-Datei geladen wird, zu der ebenfalls ein Skelett de-�niert und exportiert wurde. Folgende Leistungsmerkmale werden von OGRE dabeiunterstützt:

• Jedem Mesh kann genau ein Skelett zugewiesen werden

• Pro Skelett kann es beliebig viele Knochen geben

• Hierarchische vorwärtsgerichtete Kinematik der Knochen

• Mehrere benannte Animationen pro Skelett, z.B. �Laufen�, �Rennen� usw.

• Unbegrenzte Anzahl an Schlüsselbildern (Keyframes) pro Animation

• Lineare oder spline-basierte Interpolation zwischen Schlüsselbildern

• Ein Vertex kann mehreren Knochen mit einer bestimmten Wichtung zugewiesenwerden

• Einem 3D-Modell können gleichzeitig mehrere Animationen zugewiesen und mitbestimmter Wichtung ineinandergeblendet werden

Skeletale Animation kann entweder vom Hauptprozessor oder in Vertexshadern von derGra�kkarte berechnet werden. Wobei letzteres aufgrund der Leistungsfähigkeit heutigerGra�kkarten empfehlenswert ist.

Folgender Quellcodeausschnitt lädt das mit OGRE-ausgelieferte Robotermodell(robot.mesh) und die zugehörige Skelettdatei (robot.skeleton) und startet die Ani-

67

Page 68: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

mation Walk:

// VariablenAnimationState* mAnimationState; // Zur Ansteuerung der aktuellen

// AnimationEntity* mEntity; // Das Roboter -EntitySceneNode* mNode; // Der Roboter -Szenenknoten

// Laden des Roboters und Zuweisen zu einer Entity -VariablenmEntity = mSceneMgr ->createEntity( "Robot", "robot.mesh" );

// Erzeugen eines Szenenknotens und Anhängen des RobotersmNode = mSceneMgr ->getRootSceneNode ()-> createChildSceneNode(

"RobotNode", Vector3( 0.0f, 0.0f, 25.0f ) );mNode ->attachObject( mEntity );

// mAnimationState verweist nun auf die "Walk"-Animation des RobotersmAnimationState = mEntity ->getAnimationState( "Walk" );

// Die Animation soll sich nach dem Abspielen wiederholenmAnimationState ->setLoop( true );

// Die Animation wird gestartetmAnimationState ->setEnabled( true );

Um eine Animation jedoch wirklich ablaufen zu lassen, muss noch die seit dem letztenBild vergangene Zeit addiert werden. Dies geschieht am besten in der frameStarted-Methode einer OGRE::FrameListener-Klasse (siehe Kapitel 3.4 auf Seite 37):

mAnimationState ->addTime( evt.timeSinceLastFrame );

Übergibt man der Methode negative Werte, so sind auch rückwärts ablaufende Anima-tionen möglich.

Will man nun eine andere Animation startet, so beendet man die aktuelle, verweist aufdie neue Animation und startet diese:

mAnimationState ->setEnabled( false );mAnimationState = mEntity ->getAnimationState( "Die" );mAnimationState ->setLoop( true );mAnimationState ->setEnabled( true );

Um eine weitere Animation gleichzeitig ablaufen zu lassen, holt man sich einen weite-ren Verweis auf die zweite Animation und aktiviert diese. Über AnimationState::set-Weight() kann die Gewichtung der Animation zu anderen gleichzeitig aktiven Anima-tionen de�niert werden:

AnimationState* mAnimationState2;mAnimationState2 = mEntity ->getAnimationState( "Idle" );

68

Page 69: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

// Verringert die Gewichtung der zweiten AnimationmAnimationState2 ->setWeight (0.5);mAnimationState2 ->setLoop( true );mAnimationState2 ->setEnabled( true );

Für die Anwendung von skeletaler Animation im Kontext einer kompletten OGRE-Anwendung siehe das interaktive Beispiel in Kapitel 3.5 auf Seite 39 sowie den zugehö-rigen Quelltext im Anhang A.2 auf Seite 85.

6.2 Vertex-Animation

Bei der Vertex-Animation werden Informationen zur direkten Bewegung der zu einem3D-Modell gehörenden Vertizes gespeichert. Diese Informationen sind direkt in der.mesh-Datei enthalten. Vertex-Animation unterscheidet man nochmal in Morph- und Pose-Animation, wobei Morph-Animation eine vereinfachte Form der Pose-Animation ist.

6.2.1 Morph-Animation

Bei der Morph-Animation werden zu jedem Schlüsselbild die absoluten Positionen al-ler Vertizes eines 3D-Modells gespeichert. Man interpoliert nun linear zwischen einemSchlüsselbild und dem ursprünglichen Erscheinungsbild des 3D-Modells und erzeugt so-mit die Animationen. Es ist nicht möglich mehrere Schlüsselbilder zu überblenden. DieseArt der Animation wird bei Objekten genutzt, die nicht durch skeletale Animation ani-miert werden können, weil sich z.B. die Geometrie zu stark verformen soll.

6.2.2 Pose-Animation

Pose-Animation kombiniert mehrere Schlüsselbilder eines 3D-Modells mit einstellbarenGewichten zu einem Endresultat und wird häu�g für Gesichtsanimation von Charak-teren, insbesondere für Lippensynchronisation verwendet. Die Vertex-Daten der einzel-nen Posen werden als relative O�sets zum ursprünglichen 3D-Modell gespeichert. JedePose stellt bei der Gesichtsanimation einen Gesichtsausdruck dar. Diese können nun in-einandergeblendet oder komplett zusammengemischt werden, sofern sie unterschiedlicheBereiche des Gesichts beein�ussen.

Sowohl Morph- als auch Pose-Animationen können entweder vom Hauptprozessor odervon einem Vertexshader berechnet werden. Man sollte jedoch bei der Pose-Animation

69

Page 70: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

beachten, dass mit der Anzahl der eingesetzten Posen auch die Performance deutlichsinken kann.

Pose-Animation wird in OGRE ähnlich verwendet wie skeletale Animation. Man benötigteine AnimationState-Variable, die auf eine Pose-Animation verweist:

// Die AnimationsvariableAnimationState* mAnimState;

// Der zu animierende KopfEntity* mOgreEntity = mSceneManager ->createEntity("OgreEntity1",

"facial.mesh");

// Modell an ein Szenenknoten bindenSceneNode* mOgreSceneNode = mSceneManager ->getRootSceneNode ()->

createChildSceneNode("Ogre1Node", Vector3 (0,0,0));mOgreSceneNode ->attachObject(mOgreEntity );

// Die Animation startenmAnimState = mOgreEntity ->getAnimationState("Speak");mAnimState ->setEnabled(true);

Nun muss der Animation noch die vergangene Zeit seit dem letzten Bild in der frameStarted()-Methode eines FrameListener (siehe Kapitel 3.4 auf Seite 37) hinzugefügt werden:

mAnimState ->addTime(evt.timeSinceLastFrame );

Die Abbildung 6.1 auf Seite 70 zeigt den sprechenden Charakter, den dieses Beispielerzeugt.

Abbildung 6.1: Gesichtsanimation mit Pose-Animation

70

Page 71: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

6.2.3 Kombination von skeletaler und Vertex-Animation

Skeletale und Vertex-Animation können gleichzeitig auf einem 3D-Modell benutzt wer-den. Zuerst wird das Modell über die Vertex-Animation deformiert und erst danach wirdnoch die skeletale Animation durchgeführt. Die Animation erfolgt immer auf Submesh-Basis, d.h. man kann z.B. einen Charakter als einen Körper- und einen Kopf-Submeshde�nieren und die skeletale Animation auf den Kopf- und Körper und die Pose-Animationnur auf den Kopf anwenden. [The06b]

6.3 Szenenknoten-Animation

Szenenknoten-Animationen werden vom Szenenmanager erzeugt, um die Bewegung vonSzenenknoten und damit auch die der angehängten Objekte zu animieren. Im Grundefunktioniert die Szenenknoten-Animation genauso wie die skeletale Animation. Nach-dem man mit SceneManager::createAnimation() eine Animation erzeugt hat, de�-niert man noch einen NodeAnimationTrack pro Knoten, den man animieren will. ProNodeAnimationTrack legt man noch Schlüsselbilder fest, die Position, Orientierung undSkalierung speichern, und zwischen denen man nun linear oder splinebasiert interpolierenkann. [The06b]

Folgender Quellcodeabschnitt erzeugt eine Kamerafahrt:

// Erstellen einer splinebasierten Animation// des Kamera -SzenenknotensAnimation* camAnim;

// Animation mit Namen "CameraTrack" und einer// Dauer von 10camAnim = mSceneMgr ->createAnimation("CameraTrack", 10);camAnim ->setInterpolationMode(Animation :: IM_SPLINE );

// Erzeugen eines Tracks für die KamerafahrtNodeAnimationTrack* track = camAnim ->createNodeTrack (0, mCameraNode );

// Erstellen von Schlüsselbildern// 1. Schlüsselbild an Position 0TransformKeyFrame* key = track ->createNodeKeyFrame (0);key ->setTranslate(Vector3(0, 0, 0));// 2. Schlüsselbild an Position 2.5key = track ->createNodeKeyFrame (2.5);key ->setTranslate(Vector3 (-20,20,-20));key = track ->createNodeKeyFrame (5);key ->setTranslate(Vector3 (150 ,100 ,300));key = track ->createNodeKeyFrame (7.5);key ->setTranslate(Vector3 (0 ,50 ,0));

71

Page 72: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

// Letztes Schlüsselbild an letzter Position (10)key = track ->createNodeKeyFrame (10);key ->setTranslate(Vector3(0, 80, -30));

// Die komplette Animation wird in einem// AnimationState -Objekt gespeichertAnimationState* mCamAnimState;mCamAnimState = mSceneMgr ->createAnimationState("CameraTrack");

// Animation startenmCamAnimState ->setEnabled( true );

6.4 Animation von numerischen Werten

Neben den bisher besprochenen Animationsarten kann man auÿerdem jeden numeri-schen Wert animieren, dessen Klasse das Interface AnimableObject implementiert. Im-plementiert eine Klasse dieses Interface, so stehen verschiedenen Methoden bereit, umnumerische Daten der Klasse mit dem generischen Animationssystem von OGRE zuverbinden.

72

Page 73: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

7 OGRE 3D-Tools und Exporter

7.1 XML-Konverter

Der OGRE XML-Konverter konvertiert binäre .mesh- und .skeleton-Dateien in XML1

und zurück. Die binären Dateien werden zur �nalen Nutzung innerhalb der OGRE-Anwendung verwendet. Die XML-Dateien werden zum einfachen Austausch von Datenbenutzt, da die meisten Mesh-Exporter XML-Dateien ausgeben und diese auch nochvon Hand editierbar sind. Auÿerdem kann der XML-Konverter zusätzliche Daten fürdas Mesh erzeugen wie z.B. das Erzeugen von Begrenzungsboxen und von mehrerenDetailstufen (LODs) des Meshes. Das vorliegen von mehreren Detailstufen hat den Vor-teil, dass OGRE automatisch für weiter vom Betrachter entfernte Objekte niedrigeraufgelöste Versionen des zugrunde liegenden Meshes nimmt, somit die Anzahl der zuberechnenden Dreiecke minimiert wird und die Performance erhöht wird. Das Redu-zieren der Geometriekomplexität erledigt der XML-Konverter recht gut, jedoch werdennach diesem Vorgang die Texturen nicht mehr korrekt auf das Modell projiziert (sieheAbbildung 7.1 auf Seite 74).

Die DTD2 der XML-kodierten .mesh- und .skeleton-Dateien �ndet man im OGRE-Quellcodeverzeichnis3 unter /Tools/XMLConverter/docs.

Der XML-Konverter ist nicht im OGRE-SDK enthalten sondern muss separat herunter-geladen werden4.

So wird der XML-Konverter in der Eingabeau�orderung benutzt:

OgreXMLConverter [Optionen] Quelldatei [Zieldatei]

Gibt man als Option �-i� an, so wird man durch die möglichen Optionen geleitet.Optionen sind z.B. die Generierung von Detailstufen und ihre zugehörigen Entfernungen,die Generierung von Tangentenvektoren für Normal-Mapping usw. Weitere Optionen

1XML - Extensible Markup Language2Document Type De�nition, Dokumenttypde�niton3OGRE-Quellcode erhältlich unter: http://www.ogre3d.org4OgreCommandLineTools erhältlich unter: http://www.ogre3d.org

73

Page 74: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

(a) Original-Mesh (b) Details reduziert um 20 Prozent

(c) Details reduziert um 40 Prozent (d) Details reduziert um 80 Prozent

Abbildung 7.1: Auswirkung der Detailreduktion des XML-Konverters auf die Texturpro-jektion

be�nden sich in der entsprechenden Readme-Datei des XML-Konverters.

7.2 MeshUpgrader

Der OGRE MeshUpgrader ist ebenfalls Bestandteil der OgreCommandLineTools unddient dazu, binäre .mesh-Dateien älterer OGRE-Versionen auf die aktuelle Version zuportieren. Man kann ältere .mesh-Dateien benutzen, jedoch könnte dies einen negativen

74

Page 75: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Ein�uss auf die Performance haben und man wird in der OGRE-Log-Datei auf dieBenutzung von älteren .mesh-Dateien hingewiesen und sollte dementsprechend auf dieneue Version upgraden.

So wird der MeshUpgrader in der Eingabeau�orderung benutzt:

OgreMeshUpgrader [Optionen] Quelldatei [Zieldatei]

Auch hier wird man wieder mit der Option �-i� durch alle möglichen Optionen geleitet,die denen des XML-Konverters entsprechen.

7.3 MeshViewer

Abbildung 7.2: Der OGRE MeshViewer

Der OGRE MeshViewer steht auf derOGRE-Homepage zum Download be-reit und erlaubt es, sowohl binäre.mesh-Dateien als auch ihre XML-Pendants einzulesen und in einemGra�kfenster anzuzeigen (siehe Ab-bildung 7.2 auf Seite 75).Der MeshViewer bietet die Möglich-keit das Modell von allen Seiten zu be-trachten und sich die zugehörige Ma-terialde�ntion inklusive verwendeterTexturen anzeigen und verändern zulassen. Sind in der .mesh-Datei Ani-mationen gespeichert, so lassen sichdiese einzeln abspielen. Es lassen sichInformation zur Mesh- und Submesh-

Geometrie wie Anzahl der Indizes und Vertizes und ob für die einzelnen Vertizes Nor-malen und di�use oder spekulare Farben de�niert sind. Der MeshViewer erlaubt dieErstellung und Betrachtung von Detailstufen (LODs) des Meshes. Hier kommt es aberzu den selben Problemen hinsichtlich der Texturen wie beim XML-Konverter, da derMeshViewer diesen zur Konvertierung der Modelle benutzt. Ein weiterer Nachteil istdie Bedingung, dass sich die einer .mesh-Datei zugehörigen Materialde�nitionen und so-mit auch die zugehörigen Texturen und Shader-Programme im selben Verzeichnis wieder MeshViewer be�nden müssen. Das widerspricht der OGRE-typischen Aufteilung desmedia-Ordners.Für eine schnelle Überprüfung der aus einer Modelling-Anwendung exportierten Objek-te eignet sich der MeshViewer jedoch sehr gut und man kann auch auf die kompletteFunktionalität des XML-Konverters zurückgreifen.

75

Page 76: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

7.4 ParticleEditor

Abbildung 7.3: Der OGRE ParticleEditor

Der OGRE ParticleEditor steht eben-falls auf der OGRE-Homepage zumDownload und ist ein Echtzeit-Editorfür OGRE-Partikelskripte mit sofor-tigem gra�schen Feedback bei je-der Änderung der Partikelsysteme.Es werden alle Leistungsmerkma-le der OGRE-Partikelskripte unter-stützt. Man kann bereits bestehen-de Skripte modi�zieren oder kom-plett neue Partikelsysteme erscha�enund sich abschlieÿend die .particle-Dateien zur Integration in eigene An-wendungen ausgeben lassen. Der Edi-tor ist intuitiv bedienbar. Im linkenFenster lädt und speichert man Par-tikelskripte. Im rechten Fenster de�-

niert man die Grundparameter wie Partikelanzahl und -gröÿe sowie das benutzte Ma-terial (siehe Abbildung 7.3 auf Seite 76). Desweiteren de�niert man hier einen odermehrere Emitter mitsamt ihren vielfältigen Einstellungsmöglichkeiten und A�ektorenwie z.B. Kraftfelder und Farbmodi�kationen. Jede Änderung wird sofort im Echtzeit-Renderfenster umgesetzt und vereinfacht das Entwickeln von komplexen Partikelsyste-men enorm. Die Partikelskripte, Material- und Texturdateien müssen jedoch in bestimm-ten Unterverzeichnissen des ParticleEditor-Verzeichnisses liegen, was leider ein ständigesHin- und Herkopieren zwischen diesem und dem Projektverzeichnis nötig macht, an demman gerade arbeitet. Obwohl der ParticleViewer nur die Versionsnummer 0.08 trägt,macht er dennoch einen ausgewachsenen Eindruck und läuft auch recht stabil.Ein anderer Partikeleditor mit ähnlichem Funktionsumfang mit dem Namen Particle Ac-celerator kann unter http://www.tetracorp.net/dev/ParticleAccelerator1.0.zipheruntergeladen werden.

7.5 Mesh-Exporter

Mesh-Exporter für OGRE sind die bevorzugte Möglichkeit OGRE-Anwendungen mitInhalten zu füllen. Modelling-Anwendungen bieten unerschöp�iche Möglichkeiten zurErstellung von 3D-Modellen. Es sind Exporter für AC3D, Lightwave, Maya, Milkshape5,

5kostenlos erhältlich unter: http://www.swissquake.ch/chumbalum-soft/

76

Page 77: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

SoftImage XSI, Blender6 und 3ds Max verfügbar, wobei im Folgenden auf die beidenletzteren näher eingegangen wird.

7.5.1 3ds Max-Exporter

Der 3ds Max-Exporter für OGRE erlaubt das Exportieren beliebiger 3D-Modelle, egalmit welcher Modellierungsart sie erstellt wurden. Es können also auch Modelle, die alsNURBS7 oder Subdivision Surfaces erstellt wurden, exportiert werden. Diese werdenvor dem Exportieren implizit in �editierbare Netze�, also Listen von Dreiecken, konver-tiert. Es werden auch die Texturkoordinaten und eine Materialde�nition exportiert. DerExporter erstellt eine XML-Datei des Modells im OGRE-spezi�schen Format. Optionalkann man diese gleich durch den OGRE XML-Konverter in eine binäre .mesh-Datei um-wandeln lassen, inklusive dessen Einstellungsmöglichkeiten bezüglich der Erzeugung vonLODs, Tangentenvektoren usw. (siehe Kapitel 7.1 auf Seite 73). Auÿerdem lassen sichauch Modelle inklusive ihrer Animationen exportieren. Unterstützte Animationsartenund -einstellungen werden in Kapitel 6 auf Seite 67 erläutert.

7.5.2 Blender-Exporter

Der Blender-Exporter für OGRE ermöglicht das Exportieren von Blender-3D-Modellen.Es werden dabei alle Modellierungsarten auÿer Subdivision Surfaces unterstützt. Für ein-zelne 3D-Modelle können die Vertexfarben, mehrere Materialien, Texturkoordinaten, dieVertexnormalen und eventuelle Keyframe-Animationen, die auf ein ebenfalls exportier-bares Skelett zurückgreifen exportiert werden. Beim Exportieren kann das Modell nochskaliert und rotiert werden und entweder im Welt- oder im Objektkoordinatensystemausgegeben werden. Die Ausgabe erfolgt ähnlich dem 3ds Max Exporter als OGRE-spezi�schen XML-Mesh-Format, welches anschlieÿend vom OGRE-XML-Konverter indas binäre .mesh-Format gewandelt wird.

7.6 oFusion

oFusion8 ist eine Erweiterung zu Autodesks 3ds Max, die es ermöglicht, die erstellte Szeneinklusive aller erstellten Modelle, deren Materialien und Ausleuchtung innerhalb von3ds Max in einem echten OGRE-Renderfenster zu betrachten. Man erhält ein sofortiges

6kostenlos erhältlich unter: http://www.blender.org/7NURBS - Non Uniform Rational B-Spline8erhältlich unter http://www.ofusiontechnologies.com

77

Page 78: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

optisches Feedback auf alle Änderungen der Szene und somit entfällt das häu�ge Testender veränderten Szene in der eigentlichen OGRE-Anwendung. oFusion erlaubt auch demNichtprogrammierer hochwertige Inhalte für OGRE-Anwendungen in seiner bevorzugtenSoftware zu erstellen ohne sich um OGRE-spezi�sche Details kümmern zu müssen.

Wichtigster Bestandteil ist das oFusion-Ansichtsfenster, welches sich nahtlos in 3ds Maxintegriert (siehe Abbildung 7.4 auf Seite 78). Es werden 3D-Modelle, Lichter, Kameras,Animationen, Materialien und Shader in der Echtzeit-Ansicht unterstützt.

Abbildung 7.4: Die OGRE-Renderansicht inner-halb von 3ds Max

oFusion unterstützt die 3ds Max-Materialien Standard-, Blend-, Multi-/Sub-Object-, Shell-Material und Bit-map-Texturemap. Diese werden in-tern automatisch in OGRE-Mate-rialien konvertiert. Echte OGRE-Materialien erstellt man mithilfedes neuen OGRE-Materials (wel-ches sich nochmal in Technique-und Pass-Material aufteilt) in 3dsMax und man kann mit diesemauf alle Funktionen des OGRE-Materialsystem (siehe Kapitel 4.1 aufSeite 44) zurückgreifen. oFusion un-terstützt auÿerdem Shader in HLSLund Cg in Echtzeit. Dabei können dieParameter der Shader über einen Ei-

genschaftseditor angepasst werden.

Die in 3ds Max erstellten Inhalte können in für OGRE-geeignete Formate exportiertwerden. 3D-Modelle werden in das .mesh-, Materialien in das .-material-, Shader in das.shader- und .program- und Skelettanimation in das .skeleton-Format exportiert.Noch komfortabler exportiert man Inhalte von 3ds Max in die OGRE-Anwendung durchden oFusion Scene Loader und dem dazugehörigen .osm-Format. Dabei wird die kom-plette Szene in eine Datei exportiert, die von der OGRE-Anwendung durch einen Funk-tionsaufruf geladen wird. Somit wird die Szene genauso, wie man sie in 3ds Max erstellthat, mit wenig Aufwand in die OGRE-Anwendung importiert.

oFusion ist für nicht kommerzielle Benutzung kostenlos. Zur kommerziellen Nutzungwerden keine ö�entlichen Preisinformationen zur Verfügung gestellt.

78

Page 79: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

7.7 RenderMonkey-Shader Exporter

Der RenderMonkey-Shader Exporter9 ist eine Erweiterung zu RenderMonkey von ATITechnologies10.RenderMonkey ist eine Entwicklungsumgebung für Shader, die alle Komponenten be-reitstellt, um moderne Shader zu entwickeln. Ein Shader-Projekt besteht dabei aus demeigentlichen Shader-Quellcode sowie Variablen-, 3D-Modell-, Textur- und Lichtdeklara-tionen. Der Shader-Quellcode wird über einen Texteditor erstellt und das Ergebnis kannin Echtzeit im Vorschaufenster betrachtet werden (siehe Abbildung 7.5 auf Seite 79). Eswerden Shader in Assembler als auch in den Hochsprachen HLSL und GLSL unterstützt.Für weitere Informationen zur Shaderentwicklung mit RenderMonkey siehe [SL04].

Abbildung 7.5: Ein Bump-Mapping Shader in RenderMonkey von ATI Technologies

Mit dem Shader Exporter kann man nun den Shader in das OGRE-Shaderformat expor-tieren. Der Shader-Quellcode wird dabei in .source-Dateien und die Shader-Deklarationin .program-Dateien gespeichert. Auÿerdem wird eine Materialde�nition in einer .material-Datei erstellt. Diese Materialde�nition kann man nun 3D-Modellen innerhalb der OGRE-Anwendung mit Entity::setMaterialName() zuweisen (siehe Abbildung 7.6 auf Seite80).

9erhältlich unter: http://ogre.cvs.sourceforge.net/ogre/ogreaddons/RmOgreExporter/10erhältlich unter http://www.ati.com/developer/rendermonkey/

79

Page 80: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

(a) Shader in RenderMonkey (b) Shader innerhalb einer OGRE-Anwendung

Abbildung 7.6: Ein einfacher Specular Lighting Shader mit einer Holztextur

Der Exporter liegt in Version 2 vor und bietet neben schlankeren erzeugten Materialde-�nitionen eine Vorschau in einem OGRE-Renderfenster.

80

Page 81: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

8 Ausblick

Die Leistungsfähigkeit moderner Gra�kprozessoren wird weiter steigen und der Bedarfan interaktiven 3D-Anwendungen weiter wachsen. Bisher hat es OGRE, dank seiner en-gagierten Entwickler und der lebendigen Community, sehr gut gescha�t mit der techni-schen Entwicklung Schritt zu halten. Ein Open Source Projekt steht und fällt mit seinerCommunity und auf die kommt es in Zukunft an, um OGRE weiterzuentwickeln undauf neue Technologien abzustimmen. Wichtig wäre es, auf weitere Kooperationen mitprofessionellen Entwicklern zu setzen, um OGRE auch als Markenzeichen in der breitenÖ�entlichkeit zu etablieren. Der deutsche Entwickler des Adventures �Ankh�, Deck13,hat bereits einen Nachfolger, �Ankh - das Herz des Osiris�, wieder auf OGRE-Basisangekündigt. Auÿerdem ist gerade ein Buch, das sich mit der OGRE-Programmierungbeschäftigt, erschienen (siehe [Jun06]).

81

Page 82: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

A Quellcode

A.1 HelloWorld-Quellcode

Listing A.1: HelloWorld-Quellcode� �1 /*2 // HelloWorld.cpp3 // Einfaches OGRE -HelloWorld Beispiel4 */56 #include <Ogre.h>7 #include <OgreErrorDialog.h>8 #include <OgreEventListeners.h>9 #include <OgreKeyEvent.h>101112 using namespace Ogre;1314 class Keyboard : public KeyListener , public FrameListener15 {16 public:17 Keyboard ();18 virtual void keyClicked(KeyEvent* e);19 virtual void keyPressed(KeyEvent* e);20 virtual void keyReleased(KeyEvent* e);21 virtual bool frameEnded(const FrameEvent& evt);22 private:23 bool mEscWasPressed;24 };2526 Keyboard :: Keyboard () : mEscWasPressed(false) {}2728 void Keyboard :: keyClicked(KeyEvent* e)29 {30 if(e->getKey () == KC_ESCAPE)31 {32 mEscWasPressed = true;33 e->consume ();34 }35 }3637 void Keyboard :: keyPressed(KeyEvent* e) {}

82

Page 83: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

3839 void Keyboard :: keyReleased(KeyEvent* e) {}4041 bool Keyboard :: frameEnded(const FrameEvent& evt)42 {43 return !mEscWasPressed;44 }4546 int main(int argc , char *argv [])47 {48 try49 {50 Root* mRoot = new Root("Plugins.cfg", "Ogre.cfg", "ogre.log");5152 if(!mRoot ->showConfigDialog ())53 return 1;5455 RenderWindow* mWindow = mRoot ->initialise(true , "HelloWorld");5657 ResourceGroupManager :: getSingleton (). addResourceLocation58 ("<Pfad zum OGRE -SDK >\\ media \\ materials \\ scripts", "FileSystem");59 ResourceGroupManager :: getSingleton (). addResourceLocation60 ("<Pfad zum OGRE -SDK >\\ media \\ materials \\ programs", "FileSystem");61 ResourceGroupManager :: getSingleton (). addResourceLocation62 ("<Pfad zum OGRE -SDK >\\ media \\ materials \\ textures", "FileSystem");63 ResourceGroupManager :: getSingleton (). addResourceLocation64 ("<Pfad zum OGRE -SDK >\\ media \\ models","FileSystem");65 ResourceGroupManager :: getSingleton (). initialiseAllResourceGroups ();6667 SceneManager* mSceneManager = mRoot ->createSceneManager(ST_GENERIC );6869 Entity* mOgreEntity = mSceneManager ->createEntity("OgreEntity1",70 "ogrehead.mesh");7172 SceneNode* mOgreSceneNode = mSceneManager ->getRootSceneNode ()->73 createChildSceneNode("Ogre1Node", Vector3 (0,0,0));74 mOgreSceneNode ->attachObject(mOgreEntity );7576 mSceneManager ->setAmbientLight(ColourValue (0.1 ,0.1 ,0.1 ,1));7778 Light* mLight = mSceneManager ->createLight("Light1");79 mLight ->setPosition (-80, 80, 200);8081 Camera* mCamera = mSceneManager ->createCamera("Camera1");82 mCamera ->setNearClipDistance (5);83 mCamera ->setPosition(Vector3 (40 ,40 ,100));84 mCamera ->lookAt (0,0,0);8586 Viewport* mViewport = mWindow ->addViewport(mCamera );87 mCamera ->setAspectRatio(Real(mViewport ->getActualWidth ()) /88 Real(mViewport ->getActualHeight ()));89

83

Page 84: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

90 Keyboard* mKeyboard = new Keyboard ();91 mRoot ->addFrameListener(mKeyboard );92 EventProcessor* mEventProcessor = new EventProcessor ();93 mEventProcessor ->addKeyListener(mKeyboard );94 mEventProcessor ->initialise(mWindow );95 mEventProcessor ->startProcessingEvents ();9697 mRoot ->startRendering ();98 delete mRoot;99 }100 catch (Exception& e)101 {102 ErrorDialog* errorDlg =103 PlatformManager :: getSingleton (). createErrorDialog ();104 errorDlg ->display(e.getFullDescription ());105 delete errorDlg;106 return 1;107 }108 return 0;109 }� �

84

Page 85: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

A.2 Eine interaktive Anwendung-Quellcode

Listing A.2: Eine interaktive Anwendung-Quellcode� �1 /*2 // Ein interaktives Beispiel: Kamera - und Charaktersteuerung3 */45 #include <Ogre.h>6 #include <OgreErrorDialog.h>7 #include <OgreEventListeners.h>8 #include <OgreKeyEvent.h>910 using namespace Ogre;1112 SceneNode* mCameraNode;13 Vector3 mTranslateVector = Vector3 ::ZERO;14 Radian mRotX = Radian (0);15 Radian mRotY = Radian (0);16 const Real mMoveScale = 150;17 const Degree mRotScale = Degree (60);1819 SceneNode* mOgreSceneNode;20 AnimationState* mAnimWalk;21 AnimationState* mAnimIdle;22 Vector3 mRobotTranslate = Vector3 ::ZERO;23 Radian mRobotRot = Radian (0);2425 class Keyboard : public KeyListener , public FrameListener26 {27 public:28 Keyboard ();29 virtual void keyClicked(KeyEvent* e);30 virtual void keyPressed(KeyEvent* e);31 virtual void keyReleased(KeyEvent* e);32 virtual bool frameStarted(const FrameEvent& evt);33 virtual bool frameEnded(const FrameEvent& evt);34 private:35 bool mEscWasPressed;36 };3738 Keyboard :: Keyboard () : mEscWasPressed(false) {}3940 void Keyboard :: keyClicked(KeyEvent* e)41 {42 if(e->getKey () == KC_ESCAPE)43 {44 mEscWasPressed = true;45 e->consume ();46 }47 }48

85

Page 86: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

49 void Keyboard :: keyPressed(KeyEvent* e)50 {51 if (e->getKey () == KC_UP)52 mTranslateVector.z -= mMoveScale;53 if (e->getKey () == KC_DOWN)54 mTranslateVector.z += mMoveScale;5556 if (e->getKey () == KC_LEFT)57 mTranslateVector.x -= mMoveScale;58 if (e->getKey () == KC_RIGHT)59 mTranslateVector.x += mMoveScale;6061 if (e->getKey () == KC_PGUP)62 mTranslateVector.y += mMoveScale;63 if (e->getKey () == KC_PGDOWN)64 mTranslateVector.y -= mMoveScale;6566 if (e->getKey () == KC_W)67 mRotY -= mRotScale;68 if (e->getKey () == KC_S)69 mRotY += mRotScale;7071 if (e->getKey () == KC_A)72 mRotX += mRotScale;73 if (e->getKey () == KC_D)74 mRotX -= mRotScale;7576 if(e->getKey ()== KC_NUMPAD8)77 {78 mRobotTranslate.x += mMoveScale / 4;79 mAnimIdle ->setEnabled(false );80 mAnimWalk ->setEnabled(true);81 }82 if(e->getKey ()== KC_NUMPAD2)83 {84 mRobotTranslate.x -= mMoveScale / 4;85 mAnimIdle ->setEnabled(false );86 mAnimWalk ->setEnabled(true);87 }88 if(e->getKey ()== KC_NUMPAD4)89 {90 mRobotRot += mRotScale;91 mAnimIdle ->setEnabled(false );92 mAnimWalk ->setEnabled(true);93 }94 if(e->getKey ()== KC_NUMPAD6)95 {96 mRobotRot -= mRotScale;97 mAnimIdle ->setEnabled(false );98 mAnimWalk ->setEnabled(true);99 }100 }

86

Page 87: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

101102 void Keyboard :: keyReleased(KeyEvent* e)103 {104 if (e->getKey () == KC_UP)105 mTranslateVector.z += mMoveScale;106 if (e->getKey () == KC_DOWN)107 mTranslateVector.z -= mMoveScale;108109 if (e->getKey () == KC_LEFT)110 mTranslateVector.x += mMoveScale;111 if (e->getKey () == KC_RIGHT)112 mTranslateVector.x -= mMoveScale;113114 if (e->getKey () == KC_PGUP)115 mTranslateVector.y -= mMoveScale;116 if (e->getKey () == KC_PGDOWN)117 mTranslateVector.y += mMoveScale;118119 if (e->getKey () == KC_W)120 mRotY += mRotScale;121 if (e->getKey () == KC_S)122 mRotY -= mRotScale;123124 if (e->getKey () == KC_A)125 mRotX -= mRotScale;126 if (e->getKey () == KC_D)127 mRotX += mRotScale;128129 if(e->getKey ()== KC_NUMPAD8)130 {131 mRobotTranslate.x -= mMoveScale / 4;132 mAnimIdle ->setEnabled(true);133 mAnimWalk ->setEnabled(false );134 }135 if(e->getKey ()== KC_NUMPAD2)136 {137 mRobotTranslate.x += mMoveScale / 4;138 mAnimIdle ->setEnabled(true);139 mAnimWalk ->setEnabled(false );140 }141 if(e->getKey ()== KC_NUMPAD4)142 {143 mRobotRot -= mRotScale;144 mAnimIdle ->setEnabled(true);145 mAnimWalk ->setEnabled(false );146 }147 if(e->getKey ()== KC_NUMPAD6)148 {149 mRobotRot += mRotScale;150 mAnimIdle ->setEnabled(true);151 mAnimWalk ->setEnabled(false );152 }

87

Page 88: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

153 }154155 bool Keyboard :: frameStarted(const FrameEvent& evt)156 {157 mAnimIdle ->addTime(evt.timeSinceLastFrame );158 mAnimWalk ->addTime(evt.timeSinceLastFrame );159160 mOgreSceneNode ->yaw(mRobotRot * evt.timeSinceLastFrame );161 mOgreSceneNode ->translate(mOgreSceneNode ->getOrientation () *162 mRobotTranslate * evt.timeSinceLastFrame );163164 mCameraNode ->yaw(mRotX * evt.timeSinceLastFrame );165 mCameraNode ->pitch(mRotY * evt.timeSinceLastFrame );166 mCameraNode ->translate(mCameraNode ->getOrientation () *167 mTranslateVector * evt.timeSinceLastFrame );168169 return true;170 }171172 bool Keyboard :: frameEnded(const FrameEvent& evt)173 {174 return !mEscWasPressed;175 }176177 int main(int argc , char *argv [])178 {179 try180 {181 Root* mRoot = new Root("Plugins.cfg", "Ogre.cfg", "ogre.log");182183 if(!mRoot ->showConfigDialog ())184 return 1;185186 RenderWindow* mWindow = mRoot ->initialise(true ,187 "Interaktive Anwendung");188189 ResourceGroupManager :: getSingleton (). addResourceLocation190 ("C:\\ Programmieren \\ OgreSDK \\media \\ materials \\ scripts",191 "FileSystem");192 ResourceGroupManager :: getSingleton (). addResourceLocation193 ("C:\\ Programmieren \\ OgreSDK \\media \\ materials \\ programs",194 "FileSystem");195 ResourceGroupManager :: getSingleton (). addResourceLocation196 ("C:\\ Programmieren \\ OgreSDK \\media \\ materials \\ textures",197 "FileSystem");198 ResourceGroupManager :: getSingleton (). addResourceLocation199 ("C:\\ Programmieren \\ OgreSDK \\media \\ models","FileSystem");200 ResourceGroupManager :: getSingleton (). initialiseAllResourceGroups ();201202 SceneManager* mSceneManager =203 mRoot ->createSceneManager(ST_GENERIC );204

88

Page 89: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

205 Entity* mOgreEntity = mSceneManager ->createEntity("OgreEntity1",206 "robot.mesh");207208 mOgreSceneNode = mSceneManager ->getRootSceneNode ()->209 createChildSceneNode("Ogre1Node", Vector3 (0,0,0));210 mOgreSceneNode ->attachObject(mOgreEntity );211 mOgreSceneNode ->setScale (0.5, 0.5, 0.5);212213 mAnimWalk = mOgreEntity ->getAnimationState("Walk");214 mAnimWalk ->setLoop(true);215 mAnimIdle = mOgreEntity ->getAnimationState("Idle");216 mAnimIdle ->setLoop(true);217 mAnimIdle ->setEnabled(true);218219 mSceneManager ->setAmbientLight(ColourValue (0.1 ,0.1 ,0.1 ,1));220221 Light* mLight = mSceneManager ->createLight("Light1");222 mLight ->setPosition (-80, 80, 200);223224 Camera* mCamera = mSceneManager ->createCamera("Camera1");225 mCamera ->setNearClipDistance (5);226 mCameraNode = mSceneManager ->getRootSceneNode ()->227 createChildSceneNode("CameraNode", Vector3(0, 0, 0));228 mCameraNode ->attachObject(mCamera );229 mCameraNode ->translate (40, 40, 100);230 mCameraNode ->setDirection(-mCameraNode ->getPosition ());231232 Viewport* mViewport = mWindow ->addViewport(mCamera );233 mCamera ->setAspectRatio(Real(mViewport ->getActualWidth ()) /234 Real(mViewport ->getActualHeight ()));235236 Keyboard* mKeyboard = new Keyboard ();237 mRoot ->addFrameListener(mKeyboard );238 EventProcessor* mEventProcessor = new EventProcessor ();239 mEventProcessor ->addKeyListener(mKeyboard );240 mEventProcessor ->initialise(mWindow );241 mEventProcessor ->startProcessingEvents ();242243 mRoot ->startRendering ();244 delete mRoot;245 }246 catch (Exception& e)247 {248 ErrorDialog* errorDlg =249 PlatformManager :: getSingleton (). createErrorDialog ();250 errorDlg ->display(e.getFullDescription ());251 delete errorDlg;252 return 1;253 }254 return 0;255 }� �

89

Page 90: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

A.3 Compositor: Weichzeichner-Materialskript

Listing A.3: SimpleBlur-Materialskript� �1 // Pixelshader -Deklaration2 fragment_program SimpleBlur.Pixel_Shader hlsl3 {4 source VDS.ScreenSpace.SimpleBlur.Pixel_Shader.source5 target ps_2_06 entry_point ps_main78 default_params9 {10 param_named_auto viewport_inv_width inverse_viewport_width11 param_named_auto viewport_inv_height inverse_viewport_height12 }13 }1415 // Effekt: Ein einfacher Blur -Filter16 material ScreenSpace.SimpleBlur17 {18 technique19 {20 pass21 {22 depth_check off2324 // Verweis auf den Pixelshader25 fragment_program_ref SimpleBlur.Pixel_Shader26 {27 }2829 // Übergabe der Textur30 texture_unit Texture031 {32 tex_coord_set 033 tex_address_mode clamp34 filtering linear linear linear3536 }37 }38 }39 }� �

90

Page 91: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

A.4 Compositor: Weichzeichner-Pixelshader

Listing A.4: SimpleBlur-Pixelshader� �1 float viewport_inv_width;2 float viewport_inv_height;34 // Das gerenderte Bild in einer Textur5 sampler Texture0: register(s0);67 float4 ps_main(float2 texCoord: TEXCOORD0) : COLOR8 {9 // Filter -Kernerl10 float4 samples [4] = {11 -1.0, 0.0, 0, 0.25,12 1.0, 0.0, 0, 0.25,13 0.0, 1.0, 0, 0.25,14 0.0, -1.0, 0, 0.2515 };1617 float4 col = float4 (0,0,0,0);1819 // Wende einen Box -Filter auf das Pixel an20 for(int i=0;i<4;i++)21 col += samples[i].w*tex2D(Texture0 ,texCoord+22 float2(samples[i].x*viewport_inv_width ,23 samples[i].x*viewport_inv_height ));2425 return col;26 }� �

91

Page 92: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

A.5 Beispielshader: Vertexshader

Listing A.5: Vertexshader des Beispielshaders� �1 struct VS_INPUT2 {3 float4 Pos: POSITION;4 float3 Normal: NORMAL;5 float2 Txr: TEXCOORD0;6 };78 struct VS_OUTPUT9 {10 float4 Pos: POSITION;11 float2 Txr: TEXCOORD0;12 float4 Color: COLOR0;13 };1415 float4x4 matViewProjection; // Transformationsmatrix16 float4 viewPosition; // Die Position des Betrachters17 float4 LightAmbient; // Das ambiente Licht18 float4 LightPos; // Position der Lichtquelle19 float4 LightColor; // Farbe der Lichtquelle2021 float4 Light_PointDiffuse(float3 VertPos , float3 VertNorm ,22 float3 LightPos , float4 LightColor)23 {24 // Berechne die Richtung aus der das Licht auf den Vertex trifft und25 // normalisiere diesen Vektor26 float3 LightDir = normalize(LightPos - VertPos );2728 // Berechne die Lichtintensität bezüglich des Winkels zwischen29 // der Lichtrichtung und der Vertex -Normalen über das Punktprodukt30 float AngleAttn = dot(VertNorm , LightDir );3132 // Da dieser Wert negativ werden kann , muss er auf den Wertebereich33 // [0, 1] beschnitten werden34 AngleAttn = clamp(0, 1, AngleAttn );3536 // Berechne finale Beleuchtungsintensität37 return LightColor * AngleAttn;38 }3940 VS_OUTPUT vs_main(VS_INPUT In)41 {42 VS_OUTPUT Out;4344 // Berechne die in den Bildschirmraum projizierte Position des Vertex45 Out.Pos = mul(matViewProjection , In.Pos);4647 // Leite Texturkoordinaten unverändert weiter48 Out.Txr = In.Txr;

92

Page 93: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

4950 // Das ambiente Licht definiert den Grundanteil der Lichtintensität51 float4 Color = LightAmbient;5253 // Berechne Lichtintensität durch die zuvor definierte Funktion54 Color += Light_PointDiffuse(In.Pos , In.Normal ,55 LightPos , LightColor );5657 // Gib berechnete Farbe an den Pixelshader weiter58 Out.Color = Color;5960 return Out;61 }� �

A.6 Beispielshader: Pixelshader

Listing A.6: Pixelshader des Beispielshaders� �1 struct PS_INPUT2 {3 float2 Txr: TEXCOORD0;4 float4 Color: COLOR0;5 };67 sampler Texture0;89 float4 ps_main(PS_INPUT In)10 {11 // Die endgültige Farbe des aktuellen Pixels ergibt sich aus12 // der interpolierten Lichtintensität , die im Vertexshader13 // berechnet wurde multipliziert mit dem Farbwert der Textur14 float4 finalColor = In.Color * tex2D(Texture0 , In.Txr);1516 // Die berechnete Farbe wird ausgegeben17 return finalColor;18 }� �

93

Page 94: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

B Inhalt der Begleit-CD

Im Ordner Ausarbeitung be�ndet sich diese Bachelorarbeit als .pdf-Datei (OGRE3D,Bachelor, Lars Bilke.pdf ).Im Ordner Beispiele be�ndet sich die Visual Studio Projektdatei der in der Arbeit be-sprochenen Beispielprogramme. Die ausführbaren Dateien liegen im Unterordner debugund release Um die Beispiele auszuprobieren, muss das Beispiele-Verzeichnis erst aufFestplatte kopiert werden, da OGRE Schreibzugri� auf einige Dateien benötigt..Der Ordner OGRE3D enthält das OGRE-SDK und den OGRE-Quellcode der Version1.2.2.Nützliche Tools für OGRE sind im Ordner Tools zu �nden.

94

Page 95: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

Literaturverzeichnis

[Dev06] DevMaster.net: Vergleich von 3D-Engines. URL: http://www.

devmaster.net/engines, September 2006.

[Eng05] Engel, Wolfgang: ShaderX3. ShaderX Series. Charles River Media, 2005.

[Eri05] Ericson, Christer: Real-Time Collision Detection. Series In Interactive3D Technology. Morgan Kaufmann Publishers, 2005.

[Fer04] Fernando, Randima: GPU Gems. Pearson Education, Inc., September2004.

[Gar06] GarageGames.com: Homepage der 3D-Engine Torque. URL: http://www.garagegames.com, September 2006.

[Irr06] Irrlicht.Sourceforge.net/: Homepage der 3D-Engine Irrlicht. URL:http://irrlicht.sourceforge.net/, September 2006.

[Jun06] Junker, Gregory: Pro OGRE 3D Programming. Springer-Verlag NewYork, 2006.

[Mot03] Mothe, André La: Tricks Of The 3D Game Programming Gurus - Advanced3D Graphics And Rasterization. Sams Publishing, Juni 2003.

[Pan06] Panda3D.org: Homepage der 3D-Engine Panda3D. URL: http://www.panda3d.org, September 2006.

[Rad06] RadonLabs.de: Homepage der 3D-Engine Nebula Device. URL: http://www.radonlabs.de, September 2006.

[Ros04] Rost, Randi J.: OpenGL Shading Language. Pearson Education, Inc., 2004.

[Sch03] Scherfgen, David: 3D-Spieleprogrammierung - Modernes Game Design mitDirectX 9 und C++. Carl Hanser Verlag München, 2003.

[Sch06] Schürmann, Tim: Spieleentwicklung mit OGRE. GameStar/dev, Mai 2006.

[SL04] St-Laurent, Sebastian: Shaders For Game Programmers And Artists.Thomson Course Technology PTR, 2004.

[The06a] The OGRE Team: Ogre api reference v1.2.2, Juli 2006.

[The06b] The OGRE Team: Ogre manual v1.2.2 ('dagon'), Juli 2006.

[Unr06] Unrealtechnology.com: Homepage der Unreal-Engine. URL: http://unrealtechnology.com/, September 2006.

95

Page 96: Untersuchung des Funktionsumfangs und der Leistungsfähigkeit der Grafik-Engine Ogre3D

[Val06] ValveSoftware.com: Engine Licensing Information Sheet. URL: http://www.valvesoftware.com, September 2006.

[Wik06] Wikipedia, Online-Enzyklopädie: Diverse Artikel. URL: http://www.wikipedia.org, September 2006.

96