Erfolgreiche Spieleentwicklung
Entwicklung moderner Computer-Hardware liegt. Die Spielewelten müssen heutzutage nicht nur optisch so realistisch wie möglich erscheinen, auch die Interaktionen der Spieleobjekte untereinander und mit dem Spieler müssen möglichst glaubhaft simuliert werden. Selbst an der Hobby- und Nachwuchsszene ist diese Entwicklung nicht spurlos vorbeigegangen. Verglichen mit der Anzahl der in den diversen Onlinecommunities aktiven Mitglieder, sind die Resultate in Form von downloadbaren Spielen und 3-D-Anwendungen erschreckend dürftig. Nichts schadet der Motivation mehr als unfertige abgebrochene Projekte. Man sollte daher die eigene Messlatte zu Beginn nicht allzu hoch anlegen und sich zunächst auf die Programmierung kleinerer 3-D-Anwendungen konzentrieren, um sich in die verschiedenen Gebiete der Grafikprogrammierung einzuarbeiten. Parallel dazu bietet sich die Entwicklung eines eigenen Frameworks an, damit man bisher Geleistetes schnell und unkompliziert in späteren Projekten und Spielen wiederverwenden kann. Im Unterschied zu einer Game Engine handelt es sich bei einem Framework um ein schrittweise erweiterbares Programmiergerüst, das die Erstellung neuer Anwendungen vereinfachen soll. Die Programmbeispiele im Downloadbereich unter www.entwickler-press.de/spieleentwickeln [9] nutzen die folgenden Funktionalitäten des beigelegten (in der Entwicklung befindlichen) Grafik-Frameworks:
Routinen zum Initialisieren und Beenden einer OpenGL-Anwendung
die Mathematik-Bibliothek
die Texturverwaltung (Laden und Freigeben von Texturen, mehrfaches Laden von Texturen wird verhindert)
die Mesh-Verwaltung (Laden und Freigeben von Vertex- und Indexdaten, mehrfaches Laden von Mesh-Daten wird verhindert)
das GLSL Shader Framework (Schnittstelle zwischen der 3-D-Anwendung und den verwendeten Shader-Programmen)
das Post Processing Framework
animierbare 3-D-Modelle (Skelett-Animation)
den Rendering Manager (erleichtert den Einsatz von Geometry Instancing)
sowie das Partikelsystem-Framework
2.2 Ressourcenmanagement
Das Ressourcenmanagement zählt zu den zentralen Aufgaben eines 3-D-Grafik-Frameworks. Während sich die Shader-Programme mehr oder weniger unkompliziert verwalten lassen (Shader-Programme werden für gewöhnlich bei Programmstart geladen und bei Programmende wieder freigegeben), gestaltet sich das Management von Textur- und Mesh-Ressourcen ungleich komplizierter. Im Zuge der Darstellung von detailreichen und weitläufigen Spielewelten müssen kontinuierlich die aktuell benötigten 3-D-Daten in den Grafikspeicher geladen und nicht mehr benötigte Daten aus dem Grafikspeicher entfernt werden (Streaming). Für die Gesamtheit aller Daten steht in der Regel nicht genügend Speicherplatz zur Verfügung. Darüber hinaus gilt es zu verhindern, dass die von unterschiedlichen 3-D-Modellen gemeinsam genutzten Texturen und Mesh-Daten mehrfach in den Grafikspeicher kopiert werden. An einen Textur- bzw. Mesh-Manager sind daher die folgenden Anforderungen zu stellen:
Verhindern, dass eine Ressource mehrfach geladen wird
Freigabe einer Ressource, nachdem sichergestellt ist, dass diese nicht mehr anderweitig benötigt wird
Handhabung statischer Ressourcen (diese verbleiben ihre gesamte Lebensdauer über im Grafikspeicher)
Handhabung dynamischer Ressourcen (diese lassen sich im Hintergrund dynamisch initialisieren und entladen)
Im Gegensatz zu statischen Ressourcen ist die Initialisierung dynamischer Ressourcen ungleich komplizierter, denn der Spielfluss sollte möglichst nicht durch unnötige Ladezeiten unterbrochen bzw. durch Einbrüche der Frame-Rate gestört werden.
Schritt 1: Lesen der Daten von der Festplatte, Weiterverarbeitung der Daten falls notwendig (z. B. Berechnung einer Normal Map aus einer Height Map, Berechnung von Vertexnormalen, usw.). Da Festplattenzugriffe generell sehr langsam sind und auch die Weiterverarbeitung der Daten einiges an Rechenzeit erfordert, sollten die Arbeiten in einen separaten Thread ausgelagert werden.
Schritt 2: Kopieren der Ressourcendaten in den Grafikspeicher (schnell im Vergleich zu Schritt 1; dennoch sollten größere Datenmengen schrittweise kopiert werden)
Bei der Überwachung von Ressourcen kommen sogenannte Referenzzähler zum Einsatz. Ein Zählerstand von 0 zeigt an, dass die betreffende Ressource momentan nicht verwendet wird. Bei Anforderung einer Ressource wird der Zähler um den Wert 1 inkrementiert; zudem erfolgt bei der ersten Anforderung ihre Initialisierung. Bei Freigabe einer
Weitere Kostenlose Bücher