Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005

Die Seite wird erstellt Hannah Martens
 
WEITER LESEN
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Department für Informatik
               Universität Fribourg, Schweiz
                     http://diuf.unifr.ch/

Einführung in die Echtzeit-3D-Grafik mit Java

                  Bachelorarbeit

                  Daniel Egger
                September 2005

                  Unter der Aufsicht von:
             Prof. Dr. J. PASQUIER -ROCHA und
                        Dr. P. F UHRER
                Software Engineering Group
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
“Mighty is geometry. When joined with art, resistless.”
                                           - Euripides

  i
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
ii

Zusammenfassung
Das Ziel dieser Bachelorarbeit ist es, wie der Titel eigentlich schon treffend ausdrückt, eine Einführung
in die Echtzeit-3D-Graphik mit Java zu geben. Als erster Schritt wurden dazu die verfügbaren Optionen
untersucht und angeschaut. Nach Auswahl der Java 3D-Engine jMonkey Engine auch jME genannt [36]
wurden deren Einsaztmöglichkeiten getestet. Im dritten und letzten Teil der Arbeit wurde ein Tutorial ge-
schrieben, um den Lesern zu zeigen, wie man mit Hilfe von jME Echtzeit-3D-Grafik auf den Bildschirm
bringen kann. Es ist vor allem das Resultat dieses Tutorials, was man im Rapport finden kann. Schon
diese Einleitung beinhaltet einige Wörter, die den einen oder anderen Leser vielleicht bereits verwirren,
ich hoffe aber im Verlauf des Textes die meisten Unklarheiten klären zu können. Es wird aber voraus-
gesetzt das die Leser zumindest einige Grundkenntnisse in Java haben oder zumindest gute Kenntnisse
in einer anderen objektorientierten Programmiersprache. Falls sie noch einige Probleme mit Java haben,
kann ich das Buch Thinking in Java von Bruce Eckel[Eck02] empfehlen, das mir einen hervorragenden
Einstieg in die objektorientierte Programmierung mit Java bereitet hat.

Schlüsselwörter:
3D-Graphik, 3D-Engine, Echtzeit-Rendering, Java, jMonkey Engine, OpenGL,
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Inhaltsverzeichnis

I.     Einleitung                                                                                                                                                       2

1. Bachelorprojekt                                                                                                                                                       3
      1.1. Beschreibung der Aufgabe . . . . . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      1.2. Projektablauf . . . . . . . . . . . . . . . .                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
           1.2.1. 1. Schritt: Auswahl einer 3D-Engine                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
           1.2.2. 2. Schritt: Machbarkeitstest . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    6
           1.2.3. 3. Schritt: Tutorial . . . . . . . . .                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7
      1.3. Gliederung der Dokumentation . . . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7
      1.4. Konventionen und Notationen . . . . . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7

2. 3D-Grafik                                                                                                                                                             8
      2.1.   Was ist 3D-Grafik? . . . . . . . .   .   .   .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 8
      2.2.   Was bedeutet Echtzeit-3D-Grafik?     .   .   .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 10
      2.3.   Was ist eine 3D-Engine? . . . . .    .   .   .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 13
      2.4.   Zusammenfassung . . . . . . . .      .   .   .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 13

II.    Tutorial                                                                                                                                                         14

3. Erste Schritte mit jME                                                                                                                                               15
      3.1. Unser erstes jME-Programm . . . . .            .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
      3.2. Scenegraph . . . . . . . . . . . . . .         .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   18
           3.2.1. Was ist ein Scenegraph? . . .           .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   18
           3.2.2. Zustände im Kontext von jME             .   .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   21

4. Wie funktioniert 3D-Grafik                                                                                                                                           22
      4.1. Was macht eine 3D-Engine? . . . . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   22
      4.2. Das 3D-Koordinatensystem . . . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
           4.2.1. 2D-Koordinatensystem . . . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
           4.2.2. 3D-Koordinatensystem . . . . . .                  .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
           4.2.3. Model-Space vs. World-Space . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   24
      4.3. Transformationen im Raum . . . . . . . .                 .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
           4.3.1. Verschiebungen (engl. translation)                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
           4.3.2. Rotationen (engl. rotation) . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
           4.3.3. Skalierungen (engl. scaling) . . .                .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   25
           4.3.4. Alle Bewegungen zusammen . . .                    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
      4.4. Perspektive und Projektion . . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
      4.5. Kamera . . . . . . . . . . . . . . . . . .               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   27

                                                              iii
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Inhaltsverzeichnis                                                                                                                                                          iv

   4.6. jME, OpenGL, DirectX, 3D-Pipeline: Was ist das? Was machen die? . . . . . . . . . . . 29
   4.7. Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

5. Interaktion                                                                                                                                                              31
   5.1. Einfache Interaktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
   5.2. Ein objektorientierter Ansatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

6. Simple Formen und Modelle                                                                                                                                                37
   6.1. Einfache Formen und warum die Kugeln nicht rund sind                                            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37
   6.2. Komplexere Modelle . . . . . . . . . . . . . . . . . . .                                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   40
        6.2.1. Modell-Formate . . . . . . . . . . . . . . . . .                                         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   40
        6.2.2. Modelle laden in jME . . . . . . . . . . . . . .                                         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   41

7. Es werde Licht                                                                                                                                                           44
   7.1. Lichtquellen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
   7.2. Lichter einsetzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

8. Texturen                                                                                                                                                                 50
   8.1. Was sind Texturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
   8.2. Texturen einsetzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
   8.3. Wie geht es weiter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54

9. Landschaften                                                                                                                                                             56
   9.1.   Einführung . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   56
   9.2.   Heightmaps . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   56
   9.3.   Landschaften darstellen . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   58
   9.4.   Landschaften mit Texturen     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   61
   9.5.   Skybox . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   63

10. Final Island                                                                                                                                                            68
   10.1. Der Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
   10.2. Fazit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

A. CD-ROM                                                                                                                                                                   73

B. Ein jME-Demo in der Konsole starten und kompilieren                                                                                                                      75
   B.1. Demos starten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
   B.2. Demos kompilieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75

C. Verwendete Software                                                                                                                                                      77
   C.1. Entwicklung . . . . . . . . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   77
        C.1.1. Java . . . . . . . . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   77
        C.1.2. Eclipse . . . . . . . .          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   77
   C.2. Dokumentation . . . . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   77
        C.2.1. LATEX und Co . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   77
        C.2.2. Violet UML-Tool . . .            .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   77
        C.2.3. Dia Diagramm-Editor              .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   78
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Abbildungsverzeichnis

1.1. Screenshot aus dem finalen Projekt des Gameversity Kurses . . . . . . . . . . . . . . .                                                                    6

2.1.   Ein Screenshot von Blender . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 9
2.2.   Ein Ausschnitt aus “Geri’s Game” . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 10
2.3.   Ausschnitt aus dem Film Madagascar           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 11
2.4.   Zeitlinie Echtzeit-3D-Spiele . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   . 12

3.1.   Screenshot aus HelloWorld . . . . . . . . . . . . . . . . . . . .                                    .   .   .   .   .   .   .   .   .   .   .   .   .   16
3.2.   Screenshot des Einstellungsdialogs der bei jedem Start erscheint                                     .   .   .   .   .   .   .   .   .   .   .   .   .   17
3.3.   Eine Hierarchie von einem Haus . . . . . . . . . . . . . . . . .                                     .   .   .   .   .   .   .   .   .   .   .   .   .   19
3.4.   UML-Diagramm der Scenegraph Elemente . . . . . . . . . . .                                           .   .   .   .   .   .   .   .   .   .   .   .   .   20
3.5.   UML Diagramm der RenderStates . . . . . . . . . . . . . . . .                                        .   .   .   .   .   .   .   .   .   .   .   .   .   21

4.1.   Ein rechthändiges 3D-Koordinatensystem               .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   23
4.2.   Ein Würfel rotiert, bewegt und skaliert . .          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   27
4.3.   Projektionen . . . . . . . . . . . . . . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28
4.4.   3D-Pipeline . . . . . . . . . . . . . . . .          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   28
4.5.   jME und OpenGL . . . . . . . . . . . . .             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   29

5.1. Die verschiedenen InputActions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

6.1. Ein Screenshot aus der Demo SimpleGeometry.java . . . . . . . . . . . . . . . . . . . . 38
6.2. Milkshape 3D mit dem Ferrari Modell . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.3. Screenshot von ModelLoader.java mit Blick auf das Gittermodell . . . . . . . . . . . . . 41

7.1. Eine Szene mit Licht (links) und ohne Licht (rechts) . . . . . . . . . . . . . . . . . . . . 45
7.2. Ein Punktlicht . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
7.3. Screenshot aus der Licht Demo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

