崩溃后M = XMMatrixIdentity() - 在类对准存储器?(Crash after m

2019-06-25 23:32发布

我一直在寻找在DirectX SDK中的教程。 教程5工作正常,但我已经复制并分离出码我自己的班后,我启动我的应用程序中有奇怪的错误。

该生产线是:

g_World1 = XMMatrixIdentity();

因为它,我在xnamathmatrix.int运营商=看起来像遇到错误:

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;
}

和错误消息是:

Access violation reading location 0xffffffff

我已经在其他地方见过,它可以通过连接到XMFLOAT4X4 / XMMATRIX什么原因造成的:

你有没有考虑使用XMFLOAT4X4存储矩阵,并且只使用XMMATRIX?

但我想我已经使用XMMATRIX。

MyClass.h:

private:
    XMMATRIX g_World1;

MyClass.cpp:

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

我不认为我应该改变XMMATRIX g_World1; 到XMFLOAT4X4 g_World1,因为它产生这样的错误:

错误C2679:二进制“=”:没有操作员发现它采用类型“XMMATRIX”的右边的操作数(或没有可接受的转化率)

Answer 1:

XMVECTOR和XMMATRIX是“注册代理”的类型。 您可以放心地使用它们作为类型为Xbox 360,Xbox One上,和Windows x64平台上,因为它们都拥有本身的堆栈中的数据16字节对齐,并在堆上分配。

将它们用于Windows 32位或Windows RT / ARM需要更多的努力,因为本机对准莱比16字节。 一种方法是通过DirectX的工具包使用的技术......它使用的平普尔成语和平普尔内部类明确地16字节对齐这也正是XMVECTOR和XMMATRIX类型直接使用分配。 另一种方法是使用所有不同的“存储装置”类型,如XMFLOAT4和XMFLOAT4X4。

注: DirectXMath程序员指南涵盖了这一点。 这不是一个很长的文件阅读,它的包装了很多的提示和建议。

PS:有在MSDN代码库的Win32桌面上不需要的DirectX SDK标准的Direct3D教程的一个版本...它只是使用包含在VS 2012年或2013年VS在Windows 8.x的SDK 在这里输入链接的描述



Answer 2:

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

排序的溶液:使由16个字节结构构件对准(对于MyClass的具有g_World1“就地”)。 但你仍然必须确保,这是MyClass实例驻留在被16整除的地址。

您可以使用放置new操作符来分配MyClass的对象。

关于对准请看这里: 如何对齐指针



Answer 3:

谢谢。

最后,我决定用XMLoadFloat4x4()和XMStoreFloat4x4()函数。 我存储类的成员Float4x4,并将其转换为临时使用,以XMMATRIX每一个渲染()循环。 但是......它是一个快速或哑解决方案?



Answer 4:

在从“弗兰克D.露娜”书“介绍3D游戏编程与DirectX 11”这样说的:

不要使用XMMATRIX为一类或结构的成员。 始终使用XMFloat4x4和装载和存储回来,如果你需要它。



文章来源: Crash after m = XMMatrixIdentity() - alignment memory in classes?