您可能遇到了 AV,因为您没有正确考虑与变量的内存对齐。 DirectXMath(又名 XNAMath)有两种“SIMD”类型XMVECTOR 和XMMATRIX,它们必须始终是 16 字节对齐的。如果分配为全局变量、静态变量或在堆栈上,它们会正确对齐。它们仅在 x64 本机应用程序中在堆分配内存(new 或 malloc)中正确对齐。对于 32 位 (x86) 或 ARM,默认情况下它们不是。因此,DirectXMath 还提供了各种数据存储类型和加载/存储函数来处理此问题,而无需担心对齐问题(即 XMFLOAT4X4 和 XMLoadFloat4x4 / XMStoreFloat4x4 函数)。这在MSDN 上的程序员指南中有介绍,我强烈建议您花时间通读。
因此,不要使用 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 更新 4)。
请注意,这里的另一个选项是使用 DirectX Tool Kit 中的 SimpleMath 包装器,它使用一些 C++ '魔法' 使编写'天真的'数学代码更容易使用 Matrix、@ 等类型987654338@、Vector3、Vector4等
#include "SimpleMath.h"
using namespace DirectX::SimpleMath;
Matrix g_ProjectionMatrix;
Matrix g_worldMatrix;
Matrix g_viewMatrix;
...
Matrix wvp = proj * world * view;