[C++] Mehrere APIs verwenden

Design Patterns, Erklärungen zu Algorithmen, Optimierung, Softwarearchitektur
Forumsregeln
Wenn das Problem mit einer Programmiersprache direkt zusammenhängt, bitte HIER posten.
Antworten
Raven280438
Establishment
Beiträge: 140
Registriert: 03.10.2010, 20:14

[C++] Mehrere APIs verwenden

Beitrag von Raven280438 »

Hi,

da ich mich nicht wirklich zwischen OpenGL und DirectX entscheiden kann, habe ich mir gedacht meine "Engine" mit sowohl OpenGL als auch DirectX versuchen zu Progammieren (einfach um beides zu lernen, zuerst das Eine, dann das Andere).

Ich habe mir das als eine Art Plugin-System gedacht, in der je nachdem entweder ein OpenGL- oder ein DirectX-Plugin geladen wird.

Wie gesagt, das ist erstmal nur eine Idee.

Wie müsste ich meine Engine dann aufbauen? Ich hab mal ein bisschen gegoogelt, und die meisten Plugin-Systeme verwenden eigene DLLs für die verschiedenen Plugins.
Gibt es da noch andere Möglichkeiten? Bisher hab ich ausschließlich mit statischen Bibliotheken gearbeitet.

Könnte man für jedes Plugin auch eine lib erstellen, die dann je nach Plattform gelinkt wird? Oder kann man irgendwie Alles auch nur in 1 Projekt packen?

Kann mir da jemand ein paar Tipps geben?


Gruß
Benutzeravatar
Top-OR
Establishment
Beiträge: 330
Registriert: 02.03.2011, 16:32
Echter Name: Jens H.
Wohnort: Esslingen/Dessau
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von Top-OR »

Hi Raven,

meine kurze Antwort darauf: das lohnt sich "nicht".

Als ich so ca. 2000 rum meine Engine/Framework begonnen habe, habe ich auch so gedacht.
Inzwischen ist es 2014 und ich habe m Grunde nur mir OpenGL gearbeitet: Alles, was OpenGL ist, ist in eine DLL ausgelagert; dem eigentlichen Renderer.

Es gibt bei mir eine statische Lib, die im Grunde nur ein paar virtuelle/Abstrakte Klassen mit ein paar Convinience-Methoden und ein paar Datentypen definiert. Auf dieser bauen dann die Engine (das Programm) selbst und der Renderer auf (die DLL), die diese Klasse mithilfe von OGL dann implementiert. Meine Engine kennt weder DX noch OpenGL, sondern nur ihr Render-Interface.

Mein Plan war auch, "später", aus Langweile dann mal nen DX-Renderer zu implementieren. Bis heute hat sich diese Langeweile nicht eingestellt. DX kenne ich kaum, sehe aber immer wieder (auch in den Posts hier), wie ähnlich sich die Konzepte (also das Rendering an sich) sind bzw. dass am Ende Alles im Grunde irgendwie ähnlich auf der Graka landet; lediglich die Calls sehen oft etwas anders aus.

Ob du nun vor 10 Jahre sowas die glBegin(); ... glEnd(); gemacht hast, heute machste glDrawElements() und bei DX sonstewas ... aber im Grunde ist ein DrawCall ein DrawCall, Buffers sind Buffers und Programmierfehler sind Programmiefehler. Ich sehe heute den eigentlichen Reiz darin, zu sehen, wie bestimmte Effekte mit dem ganzen ähnlichen, aber dennoch recht low-level Set an Möglichkeiten eben umgesetzt werden können.

Ist eher meine Rat: Entscheide dich für eine Seite, und gut ist .. DL .. OGL ... ist Geschmackssache in meinen Augen. Jammern tun alle Entwickler. ;-)

Das Kapseln des Renderers hilft mir lediglich, etwas zu abstrahieren und 2x zu überlegen, was "Renderer" und was "Engine" ist bzw. sein könnte ...

Just my 2Cents,
TopOR

