PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Wie am besten 3D-API abstrahieren?


Expandable
2006-04-04, 11:47:19
Hallo allerseits,

ich bin gerade am überlegen, wie man am besten die 3D-API abstrahiert (in C++). Meine erste Idee war, eine kleine Klassenhierachie aufzubauen:

abstract Renderer
--- Renderer_OpenGL
--- Renderer_D3D

Das Problem ist nur: Man arbeitet dann ja mit vielen virtuellen Funktionen. Da man ja sehr oft pro Frame Funktionen des Renderers aufruft, stelle ich mir das sehr langsam vor. Außerdem kann der Compiler keine inline-Optimierung durchführen, da er ja nicht weiß, welche Funktion (OpenGL oder D3D) während der Laufzeit dann benötigt wird.

Eine andere Idee wäre, einen Renderer zu schreiben, dessen Funktionen mit einem if-Statement jeweils die richtigen OpenGL/D3D-Funktionen aufrufen. Das könnte man eventuell inline-en, allerdings hat man dann zu jedem Funktionsaufruf noch einen bedingten Sprung.

Im Vergleich zu einem direkten Zugriff auf OpenGL hätten wir also:
- einen virtuellen Funktionsaufruf
- einen Funktionsaufruf, einen bedingten Sprung <- wobei diese Methode sicherlich hässlicher ist als obige.

Hat jemand ein paar Werte, wie sehr das auf die Performance drücken wird (falls eine CPU-Limitierung vorliegt)?

Aber wo wir schon mal beim Thema sind:
- Kann man Klassenfunktionen inlinen? Ich habe mal gelesen, dass Funktionen einer Klasse automatisch geinlined werden, wenn sie in der Header-Datei stehen. Stimmt das? Wie kann ich Funktionen, die in der cpp-Datei sind inlinen? Wenn ich einfach ein inline davor schreibe, kommt meistens ein Compiler-Error.
- Wie kann man Template-Funktionen inlinen?

Danke schonmal!

Coda
2006-04-04, 11:55:27
Schau dir Ogre3D an

Das Problem ist nur: Man arbeitet dann ja mit vielen virtuellen Funktionen. Da man ja sehr oft pro Frame Funktionen des Renderers aufruft, stelle ich mir das sehr langsam vor.
Das ist absolut zu vernachlässigen. Vor allem bei Direct3D, da brauchen die Calls sowieso 1000x länger als eine poplige Indirektion beim Funktionsaufruf (und das ist nicht untertrieben). Aber auch für OpenGL ist das wirklich scheiß egal, da optimierst du eindeutig an der falschen Stelle.

Sobald du DLLs benützt hast du auch dauernd Indirektionen und wen scherts? Niemanden.

Expandable
2006-04-04, 12:56:10
Danke für den Tipp mit Ogre, sieht interessant aus!

Wenn das mit den Indirektionen derartig zu vernachlässigen ist, soll's mir recht sein.

Wie sieht's bzgl. der Inline-Geschichte aus?

Coda
2006-04-04, 13:18:35
Geht nicht, ist aber auch nicht weiters wichtig.

Simon
2006-04-04, 17:35:29
Hi,


ich bin gerade am überlegen, wie man am besten die 3D-API abstrahiert (in C++). Meine erste Idee war, eine kleine Klassenhierachie aufzubauen:

abstract Renderer
--- Renderer_OpenGL
--- Renderer_D3D
Ich hab das bisher in drei Projekten gemacht und kann dir nur eins empfehlen: Lass es bleiben! Entscheide dich für eine API und mach alles damit (siehe OpenSceneGraph oder iD software). Du wirst sehr schnell an einen Punkt kommen, wo Sachen wie der Call Overhead deine geringsten Sorgen sein werden...

Coda
2006-04-04, 22:12:43
Was waren denn die Probleme? Die APIs sind doch semantisch fast identisch.