8.1.   Eine Stadt mit und ohne Textur . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   51
8.2.   Textur vom Ferrari Modell . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   51
8.3.   Screenshot von der Texturen Demo     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   52
8.4.   Beispiel für Bump-Mapping . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   54

9.1.   Screenshot aus Oblivion von Bethesda Softworks . . . . . . . .                                       .   .   .   .   .   .   .   .   .   .   .   .   .   57
9.2.   Eine sehr einfache 3D-Landschaft . . . . . . . . . . . . . . . .                                     .   .   .   .   .   .   .   .   .   .   .   .   .   57
9.3.   Ein Beispiel für eine Heightmap . . . . . . . . . . . . . . . . .                                    .   .   .   .   .   .   .   .   .   .   .   .   .   58
9.4.   Eine Landschaft generiert aus der Heightmap aus Abbildung 9.3                                        .   .   .   .   .   .   .   .   .   .   .   .   .   59
9.5.   Screenshot aus TerrainDemo.java . . . . . . . . . . . . . . . . .                                    .   .   .   .   .   .   .   .   .   .   .   .   .   59

                                                        v
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Abbildungsverzeichnis                                                                                                                         vi

   9.6.   Unsere Landschaft mit einigen saftigen, grünen Hügeln       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   61
   9.7.   Rechts die Grastextur, links die Detailtextur . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   62
   9.8.   Würfelbild mit der Skybox . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   64
   9.9.   Screenshot von der Skybox Demo . . . . . . . . . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   64

   10.1. Final Island: Blick auf das Wasser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
   10.2. Final Island: Blick auf das Jeep-Modell . . . . . . . . . . . . . . . . . . . . . . . . . . 69
   10.3. Beispiel für eine Particle Engine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

   A.1. CD-Rom Inhalt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Listings

3.1. HelloWorld.java . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   15
3.2. HelloWorld.java, simpleInitGame . . . . . . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
4.1. SimpleTransformation.java . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   26
5.1. InputDemo.java . . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   31
5.2. InputActions.java simpleInitGame and simpleUpdate             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   34
5.3. InputActions.java KeyNodeUpAction . . . . . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   36
6.1. SimpleGeometry.java . . . . . . . . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37
6.2. ModelLoader.java . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   41
7.1. SimpleLight.java . . . . . . . . . . . . . . . . . . . . .    .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   46
7.2. Lichter aktivieren mit LightStates . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   48
8.1. TextureDemo.java . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   50
9.1. TerrainDemo.java . . . . . . . . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   58
9.2. TerrainWithTexture.java . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   62
9.3. SkyBoxTest.java . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   63
9.4. SkyBox.java . . . . . . . . . . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   65
10.1. FinalIsland.java . . . . . . . . . . . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   68

                                                 1
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Teil I.

Einleitung

     2
Einführung in die Echtzeit-3D-Grafik mit Java - Bachelorarbeit Daniel Egger September 2005
Bachelorprojekt
                                                                                                                                                          1
         1.1. Beschreibung der Aufgabe . . . . . . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   3
         1.2. Projektablauf . . . . . . . . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   3
              1.2.1. 1. Schritt: Auswahl einer 3D-Engine      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   3
              1.2.2. 2. Schritt: Machbarkeitstest . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   6
              1.2.3. 3. Schritt: Tutorial . . . . . . . . .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   7
         1.3. Gliederung der Dokumentation . . . . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   7
         1.4. Konventionen und Notationen . . . . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   7

1.1. Beschreibung der Aufgabe
Ziel dieser Bachelorarbeit ist es, Leuten mit Programmiererfahrung, die 3D-Grafikprogrammierung nä-
her zu bringen. Es wird sogar angenommen das die Zielgruppe keinerlei spezielle vorherige Kenntnis-
se der 3D-Grafik hat. Das bringt natürlich einige Einschränkungen mit sich. Einerseits will man zwar
schnell einige sehenswerte Ergebnisse haben, deshalb wurde auch eine Engine ausgewählt, mit der man
schnell etwas auf den Bildschirm “zaubern” kann. Andererseits sollte man trotzdem ein wenig die Theo-
rie verstehen. Das ist keine leichte Aufgabe, wenn man bedenkt wie breit und zum Teil auch komplex
allein der Teilbereich des 3D-Echtzeitrendering ist. Ich selbst bin häufig auf Schwierigkeiten gestossen,
ein bestimmtes Teilgebiet dieser Materie zu erklären. Aber ich hoffe trotz allen Problemen und Schwie-
rigkeiten ist das Tutorial immer noch verständlich.

1.2. Projektablauf
Das ganze Bachelorprojekt ist in drei Hauptschritten angegangen worden. Im ersten Schritt wurden ver-
schiedene 3D-Engines evaluiert um dann eine von diesen auszuwählen. Im zweiten Schritt wurde eine
kleine Machbarkeitsstudie ausgeführt um zu sehen. Es wurde eine grössere Beispielanwendung ent-
wickelt, die auch das Ziel des eigentlichen Tutorials ist. Im dritten und letzten und bei weitem auch
umfangreichsten Schritt wurde das Tutorial selbst mit sehr vielen kleinen Beispielanwendungen ge-
schrieben. Aber gehen wir auf die einzelnen Schritte doch noch ein wenig näher ein.

1.2.1. 1. Schritt: Auswahl einer 3D-Engine
Ziel des ersten Abschnitts meiner Bachelorarbeit bestand darin einen Überblick über die fast schon
unzähligen 3D-Engines zu gewinnen und danach eine 3D-Engine für den weiteren Verlauf des Projektes
auszuwählen. 3D-Engines gibt es wie Sand am Meer möchte man fast meinen. Allein eine Suche auf
Google mit dem Stichwort “3D Engine” ergibt 469’000 Ergebnisse (Stand: August 2005) und die Zahl

                                                      3
1.2. Projektablauf                                                                                                       4

ist steigend. Man kann sich vorstellen, dass unter diesen Bedingungen schon dieser erste Schritt nicht
ganz leicht ist. Um die Auswahl etwas zu vereinfachen und zu systematisieren wurden einige Kriterien
erstellt. Im einzelnen sind das folgende Kriterien:

   1. Die 3D-Engine muss mit Java benutzt werden können und auf verschiedenen Plattformen laufen,
      nicht nur auf Windows sondern zum Beispiel auch auf Linux oder MacOSX.

   2. Die 3D-Engine sollte frei verfügbar und gratis benutzbar sein. Am besten wäre eine Engine die
      unter einer Open-Source-Lizenz veröffentlicht wurde, die dieses Kriterium langfristig garantiert.

   3. Die 3D-Engine sollte ein gutes objektorientiertes Design vorweisen und ein “sauberes” Frame-
      work zur Verfügung stellen.

   4. Die Engine sollte aktuelle Techniken des Echtzeit-Rendering unterstützen.

   5. Die 3D-Engine sollte auch ausreichend dokumentiert sein.

Die oben genannten Kriterien ergeben nun einige Konsequenzen, die ich kurz aufgreifen möchte:

    • Punkt eins und drei verlangen, dass die Engine in einer objektorientierten Sprache geschrieben ist.
      (Falls möglich in Java, aber dazu weiter unten noch mehr.) Engines die noch in C, oder anderen
      prozeduralen Sprachen geschrieben sind fallen weg.

    • Punkt zwei schliesst von vorne Herein viele im Spielesektor bekannte, aber auch sehr teure (die
      Lizenzkosten belaufen sich zum Teil auf mehrere hunderttausend Dollar) Engines aus wie die
      Doom3-Engine von id-Software [29], die Source-Engine von Valve [58], die CryEngine [16] von
      Crytek, die Unreal3-Engine [57] von Epic, etc...

    • Punkt vier erfordert schlussendlich eine moderne, hardwarebeschleunigte Engine. Das bedeutet,
      dass die Engine entweder Direct3D [20] oder OpenGL [47] unterstützen muss, wobei Direct3D
      als Windows-only gleich wieder von der Liste verschwindet. Als Konsequenz davon müssen
      Software-Renderer gleich wieder von der Liste verschwinden. Der in Java-Kreisen bekannteste
      Vertreter eines Softwarerenderers dürfte dabei Java3D [33] von Sun sein. Als Randnotiz muss
      man aber beachten, dass seit der kürzlichen Open-Source Veröffentlichung von Sun auch von
      einer 3D-Beschleunigung durch OpenGL diskutiert wird.

    • Punkt fünf filtert schon viele Engines aus, die erst in den Kinderschuhen stecken oder gar nie
      richtig aus der Konzeptphase herausgekommen sind.