PS: Achso .. der Renderer ist nicht reingelinkt, sondern das macht meine Engine zur Laufzeit .. also kurz, bevor es losgeht ... geht also nur unter Windows. Unter Linux müsste man dann einen anderen Mechanismus verwenden. Dazu Einfach mal nach "Win32 LoadModule" googlen...
Zuletzt geändert von Top-OR am 02.09.2014, 17:32, insgesamt 1-mal geändert.
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von kimmi »

Unter Linux heißt das Ganze dlopen, soweit ich weiß.

Pitfalls, auf die man stoßen kann, wenn man nur auf eine API setzt, können wir der Vollstänfigkeit halber ja mal auflisten:
  • DirectX geht leider nur unter Windows, und da auch nicht auf allen Versionen
  • OpenGL API wird jeweils von GPU-Vendor ausgeliefert und der Support kann gerade unter Windows aufregend sein
Das kann einem Ärger machen ( wie mir im Job ), muß natürlich nicht.

Vorgehen per virtuellem Interface erkauft man sich durch Performance-Einbußen, die durhc den Ruf von virtuellen Methoden ausgelöst werden. Allerdings ist das die Lösung, mittels der man am schnellsten zum Fliegen kommt. Dann kann man so etwas mittels FunctionPointer implementieren. Eine ganz gute Sammlung findest du hier: http://aras-p.info/blog/2011/02/01/the- ... o-virtual/ .

Und es gibt noch einen weiteren Weg: RenderCommandBuffer, die du einem Backend gibst. Statt eines Interfaces implementierst du in den RenderCommands ein Protokoll, dass die API-Rufe entsprechend bedient.

Gruß Kimmi
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von Schrompf »

Ich würde davon abraten, das überhaupt dynamisch zu binden. Warum als DLL? Mach es doch einfach statisch im Programm, umschaltbar per Define. Den Performance-Unterschied wirst Du zwar erst bei vielen Millionen Aufrufen pro Sekunde messen können, aber dann wird er relevant.

Allgemein würde ich überhaupt davon abraten. Du gewinnst davon genaugenommen nix. Meine Empfehlung: denk Dir eine 3D-Beispielszene mit ein paar knuffigen Effekten aus und baue die in OpenGL. Dann, zu Übungszwecken, baust Du die Szene in DirectX nochmal, aber unbedingt völlig getrennt davon. Wenn Du dann noch unbedingt die beiden 3D-APIs hinter einem gemeinsamen Interface verstecken willst, kannst Du das dann ja anhand dieser beiden Quelltexte machen.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von Krishty »

Man gewinnt sehr wohl etwas: Man ist gezwungen, sauber zu abstrahieren. (Sobald man in der OpenGL-Version mal um die Schnittstelle herum programmieren möchte, lässt sich die Direct3D-Version nicht mehr kompilieren.)

Rückblickend wäre auf meiner Arbeit der D3D-Renderer ohne die nie ausgelieferte, aber Zombie-mäßig am Leben gehaltene, OpenGL-Version nicht so ordentlich geworden.

Privat benutze ich immernoch Renderer-Schnittstellen, aber ausschließlich statisch gebunden wegen der Optimierung.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Top-OR
Establishment
Beiträge: 330
Registriert: 02.03.2011, 16:32
Echter Name: Jens H.
Wohnort: Esslingen/Dessau
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von Top-OR »

Krishty hat geschrieben:Man gewinnt sehr wohl etwas: Man ist gezwungen, sauber zu abstrahieren. (Sobald man in der OpenGL-Version mal um die Schnittstelle herum programmieren möchte, lässt sich die Direct3D-Version nicht mehr kompilieren.)
So in der Art deckt sich das auch mit einen Erfahrungen. Es gab mal einen DX-Renderer, der fast nur aus TODO-Kommentaren bestand, aber hat man das direkte Grafikinterface einmal weggekapselt, überlegt man sich 3x, ob man "mal fix" krude Dinge direkt mit OGL/DX macht.