Simon
2006-04-04, 22:20:57
Was waren denn die Probleme? Die APIs sind doch semantisch fast identisch.
Das fängt schon bei der Wahl einer Shader Sprache an. Wie bietet man Features einer API an, die die andere nicht hat (Geometry Instancing, R2VB, ...)? Man kann nichtmal eben ne Demo runterhacken (was mich tierisch genervt hat). Man muss beide Renderer synchron aktualisieren (was v.a. alleine überhaupt keinen Spass macht).

Vielleicht lag es ja nur an meinen Projekten, aber das sind meine Erfahrungen. Gerade wenn man das alleine oder in einem kleinen Team macht, ist die vorhandene Zeit lieber in sinnvollere Dinge als einen API unabhängigen Renderer gesteckt....

Coda
2006-04-04, 22:22:19
Das fängt schon bei der Wahl einer Shader Sprache an.
Selbst das hab ich abstrahiert :tongue:

OpenGL bekommt GLSL und Direct3D HLSL ausgespuckt. Das war aber wirklich das Hauptproblem.

Wie bietet man Features einer API an, die die andere nicht hat (Geometry Instancing, R2VB, ...)?
Nun, für Instancing must du eh zwei Renderpfade machen, da SM2-Karten das unter DX9 auch nicht können, R2VB must du halt bleiben lassen oder du abstrahierst den Effekt auch auf höherer Ebene.

Vielleicht lag es ja nur an meinen Projekten, aber dasind meine Erfahrungen. Gerade wenn man das alleine oder in einem kleinen Team macht, ist die vorhandene Zeit lieber in sinnvollere Dinge als einen API unabhängigen Renderer gesteckt....
Andererseits wird dadurch aber auch das Design besser und man hat evtl. mehr Möglichkeiten Fehler zu entdecken.

Auf jedenfall steigt deine Chance die Engine bei API-Veränderungen migrieren zu können ;)

Simon
2006-04-04, 22:27:43
Selbst das hab ich abstrahiert :tongue:
hehe =)
Nur brauchst du dann auch deinen eigenen Tools und kannst nicht fxComposer verwenden. Oder doch?


Andererseits wird dadurch aber auch das Design besser
Inwiefern?
Was ist am OSG Design schlecht? Was könnte man verbessern?

und man hat evtl. mehr Möglichkeiten Fehler zu entdecken.
Eventuell?

Coda
2006-04-04, 22:32:00
Nur brauchst du dann auch deinen eigenen Tools und kannst nicht fxComposer verwenden. Oder doch?
Hm ich generier das online per Metasprache in C++ aus Modulen. Ist bisschen abgefahren ;)

Inwiefern?
Was ist am OSG Design schlecht? Was könnte man verbessern?
Es unterstützt nur OpenGL und das ist wohl im ganzen Code verstreut. Find ich nicht sehr sauber.

Eventuell?
Jo, evtl. reagiert eine API ja heftiger auf Fehler, bzw. ist toleranter.

Simon
2006-04-04, 23:23:02
Hm ich generier das online per Metasprache in C++ aus Modulen. Ist bisschen abgefahren ;)
;D
Ich schreib gerade (zwangsweise) an OpenFX, um D3D Effect Files direkt in OpenGL zu benutzen. Quasi ein CgFX-Ersatz :eek:

Es unterstützt nur OpenGL und das ist wohl im ganzen Code verstreut. Find ich nicht sehr sauber.
Mhm, als ich das letzte Mal damit gearbeitet habe, wurde das alles gekapselt. Genauso wie bei meinen Multi-API Projekten hier. :confused:

Coda
2006-04-04, 23:30:12
Mhm, als ich das letzte Mal damit gearbeitet habe, wurde das alles gekapselt. Genauso wie bei meinen Multi-API Projekten hier. :confused:
Na dann is ja gut. Dann ist es ja prinzipiell auch wieder irgendwie Multi-API fähig.

Expandable
2006-04-07, 13:27:04
Selbst das hab ich abstrahiert :tongue:

OpenGL bekommt GLSL und Direct3D HLSL ausgespuckt. Das war aber wirklich das Hauptproblem.


