XMMatrixTranspose 访问冲突读取位置 0xFFFFFFFF

XMMatrixTranspose Access violation reading location 0xFFFFFFFF

我有一个 DirectX 11 项目,我正在使用 Beginning DirectX 11 Game Programming 书中的所有章节。我已经安装好我的相机并且它一直没有崩溃但是最近在调试我的 Obj Loader 时我发现它一直在 XMMatrixTranspose 行崩溃,我已经交换了我的视图矩阵和投影矩阵四舍五入,看看它是否特定于我的视图矩阵,但它不是。

这是导致错误的代码块

vMatrix = camera.GetViewMatrix();
vMatrix = XMMatrixTranspose(vMatrix);

pMatrix = XMMatrixPerspectiveFovLH(XM_PIDIV4, (float)(screenWidth / screenHeight), 0.01f, 100.0f);
pMatrix = XMMatrixTranspose(pMatrix);

这是在我的 DX11::Render 函数中找到的。这在我的 main.cpp 游戏循环中调用,如下所示。

MSG msg = { 0 };

while (msg.message != WM_QUIT)
{
    if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        directX->Update(0.0f);
        directX->Render();
    }
}

directX->Shutdown();

我所有的变量都有内存,这段代码以前一直在工作,当它开始这样做时,它会断断续续地做,但现在它似乎一直在做。

任何帮助和指导都会很棒!我已经研究了几个小时,但找不到任何有用的东西,我已经遇到这个问题大约 7 个小时了!该走了!!

提前致谢。

更新 它现在已经回到间歇性崩溃状态

更新 2 我也在使用 xnamath 而不是 DXMath

您应该首先阅读 MSDN 程序员指南,特别是 type usage guidelines

DirectXMath and XNAMath are basically the same library. XNAMath is just the old version of it which was last updated in 2011. You should move to using DirectXMath. See this blog post.

最有可能的问题是您正在尝试使用在堆上声明的 XMMATRIX and/or XMMVECTOR 类型(即在 class 中您使用 new on) 这将 not 正确对齐 x86(32 位)和 ARM 构建。它恰好与 x64 本机代码一致,但这主要是一个幸运的意外。

换句话说,根据内存的具体布局,以下代码将在 x86(32 位)和 ARM 中生成 AV,但适用于 x64 本机:

struct A
{
    XMMATRIX m;
};

A a = new A;
a->m = XMMatrixIdentity();

为了使其在所有架构上都能稳定运行,您需要使用:

struct A
{
    XMFLOAT4X4 m;
};

A a = new A;
XMStoreFloat4x4(&A->m, XMMatrixIdentity());

您将在 class 中使用 XMFLOAT4X4 或不需要对齐的类似类型,然后使用显式 Load/Save 函数。请注意,您还可以根据矩阵内容使用更紧凑的形式,例如 XMFLOAT4X3

或者,您可以使用 SimpleMath wrapper in the DirectX Tool Kit,通过 C++ 转换运算符和构造函数的强大功能,它只能 "automagically" 做到这一点。

struct A
{
    Matrix m;
};

A a = new A;
A->m = XMMatrixIdentity();
// Note this is redundant
// as the Matrix default constructor sets it to identity already.

This functionality is not part of the base library because it has some performance implications. By making it part of the SimpleMath wrapper instead, it allows users to opt in to an easier model of use while preventing accidental use of slower conversion paths for everyone else.