Und der Performace-Overhead wegen der zusätzlichen Calls, dynamischen Bindung und Abstraktionsebene ist beim aktuellen Stand der Engine mein kleinstes Problem. ;-) ... Da vermiest mir eher der Engine-Core mit Multithreading, Objektupdates und allerlei anderen Effekten den Tag....
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Top-OR
Establishment
Beiträge: 330
Registriert: 02.03.2011, 16:32
Echter Name: Jens H.
Wohnort: Esslingen/Dessau
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von Top-OR »

kimmi hat geschrieben:Unter Linux heißt das Ganze dlopen, soweit ich weiß.

Eine ganz gute Sammlung findest du hier: http://aras-p.info/blog/2011/02/01/the- ... o-virtual/ .
Aahhh .. okay. Interesante Performance-Optimierung. Old-School, manuell .. mag ich. ;-)
Naja, kommt auf jedenfall auf meine TODO-Liste .... wenn ich mal Zeit habe ... wie der DX-Renderer .. :-/
--
Verallgemeinerungen sind IMMER falsch.
Benutzeravatar
Jonathan
Establishment
Beiträge: 2353
Registriert: 04.08.2004, 20:06
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von Jonathan »

Ich würde auch von dlls abraten. Die machen letztendlich nur Probleme und ich versuche mittlerweile sie wo es geht zu vermeiden. Die Vorteile die man durch dlls hat, sind bei mir nie wirklich zum tragen gekommen, andererseits hat man aber oft arge Probleme, wenn eine dll nicht gefunden wird, oder (noch viel schlimmer) eine falsche dll geladen wird und das Programm scheinbar zufällig abstürzt.

Und ich würde nochmal die Frage in den Raum stellen, welchen Nutzen du von 2 verschiedenen Render-APIs erwartest. Einfach, dass du beide gelernt hast? Abgesehen von ein paar sehr speziellen Features von denen man hier und da mal hört können beide eh das gleiche. OGL ist halt Multiplattform, brauchst du das, ist die Entscheidung eh schon gefallen. Willst du nur für Windows entwickeln, hat DX eventuell die schönere API (da echtes C++) aber um ehrlich zu sein ist das auch furchtbar egal. In meinem Render-Subprojekt ist eine Menge Code für Szenenverwaltung, Laden von Modelle und Texturen und berechnen von Animationen. Und da stehen am Ende überall nur eine Handvoll OpenGL Befehle, die man irgendwann mal anhand der Dokumentation dahin geschrieben hat und längst vergessen hat, wie genau die eigentlich aussehen.

Ich meine, klar kann man das ganze als Übung zur Kapselung unterschiedlicher APIs ansehen. Aber wenn es später darauf hinausläuft, dass man einfach eine Funktion hat, die entweder eine OpenGL Funktion oder eine DirectX Funktion mit den selben Parametern aufruft, hat man außer einer Menge zusätzlichen Code auch nichts gewonnen. Wenn deine Abstraktion nicht irgendwelche zusätzlichen Features liefert (und dafür musst du vermutliche beide APIs erstmal recht gut kennen) ist es ein bisschen fraglich, wofür das ganze überhaupt war.

Zusammengefasst: Sinnvoll ist das ganze nur wenn du:
1. wirklich Kapselung üben willst und kein besseres Beispiel dafür findest, oder
2. du 2 unterschiedliche Szenarien nennen kannst, bei denen du einmal zwingend DX und einmal zwingend Ogl benötigen wirst und die beide garantiert auftreten werden.

Da beides in meinen Augen unwahrscheinlich ist, würde ich sagen: Lass es und entscheide dich für eines.
Lieber dumm fragen, als dumm bleiben!
https://jonathank.de/games/
Benutzeravatar
kimmi
Moderator
Beiträge: 1405
Registriert: 26.02.2009, 09:42
Echter Name: Kim Kulling
Wohnort: Luebeck
Kontaktdaten:

Re: [C++] Mehrere APIs verwenden

Beitrag von kimmi »

Eine Kapselung hat noch einen weiteren Vorteil: man kann den Renderer leichter per Mock stubben, wenn man Tests bauen muß. Das setzt natürloch voraus, dass man das auch testbar haben will.

Gruß Kimmi
Antworten