m = XMMatrixIdentity()后崩溃 - 类中的对齐内存?

Pol*_*hic 9 c++ directx sse matrix xna-math-library

我正在查看DirectX SDK中的教程.教程5工作正常,但在我将代码复制并分离到我自己的类后,我在启动应用程序时遇到了奇怪的错误.

这条线是:

g_World1 = XMMatrixIdentity();
Run Code Online (Sandbox Code Playgroud)

因为它,我在xnamathmatrix.int operator =中出现错误,看起来像这样:

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;
}
Run Code Online (Sandbox Code Playgroud)

并且错误消息是:

Access violation reading location 0xffffffff
Run Code Online (Sandbox Code Playgroud)

我在某处读过它可能是由连接到XMFLOAT4X4/XMMATRIX的东西引起的:

您是否考虑过使用XMFLOAT4X4来存储矩阵,并且只使用XMMATRIX?

但我想我已经使用过XMMATRIX了.

MyClass.h:

private:
    XMMATRIX g_World1;
Run Code Online (Sandbox Code Playgroud)

MyClass.cpp:

void init(){
   g_World1 = XMMatrixIdentity();
}
Run Code Online (Sandbox Code Playgroud)

我认为我不应该改变XMMATRIX g_World1; 到XMFLOAT4X4 g_World1,因为它会产生如下错误:

错误C2679:二进制'=':找不到哪个运算符采用'XMMATRIX'类型的右手操作数(或者没有可接受的转换)

Vik*_*pov 6

由于XMMATRIX表示一个16字节对齐的4x4矩阵,因此g_World1的未对齐分配会导致访问冲突(简单地说,g_World1的地址不能被16整除).

解决方案类型:使结构成员对齐16个字节(对于MyClass,使g_World1"就位").但是你仍然必须确保MyClass实例驻留在可被16整除的地址.

您可以使用放置'new'运算符来分配MyClass对象.

关于对齐请参见此处:如何对齐指针


小智 5

XMVECTOR和XMMATRIX是'寄存器代理'类型.您可以安全地将它们用作Xbox 360,Xbox One和Windows x64平台的类型,因为它们本身具有16字节对齐,用于堆栈上的数据并在堆上分配.

将它们用于Windows 32位或Windows RT/ARM需要花费更多精力,因为本机对齐小于16个字节.一种方法是DirectX Tool Kit使用的技术...它使用pImpl惯用法,pImpl内部类显式分配16字节对齐,这是直接使用XMVECTOR和XMMATRIX类型的地方.另一种方法是使用所有各种"存储"类型,如XMFLOAT4和XMFLOAT4X4.

注意:DirectXMath程序员指南涵盖了这一点.这不是一篇很长的文档,它包含了大量的提示和建议.

PS:MSDN代码库上的Win32桌面的标准Direct3D教程版本不需要DirectX SDK ......它只使用VS 2012或VS 2013附带的Windows 8.x SDK.在此处输入链接描述