Mit Hilfe dieser Kriterien wurde nun eine Internetrecherche durchgeführt und die ersten Engines zur
näheren Betrachtung ausgewählt. Eine grosse Hilfe war dabei die 3D Engines Database [1]. Die Daten-
bank ist sehr umfangreich und man kann die Engines sogar anhand von bestimmtem Kriterien sortieren
und filtern.

Java gegen C++

In der Spieleindustrie ist immer noch C++, die am weitesten verbreitete Sprache. Das hat zur Folge,
dass auch die meisten 3D-Engines in C++ geschrieben sind. Es gibt viele Gründe dafür. Die am wei-
testen verbreiteten 3D-APIs1 , OpenGL und Direct3D, sind selbst C-APIs. Wie oben bereits erwähnt ist
OpenGL-Unterstützung eine Bedingung für die 3D-Engine. Als Java Programmierer können wir nun
zwei Wege gehen. Einerseits gibt es OpenGL-Wrapper für Java, wie JOGL von Sun [37] oder die Light-
weight Java Game Library LWJGL [40]. Andererseits bieten viele C++-Engines eine Java Unterstützung,
die auf dem Java Native Interface (JNI) basiert.
 1 API = Aplication Programming Interface. Eine API stellt ein Interface zur Verfügung, dass man als Programmierer benutzen

   kann.
1.2. Projektablauf                                                                                      5

C++-Engines

Als erstes habe ich einige C++-Engines untersucht. Diese sind:

   • Irrlicht Engine [30]

   • OGRE Engine [46]

   • Crystal Space Engine [17]

Diese Engines sind alle in C++ geschrieben. Sie sind alle Open Source und haben eine beeindruckende
Feature Liste. Mit der OGRE Engine wurde sogar ein kommerzielles Spiel programmiert. Leider haben
aber auch alle drei Engines eine entscheidenden Nachteil. Es existiert zwar bei allen eine Java Unterstüt-
zung, der Wrapper ist aber bei allen drei Engines sehr vernachlässigt worden und sogar die Entwickler
selbst raten davon ab ihn zu benutzen. Das heisst nun konsequenterweise, das alle diese Engines von der
Liste gestrichen werden.

Java-Engines

Glücklicherweise gibt es aber auch noch einige Engines, die direkt mit Java geschrieben wurden. Leider
führt Java im Spielentwicklungsbereich immer noch ein Mauerblümchendasein. Einerseits ist das immer
noch auf das alte und eigentlich ausgemerzte Performanceproblem zurückzuführen, das sich in einigen
Kreisen aber immer noch sehr hartnäckig weiter vertreten wird. Ehrlicherweise muss man aber auch
gestehen, dass sich Java in Sachen Grafikperformance bis vor kurzer Zeit nicht gerade mit Ruhm bekle-
ckert hat. Obwohl Sun das Problem zuerst dementiert und relativiert hat, arbeiten sie aber in letzter Zeit
direkt an der bereits angesprochenen Unterstützung von OpenGL. Es gibt auch einige Bücher die sich
direkt mit der Spiele- und Grafikprogrammierung unter Java beschäftigen wie [BBV03] und [Dav05].
Ich habe drei Java 3D-Engines in die nähere Betrachtung gezogen:

   • Aviatrix3D [9]

   • Espresso3D [24]

   • jME jMonkey Engine [36]

Leider muss man bei Aviatrix3D einige Abstriche machen, da die Dokumentation einiges zu wünschen
übrig lässt. Die Installation ist ausserdem sehr aufwändig. Espresso3D ist eine Engine, die noch nicht
lange in Entwicklung ist. Es gibt noch nicht sehr viele Features. Sehr überzeugt hat mich hingegen
jME. Die Website von jME [36] enthält schon eine ziemlich umfangreiche Dokumentation und auch die
Demos sehen sehr gut aus.

Entscheidung

Nach den Tests habe ich mich schlussendlich für jME entschieden. Sie hat alle Kriterien, die ich am
Anfang aufgestellt habe erfüllt.

   • jME ist komplett in Java geschrieben.

   • jME steht unter der BSD-Lizenz [13]. Diese Open-Source Lizenz ist sehr liberal und erlaubt sogar
     den kommerziellen Einsatz. Die Engine ist also frei für jedermann und kann von allen herunter-
     geladen, benutzt und sogar verändert werden.

   • Die Engine stellt ein gutes Framework zur Verfügung und ist leicht zu benutzen.

   • jME verwendet OpenGL [47] mit LWJGL [40]. Die Engine unterstützt also hardwarebasiertes
     Echtzeit-Rendering.
1.2. Projektablauf                                                                                 6

             Abbildung 1.1.: Screenshot aus dem finalen Projekt des Gameversity Kurses

   • jME hat bereits jetzt eine umfangreiche Dokumentation, was für ein Open Source Projekt doch
     sehr positiv bemerkbar ist.

In diesem ersten Schritt habe ich also jME ausgewählt. Die weiteren Schritte basieren natürlich auf
dieser Entscheidung.

1.2.2. 2. Schritt: Machbarkeitstest

Nachdem nun eine 3D-Engine ausgewählt worden ist, hat sich die Frage gestellt, was man damit anfan-
gen soll. Nach einigen Besprechungen mit den verantwortlichen Lehrpersonen wurde beschlossen ein
Tutorial zum Thema 3D-Grafik zu schreiben, das auch Anfänger mit Programmierkenntnissen verstehen
sollten.
Ich musste selbst noch meine 3D-Kenntnisse erweitern und habe dazu online Kurse besucht bei Game-
versity [27] und Game Institute [26]. Konkret habe ich bei Game Institute den Kurs Graphics Program-
ming with DirectX 9 - Module I und bei Gameversity den Kurs DirectX Graphic Programming besucht,
einige Scripts aus diesen Kursen können Sie auf der CD (siehe Anhang A) im Verzeichnis dateien be-
gutachten. Die Kurse werden sogar in einen amerikanischen Universitäten anerkannt. Das erfolgreiche
Bestehen dieser Kurse, ist ungefähr äquivalent mit 10 ECTS Punkten hier in der Schweiz. Diese Kurse
sind wirklich sehr empfehlenswert und jeder, der sich noch tiefer und grundlegender mit der Materie
in dieser Arbeit beschäftigen will, kann ich diese Kurse sehr ans Herz legen. Diese Erfahrung hat mit
gezeigt, dass man sehr wohl in Online basierten Kursen hervorragendes Wissen vermitteln kann.
Lange Rede kurzer Sinn. Beim Gameversity Kurs, erlernte man das Anwenden und die Implementation
einer 3D-Engine und musste als letzte Aufgabe eine kleine Demo mit einer Insel, Wasser und noch
einigem mehr machen. Eine Abbildung dieser Demo sehen Sie auf Screenshot 1.1. Die ganze Demo
finden Sie auch auf der CD zum Projekt, sehen Sie sich dazu Anhang A an. Da die Demo Direct3D
benutzt, läuft sie nur unter Windows-Betriebssystemen. In dieser Bachelorarbeit geht es hauptsächlich
um das Anwenden der 3D-Engine jME, ich habe mir also gedacht, das man die gleiche Demo in jME
implementieren könnte.
1.3. Gliederung der Dokumentation                                                                    7

Gesagt, getan. In einer Coding-Session von gut einer Woche wurde eine ähnliche Demo in jME pro-
grammiert. Es ist also durchaus möglich eine Applikation, die in C++ geschrieben wurde und Direct3D
benutzt in Java zu schreiben und eine plattformübergreifende Engine zu benutzen. Der 2. Schritt ist
damit abgeschlossen.

1.2.3. 3. Schritt: Tutorial
Nachdem nun die Engine ausgwählt und ein Endziel festgelelgt wurde, ging es im dritten und letzten
Schritt darum die einzelnen Zwischenschritte zu erstellen, jeweils mit Bespielapplikationen, im Verlauf
des Dokuments Demos gennant, und dem jeweiligen Begleittext. Obwohl die Arbeit klar strukturiert
und das Resultat klar umschrieben werden konnte, handelte es sich bei diesem Teil, dennoch um den
mit Abstand zeitaufwändigsten und arbeitsintensivten Schritt. Einige fast unüberwindbar scheinende
Hürden, mussten umschifft werden, bis wir zu diesem Endresultat gelangten. Ich hoffe Sie als Leserinnen
und Leser können mit dieser Arbeit nun etwas sinnvolles anfangen.

1.3. Gliederung der Dokumentation
Dieses Dokument ist in zwei Hauptteile gegliedert:
   1. Im ersten Teil befindet sich eine kurze allegemeine Einführung in die 3D-Computergrafik. Diese
      Arbeit beschäftigt sich mit einem Unterteil dieses Themas. Desweiteren gibt es einen Überblick
      über das Bacholorprojekt im allgemeinen.
   2. Der zweite Teil dieses Dokumentes beschäftigt sich mit der 3D-Engine jME[36]. In jedem Ka-
      pitel wird im Tutorialstil Schritt für Schritt ein weiters Element der Engine jME und der 3D-
      Grafikprogrammierung beschrieben, bis wir am Schluss in der Lage sind die Demo in Kapitel 10
      nach zu vollziehen.
