## Einfaches OpenGL/C++-Spiel mit white_dune erzeugen

Mit white_dune lassen sich in der Programmiersprache C++ geschriebene OpenGL-Programme erzeugen.
Hier wird ein einfaches Beispiel vorgestellt, dass nur wenige Zeilen Programmcode benötigt.
Im ersten Schritt wird ein Prototyp in X3D/javascript erstellt, das später mit C++ erweitert wird.

### javascript/X3D Prototyp

Als Basis wird das in X3D verfügbare white_dune-Logo benutzt.
Dabei steht ein 3D-Modell eines Pinguins zur Verfügung, das auf einer Dünen-Landschaft mit einer Pyramide steht.
Für die Programmierung macht es aber keinen Unterschied, wenn man statt des Pinguins eine Box und statt der Dünen-Landschaft eine dünne und breite/lange Box benutzt.
Im ersten Schritt wird das Ziel (Pinguin oder Box) so animiert, so dass es sich entlang eines Pfades bewegt (Kurven-Animation).
Als nächstes wird ein Text-Knoten mit "Game over" eingefügt.
Als nächstes wird ein Switch-Noten einfügt und das Ziel in ihn verschoben.
Damit das Ziel sichtbar ist, muss Switch.whichChoice auf 0 gestellt werden.
Als nächstes wird ein Switch-Noten einfügt und der Text wird in ihn verschoben.
Als nächstes wird ein Script-Noten einfügt.
Dann wird Routes/IS -> Neu aufbauen benutzt. Dabei wird ein neues Fenster aufgeklappt, das die Pfad-Animation zeigt.
Als nächstes wird der Script-Noten angeklickt.
Dann wird eine SFVec3f-Eingangs-Funktion "transform_in" angelegt
Genauso wird eine SFVec3f-Eingangs-Funktion "proximity_in" angelegt
Dann wird eine SFInt32-Ausgangs-Varible "out_text" angelegt
Dann wird eine SFInt32-Ausgangs-Varible "out_tux" angelegt
Jetzt wird ein Proximity-Sensor-Knoten erzeugt und Routes/IS -> Zeige Knoten ganz oben bentzt.
Jetzt wird der Script-Knoten angeklick und Routes/IS -> Zeige Knoten ganz oben bentzt.
Danach verschiebt man die Knoten passend und verbindet ProxomitySensor.position_changed und Script.proximity_in
Danach verbindet man CurveAnimation1.position_changed und Script.translation_in
Danach verbindet man Script.out_text und Switch.set_whichChoice vom Switch des Textes.
Danach verbindet man Script.out_tux und Switch.set_whichChoice vom Switch des Ziels.
Jetzt wird der Script-Knoten angeklickt und eine SFVec3f-Daten-Variable transfrom_data angelegt.
Danach wird eine SFBool-Daten-Variable game_over angelegt.
Jetzt wird der Script-Knoten angeklickt und Edit -> URL edit benutzt.
Das folgende javascript-Programm muss eingefügt werden:

    "ecmascript:

            function transform_in(value)
            {
               transform_data = value;
            }

            function proximity_in(value)
            {
               if (!(game_over) &&
                   (Math.abs(transform_data.x - value.x) < 2) &&
                   (Math.abs(transform_data.y - value.y) < 3) &&
                   (Math.abs(transform_data.z - value.z) < 2)) {
                   game_over = true;
                   out_text = 0; // Text anzeigen
                   out_tux = -1; // TUX ausblenden
                   }
            }
    "

Damit das X3D-Spiel angezeigt werden kann, muss der X3D-Broswer "FreeWRL" installiert werden und mit Optionen -> Vorschau Einstellungen für Datei -> Vorschau eingerichtet werden.
Jezt wird Datei -> Vorschau gedrückt und es muss mit der FreeWRL-Navigation dem Ziel nahe gekommen werden, so dass der "Text anzeigen/TUX ausblenden" Code erreicht wird.
Screenshots aus dem Spiel:
Vor dem Nahekommen ans Ziel:
Nach dem Nahekommen ans Ziel:

### Erweiterung mit C++

Jetzt wird der Script-Knoten angeklickt und Edit -> URL edit benutzt.
Der Programm-Code wird um einen C++-Teil erweitert:

    "ecmascript:

            function transform_in(value)
            {
               transform_data = value;
            }

            function proximity_in(value)
            {
               if (!(game_over) &&
                   (Math.abs(transform_data.x - value.x) < 2) &&
                   (Math.abs(transform_data.y - value.y) < 3) &&
                   (Math.abs(transform_data.z - value.z) < 2)) {
                   game_over = true;
                   out_text = 0; // Text anzeigen
                   out_tux = -1; // TUX ausblenden
                   }
            }
    "
    "c++:

       X3dScript_Script1 *self = (X3dScript_Script1 *)node;
       self->transform_data[0] = self->transform_in[0];
       self->transform_data[1] = self->transform_in[1];
       self->transform_data[2] = self->transform_in[2];
       if (!(self->game_over) &&
           (fabsf(self->transform_data[0] - self->proximity_in[0]) < 2) &&
           (fabsf(self->transform_data[1] - self->proximity_in[1]) < 3) &&
           (fabsf(self->transform_data[2] - self->proximity_in[2]) < 2)) {
           self->game_over = true;
           self->out_text = 0; // Text anzeigen
           self->out_tux = -1; // TUX ausblenden
       }
    "

Jetzt muss das C++-Export-Verzeichnis von white_dune ins HOME-Verzeichnis kopiert werden:

    $ cp -r wdune-*/docs/export_example_c++/opengl_example/ $HOME

Jetzt muss die entstande X3D-Datei nach $HOME/opengl_example/robot.x3dv abgespeichert werden.
Wechseln sie in das Verzeichnis

    $ cd $HOME/opengl_example/

Und bentzen Sie

    $ make && ./render

um das Programm zu kompilieren und auszuführen.