0

チュートリアルhttp://3dgep.com/introduction-to-directx-11を行いました。

チュートリアルでは、3 つのマトリックス (投影、ビュー、およびワールド マトリックス) が頂点シェーダーに送信され、そこで乗算されます。

3 つの行列を乗算して、頂点シェーダーに送信する必要がある行列を 1 つだけ取得したいと考えています。

それらを XMMatrixMultiply() 関数で乗算しようとすると、アクセス違反エラーが発生します。

XMMatrix wvp=XMMatrixMultiply(g_ProjectionMatrix,XMMatrixMultiply(g_worldmatrix,g_viewmatrix));
4

1 に答える 1

0

変数とメモリのアライメントを適切に考慮していないため、AV にヒットしている可能性があります。DirectXMath (別名 XNAMath) には 2 つの「SIMD」型がXMVECTORあり、XMMATRIX常に 16 バイトでアラインされている必要があります。グローバル変数、静的変数、またはスタック上に割り当てられた場合、それらは適切に配置されます。これらは、x64 ネイティブ アプリケーションでのみ、ヒープに割り当てられたメモリ (newまたは)に適切に配置されます。malloc32 ビット (x86) または ARM では、デフォルトではありません。そのため、DirectXMath は、アラインメントを気にせずにこれを処理するためのさまざまなデータ ストレージ タイプとロード/ストア関数も提供します (つまりXMFLOAT4X4XMLoadFloat4x4/XMStoreFloat4x4関数)。これについては、 MSDNの Programmer's Guide で説明されています。時間をかけて一読することを強くお勧めします。

したがって、データ ストレージ変数として使用する代わりに、次のXMMATRIXようにします。

XMFLOAT4X4 g_ProjectionMatrix;
XMFLOAT4X4 g_worldMatrix;
XMFLOAT4X4 g_viewMatrix;

...

XMMATRIX proj = XMLoadFloat4x4( &g_ProjectionMatrix );
XMMATRIX world = XMLoadFloat4x4( &g_worldMatrix );
XMMATRIX view = XMLoadFloat4x4( &g_viewMatrix );
XMMATRIX wvp = XMMatrixMultiply( proj, XMMatrixMultiply( world, view ) );

これは少し冗長ですが、ハードウェアが実際に行っていることにより直接的に対応しているため、ロード/ストアのオーバーヘッドを回避し、SIMD レジスターに長時間保持される可能性が高いデータを操作し続ける機会を確認できます。

とは言っても、そのチュートリアルに示されているようにg_ProjectionMatrix、 、g_worldmatrix、およびg_viewmatrix変数が真にグローバルであり、AV にヒットしている場合は、コンパイラのバグにもヒットしている可能性があります。どのバージョンの VS を使用していますか? VS 2008 と VS 2010 は組み込み関数に関して少しバグがあります。VS 2010 Service Pack 1 は、VS 2010 RTM よりも少し優れています。VS 2012 と VS 2013 ははるかに優れています。VS 2012 または VS 2013 の最新の更新プログラムを使用していることを確認してください。VS 2013 Pro+ の予算がない場合は、VS 2013 コミュニティ (VS Update 4 でもあります) に移行することをお勧めします。

ここでの別のオプションは、 DirectX ツール キットのSimpleMathラッパーを使用することです。これは、C++ の「魔法」を使用して、、、、 などの型で「素朴な」数学コードをより柔軟に記述できるようにするものです。MatrixVector2Vector3Vector4

#include "SimpleMath.h"
using namespace DirectX::SimpleMath;

Matrix g_ProjectionMatrix;
Matrix g_worldMatrix;
Matrix g_viewMatrix;

...

Matrix wvp = proj * world * view;
于 2015-01-07T19:17:35.873 に答える