ClanLib Anfängertutorial
Willkommen bei meinem ClanLib Anfängertutorial in dem ich ein Basisprojekt aufsetze und einige der Grundlagen erkläre. ClanLib eignet sich sehr gut um schnell und einfach eine Plattform unabhängige Fensteranwendung zu bauen. Mit Unterstützung für 2D und 3D Rendering und eigenem UI.
ClanLib Anfängertutorial
Ich benutze ClanLib seit dem Studium für schnelle Prototypen und das ein oder andere Programm für eine Simulation. Die Bibliothek eignet sich gut dafür Betriebssystem unabhängigen C++ Code zu schreiben und Dinge in einem Fenster zu zeichnen. Besonders einfach geht das in 2D. Kombinieren lässt sich die Ausgabe für realistische Simulationen mit einer beliebigen kompatiblen Physik-Engine. Mit dem UI Modul lassen sich auch recht einfach Programme mit den bekannten Controls bauen. Ein Texteditor ist so recht schnell zusammengebaut, Bürosoftware sollte man aber dennoch nicht damit umsetzen, da würde ich mir lieber Office kaufen. Spaß beiseite, beginnen wir mit einem einfachen Beispiel. Ich gehe davon aus, dass ClanLib bereits auf dem Rechner installiert ist. Wie man das unter Linux aus dem Source Code macht habe ich bereits gezeigt (ClanLib unter Linux kompilieren).
Fertiges Programm
Das fertige Programm sieht wie folgt aus:
Den Source Code findet man in meinem Repo als eigenen Branch auf GitHub. Auf den Blick mag das nicht nach viel aussehen. Was jedoch passiert ist: es wird über die Engine ein Fenster erstellt und angezeigt. Das Funktioniert sowohl in Linux, Windows oder Mac OSX. Der schwarze Inhaltsbereich ist das in 2D gezeichnete Bild, das wird bereits mit Double Buffering gezeichnet.
Exkurs: Double Buffering
Unter Double Buffering versteht man, dass der Speicher für das Bild (in diesem Fall) doppelt vorhanden ist. Der eine Speicher wird auf dem Bild gezeichnet, während unser Programm den zweiten Speicher beschreiben kann. Nachdem man den zweiten Speicher vollständig gezeichnet hat wird getauscht, d.h. der zweite Speicher wird angezeigt und man beginnt damit den ersten Speicher neu zu befüllen. Mit diese Methode verhindert man, dass man den Bildaufbau sieht. Es kommt zu keinen ungewöhnlichen Artefakten und Flickern.
ClanLib
Zurück zum Thema. Das Programm besteht aus einer Klasse und einem Header, in dem die ClanLib Header eingebunden werden.
In so gut wie jedem Programm benötigt man die core.h, application.h, display.h und je nach Betriebssystem d3d.h oder gl.h. Unter Windows verwendet man Direct3D, unter Linux oder Mac Open GL. Über die Präprozessor Direktiven lassen sich je nach Betriebssystem Codebereiche ein- oder ausschalten.
Eine minimale App besteht aus einer von ClanLib Application geerbten Klasse die den Konstruktor und die update Methode überschreibt:
Ich habe in meinem app.h Header noch einige private Methoden definiert die ich immer benötige. Das sind zum einen Handler für den Input (Maus on_mouse und Keyboard on_keyboard) und zum anderen habe ich den Programmfluss wie man es im Game Engineering lernt in die 3 Methoden
- init
die zu rendernde Szene wird vorbereitet, alle Assets werden geladen. - render
die Szene wird gezeichnet - compute
die Game Logik wird berechnet.
unterteilt.
Fenster erstellen
Die wichtigste Zeile der ganzen Applikation ist zugleich auch die unscheinbarste. Viele Programmieranfänger fragen sich bestimmt: Wo ist der Einsprungspunkt der Applikation? Wo ist die main Methode? Die Antwort: darum muss man sich nicht kümmern, das macht alles ClanLib. Das was wir aber machen müssen, ist folgendes:
clan::ApplicationInstance<App> clanapp;
Mit dieser Zeile wird eine Instanz der App Klasse erzeugt. Damit ist unser Einsprungspunkt im Source Code dessen Konstruktor. In der Folge wird Frame für Frame die update Methode ausgeführt.
Im Konstruktor wird das Fenster erstellt. Als erstes legen wir nach Betriebssystem unabhängig fest ob OpenGL oder Direct3D verwendet wird, danach erstellen wir 3 Dinge:
- DisplayWindowDescription
über dieses Objekt lassen sich Eigenschaften eines Fensters setzen. In meinem Fall setze ich dessen Titel, die Fenstergröße und ob es erlaubt ist das Fenster zu maximieren. - DisplayWindows
erstellt das eigentliche Fenster und bekommt als Parameter ein DisplayWindowDescription Objekt. - Canvas
das ist der Zeichenbereich in denen wir hinein zeichnen. Als Parameter bekommt das Canvas ein DisplayWindows Objekt.
Die folgenden Zeilen Code binden die Callback Funktionen für Maus und Keyboard Events ein. Außerdem wird der Windows Close Befehl vom Fenster so eingestellt, dass er die Variable quit auf true setzt. Dieser Boolean wird die Abbruchbedingung der Applikation sein.
Rendern
Die update Methode der Application Klasse von ClanLib läuft unendlich oft, zumindest so lange sie immer true zurück liefert. Aus diesem Grund gebe ich den Wert der quit Variable zurück. Sobald das Fenster geschlossen wird (quit = true) läuft die update Methode noch ein letztes Mal, danach beendet ClanLib sauber das Programm.
Der Inhalt der update Methode ist in meinem ersten Beispiel überschaubar. Der Inhalt des Canvas wird mit einer Hintergrundfarbe gelöscht. Diese ist fix mit schwarz definiert. Danach wird die render Methode aufgerufen für die Game Logic. Die macht aktuell nichts. Zuletzt wird dann noch der Grafikspeicher für das Canvas mittels double buffering getauscht.
Fazit
Im ClanLib Anfängertutorial habe ich gezeigt wie man ein Fenster erstellt und einen leeren Zeichenbereich darstellt. Diesen Code kann man nun als Blueprint für eigene Anwendungen nehmen. Im nächsten Artikel zeige ich wie man in das Canvas zeichnet.
Bis auf den Halbsatz zu Office, der auch noch falsch ist, „kann würde“ – was den jetzt? -, ist der Artikel gut.
Noch ein paar Schreibfehler / fehlendes Wort:
Auf den ERSTEN Blick <- ersten fehlt
zum anderen <- Anderen groß
Damit wird ist unser <- wird weg
Danke für die Hinweise! Zum anderen lass ich aber mal so laut Duden korrekt.