Am Ende des Dokumentes befinden sich noch einige Anhänge. Sie zeigen unter anderem den Inhalt
der mitgelieferten CD auf (siehe Anhang A) und beschreiben wie Sie die jeweiligen Demos starten,
bearbeiten und neu kompilieren können (siehe Anhang B).

1.4. Konventionen und Notationen
   • Dateiname: wird benutzt um Dateinamen, Dateierweiterungen und Pfade anzugeben.
   • Wichtig wird benutzt um wichtige Namen hervorzuheben.
   • Variable wird benutzt um Klassennamen und Variablennamen und weiter Quellcodeextrakte im
     Text anzuzeigen.
   • Längere Quellcodeabschnitte und Listings werden folgendermassen angezeigt:

System . out . println ( " Hallo schöne jME - Welt !" );

   • Abbildungen und Listings sind innerhalb eines Kapitels nummeriert.
   • Referenzen zu einem Objekt innerhalb des Literaturverzeichnisses sieht so aus: [AMH02]. Das
     komplette Literaturverzeichnis befindet sich am Ende dieses Dokumentes.
   • Referenzen auf Webseiten sehen folgendermassen aus: [36]. Das gesamte Verzeichnis mit den
     Web Ressourcen befindet sich ebenfalls am Ende dieser Bachelorarbeit.
   • Bei den einzelnen Klassendiagrammen in diesem Dokument handelt es sich um herkömmliche
     UML-Klassendiagramme. Mehr zu UML können Sie im Buch UML Distilled[Fow04] lesen.
3D-Grak
                                                                                                               2
          2.1. Was ist 3D-Grafik? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .            8
          2.2. Was bedeutet Echtzeit-3D-Grafik? . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
          2.3. Was ist eine 3D-Engine? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
          2.4. Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3D-Grafik oder genauer gesagt 3D-Computergrafik ist ein sehr breites Thema und es kann leicht sein,
dass man sich zu schnell von den Details erschlagen lässt. Deshalb will ich in den folgenden Unter-
kapiteln eine kurze allgemeine Einführung in das Thema bereiten. Die Einführung wird sehr kurz sein
und sich nur auf das Wesentliche konzentrieren. Aber ich hoffe dennoch, dass Sie damit einen kurzen
Überblick über das Thema gewinnen. Ich hoffe vor allem Leute, die sich noch nie mit dieser Thema-
tik beschäftigt haben, werden einiges dazulernen, aber auch alle andern sollte dieser Überblick und die
dazugehörige Abgrenzung der Themen helfen.

2.1. Was ist 3D-Grafik?
Was ist 3D-Grafik? Das ist vielleicht die grundlegendste Frage, die man im Zusammenhang mit 3D-
Grafik überhaupt stellen kann. Und die Beantwortung ist gar nicht so einfach. Grundsätzlich gibt es
zwei Teilbereiche in der 3D-Grafik: das Modellieren und das Rendern von räumlichen Daten.
Mit der Modellierung bezeichnet man das Erstellen von räumlichen Daten, so genannten 3D-Objekten.
Diese 3D-Objekte werden weitgehend von Hand mit spezialisierter Software erstellt. Diese Software
wird 3D-Modelliersoftware oder auch nur “3D-Modeller” genannt. Einige der bekanntesten unter ihnen
sind “3D-Studio Max” von Autodesk [3] , Maya von Alias [5] und SOFTIMAGE|XSI von Softima-
ge [54] . Die meisten dieser Applikationen sind sehr teuer, zum Teil mehrere zehntausend Franken1 .
Glücklicherweise gibt es auch einige freie Open-Source Alternativen wie Blender [12] (siehe auch Ab-
bildung 2.1) oder Wings3D [62] . Abschliessend bleiben noch einige günstige Shareware Programme zu
erwähnen, die auch ihre Daseinsberechtigung haben, zum Beispiel Milkshape 3D [43] oder AC3D [4] .
Die Modellierung von 3D-Objekten ist sehr aufwändig, braucht viel Zeit und Geduld und auch einiges
künstlerisches Geschick, wie ich aus eigener missglückter Erfahrung berichten kann. Wir werden im
weiteren Verlauf nicht mehr auf das Modellieren eingehen, wer sich dafür interessiert findet unzählige
Tutorials und WebSites auf dem Internet dazu, wie zum Beispiel auf 3D Links [2] und den Seiten der
einzelnen oben genannten Programme. Die einzelnen 3D-Objekte werden dann unter Umständen noch
zusammengefasst zu grösseren Szenen. Man kann sich zum Beispiel eine Stadtszene vorstellen, in der
 1 Es gibt aber meistens auch eine gratis Learning- bzw. Personal-Edition für Heimanwender und Studenten, die im Funktions-

   umfang eingeschränkt ist. Beispiele dafür sind “gmax” von den 3D Studio Max Entwicklern Autodesk [28] und die “Maya
   Personal Learning Edition” von Alias [42].

                                                            8
2.1. Was ist 3D-Grafik?                                                9

                          Abbildung 2.1.: Ein Screenshot von Blender
2.2. Was bedeutet Echtzeit-3D-Grafik?                                                                10

                                 Abbildung 2.2.: Ein Ausschnitt aus “Geri’s Game”

wir einige Autos sehen, im Hintergrund hat es Geschäfte und Hochhäuser, das sind alles einzelne 3D-
Objekte die in einer Szene zusammen kommen.
Der zweite wichtige Teilbereich in der 3D-Grafik ist das Rendern. Unter dem Rendern verstehen, wir
das Erzeugen eines zweidimensionalen Bildes aus den räumlichen 3D-Daten. Es geht also darum nun die
erzeugten 3D-Objekte auf dem Bildschirm anzuzeigen. Man kann es vergleichen mit dem Fotografieren
oder dem Filmen einer Szene, wir betrachten also unsere 3D-Szene aus einer virtuellen Kamera. Dazu
gibt es auch viele verschiedene Methoden und Techniken. In diesem Tutorial beschäftigen wir uns mit
dem Echtzeit-Rendern. Wie in der Einleitung erwähnt, wollen wir ja Bilder mit Hilfe von Java in Echtzeit
auf den Bildschirm bringen.
Auf der Abbildung 2.2 können wir einen Ausschnitt aus dem Pixar Kurzfilm Geri’s Game [51] sehen.
Links ist das Drahtmodell (engl. wireframe) zu sehen, das in einem 3D-Modeller modelliert wurde.
Rechts ist eine fertig gerenderte Szene mit dem gleichen Kopf aus dem Film zu sehen.

2.2. Was bedeutet Echtzeit-3D-Grafik?

Wie der Titel schon andeutet, behandeln wir hier Echtzeit-3D-Grafik. Unter Echtzeit verstehen wir, dass
wir eine 3D-Szene in Echtzeit rendern wollen.
Viele von ihnen kennen vielleicht die bekannten Animationsfilme von Pixar [50] oder Dreamworks Ani-
mation [21], wie “Shrek”, “The Incredibles”, “Findet Nemo” oder den neusten Titel “Madagascar”. Und
obwohl diese Filme auch mit Hilfe von 3D-Grafik erstellt wurden (und keineswegs, wie manche viel-
leicht meinen mit klassischen Trickfilmzeichnungen), handelt es sich eben gerade nicht um Echtzeit
3D-Grafik. In solchen Filmen wird jeder einzelne Frame2 vorher gerendert und später zu einem Film zu-
sammengefügt. Dieses Rendering einer einzelnen Szene kann aufgrund der verwendeten Effekte, Licht-
einstellungen und anderen speziellen Einstellungen mitunter Stunden dauern. Das Ziel ist es das Bild
möglichst realistisch erscheinen zu lassen, natürlich in einem gewissen Rahmen, der für die Computer
noch machbar ist. Ein Oberbegriff für diese Art des Renderns ist Raytracing. Beim Raytracing werden
Lichtstrahlen simuliert und die Lichtverteilung errechnet um möglichst realistische Schatten und Farb-
schattierungen zu erhalten. Die Methoden sind dabei auch für heutige Rechner sehr zeitaufwändig und
lassen sich noch nicht in Echtzeit ausführen.
 2 Ein   Frame ist ein einzelnes Bild aus einem Trickfilm oder eben einer 3D-Animation.
2.2. Was bedeutet Echtzeit-3D-Grafik?                                                              11

                        Abbildung 2.3.: Ausschnitt aus dem Film Madagascar

