Sie machen eine 3D-Engine. Sie wollen das Beste aus Multiplattform-Welten. Plötzlich wird Ihnen klar, dass Sie, wenn Sie Direct3D auf Windows-Computern und OpenGL unter OSX / Linux verwenden möchten, die unterstützten Funktionen beider auf den kleinsten gemeinsamen Nenner bringen müssen.
Einige verwenden OpenGL möglicherweise für drei Betriebssysteme, da es anscheinend der kleinste gemeinsame Nenner für sich ist. Alles ist gut. Anschließend müssen Sie Ihr Grafik-API-Backend auf Nintendos GX portieren und einen PS3- und Xbox360-Pfad erstellen.
Wie geht's? Entwerfen Sie Ihre eigene API, die an sich den kleinsten gemeinsamen Nenner hat, und schreiben Sie Back-End-Implementierungen für jede Plattform, oder schreiben Sie für jede Plattform einen eigenen Zweig?
Wenn Sie sich für das Entwerfen Ihrer eigenen API entscheiden, verwenden Sie ein Brückenmuster oder Ihren eigenen Voodoo? Wo hört der Wahnsinn auf, wo man merkt, dass alles aufhört und die Küchenspülmethode aufhören muss und man im Grunde für jede Plattform einen eigenen Motor als Zweig hat. Oder Sie bleiben bei allem und der Küchenspüle und behalten die Plattformspezifikationen in den Back-End-Modulspezialisierungen für jede Plattform bei.
Ich kann nur einen Blick auf Ogre3D werfen . Es ist in C ++, Open Source (jetzt MIT-Lizenz) geschrieben und läuft auf jeder wichtigen Plattform ab Werk. Es abstrahiert die Rendering-API und kann mit nur wenigen Einstellungen von DirectX zu OpenGL wechseln. Ich weiß jedoch nicht genug über die Unterschiede zwischen den Funktionssätzen von DirectX und OpenGL, um zu sagen, dass es eine bestimmte Funktion unterstützt oder nicht.
Torchlight von Runic Games wurde mit Ogre geschrieben und ich habe es auf Mac und PC gespielt und es läuft auf beiden sehr gut.
quelle
Für Grafiken habe ich das nicht gemacht, aber ich habe ein plattformübergreifendes Audio-Toolkit (PC / XBOX / PS2) erstellt. Wir sind den Weg gegangen, eine eigene API mit Funktionen für den kleinsten gemeinsamen Nenner sowie optionalen plattformspezifischen Funktionen zu erstellen. Hier sind einige Lektionen gelernt:
Der Schlüssel besteht darin, einen Verarbeitungspfad zu definieren, der die Kernfunktionen jeder Plattform zusammenfasst und Wachstum ermöglicht. Dazu müssen Sie die Low-Level-API jeder Plattform wirklich verstehen, damit Sie die richtigen Abstraktionen identifizieren können. Stellen Sie sicher, dass die Kette für die am wenigsten leistungsfähige Plattform funktioniert, und bieten Sie gleichzeitig Zugriff auf die erweiterten Funktionen der leistungsfähigsten patform. Tun Sie die Arbeit, um dies richtig zu machen, und Sie werden später eine Menge Aufwand sparen.
Für Audio war die Kette so etwas wie
SoundSources -> [Decoders] -> Buffers -> [3D Positioner] ->[Effects] -> Players
.Bei Grafiken kann es sein
Model -> Shapes -> Positioner -> Texturer -> [Lighting] -> [Particle Effects] -> Renderer
. (Dies ist wahrscheinlich ein völlig falscher Satz, ich bin kein Grafiker).Schreiben Sie eine Front-End-API, die Ihre Kernobjekte verarbeitet, und ein plattformspezifisches Back-End, das die API den Funktionen auf niedriger Ebene zuordnet. Geben Sie für jede Funktion die bestmögliche Leistung an. Beispielsweise wurde auf dem PC und der XBOX die 3D-Audiopositionierung mithilfe der HRTF-Funktionen der Soundchips durchgeführt, während für PS2 ein einfaches Schwenken und Überblenden verwendet wurde. Eine Grafik-Engine könnte etwas Ähnliches mit der Beleuchtung tun.
Implementieren Sie so viel Front-End wie möglich mit plattformneutralem Code. Der Code zum Anpassen eines Reverb-Objekts an ein Sound-Objekt oder eines Textur-Assets an ein Shape-Objekt sollte ebenso wie der Code zum Durchlaufen und Verarbeiten aktiver Objekte vollständig identisch sein. Andererseits können die Low-Level-Objekte bis auf die gemeinsame Schnittstelle vollständig plattformspezifisch sein.
Stellen Sie sicher, dass die API oder die Konfigurationsdateien es dem Benutzer ermöglichen, plattformspezifische Optionen anzugeben. Wir haben versucht, zu vermeiden, dass plattformspezifischer Code auf die Spielebene verschoben wird, indem er in Konfigurationsdateien gespeichert wird: In der Konfigurationsdatei einer Plattform kann "effect: SuperDuperParticleGenerator" angegeben werden, während in einer anderen "effect: SoftGlow" angegeben wird.
Definitiv die Plattformen parallel entwickeln. Stellen Sie sicher, dass die plattformspezifischen Schnittstellen gut definiert und eigenständig testbar sind. Dies verhindert eine Menge der "Ist es die Plattform-Ebene oder die API-Ebene?" Probleme beim Debuggen.
quelle
Ich schreibe eine Open-Source-Spiele-Engine namens YoghurtGum für mobile Plattformen (Windows Mobile, Android). Dies war eines meiner großen Probleme. Zuerst habe ich es so gelöst:
Hast du das gesehen
void*
? Dies liegt daran, dassRenderMethodDirectDraw
eine DirectDraw-Oberfläche undRenderMethodDirect3D
ein Vertex-Pool zurückgegeben werden. Alles andere war ebenfalls gespalten. Ich hatte eineSprite
Klasse, die entweder einenSpriteDirectDraw
Zeiger oder einenSpriteDirect3D
Zeiger hatte. Es hat irgendwie gelutscht.In letzter Zeit habe ich viele Dinge umgeschrieben. Was ich jetzt habe, ist ein
RenderMethodDirectDraw.dll
und einRenderMethodDirect3D.dll
. Sie können sogar versuchen, Direct3D zu verwenden, fehlschlagen und stattdessen DirectDraw verwenden. Das liegt daran, dass die API gleich bleibt.Wenn Sie ein Sprite erstellen möchten, tun Sie dies nicht direkt, sondern über eine Factory. Die Factory ruft dann die richtige Funktion in der DLL auf und konvertiert sie in eine übergeordnete Funktion.
Das ist also in der
RenderMethod
API:Und das ist die Definition in
RenderMethodDirectDraw
:Ich hoffe das macht Sinn. :)
PS Ich hätte gerne STL verwendet, aber es gibt keine Unterstützung für Android. :(
Grundsätzlich:
EDIT: Ja, es macht Sinn, virtuelle Schnittstellen wie diese zu haben. Wenn Ihr erster Versuch fehlschlägt, können Sie eine andere Rendermethode ausprobieren. Auf diese Weise können Sie alle Code-Rendering-Methoden unabhängig machen.
quelle
Ich verwende dafür gerne SDL . Es verfügt über Renderer-Backends für D3D, OpenGl, OpenGL ES und eine Handvoll anderer plattformspezifischer Backends. Es ist für alle möglichen Plattformen verfügbar und befindet sich derzeit in der aktiven Entwicklung. Bindungen für viele verschiedene Sprachen sind verfügbar.
Es abstrahiert die verschiedenen Renderer-Konzepte und stellt die Erstellung von Videos (sowie die Verarbeitung von Sound und Eingaben und ein paar anderen Dingen) in einer einfachen plattformübergreifenden API zur Verfügung. Und es wurde von Sam Lantinga, einem der führenden Entwickler von Blizzard, entwickelt, um das Portieren von Spielen und das Erstellen von plattformübergreifenden Spielen zu vereinfachen. So wissen Sie, dass Sie es mit einer hochwertigen Bibliothek zu tun haben.
quelle