[Tutorial Serie] LWJGL 3.1.0 & GLFW (mit OpenGL) – Teil 1

In dieser neuen Tutorial-Serie soll uns einmal um die Lightweight Java Game Library 3 (kurz: LWJGL 3) gehen, eine Library für Java um 3D und 2D Spiele entwickeln zu können. Dabei werden allerdings OpenGL oder Vulkan vorausgesetzt. LWJGL soll den Zugriff auf OpenGL, OpenAL und OpenCL, sowie seit neuestem auch auf Vulkan Funktionen erleichtern und euch eine Menge Arbeit abnehmen. In diesem Tutorial soll es uns aber nur um OpenGL gehen.

LWJGL Logo

Die aktuell unterstützte maximale OpenGL Version ist OpenGL 4.5, wenn ihr aber wollt, dass euer Spiel (oder was auch immer) auch mit OpenGL 2.0 funktioniert, müsst ihr eben auf OpenGL 2.0 setzen. Außerdem erleichtert euch LWJGL das Dekodieren von Bildern (z.B. PNG) und Musik. Auch beim Input Handling (Tastatur, Maus und Controller wie z.B. Gamepads) unterstützt LWJGL euch. Außerdem ist LWJGL Plattform-unabhängig und schnell, d.h. es stehen natives für Windows, Linux & Mac OSX (allerdings keine Linux 32 Bit Version mehr!) zur Verfügung. Außerdem wird der Speicher bei LWJGL oftmals native alloziert (Java Off-Heap Speicher), was wiederum für einen Performance Boost sorgt, damit eure Spiele in etwa an die Performance von C / C++ gelangen können. Die meisten 3D Spiele & Game Engines, die in Java geschrieben wurden, setzen auf LWJGL auf, z.B. die 3D Game Engine jMonkeyEngine, wenn ihr allerdings direkt auf Low-Level Ebene mit LWJGL & OpenGL arbeitet, könnt ihr euer Spiel viel besser optimieren und erreicht (vermutlich) auch eine gute Performance.

 

Allgemein zum Projekt

In diesem Tutorial werden wir nur LWJGL & behandeln, sowie OpenGL anreißen. Wenn ich auf jede Kleinigkeit eingehen würde, würde dies hier den Rahmen sprengen. Außerdem werden wir Maven als Dependencie Management & Build Tool verwenden. Wer noch nie was von Maven gehört hat oder sich damit nicht auskennt, sollte sich mein Maven Tutorial mal genauer anschauen. Außerdem gab es mit der Version 3.1.0 eine wichtige Neuerung: Die ganze Library wurde in einzelne Module unterteilt, die man jetzt einzeln hinzufügen muss. In diesem 1. Teil des Tutorials wollen wir LWJGL einbinden und ein erstes Fenster mit GLFW erstellen.

Außerdem noch eine Anmerkung: Die meisten GLFW & OpenGL Methoden werden statisch importiert, da OpenGL eine C Api ist, die kein OOP nutzt. Wir rufen sozusagen native Funktionen auf.

 

Als erstes legen wir die Maven pom.xml Datei an, um die Library einzubinden:

 

Damit wir ein Fenster erstellen und dann OpenGL nutzen können, müssen wir zuerst GLFW initialisieren.

Dazu schreiben wir uns eine kleine Utils-Klasse GLFWUtils:

 

In der init() Methode wird zuerst ein Error Callback gesetzt, in diesem Fall geben wir an, dass GLFW die Fehler direkt auf der Konsole ausgeben soll. Danach wird mittels glfwInit() GLFW initialisiert. Diese Methode gibt false zurück, wenn die Initialisierung fehlgeschlagen ist, ansonsten true.

 

Als nächstes erstellen wir unsere Main Klasse:

 

Hier initialisieren wir zuerst die Logger Library log4j, die somit alle Meldungen auf der Konsole ausgibt.

Danach initialisieren wir GLFW und fahren GLFW am Ende wieder herunter. Bis jetzt also nichts besonderes.

 

Als nächstes legen wir noch eine OpenGLUtils Klasse an, damit wir die unterstützte OpenGL Version herausfinden können:

 

Mit dieser Klasse können wir die unterstützte OpenGL Version herausfinden. Falls ihr jetzt schon versucht, mittels System.out.println(“supported OpenGL version: ” + OpenGLUtils.getVersionString()) die OpenGL Version in der Main ausgeben zu lassen, werdet ihr auf diesen Fehler stoßen:

 

Dies liegt daran, dass wir aktuell noch keinen OpenGL Kontext erstellt haben (OpenGL muss ebenfalls erst initialisiert werden).

 

Als nächstes legen wir (der Einfachheit halber vorerst in der Main Klasse) einige GLFW Window Hints (Einstellungen) fest:

 

Mittels glfwDefaultWindowHints() laden wir die GLFW “Standard-Einstellungen”, um nicht jede Kleinigkeit einzeln setzen zu müssen. Mit glfwWindowHint(GLFW_VISIBLE, GL_FALSE) legen wir fest, dass das Fenster nach der Erstellung vorerst noch nicht angezeigt, sondern versteckt werden soll. Außerdem legen wir mit glfwWindowHint(GLFW_RESIZEABLE, GL_TRUE) fest, dass man das Fenster resizen, also verkleinern und vergrößern kann. Danach legen wir die mindestens benötigte OpenGL Version fest, in unserem Fall benötigen wir vorerst nur OpenGL 3.2, um die meisten Computer unterstützen zu können.

 

 

Jetzt wollen wir aber endlich mal das Fenster erstellen! Dazu müssen wir zunächst festlegen, auf welchem Monitor dieses erscheinen soll, wir setzen hier NULL (eine Konstante!), damit der erste Bildschirm ausgewählt wird. Danach definieren wir, wie hoch und breit das Fenster werden soll, sowie den Fenstertitel. Mit glfwCreateWindow() erstellen wir dann letzendlich das Fenster und übergeben dabei alle wichtigen Parameter. Diese Methode gibt dann eine eindeutige ID des Fensters zurück, die wir in einer Variablen speichern, damit wir später noch Einstellungen des Fensters ändern können. Danach wird geprüft, ob die Fenstererstellung erfolgreich war und wir holen uns die Auflösung des Monitors, um die Mitte berechnen zu können und das Fenster dann mittig auf dem Bildschirm ausrichten zu können. Mit glfwMakeContextCurrent(windowID) aktivieren wir OpenGL und setzen den Kontext für dieses Fenster. Mittels glfwShowWindow(windowID) zeigen wir es endlich an und um OpenGL wirklich nutzen zu können müssen wir noch GL.createCapatibilities() ausführen, damit die OpenGL Bindings aktiviert werden.

 

Hier nochmal die vollständige Klasse Main:

 

GLFW Window

 

Wenn ihr alles richtig gemacht habt, sollte jetzt ein Fenster erscheinen. 😀

Bitte beachtet, dass der Schließen Button oben rechts noch nicht funktioniert, weil wir noch nicht festgelegt haben, was beim Schließen genau passieren soll, dies werden wir dann u.a. im 2. Teil erledigen. 😀

Hinterlasst doch mal ein Feedback, ob es bei euch funktioniert hat, ob ihr Probleme hattet oder ob euch das Tutorial gefallen hat! Der 2. Teil ist bereits in Arbeit.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.