Wenn wir von Echtzeit sprechen, meinen wir nun, dass eben genau diese Rendering nur Bruchteile von
Sekunden dauern darf, damit wir uns auch frei in einer 3D-Welt umher bewegen können. Diese Echtzeit-
Rendering wird in 3D-Simulationen und auch 3D-Spielen verwendet. Um aber das ganze in Echtzeit zu
bekommen, muss man auch einige Kompromisse eingehen. Die erzeugten Echtzeit-3D-Welten sind in
der Regel nicht so realistisch, wie die vorgerenderten 3D-Welten. Das primäre Ziel ist die erzielbare
Geschwindigkeit, mit der ein Frame gerendert werden kann, möglichst zu minimieren. Die Echtzeit-3D-
Grafik wird aber immer realistischer. Das hängt auch mit der Einführung der so genannten 3D-Karten
zusammen, die man mittlerweile als Standardausrüstung, sogar auf Mittelklasse PCs zählen kann. Der
Markt für 3D Karten war in den letzten Jahren sehr dynamisch, im Moment gibt es aber nur zwei Firmen,
die Karten für den End-User Markt herstellen: ATI [8] und NVidia [44]
Auf der Abbildung 2.4 können Sie die Entwicklung der Echtzeit-3D-Grafik in Spielen kurz, aber keines-
falls wirklich repräsentativ, mitverfolgen. Auf dem Teilbild oben links sehen Sie einen Ausschnitt aus
dem Spiel Battlezone [10] aus dem Jahre 1980. Das ist das erste Spiel, das eine Art pseudo 3D-Grafik
enthielt. Oben rechts ist ein Ausschnitt aus dem Spiel Wolfenstein3D [63] der Firma id Software [29]
zu sehen. Das ist eines der ersten 3D-Spiele für den PC und auch der erste “First-Person-Shooter” und
somit auch der Vater aller anderen Spiele dieser Art. Es wurde 1992 veröffentlicht. Aus dem Jahr 1999
stammt der dritte Screenshot unten links. Es handelt sich um das Spiel Quake 3 [53], wiederum von id
Software. Man kann hier schon gut die ersten eingesetzten Lichteffekte erkennen. Der letzte Screenshot
ist von Far Cry [25] . Ein Spiel das 2004 herausgeben wurde. Auf diesem Bild kann man einige inter-
essante Wassereffekte erkennen. Auch die Darstellung der Bäume und Pflanzen ist bemerkenswert und
der Detailreichtum der Umwelt.
Dieses Echtzeit-Rendering war zuerst nur auf spezieller Hardware möglich, die vor allem militärischen
3D-Simulationen dienten. Im Jahre 1996 hat aber die Firma 3dfx [61] eine erste 3D-Beschleuniger Kar-
te in bezahlbaren Regionen für den Endkundenmarkt hergestellt. Erst mit Hilfe dieser Karten ist das
einigermassen realistische 3D-Echtzeit Rendern auf normalen Computern möglich geworden. Die Ent-
2.2. Was bedeutet Echtzeit-3D-Grafik?                                      12

                            Abbildung 2.4.: Zeitlinie Echtzeit-3D-Spiele

                             oben links     Battlezone [10] , 1980
                             oben rechts    Wolfenstein 3D [63] , 1992
                             unten links    Quake 3 [53] , 1999
                             unten rechts   Far Cry [25] , 2004
2.3. Was ist eine 3D-Engine?                                                                                         13

wicklung der 3D-Grafik-Karten verläuft immer noch rasant. Sie übertrifft sogar das Moorsche Gesetz3 .
Die Geschwindigkeit der neuesten 3D-Grafikkarten verdoppelt sich fast alle sechs Monate und ein Ende
ist nicht abzusehen. Und das obwohl sich, nach einigen Konkursen und Übernahmen nur zwei grosse
Player, ATI [8] und NVidia [44], auf dem Endkundenmarkt tummeln. Es wird also nicht mehr lange
dauern, bis wir auch 3D-Echzeitgrafik in der gleichen Qualität, wie die aktuellen Pixar und Dreamworks
Animation Filme geniessen können.
Was es mit diesen 3D-Grafik-Karten auf sich hat und wie sie intern arbeiten, werden wir ein bisschen
genauer im Kapitel 4 unter die Lupe nehmen.

2.3. Was ist eine 3D-Engine?
Wir wollen mit Hilfe der 3D-Engine jME [36] eine 3D-Welt aufbauen und schlussendlich auf den Bild-
schirm bringen. Aber was genau ist eine 3D-Engine? Eine 3D-Engine verwaltet die ganzen 3D-Objekte
und die Szenen, die ein 3D-Künstler oder wir selbst vorher angefertigt haben. Sie verwalten also kurz ge-
sagt die ganzen 3D-Daten. Des weiteren ist eine 3D-Engine dafür zuständig, was wir auf den Bildschirm
bringen und wie wir das ganze Zeichnen wollen. Diese Entscheidungen werden auf einer unteren und
einer oberen Ebene gemacht. Die Entscheidung auf der oberen Ebene werden von unserem Spiel oder
unserer Anwendung mit Hilfe eines Scenegraphs auf Softwareebene gemacht, das ganze wird im Ab-
schnitt 3.2 erläutert. Die Entscheidungen der unteren Ebene werden vom Renderer selbst gemacht. Das
bedeutet das wir die meiste Arbeit an die Hardware oder genauer gesagt an die Grafik-Karte delegieren
können. Wie das genau funktioniert wird im Kapitel 4 näher erklärt.

2.4. Zusammenfassung
Ich hoffe, dass Sie als Leser nun ein bisschen mehr Ahnung von der 3D-Grafik haben. Was Sie behal-
ten sollten, ist das wir uns hier im Tutorial auf das Rendern mit der Java 3D-Engine jME beschränken
werden. Wir werden uns genauer gesagt sogar auf das interaktive Echtzeit-Rendern beschränken. Wie
das abläuft, werden wir im Tutorial sehen. Im Tutorial werden wir uns auf die Handhabung von jME aus
Sicht eines Endbenutzers beschränken und nur wo nötig auf implementationstechnische Details einge-
hen.

 3 AlsMooresches Gesetz wird die Beobachtung bezeichnet, dass sich durch den technischen Fortschritt die Komplexität von
   integrierten Schaltkreisen etwa alle 24 Monate verdoppelt.
Teil II.

Tutorial

    14
Erste Schritte mit jME
                                                                                                          3
             3.1. Unser erstes jME-Programm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
             3.2. Scenegraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
                  3.2.1. Was ist ein Scenegraph? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
                  3.2.2. Zustände im Kontext von jME . . . . . . . . . . . . . . . . . . . . . . . . . . 21

     3.1. Unser erstes jME-Programm
     Jetzt geht es los liebe Leser! Statt lange um den heissen Brei zu reden, tauchen wir gleich ein in un-
     ser erstes jME-Programm. Wie jedes anständige Programmiertutorial beginnt auch dieses Tutorial mit
     einem HelloWorld Programm. Zu sehen ist aber nicht ein kurzer Textstring sondern ein einfacher Wür-
     fel. Sie finden den Quellcode und die Klasse selbst im Verzeichnis demos/firststeps mit dem Namen
     HelloWorld.java. Wie die CD genau aufgebaut ist, wird in Anhang A erklärt. Im Unterverzeichnis de-
     mos der CD finden Sie ausserdem zwei Dateien mit dem Namen firststeps_helloworld.bat und first-
     steps_helloworld.sh. Es handelt sich dabei um Startdateien, mit denen Sie die Demo unter Windows
     bzw. unter Linux und MacOSX direkt starten können. Wie sie die Demo direkt in der Konsole starten
     können, wird im Anhang B erläutert.

                                            Listing 3.1: HelloWorld.java
 1   package firststeps ;
 2

 3   import helper . TutorialGame ;
 4
 5   import com . jme . math . Vector3f ;
 6   import com . jme . scene . shape . Box ;
 7
 8   public class HelloWorld extends TutorialGame
 9   {
10     public static void main ( String args [] )
11     {
12       new HelloWorld () ;
13     }
14
15     protected void simpleInitGame ()
16     {
17       // set the title of our application
18       display . setTitle ( " Hello World !!! " );
19

                                                          15
3.1. Unser erstes jME-Programm                                                                   16

                                   Abbildung 3.1.: Screenshot aus HelloWorld

20           // create a simple cube
21           Box b = new Box ( " box " , new Vector3f ( 0, 0, 0 ) , new Vector3f ( 1, 1, 1
                ) );
22
23           // put the box in the scene graph
24           rootNode . attachChild ( b );
25       }
26   }
     Dieses einfache Programm beinhaltet bereits alles was auch ein grösseres jME-Programm beinhalten
     muss. Wir erben von einer Klasse namens TutorialGame. In TutorialGame werden verschiedene Din-
     ge aufgesetzt, die in jedem unseres jME-Programme nützlich sind:

         • Eine einfache Kamera wird erzeugt, die wir mittels der in Spielen üblichen Manier bewegen kön-
           nen. Das heisst konkret: mit der Maus verändern wir unsere Blickrichtung, während wir uns mit
           der ’W’- und ’S’-Taste vorwärts und rückwärts bewegen. Mit ’A’ und ’D’ bewegen wir und links
           bzw. rechts seitwärts. Das wird auch für die meisten anderen, kommenden Demos, die Standard-
           methode sein, mit der wir uns fortbewegen können. Wer bereits einen modernen 3D-Shooter ge-
           spielt hat, wird sich gleich zu Hause fühlen.

         • Ein simples Licht wird aufgesetzt. In Kapitel 7 werden wir genauer darauf eingehen.

         • Ein Scenegraph wird eingerichtet. Was ein Scenegraph genau ist werden wir am Ende dieses
           Kapitels genauer erklären.

         • Einige simple Tastenkommandos werden definiert wie zum Beispiel:

               – ’T’ und den Wireframe-Modus ein- bzw. auszuschalten
               – ’C’ um die Position der Kamera in der Konsole auszugeben
               – ’L’ um die Lichter zu deaktivieren bzw. wieder zu aktivieren
3.1. Unser erstes jME-Programm                                                                       17

                Abbildung 3.2.: Screenshot des Einstellungsdialogs der bei jedem Start erscheint

              – ESCAPE um das Programm zu beenden

        • TutorialGame stellt auch zwei Methoden namens simpleInitGame und simpleUpdate zur Ver-
          fügung, die wir in unseren eigenen Programmen überschreiben können, wenn wir etwas initiali-
          sieren wollen oder etwas in jedem Frame ändern wollen.

     Für uns ist es nicht so wichtig zu wissen, wie TutorialGame genau seine Arbeit macht, wichtig zu
     wissen ist aber, das jedes unserer Programme von TutorialGame erben wird.
     Beschreiben wir nun unser erstes Programm ein bisschen genauer. Die Dialogbox mit dem Uni-Fribourg
     Logo, die bei jedem Start gezeigt wird, ist sicher auch schon einigen aufgefallen, auf der Abbildung 3.2
     können Sie einen Screenshot davon sehen. Der Konstruktor von TutorialGame, ist dafür verantwortlich,
     dass dieser Dialog immer erscheint. In diesem Dialog kann man die Bildschirmauflösung des folgenden
     Programms auswählen und bestimmen, ob die Applikation in einem Fenster oder als Vollbildanwendung
     ausgeführt wird. Es ist also durchaus sinnvoll diesen Dialog vor jedem Start anzuzeigen.
     In Zeile 12 beginnt unser Programm dann richtig. Mit dem Aufrufen des Konstruktors wird auch der
     Konstruktor von TutorialGame aufgerufen, der wiederum eine Endlosschleife ausführt, die erst been-
     det wird, wenn wir auf ’Fenster schliessen’-Kreuz drücken oder die Taste Escape betätigen. Bevor die
     Schleife startet wird das System initialisiert und unter anderem auch simpleInitGame aufgerufen. In
     der Schleife selbst werden danach in jedem Iterationsschritt zwei Dinge gemacht: zunächst erhält jedes
     Objekt, denn Befehl sich zu bewegen und simpleUpdate wird aufgerufen, als zweites wird alles auf
     den Bildschirm gerendert.
     Unser main wird in jeder Demo gleich aussehen, die eigentliche Arbeit werden wir immer in den Metho-
     densimpleInitGame und zum Teil auch in simpleUpdate machen. Besprechen wir also im folgenden
     Abschnitt simpleInitGame etwas genauer:

                                 Listing 3.2: HelloWorld.java, simpleInitGame
15     protected void simpleInitGame ()
16     {
17       // set the title of our application
3.2. Scenegraph                                                                                      18

18         display . setTitle ( " Hello World !!! " );
19
20         // create a simple cube
21         Box b = new Box ( " box " , new Vector3f ( 0, 0, 0 ) , new Vector3f ( 1, 1, 1
              ) );
22

23         // put the box in the scene graph
24         rootNode . attachChild ( b );
25     }
     Schon beim betrachten des Codes sehen wir, das genau drei Dinge passieren:

        1. Wir geben unserer Demo einen Titel. Der Titel wird auf dem Fenster angezeigt und wird auch der
           Name sein, mit dem das jeweilige Betriebssystem unsere Applikation kennt.

        2. Als nächstes erstellen wir einen Würfel mit Box. Der Würfel ist, dieses Ding, das man auf dem
           Bildschirm sehen konnte.

        3. Wir fügen unseren neu erstellten Würfel der Wurzel unseres Scenegraphen an. Die Wurzel des
           Scenegraphen heisst rootNode und wird uns von TutorialGame zur Verfügung gestellt.

     Wie wir oben sehen können, benutzen wir drei Argumente um einen Würfel zu kreieren. Als erstes
     geben wir dem Objekt mittels eines String Objektes einen Namen. Allen Objekte, die wir irgend einmal
     einem Scenegraph anhängen wollen müssen wir einen Namen geben. Dieser Würfel wurde in diesem
     Beispiel box genannt, wir hätten aber auch irgend einen anderen Namen wählen können. Die Nächsten
     zwei Argumente geben zwei Ecken unseres Würfels an. Der Würfel hat eine Ecke im Ursprung (0; 0; 0)
     und eine Ecke im Punkt (1; 1; 1) es handelt sich also um einen Einheitswürfel.
     Jetzt haben wir also einen Würfel erstellt, wir wollen diesen Würfel aber auch sehen. Deshalb müssen
     wir den Würfel mittels rootNode.attachChild unserem Scenegraph anhängen. Alle Objekte, die ge-
     rendert werden sollen, müssen wir dem Scenegraphen anhängen. rootNode ist dabei die Wurzel des
     Scenegraph, der in TutorialGame definiert wurde. In diesem Beispiel besteht unser ganzer Scenegraph
     aus der Wurzel rootNode mit dem angehängten Würfel box. Wenn nun von TutorialGame der Befehl
     kommt rootNode zu zeichnen wird automatisch auch der Würfel mitgerendert.

     3.2. Scenegraph
     3.2.1. Was ist ein Scenegraph?
     Kommen wir zurück zu der grundlegenden Frage, was eine 3D-Engine eigentlich macht. Wir haben be-
     reits gesagt, dass es die Hauptaufgabe einer 3D-Engine ist verschiedene 3D-Objekte zu verwalten und
     auf den Bildschirm zu bringen. Die einfachste Möglichkeit diese Objekte zu verwalten, wäre eine ver-
     kette Liste mit allen Objekte, die wir dann eines nach dem anderen auf den Bildschirm zeichnen. Das ist
     eine einfache aber leider nicht sehr effiziente Methode Objekte zu verwalten. Wenn man sich näher mit
     einem modernen 3D-Spiel beschäftigt, erkennt man, dass die 3D-Welten aus tausenden von 3D-Objekten
     bestehen. Diese tausenden von Objekte in einer Liste zu speichern und nacheinander zu verarbeiten wür-
     de viele Spiele wohl zu einer eher langweiligen Dia-Show ausarten lassen. Denn selbst Objekte die nicht
     auf dem Bildschirm erscheinen würde man in diesem Falle einer zeitraubenden Bearbeitung unterziehen
     müssen und wertvolle Ressourcen rauben. Die 3D-Hardware weiss noch nicht einmal, dass viele Objek-
     te nicht zu zeichnen sind, und schmeisst solche Objekte erst sehr spät aus der Pipeline, deshalb spricht
     man auch davon, dass die 3D-Beschleuniger auf einem sehr tiefen sogenannten low-level arbeiten. Als
     Programmierer haben wir aber sehr wohl eine grössere high-level Ahnung von den 3D-Objekten auf dem
     Bildschirm und wie sie miteinander in Beziehung stehen.
     Die ganze Welt aus den 3D-Objekten wird, wie wir bereits einmal erwähnt haben als Szene (engl. scene)
     bezeichnet. Wenn wir nun unser Wissen von den Beziehung dieser 3D-Objekten einbringen erhalten
3.2. Scenegraph                                                                                                       19

                               Abbildung 3.3.: Eine Hierarchie von einem Haus

wir einen Scenegraphen1 . Als Scenegraph wird in jME ein Baum verwendet. In einem Baum gibt es
eine Wurzel und jedes Element kann mehrere Kindobjekte enthalten, besitzt aber nur ein Elternelement.
jME stellt uns mit rootNode bereits die Wurzel eines Scenegraphen zur Verfügung, an den wir weitere
Blätter anfügen können. Mit einem Baum können wir als Benutzer einer Engine eine Hierarchie von 3D-
Objekten aufbauen. Dieser Ansatz gibt uns viele Vorteile, wie Sie in [Ebe00] auch nachlesen können:

    • Stellen wir uns vor wir haben eine 3D-Welt, die aus vielen verschiedenen Räumen besteht. Wenn
      wir nun ein Licht einsetzen, wie wir es in Kapitel 7 zeigen, dann wollen wir das dieses Licht nur
      diesen Raum betrifft und beleuchtet auch aus Performancegründen. Mit einem Scenegraph ist das
      einfach in dem wir das Licht einfach im Raum einsetzen den wir beleuchten wollen. Das Licht
      beleuchtet dann automatisch auch alle Kindobjekte von diesem Raum.

    • Zweitens, in einem Scenegraphen kann man leicht lokale Gruppierung darstellen. Das hilft beson-
      ders, weil man mit dieser Methode schnell ganze Objektgruppen eliminieren kann, die nicht auf
      dem Bildschirm zu sehen sind. Nehmen wir als Beispiel an wir befinden uns im Raum 2 wie auf
      der Abbildung 3.3 zu sehen. Der Renderer kann den ganzen Unterbaum von Raum 1 direkt von der
 1 Für diesen
          Begriff scheint es leider keine geläufige deutsche Übersetzung zu geben, deshalb werden wir uns im Verlaufe des
   Dokuments auf den englischen Begriff Scenegraph beschränken.
3.2. Scenegraph                                                                                     20

                     Abbildung 3.4.: UML-Diagramm der Scenegraph Elemente

      Bearbeitung ausschliessen, weil dieser Raum nicht zu sehen ist. Wenn man Objekte von der Be-
      arbeitung ausschliesst, die nicht auf dem Bildschirm zu sehen sind spricht man vom sogenannten
      Frustum Culling. Das ist ein Konzept, das sehr wichtig ist im Echzeitrendern.

   • Viele 3D-Objekte die wir darstellen wollen sind schon von Natur aus auf hierarchische Weise
     aufgebaut. Das ist ein dritter Vorteil, den wir mit Scenegraphen haben. Das gilt besonders für
     humanoide Objekte. Die Lage und die Rotation von einer Hand hängt auf natürliche Weise ab von
     der Lage und der Rotation des Ellbogens, der Schulter und der Hüfte. Mit einem Scenegraphen
     ist es leicht solche Abhängigkeiten darzustellen. Wenn wir das ganze von Hand machten müssten,
     würde es sehr schnell kompliziert werden, wie Sie im Abschnitt 4.2.3 selbst sehen können.

Kommen wir nun zum Scenegraphen zurück den jME für uns bereitstellt. In jME gibt es Objekte von
drei Klassen, die Elemente eines Scenegraphen sein können, die Klassen Spatial, Geometry und Node.
Wie auf der Abbildung 3.4 zu sehen ist, ist die Klasse Spatial die Oberklasse. Man kann Spatial nicht
instanzieren, da es sich um eine abstrakte Klasse handelt. In Spatial werden aber die Lage und die
Rotation gespeichert, jedes Element des Scenegraphen hat also seine eigenen Standort, der immer relativ
zum Elternelement ist. Man kann auch sogenannten RenderStates setzen, der die Lichter und Texturen
beschreibt, dazu gibt es im weiteren Verlauf des Tutorials mehr.
Die Klasse Geometry und ihre Unterklassen beinhalten all die geometrischen Daten, das heisst die Drei-
ecke, die ein 3D-Objekt enthalten. Das heisst jedes Objekt, das wir am Schluss auf dem Bildschirm sehen
ist ein Geometry-Objekt. Die Box, die wir im ersten Demo benutzt haben (siehe Listing 3.1 und 3.2 Zeile
21), ist auch im UML-Diagramm zu erkennen. Bei den Geometry-Objekten handelt es sich aber nur um
die Endblätter unseres Scenegraph-Baumes. Die Knoten werden durch die Klasse Node verwaltet, der
3.2. Scenegraph                                                                                    21

                         Abbildung 3.5.: UML Diagramm der RenderStates

man beliebig viele Kindknoten und Kind Geometry-Objekte anfügen kann, dazu können Sie noch einmal
die Abbildung 3.3 betrachten. Für alles das wir in jME auf den Bildschirm sehen existieren also eigene
Geometry-Unterklassen oder spezialisierte Node-Klassen. Solche spezialisieren Klassen sind schwierig
auf eine gute Art und Weise zu implementieren und das ist eine der eigentlichen Schwierigkeiten, wenn
man eine 3D-Engine entwickeln will.
Man kann ohne zu übertreiben sagen, dass der Scenegraph das Rückgrat der 3D-Engine von jME ist. Das
Design und die Implementierung von jME ist dabei sehr komplex. Der Autor von jME sagt in seiner In-
ternetseite, dass er das Design von jME an die beiden Bücher von David H. Eberly angelehnt hat [Ebe00]
und [Ebe04]. In [Ebe00] wird die Implementierung einer Scenegraph basierten Engine beschrieben. Der
Text ist dabei sehr mathematisch gehalten. In [Ebe04] wird die Architektur dieser weiterentwickelten
Scenegraph-Engine aus einem etwas höheren Level beschrieben. Beide Bücher sind über 500 Seiten
dick, das sollte nur ein kleiner Hinweis sein, wie komplex eine moderne 3D-Engine ist.
Der ganze Scenegraph entspricht ausserdem dem Composite Pattern, wie er aus dem allseits bekann-
ten Buch der Gang of Four, Design Patterns [GHJV95] bekannt ist. Im Scenegraphen, dessen Wurzel
rootNode in unserem Programm verwendet wird, wird einmal pro Frame die Methode draw aufgerufen.
Dieser Aufruf bringt die ganze Engine zum Laufen.
Im Artikel [BZ] von Avi Bar-Zeev finden Sie noch einige weiter Anmerkungen zu einem Scenegraphen
allgemein. Die meisten modernen 3D-Engines benutzen eine Scenegraph-Implementierung, die der von
jME ähnlich ist.

3.2.2. Zustände im Kontext von jME
Wir werden im Verlauf des Tutorials auch einige Zuständen verwenden. Vor allem Lichter in Kapitel 7
und Texturen in Kapitel 8. Ein Zustand den wir in jME verwenden können ist immer eine Unterklasse von
RenderState. Abbildung zeigt ein UML-Diagramm mit einigen der Zustände. Sehen Sie sich nun noch
einmal die Abbildung mit den Scenegraph-Elementen (Abbildung 3.4) an. Wie Sie auf dieser Abbildung
sehen können, können wir zu jedem Element unseres Scenegraphen, das heisst zu jedem Spatial, einen
RenderState also einen Zustand setzen, mit der treffenden Methode setRenderState. Der Zustand,
den wir setzen, wirkt sich dann im Scenegraph auf alle Kinder, des jeweiligen Spatials aus dessen
Zustand wir erweitern. Betrachten wir dazu noch einmal die Hierarchie auf Abbildung 3.3. Falls wir im
Raum1 ein Licht setzen, beleuchtet das Licht alle Elemente der Tischgruppe und auch den Stuhl, Raum2
merkt aber nichts vom Licht.
Wie funktioniert 3D-Grak
                                                                                                      4
        4.1. Was macht eine 3D-Engine? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
        4.2. Das 3D-Koordinatensystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
              4.2.1. 2D-Koordinatensystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
              4.2.2. 3D-Koordinatensystem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
              4.2.3. Model-Space vs. World-Space . . . . . . . . . . . . . . . . . . . . . . . . . . 24
        4.3. Transformationen im Raum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
              4.3.1. Verschiebungen (engl. translation) . . . . . . . . . . . . . . . . . . . . . . . . 25
              4.3.2. Rotationen (engl. rotation) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
              4.3.3. Skalierungen (engl. scaling) . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
              4.3.4. Alle Bewegungen zusammen . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
        4.4. Perspektive und Projektion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
        4.5. Kamera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
        4.6. jME, OpenGL, DirectX, 3D-Pipeline: Was ist das? Was machen die? . . . . . . . . 29
        4.7. Ressourcen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

