© saicle/Shutterstock.com
Kolumne: The Good Parts

Kolumne: The Good Parts


JavaScript ist mittlerweile viel mehr als nur eine Sprache – es ist eine Plattform. Unterschiedlichste Sprachen können automatisiert in JavaScript übersetzt werden. Zur Entwicklung von Programmen im Browser ist daher der Einsatz von JavaScript keine zwingende Voraussetzung mehr. Durch diesen Ansatz werden moderne Webapplikationen nicht nur unabhängig von der Sprache, es ist außerdem möglich, Applikationen durch einen Cross-Compiler sowohl nativ als auch fürs Web zu übersetzen.

JavaScript on Steroids

Eine Codebasis, sie alle zu knechten

Epic hat es in Kooperation mit Mozilla vorgemacht: Ihre Epic-Citadel-Demo [1] ist eine mittels Emscripten [2] für den Browser übersetzte Version der Unreal Engine. Mit relativ moderaten Anpassungen war es Epic möglich, ihre Technologiedemo für den Browser zu kompilieren. Ergebnis: Eine Codebasis, ursprünglich gedacht für die native Ausführung auf einer Plattform, ist nun im Browser auf jedem aktuellen System einsetzbar.

Denkt man diese Idee weiter, so erkennt man schnell, dass dieser technologische Ansatz im Bereich von 3-D-Anwendungen großes Potenzial besitzt. Ein Spiel z. B. könnte so aus der gleichen Codebasis nicht nur auf aktuelle Mobile-Plattformen wie iOS und Android, Desktopsysteme wie Linux, Windows und Mac OS, sondern auch auf jeden modernen Browser deployt werden.

Ein Beispiel sagt mehr als tausend Worte

Im Folgenden wird die schrittweise Erstellung einer OpenGL-Applikation gezeigt. Ziel ist es, sie anschließend nativ für Windows, Linux und Mac OS zu kompilieren und sie mithilfe von Emscripten für den Browser zu übersetzen. Die Applikation selbst gestaltet sich sehr einfach: Sie soll ein Fenster öffnen, in dem ein dreidimensionaler Würfel dargestellt wird, der sich um alle drei Achsen dreht. Auf allen Seiten des Würfels soll das Qafoo-Firmenlogo angezeigt werden, welches zuvor als Textur aus einer PNG-Datei geladen wurde. Abbildung 1 zeigt das Ergebnis der fertigen Applikation ausgeführt unter Mac OS.

westhoff_opengl_1.tif_fmt1.jpgAbb. 1: OpenGL-Applikation in Aktion – ein sich drehender Qafoo-Würfel

Die Entscheidung für die Entwicklungssprache fällt auf C. Vornehmlich aus zwei Gründen: Erstens unterstützt Emscripten als Ausgangssprache nur C und C++. Dies schränkt die Auswahl natürlich bereits maßgeblich ein. Auch wenn es noch andere Transpiler z. B. für die .NET-Sprachenfamilie gibt, so ist Emscripten derzeit doch eines der interessantesten Projekte. Zweitens fällt die Entscheidung auf C, weil diese Sprache für das gewählte Beispiel einfacher verständlich ist als C++.

Nach einer Evaluation der Applikationsanforderungen ist schnell klar: Es müssen drei maßgebliche Aufgaben bewältigt werden:

  • Bereitstellung eines OpenGL-Kontexts, der in einem Fenster dargestellt wird.

  • Laden des Qafoo-Logos als Textur aus einer PNG-Datei.

  • Zeichnen des rotierenden Würfels mit entsprechender Textur.

Das Rad muss nicht neu erfunden werden

Zunächst wird die JavaScript-Umsetzung ausgeblendet. Somit fällt für die ersten beiden Punkte die Entscheidung, bereits existierende Libraries einzusetzen. Die einfache Bereitstellung eines OpenGL-Kontexts wird GLFW [3] erledigen, wohingegen das Laden der PNG-Textur mit der Image-Bibliothek von SDL [4] vollzogen wird. Die Hauptaufgabe – das Zeichnen des Würfels – kann natürlich nicht von einer fertigen Komponente übernommen werden, auch wenn OpenGL sich um die korrekte Geometrieberechnung und Bereitstellung der Graphik-Pipeline kümmert.

Sind die beiden Bibliotheken SDL und GLFW installiert, so kann es auch schon losgehen. Zu Beginn wird eine Datei mit dem Namen qafoo.c erstellt (Listing 1). Zunächst richtet sich das Augenmerk auf die Funktion main. Hierbei handelt es sich um den Haupteintrittspunkt der Applikation, also jenen Teil, der bei einem Aufruf als Erstes ausgeführt wird. Der Inhalt dieser Funktion ist bis auf wenige Ausnahmen nicht sonderlich spannend. Als Erstes wird die GLFW-Bibliothek mittels glfwInit initialisiert. Wie bei allen weiteren Aufrufen wird das Programm im Fehlerfall einfach beendet. Anschließend wird ein 640 x 480 Pixel großes Fenster mit einem OpenGL-Kontext geöffnet. Die erste Anforderung an die Applikation ist somit bereits umgesetzt: Öffnen eines Fensters, das einen OpenGL-Kontext beinhaltet.

Listing 1

#include <GL/glfw.h> void initGlScene(); void renderGlScene(double delta); void doRenderingLoop(); double lastSceneRendered, currentSceneRendered; void renderFrame() { currentSceneRendered = glfwGetTime(); renderGlScene(currentSceneRendered - lastSceneRendered); lastSceneRendered = currentSceneRendered; glfwSwapBuffers(); } int main(void) { if (!glfwInit()) { return -1; } if(glfwOpenWindow(640, 480, 0,0,0,0,16,0, GLFW_WINDOW) != GL_TRUE) { glfwTerminate(); return -1; } initGlScene(); lastSceneRendered = glfwGetTime(); doRenderingLoop(&renderFrame); glfwTerminate(); return 0; }

Der nächste Aufruf, initGlScene, stammt nicht aus einer fertigen Bibliothek, sondern wird im Laufe dieses Artikels noch implementiert. initGlScene wird sich unter anderem um den zweiten Punkt der Anforderungen kümmern: Laden der Qafoo-Textur. Bevor dieser Punkt allerdings nähere Betrachtung findet, noch einige Worte zur main-Funktion. In Zeile 31 wird die Funktion doRenderingLoop aufgerufen, der ein Pointer auf die Funktion renderFrame übergeben wird. Die Aufgabe der doRenderingLoop-Funktion ist, die ihr übergebene Funktion aufzurufen, wann immer ein neues Frame der Animation gezeichnet werden muss. Dies geschieht so lange, bis das Pr...

Neugierig geworden?

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang