Seite 1 von 2

[D3D10] Welche Mathe lib

Verfasst: 01.04.2015, 20:24
von Andi
Hallöchen,

ich will demnächst ein kleines Projekt starten und frag mich z.Z. in welche Richtung ich einschlagen soll. Ich würde mich mittlerweile wieder als totaler Anfänger einschätzen. Zeit für die Entwicklung hab ich genug, hab überhaupt keinen Zeitplan oder Zeitdruck.

So, D3DX10 ist im Windows 8.1 SDK deprecated und nicht mehr vorhanden. Mit DX9 hab ich praktisch alles mit gemacht. Somit bleibt dann vermutlich nur noch D3DMath, DirectXMath, eine fertige 3rd Party lib oder direkt was selber schreiben. Habt ihr Empfehlungen für mich, pros und cons etc.?

Re: [D3D10] Welche Mathe lib

Verfasst: 01.04.2015, 21:15
von dot
Meine Empfehlung: 1) vergiss D3D10 und verwend D3D11, 2) schreib dir selbst was... ;)

Re: [D3D10] Welche Mathe lib

Verfasst: 01.04.2015, 21:33
von Andi
Danke für deine Empfehlung

Eigentlich war D3D11 geplant, entwickle meistens auf meinem alten Laptop der kann leider kein 11 :( Aber immerhin löse ich mich langsam von D3D9 ;)

Re: [D3D10] Welche Mathe lib

Verfasst: 01.04.2015, 21:57
von dot
D3D11 ist im Gegensatz zu D3D10 abwärtskompatibel und läuft auch auf D3D9 Hardware. Es gibt seit dem Tag an dem D3D11 erschienen ist wirklich keinen einzigen Grund, noch D3D10 zu verwenden... ;)

Re: [D3D10] Welche Mathe lib

Verfasst: 02.04.2015, 10:44
von Krishty
Ja, genau. Du übergibst beim Erzeugen deines D3D-11-Devices einfach das FEATURE_LEVEL_10_0.

Was die Mathebibliothek betrifft: Willst du lernen (selber schreiben!) oder willst du produktiv sein?

Re: [D3D10] Welche Mathe lib

Verfasst: 02.04.2015, 18:27
von Andi
Vielen danke für den Tollen Tipp, hätte vermutlich erst die Doku lesen sollen. Da sieht man wieder das ich mich zu lange nicht mehr mit dem Thema auseinandergesetzt habe ;)
Ist jetzt zwar off Topic aber: man kann mehrere Feater Levels mit geben, was ich nicht verstehe ist, enumeriert er durch bis zum höchsten / neusten oder wird das erst Beste genommen? Definiere ich zum Beispiel im Array 10_1 vor 10_0 wird das Device nicht erstellen. Habe ich was falsch verstanden oder mach ich was falsch?
Krishty hat geschrieben:Was die Mathebibliothek betrifft: Willst du lernen (selber schreiben!) oder willst du produktiv sein?
Beides wäre natürlich super, aber mit wenig Erfahrung eher unwahrscheinlich. Aber in erster Linie soll schon der Lernfaktor grösser als die Produktivität sein.

Re: [D3D10] Welche Mathe lib

Verfasst: 02.04.2015, 19:04
von B.G.Michi
Na dann selber schreiben. Dauert dann zwar etwas länger bis das erste (perspektivische) Dreieck auf dem Bildschirm landet, aber es ist ein gutes Gefühl zu wissen welchen weg jedes einzelne float nimmt bis es auf der Scheibe ankommt. Und ein paar Klassen für Vektoren, Matrizen, evtl. noch Kamera oder was man sonst noch zur "mathe lib" zählt zu schreiben, ist auch kein Hexenwerk.

Re: [D3D10] Welche Mathe lib

Verfasst: 02.04.2015, 20:49
von Krishty
Ja; dann unbedingt selber schreiben. Ich empfehle auch Dreiervektoren mit 3×4-Matrizen für nicht-projektives Arbeiten; dann ist das Selbstgeschriebene ähnlich schnell wie der SSE-Kram, den einem die fertigen Bibliotheken verkaufen wollen, aber dazu noch lesbar.

Re: [D3D10] Welche Mathe lib

Verfasst: 02.04.2015, 21:19
von Andi
Hab mir kurz DirectXMath angeguckt, kann mich damit nicht anfreunden und sieht dazu grässlich aus. Also selbst schreiben ist die Devise.
@B.G.Michi
Ist ne gute frage ob man vom Designkonzept die Kamera und solchen Kram zur Mathe nehmen soll. Da muss ich mir jetzt mal nen Kopf machen.

@Krishty
Gut das du SSE erwähnst, das währe meine nächste Frage gewesen, ob sich der Aufwand für Optimierung überhaupt lohnt.