4.1. Was macht eine 3D-Engine?
Man kann kurz sagen, eine 3D-Engine ist verantwortlich dafür die 3D-Daten zu verwalten und zu bestim-
men, was auf den Bildschirm kommt und wie es zu zeichnen ist. Wir haben oben im Kapitel vor allem das
was beschrieben, das wie ist dabei meistens die Aufgabe der sogenannten Rendering-Pipeline. Das Ziel
der Rendering-Pipeline ist es ein zweidimensionales Bild auf dem Bildschirm zu erzeugen, aus dreidi-
mensionalen Objekten, einer virtuellen Kamera, Texturen, Lichtern und noch einigem mehr. Als Benut-
zer einer 3D-Engine haben wir es dabei glücklicherweise um einiges leichter. Die 3D-Engine ist meistens
ein Wrapper um eine gegebene 3D-Schnittstelle, wie OpenGL oder Direct3D und abstrahiert dement-
sprechend die so genannte Rendering-Pipeline. Die Rendering-Pipeline selbst ist heutzutage auch direkt
in der Hardware implementiert, in den sogenannten 3D-Beschleunigern. Das sind 3D-Grafikkarten, die
mittlerweile wohl jeder Computer enthält. Wir müssen uns also um die meisten Low-Level Angelegen-
heiten nicht mehr selbst kümmern und können ganz einfach die 3D-Engine walten lassen.
Dennoch ist es von Vorteil, zumindest ein grundlegendes Wissen zu haben, was in dieser ominösen
Pipeline passiert. Und genau deshalb werden wir uns in diesem Teil des Tutorials ein wenig um die
theoretischen Grundlagen kümmern. Ich hoffe, dass ich damit ein wenig Licht in das bereits jetzt von
Fachwörtern gespickte Tutorial bringen kann. Gezwungenermassen kann ich hier keinen tiefen Einblick
in das Thema geben. Ich verweise die interessierten Leser aber auf die kommentierte Bibliographie am
Ende dieses Kapitels in Abschnitt 4.7.

                                                      22
4.2. Das 3D-Koordinatensystem                                                                     23

                      Abbildung 4.1.: Ein rechthändiges 3D-Koordinatensystem

Trotz allem wird hier ein wenig Vorwissen vorausgesetzt. Der Leser sollte wissen, was ein Vektor und
eine Matrix ist. Grundlegende Vektor- und Matrix-Operationen sollten, deshalb auch schon verstanden
werden. Wer noch ein wenig Mühe mit dieser Materie hat oder sein mathematisches Wissen ganz all-
gemein ein bisschen auffrischen will findet im Buch von Fletcher und Parberry 3D Math Primer for
Graphics and Game Development [DP02] eine hervorragende Einführung.

4.2. Das 3D-Koordinatensystem

4.2.1. 2D-Koordinatensystem

Fast jeder wird wohl schon von einem kartesischen 2D-Koordinatensystem gehört haben und es wohl
sogar selbst benutzt haben. Ein Koordinatensystem besteht aus einer oder mehreren Zahlengeraden.
Jeder dieser Zahlengeraden heisst Achse. Die Anzahl Achsen in einem System entspricht der Anzahl
Dimensionen, die in diesem System repräsentiert werden. In einem 2D-Koordinatensystem sind das nor-
malerweise die x- und die y-Achse. Diese Achsen entspringen dem Ursprung (engl. origin) des Systems.
Dieser Ursprung entspricht dem Punkt (0; 0) in einem 2D-System, deshalb wird der Ursprung häufig
auch Nullpunkt genannt.

4.2.2. 3D-Koordinatensystem

Ein 3D-System fügt nun dem 2D-System eine dritte Tiefendimension hinzu. Diese neue Achse wird
normalerweise als z-Achse bezeichnet. Alle drei Achsen in einem 3D-Koordinatensystem stehen im
rechten, 90 Grad, Winkel zueinander.
Es gibt zwei Versionen des 3D-Koordinatensystem, die häufig benutzt werden. Das linkshändige System
(engl: left-handed system) und das rechtshändige System (engl: right-handed system). Der Unterschied
zwischen den beiden ist die Richtung in welche die z-Achse zeigt. In einem linkshändigen System zeigt
die positive z-Achse gegen vorwärts und negative Zahlen zeigen sozusagen hinten von uns weg. In einem
4.2. Das 3D-Koordinatensystem                                                                                 24

rechtshändigen System ist das genau umgekehrt. jME benutzt ein rechtshändiges Koordinatensystem,
da auch das darunterliegende OpenGL ein rechtshändiges Koordinatensystem benutzt. Das linkshändige
Koordinatensystem wird von der anderen bekannten 3D-API Direct3D benutzt. Auf der Abbildung 4.1
sehen Sie ein rechtshändiges Koordinatensystem.

4.2.3. Model-Space vs. World-Space

Im Bereich der 3D-Grafik benutzt man oft verschiedene Koordinatensysteme. Im Besonderen unter-
scheidet man zwischen dem sogenannten World Space, dem Model- oder Object Space und dem Ca-
mera Space. Man benötigt verschiedene Koordinatensysteme, weil einige Informationen nur in einem
bestimmten Kontext (das bedeutet in unserem Fall in einem bestimmtem Koordinatensystem) von Nut-
zen sind. Das ganze Konzept ist am Anfang vielleicht ein bisschen schwierig zu verstehen aber die
Konzepte sind grundlegend.
Am besten wir beginnen mit dem World Space. Das World Space ist ein absolutes Koordinatensystem.
Jede Position auf der Welt hat seine eigenen Koordinaten, die unverwechselbar sind. Am besten kann
man sich das mit einer normalen Weltkarte verbildlichen. Auf einer Weltkarte ist die Welt in Längen- und
Breitengrade aufgeteilt. Jeder Ort auf der Welt lässt sich nun eindeutig mit diesen Koordinaten beschrei-
ben. Die Koordinaten von Freiburg sind zum Beispiel, 46,8◦ nördliche Breite, 7,15◦ östliche Länge.
Auch jede 3D-Welt, besitzt nun ein solches absolutes Koordinatensystem, in dem jeder Ort eindeutig
durch die x-, y-, z-Koordinaten beschrieben werden kann. Um dieses Konzept besser zu illustrieren, sind
in den meisten Demos, die dieses Kapitel begleiten die Achsen des World Space zu sehen.
Jedes Objekt in unserer 3D-Welt hat hingegen sein eigenes lokales Koordinatensystem, besitzt seinen
eigenen Achsen und hat seinen eigenen Nullpunkt. Der Nullpunkt kann beispielsweise in der Mitte des
Objekts liegen. Die Achsen zeigen an, welche Richtungen für das Objekt “oben”, “unten”, “rechts”,
“links”, “vorne” und “hinten” sind. Das ist genau so in der “echten” Welt. Für mich bedeutet zum Bei-
spiel “links” etwas anderes als für jemanden, der vis-à-vis von mir sitzt. Diese lokale Koordinatensys-
tem wird Object Space genannt. Ausserdem bewegt sich das lokale Koordinatensystem mit dem Objekt.
Wenn sie zum Beispiel den linken Arm ausstrecken, wird dieser linke Arm immer einen Meter links von
ihnen sein, egal wie sie sich im Raum umher bewegen.
Wenn sie sich aber bewegen, wird sich ihre Position in der Welt verändern. Die Position, die sie inneha-
ben, wenn sie sich umher bewegen wird in Weltkoordinaten ausgedrückt. Natürlich hat auch ihr linker
Arm, den sie immer noch ausgestreckt haben eine Position im World Space. Es genügt nun aber, wenn
wir nur die Position ihres Nullpunktes kennen (nehmen wir an der Nullpunkt von ihnen befindet sich
in der Körpermitte). Die Position ihres linken Armes kann man nun leicht ausrechnen, weil man weiss,
dass sich ihr linker Arm ein Meter links von ihrem Nullpunkt entfernt befindet.
Weil sich ein 3D-Objekt mitsamt seinem lokalen Koordinatensystem im absoluten globalen Koordina-
tensystem bewegt, kann es hilfreich sein, das globale Koordinatensystem (World Space) als Eltern-Space
und das lokale Koordinatensystem als Kind-Space zu verstehen. Ausserdem ist es sehr nützlich, die 3D-
Objekte in weiter Subobjekte zu unterteilen. Der Roboter hat zum Beispiel einen Kopf mit einer Nase,
zwei Arme und zwei Beine. Falls der Roboter nun nicken will, bewegt sich sein Kopf mitsamt Nase
relativ zum Roboterkörper. Um den ganzen Roboter zu bewegen müssen, wie aber den Kopf und die
Nase mit bewegen. Wir erhalten also ein Hierarchie von Objekten, die sich alle relativ zueinander bewe-
gen. Genau diese Hierarchie kann man nun mit einem Scenegraph implementieren und das macht es uns
leicht in jME1 solche Hierarchien von Objekten zu benutzen.

 1 ImGegensatz zur “herkömmlichen” 3D-Programmierung mit OpenGL und Direct3D, in denen man solche Hierarchien und
   relative Bewegungen mühsam von Hand selbst verwalten muss. Ausser man implementiert seinen eigenen Scenegraph
   natürlich.
Sie können auch lesen