我做了教程http://3dgep.com/introduction-to-directx-11。
在教程3中,矩阵(投影,视图和世界矩阵)被发送到顶点着色器并在那里相乘。
我想将3个矩阵相乘,只得到一个我必须发送到顶点着色器的矩阵。
当我尝试将它们与XMMatrixMultiply()函数相乘时,我得到了一个访问错误。
XMMatrix wvp=XMMatrixMultiply(g_ProjectionMatrix,XMMatrixMultiply(g_worldmatrix,g_viewmatrix));
答案 0 :(得分:0)
您可能正在使用AV,因为您没有正确考虑与变量的内存对齐。 DirectXMath(又名XNAMath)有两个'SIMD'类型XMVECTOR
和XMMATRIX
,它们必须始终是16字节对齐的。如果分配为全局变量,静态变量或堆栈,它们将正确对齐。它们仅在堆分配的内存(new
或malloc
)中与x64本机应用程序正确对齐。对于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有点儿马车了w.r.t。内在的。 VS 2010 Service Pack 1比VS 2010 RTM好一点。 VS 2012和VS 2013要好得多。确保您使用的是VS 2012或VS 2013的最新更新。如果您没有VS 2013 Pro +的预算,我建议您迁移到VS 2013社区(也是VS Update 4)。
请注意,此处的另一个选项是利用SimpleMath中的DirectX Tool Kit包装器,该包装器使用一些C ++'magic'来使'naive'数学代码更加宽容,类似于{ {1}},Matrix
,Vector2
,Vector3
等
Vector4
...
#include "SimpleMath.h"
using namespace DirectX::SimpleMath;
Matrix g_ProjectionMatrix;
Matrix g_worldMatrix;
Matrix g_viewMatrix;