現在 DirectX/Direct3D11 をレンダリング バックエンドとして使用する C++11/VC11 で別のゲーム エンジンを作成しています。DirectX 型をパブリック インターフェイス (および OpenGL バックエンドの将来の実装の可能性) から隠すために、線形代数ライブラリを独自に展開していますが、これはまだ内部で DirectX Math を使用しています。DirectX Math は多かれ少なかれ、C++ SIMD 組み込み関数 (__m128 など) に関する typedef の集まりです。インダイレクションのレベルを低く保ち、可能な限り「アトミック」でインライン化するために、DirectX Math 型 (この場合は XMVECTORF32) から直接継承することを好みます。メンバー変数:
struct vector4 : private DirectX::XMVECTORF32
MSDN は、XMVECTORF32 構造体の正しい初期化の例を次のように示しています。
XMVECTOR data;
XMVECTORF32 floatingVector = { 0.f, 0.f, 0.1f, 1.f };
data = floatingVector;
ただし、XMVECTORF32 を基本構造として初期化しようとしても、コンパイラは認識しません。
struct vector4 : private DirectX::XMVECTORF32 // not XMFLOAT4 due to possible conversation overhead
{
friend class matrix44;
inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
: DirectX::XMVECTORF32{v0, v1, v2, v3} // ERROR: ';' expected
{
}
};
何か不足していますか?私がしようとしているベースの初期化を正しく実行する方法は? 私を助けるための新しいC++ 11初期化シュガーはありますか?
------------編集-----------
何らかの理由で、私は明らかなことを見ていませんでした。XMVECTORF32 の定義を調べたところ、基になるユニオン フロート配列 "f" にアクセスできることが明らかになったので、初期化は次のようになります。
struct vector4 : private DirectX::XMVECTORF32
{
friend struct matrix44;
inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
{
f[0] = v0;
f[1] = v1;
f[2] = v2;
f[3] = v3;
}
};
キャストも共用体も C 配列もありません。インライン化を使用すると、パフォーマンスがほぼ最適になります。
------------編集 2 -----------
XMVECTORF32 は、データを格納するためのものではありません。したがって、ベクトルは XMFLOAT4 から継承する必要があります。そうしないと、特に最適化がオンになっている場合に、再現性のないアクセス違反の例外が発生します。背景は次のとおりです。 http://www.asawicki.info/news_1429_xna_math_and_access_violation.html
私の最終的なコードは次のようになります。
struct vector4 : private DirectX::XMFLOAT4
{
friend struct matrix44;
inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
: DirectX::XMFLOAT4(v0, v1, v2, v3)
{
}
inline scalar& v0() { return x; }
inline scalar& v1() { return y; }
inline scalar& v2() { return z; }
inline scalar& v3() { return w; }
};
ベクトル データは、SIMD 計算の前に XMLloadFloat4 を使用して XMVECTOR にロードする必要があります。XMVECTOR は、メモリの場所ではなく、レジスタのようなものと考えてください。