2012-07-01 9 views
9

私はDirectX SDKのチュートリアルを見ていました。チュートリアル5は問題なく動作しますが、コードを自分のクラスにコピーして分割した後、アプリケーションの起動中に奇妙なエラーが発生しました。m = XMMatrixIdentity()後のクラッシュ - クラス内のメモリの魅力?

行は次のとおりです。

XMFINLINE _XMMATRIX& _XMMATRIX::operator= 
(
    CONST _XMMATRIX& M 
) 
{ 
    r[0] = M.r[0]; 
    r[1] = M.r[1]; 
    r[2] = M.r[2]; 
    r[3] = M.r[3]; 
    return *this; 
} 

、エラーメッセージは次のとおりです:

g_World1 = XMMatrixIdentity(); 

それのために、私はそのように見えた= xnamathmatrix.intオペレーターにエラーが発生しました

Access violation reading location 0xffffffff 

私はXMFLOAT4X4/XMMATRIXに接続された何らかの原因で発生する可能性があると読んでいます:

XMFLAT4X4を使用して行列を保存することを検討しましたが、XMMATRIXのみを使用しましたか?

私は既にXMMATRIXを使用していると思います。

MyClass.h:

private: 
    XMMATRIX g_World1; 

MyClass.cpp:

void init(){ 
    g_World1 = XMMatrixIdentity(); 
} 

私はXMMATRIX g_World1を変更する必要がありますとは思いません。

エラーC2679:バイナリ「=」:それはのようなエラーを生成するためXMFLOAT4X4 g_World1に、全くオペレータは

タイプ「XMMATRIX」の右側のオペランドをとる(または全く許容される変換は存在しない)が見つかりません

問題は何ですか?

答えて

5

XMVECTORとXMMATRIXは「レジスタプロキシ」タイプです。 Xbox 360、Xbox One、およびWindows x64プラットフォームのタイプとして安全に使用できます。これらは、スタック上のデータに対してネイティブに16バイトのアラインメントを持ち、ヒープに割り当てられます。

Windows 32ビットまたはWindows RT/ARM用にそれらを使用すると、ネイティブの配置が16バイトよりも短いため、より多くの労力がかかります。 1つのアプローチは、DirectX Tool Kitで使用される手法です.pImplイディオムを使用し、pImpl内部クラスはXMVECTOR型とXMMATRIX型が直接使用される16バイト境界で明示的に割り当てられます。別のアプローチは、XMFLOAT4やXMFLOAT4X4のようなさまざまな「記憶域」タイプをすべて使用することです。

注:DirectXMath programmer's guideはこれをカバーしています。それは長い文書ではなく、多くのヒントや推奨事項が満載です。

PS:DirectX SDKを必要としない、Win32デスクトップ用の標準Direct3Dチュートリアルのバージョンがあります。これは、VS 2012またはVS 2013に付属のWindows 8.x SDKを使用しています。enter link description here

6

XMMATRIXは16バイトのアライメントされた4x4行列を表すため、g_World1のアラインメントのない割り当てによってアクセス違反が発生します(g_World1のアドレスは16で割り切れません)。

解決策の並べ替え:16バイト(MyClassがg_World1を「適切な位置に」持つために)で構造体の配置を可能にする。しかし、MyClassインスタンスが16で割り切れるアドレスにあることを保証する必要があります。

MyClassオブジェクトを割り当てるには、プレースメントの「new」演算子を使用できます。アライメントについて

はこちらをご覧ください:How to align pointer

+0

それは愚かな質問かもしれませんが、どうやってそれを達成するのですか?私は4つの行列(ビュー、世界など)を含む構造体Matrixを作成しましたが、構造体の位置合わせを16バイトで有効にする方法はありますか? – PolGraphic

+0

VStudioの場合:プロジェクトプロパティ - >構成プロパティ - > C/C++ - >コード生成 - > Struct Memeber Alignment - >ここで16を選択してください –

+0

GCCの場合、構造体には "__attribute__((aligned(16)))"があります –

1

ありがとうございました。

最後に、XMLoadFloat4x4()とXMStoreFloat4x4()関数を使用することにしました。私は、クラスのメンバーをFloat4x4として保存し、それらを一時的な使用のためにXMMATRIXの各render()ループに変換します。 しかし...それは速い、またはばかな解決策ですか? 「フランクD.ルナ」からブック「DirectX 11の使用したプログラミング、3Dゲームの概要」では

+1

別の質問を開始することを検討してください。これはディスカッションフォーラムではありません。行列の数が少ない場合、これは問題にはなりません。 –

+0

彼らは等しく見えます。もちろん、計算のためにXMMatrixに変換しない場合(笑)、もちろんです。 – Loryan55

+0

これはまさにあなたがアラインメントを処理すると予想される方法です... –

1

それは言う:

クラスや構造体のメンバとしてXMMATRIXを使用しないでください。いつでもXMFloat4x4を使用し、必要に応じてロードして保存し直してください。

関連する問題