Matrixmultiplication with DirectXMath

2.6k Views Asked by At

I did the tutorial http://3dgep.com/introduction-to-directx-11.

In the tutorial 3 matrices (the projection, view, and world matrix) are send to the vertexshader and are multiplied there.

I want to multiply the 3 matrices to get only one which I have to send to the vertexshader.

When I tried to multiply them with the XMMatrixMultiply() function I get an accessviolation error.

XMMatrix wvp=XMMatrixMultiply(g_ProjectionMatrix,XMMatrixMultiply(g_worldmatrix,g_viewmatrix));
1

There are 1 best solutions below

1
On BEST ANSWER

You are likely hitting an AV because you have not properly accounted for memory alignment with your variables. DirectXMath (aka XNAMath) has two 'SIMD' types XMVECTOR and XMMATRIX which must always be 16-byte aligned. They are properly aligned if allocated as global variables, static variables, or on the stack. They are properly aligned in heap allocated memory (new or malloc) only with x64 native applications. With 32-bit (x86) or ARM, they are not by default. As such, DirectXMath also provides an assortment of data storage types and load/store functions for handling this without worrying about alignment (i.e. XMFLOAT4X4 and the XMLoadFloat4x4 / XMStoreFloat4x4 functions). This is covered in the Programmer's Guide on MSDN which I highly recommend you take the time to read through.

So instead of using XMMATRIX as a data storage variable, you'd do something like:

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 ) );

While this is a bit verbose, it more directly maps to what the hardware is actually doing, allowing you to see opportunities to avoid load/store overhead and keep working with data likely to be held in SIMD registers for longer.

All that said, if your g_ProjectionMatrix, g_worldmatrix, and g_viewmatrix variables are truely global as shown in that tutorial and you are hitting the AV, you might also be hitting a compiler bug. What version of VS are you using? VS 2008 and VS 2010 are a bit buggy w.r.t. to intrinsics. VS 2010 Service Pack 1 is a bit better than VS 2010 RTM. VS 2012 and VS 2013 are a lot better. Make sure you are using the latest Update for VS 2012 or VS 2013. I'd recommend moving to VS 2013 Community (which is also VS Update 4) if you don't have the budget for VS 2013 Pro+.

Note that another option here is to make use of the SimpleMath wrapper in the DirectX Tool Kit which uses some C++ 'magic' to make writing 'naive' math code a lot more forgiving with types like Matrix, Vector2, Vector3, Vector4, etc.

#include "SimpleMath.h"
using namespace DirectX::SimpleMath;

Matrix g_ProjectionMatrix;
Matrix g_worldMatrix;
Matrix g_viewMatrix;

...

Matrix wvp = proj * world * view;