So habe ich meine eigene Physik-Engine aus und wieder für eine Weile geschrieben und ich habe vor kurzem begonnen, DirectX-Rendering anstelle von Hardcoding in meinem Rendering mit OpenGL. Jetzt, am Ende, bin ich auf ein sehr seltsames Verhalten gestoßen, das ich nicht verstehen kann.Casting benutzerdefinierte Matrix zu float *
Um Matrices zu einem Shader passieren Dinge zu zeichnen, rufen Sie eine Funktion, die ein const float*
und die typische Art und Weise geschieht dies zu tun, ist in einem D3DXMATRIX
cast float*
passieren. D3DXMATRIX
und die gegossenen Operatoren sind als deklariert:
typedef struct _D3DMATRIX {
union {
struct {
float __11, _12, _13, _14;
float __21, _22, _23, _24;
float __31, _32, _33, _34;
float __41, _42, _43, _44;
};
float m[4][4];
};
} D3DMATRIX;
Die beiden Umwandlungsoperatoren definiert werden in einer anderen Datei (D3DX10math.inl) als:
D3DX10INLINE
D3DXMATRIX::operator FLOAT*()
{
return (FLOAT *) &_11;
}
D3DX10INLINE
D3DXMATRIX::operator CONST FLOAT*() const
{
return (CONST FLOAT *) &_11;
}
typedef struct D3DXMATRIX : public D3DMATRIX
{
...
operator FLOAT*();
operator CONST FLOAT*() const;
....
} D3DXMATRIX, *LPD3DMATRIX;
und D3DMATRIX
als erklärt
Die Schlüsselwörter CONST
und FLOAT
sind in minwindef.h
unddefiniert 210 ist in D3DX10.h wie folgt definiert:
#ifndef CONST
#define CONST const
#endif
....
typedef float FLOAT;
....
#define D3DX10INLINE __forceline
Der Aufruf die Funktion I beschrieben ist einfach:
D3DXMATRIX m;
foo->SetMatrix((float*)&m);
Während mein gesamte Motor Ich habe meine eigene Matrix
Klasse benutzen, und wenn ich versuche, übergeben Sie es in die obige Funktion anstelle einer D3DXMATRIX
, sendet es falsche Daten. Meine Matrix
Klasse ist (scheinbar) in der gleichen Weise wie D3DXMATRIX
definiert, weigert sich jedoch, auf die gleiche Weise zu funktionieren. Hier meine Matrix-Klasse (oder die relevanten Teile):
class Matrix {
public:
....
operator float*();
operator const float*() const;
....
private:
union {
struct {
float _00, _01, _02, _03;
float _10, _11, _12, _13;
float _20, _21, _22, _23;
float _30, _31, _32, _33;
};
float m[4][4];
}
};
und die Funktionen definieren als:
__forceinline
Matrix::operator float*()
{
return (float *) &_00;
}
__forceinline
Matrix::operator const float*() const
{
return (const float *) &_00;
}
Ich habe versucht, die Definition der Operatoren in der CPP-Datei, in der Header-Datei, in der Klassendefinition, alle mit und ohne inline
und __forceinline
, aber nichts wird jemals funktionieren. Ich nehme an, ich könnte alle Daten in jeder meiner Matrizen zu einer D3DXMATRIX
kopieren, aber das verschwendet eine Menge Zeit/Operationen und sollte irrelevant sein. Das größte Problem ist, dass ich für das Leben meiner Figur nicht herausfinden kann, warum sich alles so verhält. Ich kann unmöglich sehen warum.
sicher der Daten Um in die Funktion DirectX geleitet wird, habe ich so eine Testfunktion bis ich es debuggen können und sehen, was die genauen Werte in weitergegeben werden:
void Test(const float *a, const float *b)
{
bool result[16] = {false};
float aa[16], bb[16];
for(unsigned int i = 0; i < 16; ++i)
{
result[i] = a[i] == b[i];
aa[i] = a[i];
bb[i] = b[i];
}
}
Zum Beispiel, wenn ich Pass in einem D3DXMATRIX
mit den Werten 1-16
für jeden der 16 Schwimmer als ersten Parameter eine meiner Matrizen mit den gleichen Werten wie b
dann aa
1-16
ganz gut mit den Werten gefüllt werden, aber bb
wird = {0.0, 1.875, 0.0, 2.0, 0.0, 2.125, 0.0, 2.5, 0.0, 2.315, 0.0, 2.375, 0.0, 2.4375, 0.0, 2.5}
Also ... hat jemand irgendwelche Ideen, warum sich dieser Code so verhält?
Haben Sie andere Membervariablen in 'Matrix'? –
@AntonSavin Nein, das ist es. – ArcRaizen