Auf Jeden fall vielen Dank für die Empfehlungen und Tipps, das bringt mich beim Konzept erstellen schon mal eine Ecke weiter.

Zum Off-Topic erstelle ich ein neues Thema, falls ich da nicht schlauer draus werde, hab nämlich noch ein anderes Problemchen beim seten des Adapters :D

Re: [D3D10] Welche Mathe lib

Verfasst: 03.04.2015, 02:26
von B.G.Michi
meine persönliche Meinung zu SSE und Konsorten: wenn du es lernen willst dann tu es. Ansonsten lass den Compiler seine Arbeit machen und optimiere selbst wenn es nötig wird. Aber ein paar (zehntausend) Matrixmultiplikationen sind da noch keine Hausnummer für heutige CPUs.

Re: [D3D10] Welche Mathe lib

Verfasst: 03.04.2015, 11:49
von Spiele Programmierer
Man sollte allerdings hinzufügen, dass zumindest der MSVC Compiler, sich mit Autovektorisierung äußerst schwer tut. Effektive SIMD Nutzung gibt es extrem selten.

Allerdings ist es sehr schwer, kleine lokale Vektoren auf SIMD zu optimieren, ohne größere Teile des Programmes auf SIMD umzustellen. AVX macht 8 Float Operationen gleichzeitig. Vektoren mit 3 Elementen sind da offensichtlich nicht wirklich im Bereich der optimalen Nutzung. Und dann gibt es noch die Alignment-Probleme. Ich habe es nie geschaft eine 2 oder 3 Komponenten Vektor-Klasse zu schreiben, die durch SIMD von selbst schneller wird.

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 19:49
von Andi
Ich stecke bei den Matrizen fest. Welchen casting operator braucht meine 4x4 Klasse?

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 20:07
von Schrompf
Keinen. Ich würde explicit Konstruktoren anbieten - aus ner 3x3-Matrix, evtl. aus ner 4x3-Matrix, aus Basisvektoren und evtl. aus Einzelfloats.

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 20:16
von Andi
Und wie sieht es aus für die Datenweiterleitung beispielsweise zur Übergabe an einen Shader?

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 20:39
von Schrompf
Ich hab dafür irgendwann mal ein GetFloatPointer() eingeführt. Ist aber Geschmackssache - ich hab z.B. Shader und Konstantenverwaltung eh gekapselt - damit haben meine Shaderklassen Überladungen für meine Matrizen.

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 21:01
von Andi
Ich weiss nicht ob ich dein Konzept richtig Verstanden habe. Deine Konstantenverwaltung übergibt einen GetFloatPointer() der Matrix an den Shader weiter, ist das korrekt? Ich versuche eine Kapselung zu schreiben die ähnlich dem D3DXEffect Interface ist, ob das Sinn macht weiss ich noch nicht.

Was für einen Datentyp gibt GetFloatPointer zurück? Eine float**?

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 21:55
von Schrompf
Korrekt. GetFloatPointer() gibt einen Float-Pointer zurück. Principle Of Least Surprise, nöch?

Code: Alles auswählen

 Matrix4x4 
{
  float a1, a2, a3, a4; float b1, b2, b3, b4; ...
  const float* GetFloatPointer() const { return &a1; }
};
Ich habe allerdings auch meine Shaderklasse darauf angepasst. Da sieht's dann so aus:

Code: Alles auswählen

class ShaderBasis
{
  SetKonstante( KonstantIndex k, const TMatrix4x4& mat);
};

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 22:32
von Spiele Programmierer
Ich würde einfach das interne Datenarray selbst public machen.

Ich habe übrigens sowohl meinen Vektor als auch meine Matrix als Template für Typ und Größe geschrieben.
Das spart viel Schreibarbeit und würde ich unbedingt empfehlen. "template<size_t Dim, typename T> class Vec" und "template<size_t X, size_t Y, typename T> class Matrix"

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 22:39
von Krishty
Spiele Programmierer hat geschrieben:Ich würde einfach das interne Datenarray selbst public machen.
this

und weil man Constant Buffers sowieso selten typlos herumreicht, kann man sich da direkt einen Wrapper schreiben, der zum richtigen Typ mappt:

  struct ShaderConstants {
    Matrix<float, 4, 4> objectToScreen;
    Vector<float, 4>    lightDir;
  };

  auto constantBuffer = createConstantBuffer<ShaderConstants>(gpu);
  auto & constants = map(gpuContext, constantBuffer);
  constants.objectToScreen = eyeToScreen * worldToEye * objectToWorld;
  constants.lightDir = light.position - object.position;
  unmap(gpuContext, constantBuffer);


Da muss man nix konvertieren und keine Getter schreiben und nix. Geht auch mit RAII wenn man drauf steht.

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 22:46
von Andi
Oh sehr Interessant was ihr mir da Zeigt.
Templates wollte ich mir schreiben sobald die Klasse mal soweit die Grundfunktionalitäten besitzt und interagiert. Noch wäre wenig zum anpassen.

Wollte eben noch nachfragen was für float a1, a2,.... b1, b2,.... anstannt einem Array wie float m[4][4] oder vector4 m[4] spricht.

Re: [D3D10] Welche Mathe lib

Verfasst: 09.04.2015, 22:48
von Spiele Programmierer
Mir ist noch eine Sache eingefallen: Ich habe meinen Vektor mit einer "union" um zusätzlich noch die altbekannten Buchstaben X, Y, Z, W, ... zur Verfügung zu haben. Mit einem miesen Trick kann man das auch mit dem Templates für die Größe verwenden.

Bei einer Matrix habe ich zwar analog dazu noch M00, M01, und so weiter als Variablen, ob es das allerdings unbedingt braucht, ist fragwürdig.

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 01:23
von Andi
@Spiele Programmierer
Das hört sich scheusslich an mit dem Template und den altbekannten Buchstaben. Derweil hab ich jedenfalls in meinen Vektoren Klassen floats für x, y(z, w) als Member, in den Matrizen ein zweidimensionales Array. Das mit dem Array ist glaube ich keine gute Lösung.

Es geht jedenfalls voran, mein erster Würfel ist auf dem Schirm, frei von D3DX Mist und ohne zusätzliche Mathe Libs *happy*

Ist das ne gute Idee, "Hilf"-Funktionen wie Rotation, Transponieren, Normalisieren etc. als statische Member zu definieren., evtl auch noch zu inlinen?

Pseudocode:

Code: Alles auswählen

class Matrix
{
  public:
    static Matrix4& LookAtLH(const Vector3& position, const Vector3& target, const Vector3& up);
....
    static Matrix4* RotateX(Matrix4* m, float angle);
....
    static Matrix4* Transpose(Matrix4* m)
....
};
PS: sollte ich den Topic Titel umbennen? Langsam ist es mehr ein "habt ihr Tipps für mich" Topic. Im sorry :P

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 01:56
von Krishty
Worauf geben die statischen Funktionen denn eine Referenz zurück, wenn sie keine Matrix als Parameter bekommen?

Wozu statisch machen? Das bedeutet doch, dass du immer den Klassennamen tippen musst, statt dich einfach auf ADL zu verlassen …

Inlining ist nur nötig, wenn du ohne globale Optimierungen kompilierst (macht heute mit Recht fast niemand mehr).

Ich unterscheide übrigens via Typ zwischen Vektor und Punkt (Punkt - Punkt = Vektor; Punkt + Vektor = Punkt; Vektor + Vektor = Vektor, usw). Spart einem manche Dummheit und erlaubt eindeutige Überladungen.

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 12:57
von Spiele Programmierer
@Andi
Wie kommst du darauf, dass es scheußlich sein soll? Es ist sehr praktisch.

Ich würde es auch unbedingt als Array zur Verfügung stellen. Sowohl Vektor als auch Matrix. Beim Vektor sind eigentlich alle Operationen außer das Kreuzprodukt für alle Dimensionen gleich und eine einfache Iteration über alle Komponenten. Bei Matrizen viele Dinge auch. Statt die 16 Werte einzeln zu addieren, macht man eine Schleife und schreibt nur eine Addition. Wenn man mehrere Dinge der gleichen Art hat, verwendet man in der Programmierung ein Array. Das gilt auch für Vektoren und Matrizen.

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 13:45
von Schrompf
Größe als Template-Parameter: hab ich seit Ewigkeiten mal vor, aber noch nicht gemacht. Bei mir gibt's nur handgeschriebene Klassen für Vek3, Mat3x3 und Mat4x4. Gelegentliche 2D-Rechnungen oder 4D-Vektoren werden mühsam manuell umgebaut... nuja, Template wär mal nötig. Ich mag nur meine "sprechenden" Benamungen dafür nicht aufgeben. Ich hab vor Kurzem sogar die kompletten Swizzling-Operationen für meinen Vek3 gebaut - 125 Einzelfunktionen per Copy&Paste :-)

Matrix-Helferklassen: mach ich auch so, ist aber wirklich nicht unbedingt tippfreundlich. Dafür konsequent: bei mir heißt der namespace mit den Helferfunktionen sogar anders als die Matrixklasse. Die Rückgabe per Referenz ist aber wirklich ne dumme Idee - gibt es per Value und fertig. Der Compiler wird das eh inlinen und alles ist gut.

Das Inlining bzw. die Optimierung im Allgemeinen ist der Teil, der mir an dem union { Array[], sprechendeNamen }; nicht gefällt - ich glaube irgendwo mal aufgeschnappt zu haben, dass speziell Visual Studio heftige Probleme mit solchen Konstrukten und der Aliasing-Analyse hat.

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 14:04
von Spiele Programmierer
Ich habe bisher bei mir keine besonderen Probleme damit beobachtet.

Zu beachten ist übrignes, das man "union { T Array[]; struct { T X; T Y; T Z; } }" braucht.
Die anonyme Struct ist nicht Teil des C++ Standards, werden aber von wirklich jeden Compiler den ich bisher begegnet bin unterstützt. Zudem sind sie Teil des C11 Standards.

Wenn man es in ein Template unabhänig von der Größe machen will, muss man die "sprechenden Namen" in Spezialisierungen packen.
Damit man nicht alle Methoden in alle Spezialisierungen kopieren muss, kann man die Union-Geschichte mit Spezialisierungen in eine versteckte Basis-Klasse packen und in eine Template Klasse vererben, die dann alle Methoden bereit stellt.

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 18:08
von B.G.Michi
Ich empfehle die Basisklasse als Templateparameter zu übergeben. Meine Vektor/Matrixklasse sieht mittlerweile nach dem 3. oder 4. rewrite so aus:

Code: Alles auswählen

template<class T, int... SIZE> TensorStorage;
template<class T, int... SIZE, template<class, int...> class = TensorStorage> Tensor;

typedef Tensor<float, 1, 4> Vector4F;
typedef Tensor<float, 4, 4> Matrix4F;
Das hat den Vorteil, dass man nur TensorStorage mit der entsprechenden union { struct { ... }; }; zu überladen braucht und die ganze Logik in Tensor bleibt gleich. Damit hat man eine Klasse für alle möglichen Variationen eines Tensors. (Vlt sollte ich ihn in GodTensor umbenennen :twisted: ). Wenn man auf die Elemente der Union intern dann mit einem Getter zugreift, kann man eine Klasse TensorStorageDynamic schreiben, die die Basisklasse für einen Tensor beliebiger größe auf dem Heap darstellt. Auch Column-/Row-Major Matrizen lassen sich damit wunderbar unter einen Hut bringen.

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 19:24
von Andi
Ich hab oben meinen Post mit den statics Editiert, hab das noch im Halbschlaf geschrieben, so wie jetzt siehts in etwa aus. Nur die "Camera" Matrizen geben eine Referenz zurück. Per Value anstatt per Referenz lässt sich schnell umschreiben.

Ob ich jetzt Matrix(Funktionname) oder Matrix::(Methodenname) habe, spielt für mich irgendwie nicht so eine wesentliche Rolle. Bei mir liegt alles in den Namensraum Math, also hab ich sowieso Schreibarbeit zwei Zeichen mehr machen "noch" keinen Unterscheid.

Ich habe in meinen Vectoren Klasse jeweils einen catsing operator float* der x, y (z, w) als Array zurück gibt. Die Template für die grössen sollte ich glaub ich bald mal angehen, um nicht zwei mal zu schreiben.

@Krishty und alle
Hast du eigene Strukteren/Klassen für Punkte?

@Spiele Programmierer
Hab da nicht mitgedacht, sieht nicht schrecklich aus, im Gegenteil :D

Auf jeden Fall schon mal bis dahin, danke, danke, danke an alle für die Tipps.
Hoffe morgen wieder etwas Zeit zu finden um weiter zu schreiben ;)

Re: [D3D10] Welche Mathe lib

Verfasst: 10.04.2015, 19:26
von Spiele Programmierer
@B.G.Michi
Wenn man eine Lib für Mathematikzwecke schreibt vielleicht. Andernfalls für typsichen 3D Renderingzwecke unterscheiden sich die Operationen zwischen Matrix und Vektor eigentlich doch schon so stark, dass ich wenig Sinn darin sehe, dass zu vereinheitlichen.

@Andi
;)

Es macht möglicherweise aber einen Unterschied ob du zb. "MeineHelperLib::Math::Matrix<3, 3, float>::DoSomething(MatrixObj)" machen musst oder "MatrixObj.DoSomething()". Darum ging es Kristhy, denke ich.

Den Casting Operator halt ich für eine weniger schöne Idee.
Dann sollten so Dinge gehen wie...

Code: Alles auswählen

float* GarbagePointer = (float*)Vec3(0.0, 0.0, 0.0);
Ich würde lieber den []-Operator überladen und eben ein Array einfügen.

Re: [D3D10] Welche Mathe lib

Verfasst: 13.04.2015, 20:26
von Andi
Spiele Programmierer hat geschrieben:Den Casting Operator halt ich für eine weniger schöne Idee.
Dann sollten so Dinge gehen wie...

Code: Alles auswählen

float* GarbagePointer = (float*)Vec3(0.0, 0.0, 0.0);
Ich würde lieber den []-Operator überladen und eben ein Array einfügen.
Auch wieder wahr. Nur der []-Operator tut es auf jeden Fall.