9

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

该行是:

g_World1 = XMMatrixIdentity();

因此,我在 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;
}

错误信息是:

Access violation reading location 0xffffffff

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

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

但我想我已经在使用 XMMATRIX。

MyClass.h:

private:
    XMMATRIX g_World1;

我的类.cpp:

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

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

错误 C2679:二进制“=”:未找到采用“XMMATRIX”类型右侧操作数的运算符(或没有可接受的转换)

4

4 回答 4

6

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

解决方案排序:使结构成员对齐 16 个字节(以便 MyClass 将 g_World1 “就位”)。但是您仍然必须确保 MyClass 实例位于可被 16 整除的地址。

您可以使用放置“新”运算符来分配 MyClass 对象。

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

于 2012-07-01T21:27:37.250 回答
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。在此处输入链接描述

于 2014-06-26T07:28:04.730 回答
1

谢谢你。

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

于 2012-07-01T23:02:24.000 回答
1

在“Frank D. Luna”的“Directx 11 3D 游戏编程简介”一书中,它说:

不要将 XMMATRIX 用作类或结构的成员。如果需要,请始终使用 XMFloat4x4 并加载并存储回来。

于 2014-06-24T22:18:28.497 回答