2

現在 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 は、メモリの場所ではなく、レジスタのようなものと考えてください。

4

1 に答える 1

1

それDirectX::XMVECTORF32が集約クラスである場合、コードはC ++ 11で問題ありません(その使用法を示す実際のを参照してください)。

ただし、使用しているコンパイラは( StackOverflowに関するこのQ&Aで明らかにされているように)均一な初期化をサポートしておら、C ++ 03では、変数をコピー初期化する場合のように基本集計クラスを初期化できません。

したがって、初期化リストで基本クラスのメンバーを明示的に初期化するか、コンストラクターSetVector()の本体のようなものを呼び出す必要があります。vector4

于 2013-03-09T14:23:35.307 に答える