Beim Erstellen einer Systemabstraktion ist es besser, die Plattform über verschiedene APIs zu informieren, die durch eine gemeinsame Schnittstelle auf der untersten Ebene sinnvoll sind.
Berücksichtigt die verschiedenen modernen (ohne Pipeline mit festen Funktionen) nativen Grafik-APIs: OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM
Wenn man eine zustandslose Grafik-API auf niedriger Ebene erstellen würde , um auf allen zu sitzen, was wäre der beste Weg, um sie so dünn und schnell wie möglich zu machen?
architecture
software-engineering
graphics
cross-platform
NocturnDragon
quelle
quelle
Antworten:
Die niedrigste Ebene, die aus meiner Sicht sinnvoll ist, befasst sich mit den Ressourcen, die beim Rendern erforderlich sind - vb / ib, Renderoberflächen, Texturen, Shader, Statusblöcke usw.
Das Problem hierbei ist, dass einige davon je nach API in unterschiedlichen Formaten vorliegen müssen - dort wird es etwas schwierig. Der einfachste Weg, dies zu umgehen, besteht darin, statische Ressourcen für die jeweilige API vorzuverarbeiten. Verwenden Sie für dynamische Shader nur Shader, um sie zu generieren. Dies macht es ziemlich einfach, in nativen Formaten zu bleiben.
Alles, was Sie dann auf der höheren Ebene tun, ist, Pipelines mit angehängten Ressourcen einzurichten und diese an die GPU zu übergeben. Sie werden feststellen, dass nicht alles auf diese Weise gut abstrahiert werden kann, insbesondere wenn Sie hardwarespezifische Tricks nutzen. Aber es ist ein guter Anfang.
(Nebenbemerkung: Wenn Sie plattformspezifische Tricks als eine besondere Art von Ressource behandeln, können Sie dieses gesamte Konzept ziemlich weit treiben.)
In gewisser Weise erstellen Sie zwei Dinge: einen Hardware-Ressourcenmanager sowie ein Toolkit zum Einrichten einer DAG dieser Ressourcen.
quelle
Angesichts des breiten Spektrums an APIs, die Sie abdecken möchten, ist der typische Wrapping-Ansatz wahrscheinlich ineffizient und neigt dazu, API-Konzepte auf mehrere andere APIs abzubilden, die bestimmte Funktionen in unterschiedlichem Maße unterstützen oder nicht.
Daher wäre es am sinnvollsten, eine funktionsorientierte API zu erstellen . Dieser Ansatz verhindert zwar, dass der API-Benutzer alle verfügbaren Funktionen nutzt, vereinfacht jedoch die Implementierung jedes Backends erheblich und ermöglicht backendspezifische Optimierungen, die sonst nicht möglich wären.
Dies vereinfacht auch die Verwaltung nicht unterstützter Funktionen für den API-Benutzer erheblich. Sie müssen nicht mehr prüfen, ob Funktion X vorhanden ist, und feststellen, welche Funktionen betroffen sind, sondern müssen nur die Funktion selbst abfragen, um festzustellen, ob sie von der aktuellen Konfiguration unterstützt wird. Selbst wenn Sie teilweise oder eingeschränkte Modi für Funktionen unterstützen, erleichtert der bereitgestellte Kontext die Verwaltung erheblich.
Beim Erstellen eines zustandslosen (auch als Submission-based ) Renderers bezeichnet wird normalerweise ein 64-Bit-Schlüssel zum Packen und Senden von Befehlen zum Rendern verwendet. Ab diesem Zeitpunkt besteht eine große Flexibilität hinsichtlich der Ausführung von Befehlen und der zu übermittelnden Informationen, je nachdem, welche Funktionen und Fähigkeiten Sie unterstützen möchten.
quelle
Zunächst macht jede API die Dinge anders, daher sollte es selbstverständlich sein, dass das Umschließen aller oben genannten APIs schwierig ist. Das ist manchmal notwendig: Irgendwann muss ein Spiel einfach auf mehr als einer Plattform laufen, unabhängig davon, wie schwierig es ist.
Ich denke, der beste Weg, dies zu tun, besteht darin, die Funktionalität zu entwickeln, die auf allen zugrunde liegenden APIs implementiert werden kann, und dies und nur das zu abstrahieren. Wenn Sie ein Multiplattform-Spiel entwickeln, würden Sie nicht jede obskure Funktionalität implementieren, die jede API unterstützt, sondern nur das implementieren, was Sie benötigen. Dies hilft auch, die API klein und schnell zu halten.
Um zu vermeiden, dass die Implementierung der einzelnen APIs in die Ausgabe gepackt wird, sollte das Kompilieren mit plattformneutralen Headerdateien und plattformspezifischen Codedateien erfolgen. Dann wäre die für die Zielplattform spezifische Codedatei die einzige, die kompiliert wird und die API klein hält.
quelle
Es gibt einen Artikel auf GPU Pro darüber von Emil Persson (Humus)
http://gpupro.blogspot.com/2009/12/making-it-large-beautiful-fast-and.html
quelle
Vielleicht möchten Sie die SDL-Bibliothek oder Allegro überprüfen . Bei beiden handelt es sich um hoch portable Spielbibliotheken auf niedriger Ebene, mit denen Sie sie in einen OpenGL-Kontext einbinden können, damit Sie Ihre Grafiken dort rendern können. SDL hat den Ruhm, von Loki Games verwendet zu werden, um einige beliebte Spiele aus den 2000er Jahren auf Linux zu portieren, und Allegro hat viel Zeit und eine großartige Community von Amateur-Spielentwicklern.
quelle