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