Ich bin da gerade am überlegen... ob ich statt HLSL und GLSL lieber nVidias cg nehmen sollte. Das funktioniert ja API-unabhängig. Gibt es irgendwelche Gründe, die da dagegen sprechen?

Simon
2006-04-07, 14:12:46
Ich bin da gerade am überlegen... ob ich statt HLSL und GLSL lieber nVidias cg nehmen sollte. Das funktioniert ja API-unabhängig. Gibt es irgendwelche Gründe, die da dagegen sprechen?
Eigentlich nicht. Die 1.5er Beta ist ja für so ziemlich alle Plattformen erhältlich =)

Expandable
2006-04-07, 14:22:36
Zu cg findet Google überraschend wenig nützliches. Die meisten werden wohl HLSL für D3D und Programs bzw. GLSL für OpenGL einsetzen, nicht aber cg. (Gibt es denn ein Spiel, dass cg verwendet?).

Weiß jemand zufällig, ob cg gut mit ATi-Karten zusammenarbeitet (sollte es ja eigentlich rein technisch gesehen) und ob das langsamer als HLSL/GLSL ist (wahrscheinlich, aber ist das spürbar?)?

;D
Ich schreib gerade (zwangsweise) an OpenFX, um D3D Effect Files direkt in OpenGL zu benutzen. Quasi ein CgFX-Ersatz :eek:

Darf ich fragen, warum Du nicht einfach CgFX verwendest?

Coda
2006-04-07, 14:36:27
Ich bin da gerade am überlegen... ob ich statt HLSL und GLSL lieber nVidias cg nehmen sollte. Das funktioniert ja API-unabhängig. Gibt es irgendwelche Gründe, die da dagegen sprechen?
Soweit ich weiß kann es unter OpenGL kein GLSL ausgeben und damit auch keine SM3-Features für ATI-Karten verwenden.

Expandable
2006-04-07, 14:37:55
Soweit ich weiß kann es unter OpenGL kein GLSL ausgeben und damit auch keine SM3-Features für ATI-Karten verwenden.

Doch geht mit 1.5 Beta 1.

Corrail
2006-04-07, 15:51:55
Doch geht mit 1.5 Beta 1.

Funktionieren die glslv und glslf Profile auch mit CgFX? Hab es in einem Sampleprogramm ausgebessert, aber er hatte dann den Fehler, dass er den Effekt nicht erstellen konnte...

Simon
2006-04-07, 21:05:39
Zu cg findet Google überraschend wenig nützliches. Die meisten werden wohl HLSL für D3D und Programs bzw. GLSL für OpenGL einsetzen, nicht aber cg. (Gibt es denn ein Spiel, dass cg verwendet?).
Richtig :|

Weiß jemand zufällig, ob cg gut mit ATi-Karten zusammenarbeitet (sollte es ja eigentlich rein technisch gesehen) und ob das langsamer als HLSL/GLSL ist (wahrscheinlich, aber ist das spürbar?)?
Also, die ersten Versionen liefen auf ATI Karten merklich langsamer, 10-15% afair. Da gibts auf gamedev.net min. einen Beweisthread zu. Das soll sich aber gebessert haben...



Darf ich fragen, warum Du nicht einfach CgFX verwendest?
1) Ich will doch was bei Lernen ;D
2) Hatten wir versch., unerklärliche Probleme mit CgFX. Hauptsächlich wurden States nicht erkannt :confused:

Expandable
2006-04-07, 23:19:29
Funktionieren die glslv und glslf Profile auch mit CgFX? Hab es in einem Sampleprogramm ausgebessert, aber er hatte dann den Fehler, dass er den Effekt nicht erstellen konnte...

Also bei mir gab's damit kein Problem... 6800GT @ FW 84.20.

TheGamer
2006-04-09, 20:57:23
Soweit ich weiß kann es unter OpenGL kein GLSL ausgeben und damit auch keine SM3-Features für ATI-Karten verwenden.


In der Beta scheints zu gehen. Habe das vor kanpp ueber nem Jahr mal per Mail bei Nvidia nachgefragt. Damals meinten Sie das noch nciht in die Richtung geplant sein. Naja bis jetzt :D