Plattformübergreifende Low-Level-Grafik-API


11

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?


Die Anforderung, dass die API zustandslos sein muss, ist interessant. OpenGL zum Beispiel ist statusbehaftet, und ich denke, eine zustandslose API, die es umschließt, wäre nur dann sinnvoll, wenn es viel höher wäre, so dass es nicht zum Beispiel erforderlich ist, für jedes einzelne die gleichen Matrizen zu pushen und zu platzen Oberfläche, die es rendert.
SpoonMeiser

Das Vermeiden nutzloser Statusänderungen könnte immer noch auf einer höheren Ebene implementiert werden, z. B. indem die Renderaufrufe nach ihrem Status sortiert werden, bevor sie an das Gerät gesendet werden. Und indem Sie den Status nur festlegen, wenn er sich vom aktuellen unterscheidet.
NocturnDragon

Das ist aber nicht staatenlos. Vielleicht irre ich mich, aber was ich denke, wenn ich an zustandslos denke, ist eine API, bei der jeder Aufruf überhaupt nicht von vorherigen Aufrufen abhängt. Das bedeutet, dass alle Informationen, die normalerweise irgendwo gespeichert werden, bei jedem Aufruf übergeben werden müssen, der diese Informationen benötigt. Für OpenGL wären dies beispielsweise Matrizen für die Optionen Stapel, Beleuchtung, Z-Pufferung und Normalisierung.
SpoonMeiser

Ja, für jeden Draw-Aufruf, den Sie benötigen, die Netzdaten, den Mischstatus, die zu bindenden Texturen, die Stichprobenzustände usw. Optimierungen können später vorgenommen werden, ohne die API zu ändern. Oder vielleicht lese ich Ihren Kommentar falsch ..
NocturnDragon

Antworten:


6

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.


Ich habe nie daran gedacht, plattformspezifische Dinge als Ressourcen zu behandeln. Das klingt nach einer sehr guten Idee! Vielen Dank.
NocturnDragon

10

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.


Das ist eigentlich eine gute Idee. Und es ist Teil des Designs, das ich erstellen möchte, aber ich hatte vor, diese Funktionen zusätzlich zu einer gemeinsamen Low-Level-API zu implementieren. Es kann jedoch vorkommen, dass Sie für einige Funktionen in bestimmten Fällen noch tief in die native API eintauchen müssen.
NocturnDragon

Ein Teil der Idee besteht darin, die Erstellung einer gemeinsamen Low-Level-API zu vermeiden und sich mit dem Wrapping mit einem Ansatz mit dem kleinsten gemeinsamen Nenner befassen zu müssen. Indem Sie die Abstraktionsebene um eine Stufe nach oben verschieben, schränken Sie den Funktionsumfang etwas ein, erhalten aber auch die Möglichkeit, jede Plattform auszunutzen. Um die gelegentliche Notwendigkeit eines tieferen Zugriffs zu bewältigen, bevorzuge ich die Bereitstellung eines Headers, der die Plattform-Header und einige interne Helfer verfügbar macht. Es kann Version zu Version brechen, aber es ist da, wenn Sie es brauchen.
Jason Kozak

1

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.



-4

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.


4
Dies beantwortet die Frage nicht wirklich, ganz zu schweigen davon, dass es sehr gut möglich ist, sowohl OpenGL als auch DirectX zu verpacken (siehe Ogre3D, Irrlicht usw.).
Jason Kozak

Betrachten Sie die Spiele, die Sie gespielt haben. Wie viele von ihnen haben Optionen zur Verwendung von DirectX oder OpenGL? So viele Erstellungs-Wrapper für die beiden Bibliotheken können beide unterstützen. Sie haben eine begrenzte Vorstellungskraft. :-P
Ricket

Ich erkenne, dass es einige Spiele gibt, in denen Sie auswählen können, ob Sie Grafiken mit OpenGL oder DirectX rendern möchten, aber die Frage bezieht sich auf eine plattformübergreifende API. Ich denke, die Antwort ist angemessen. Ich werde den ersten Absatz bearbeiten. obwohl.
Chiguire

1
Die Frage bezieht sich auf eine plattformübergreifende zustandslose Low-Level-API. SDL und Allegro haben nichts damit zu tun.
NocturnDragon

@NocturnDragon - der Titel der Frage ist etwas irreführend. Auf den ersten Blick erwartete ich, dass es sich bei der Frage um die Auswahl der verfügbaren API handelt, und ich gehe davon aus, dass dies auch bei diesem Antwortenden der Fall war.
a_m0d
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.