Introduction to XNA Math

Warning! Some information on this page is older than 3 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

May 2010

Introduction to XNA Math

I've recently shared my XNA Math Cheat Sheet Today I'd like to post some more information about XNA Math. It is a new C++ math library for gamedev distributed with DirectX SDK, intended to replace math support from D3DX. Its online documentation can be found here: XNA Math Library Reference and the offline one is in DXSDK\Documentation\DirectX9\directx_sdk.chm file. It's worth noticing that the documentation in recent DX SDK versions is split across two separate CHM files. windows_graphics.chm describes only graphics programming (Direct3D 9, 10 and 11, D3DX, DXGI, HLSL language, effects format, DDS format, X format etc.), while directx_sdk.chm is about all other stuff (DirectSetup, DXUT, XNA Math, XAudio2, XInput etc.).

XNA Math is different from old D3DX and I'm afraid also harder to use. But I believe it's better. It's your decision whether you start to use it or not, because it's completely separate library that can be used with DirectX 11, 10, 9 or without anyone of them. On the other hand, you can still link with old D3DX while coding in new DirectX 11, so it's all your choice.

By the way, I don't know why is this library called "XNA Math". It looks like it has nothing to do with the XNA technology. XNA is a .NET library with its own vector and matrix classes while XNA Math is pure native C++ library distributed with DirectX SDK. It looks like a misnomer.

Beginning with XNA Math is simple. You just #include <xnamath.h> and that's all. There is even no need to link with any LIB file - all code is inline in this header or INL files included by it (which sum up to 26530 lines :) It provides support for vectors (up to 4D), matrices (up to 4x4), colors, planes and quaternions - all made of 32-bit floats, just as we all use in gamedev.

But design ideas of this API are totally different from D3DX. There is now one main data type called XMVECTOR - a vector of 4 floats. When the library uses SSE (which is the default on PC), this type is simply a typedef to __m128 (if you know what I mean). So it must be always aligned to 16-byte boundary. As a consequence, it's safe to cast this type to any other one interpreted as a vector of floats (like float[4] or D3DVECTOR), but not the other way around (because the pointer you cast might not be property aligned). This single type is used in all computations and interpreted as a 2D, 3D or 4D vector, plane, quaternion, part of 4x4 matrix or even a vector of unsigned integers, depending on the context. It may also feel strange at the beginning that this not-so-small object is usually passed and returned by value, not by reference.

Old DirectX versions used a D3DVECTOR and D3DMATRIX structures, which were extended by inheritance in D3DX library as D3DXVECTOR and D3DXMATRIX - structures with lots of overloaded operators and methods to operate on. The idea behind new DirectX 11 is that the graphics API is not dependent on any particular math library - it only uses float* or even void* and it's you job to use some library that would help you with math computations (like D3DX or XNA Math).

If you ever coded in SSE or other vector instruction set, you might know the concept of loading and storing. Here is an example that sets and gets vector as well as its components in many different ways.

XMVECTOR v = XMVectorZero();
// v is now (0, 0, 0, 0)
v = XMVectorSplatOne();
// v is now (1, 1, 1, 1)
v = XMVectorReplicate(5.f);
// v is now (5, 5, 5, 5)
v = XMVectorSet(1.f, 2.f, 3.f, 4.f);
// v is now (1, 2, 3, 4)
v = XMVectorSetX(v, 10.f);
// v is now (10, 2, 3, 4)
std::cout << XMVectorGetW(v);
// Prints 4

There are lots of structures defined in XNA Math that represent different ways vectors can be stored and packet in the memory. Many of them are very weird, but there is good reason for their existence - they are CPU equivalents for some of DXGI_FORMAT-s available in DirectX 10/11. For example, the XMUDECN4 type, representing DXGI_FORMAT_R10G10B10A2_UNORM, is defined as follows:

union {
  struct { UINT x : 10; UINT y : 10; UINT z : 10; UINT w : 2; };
  UINT v;

It is a 32-bit value that stores 4D vector in 10+10+10+2 bit format, where float values 0.0 .. 1.0 are mapped to integers 0..1023 for x, y, z components and 0..3 for w component (just a bit smaller precision, nothing more ;) XNA Math provides us with functions to load and store XMVECTOR from/to all these strange types, so you can just do something like this:

XMVECTOR v = XMVectorSet(0.f, 1.f, 0.5f, 0.5f);
XMUDECN4 packedV;
XMStoreUDecN4(&packedV, v);
// packedV is 0x5ffffc00
XMVECTOR v2 = XMLoadUDecN4(&packedV);
// v2 is (0, 1, 0.499511, 0.333333)

XNA Math contains lots of functions that we all know from old good D3DX. (The only missing thing are SH* functions for spherical harmonics, but well - I have never used them anyway :) For example, a function for normalizing 3D vector now has a signature:


XNA Math also supports matrices. XMMATRIX type is a 4x4 matrix. It contains 4 XMVECTOR-s inside. Functions for manipulating matrices include XMMatrixTranslation, XMMatrixRotationRollPitchYaw, XMMatrixPerspectiveFovLH and so on. You can also do computations on 3D planes if only you agree to treat (x, y, z, w) vectors as (A, B, C, D) factors of plane equation. Same applies to colors - functions like XMColorAdjustSaturation also operate on XMVECTOR, but treat its components as (R, G, B, A) values.

XNA Math wouldn't be complete without some basic functions, constants and macros for scalars, such as XM_PI, XMMax, XMScalarSin. Functions with -Est suffix (from "estimated") are faster but less precise versions, e.g. XMScalarSinEst.

If you want to make full use of the performance of vector arithmetic, you should also use swizzling, permutation and comparison functionality. Swizzling is about permutation of components of a vector. It's elegant and intuitive in languages designed with gamedev in mind (like HLSL), where you just write:

float4 v2 = v1.xyxy;

In C++ with XNA Math, same operation can be written as:

XMVECTOR v2 = XMVectorSwizzle(v1, 0, 1, 0, 1);

When it comes to comparisons, functions with -R suffix return additional UINT value, which is a bitfield designed to be tested with special functions. For example:

XMVECTOR v1 = XMVectorSet(0.0f, 1.0f, 0.5f, 0.5f);
XMVECTOR v2 = XMVectorSet(0.0f, 0.0f, 1.0f, 1.0f);
res.v = XMVectorGreaterR(&cr, v1, v2);
// res contains (0, 0xffffffff, 0, 0)
std::cout << XMComparisonAnyTrue(cr);
// Prints 1.

Comments (4) | Tags: math directx | Author: Adam Sawicki | Share


Leroy "Billybob" Jenkins
2014-12-09 03:55:03
2015-08-12 18:00:03
Nice work.
Helps a lot.
2016-03-29 09:54:40
2016-03-29 10:00:40
beautiful things to read more, look for a long time, I felt closer to reality very far away, life is short, if put too much time is spent on practical things, really is a waste of life, but some things, but if the raw flavor, leisure goods for gossip, so I love romantic dreamer, but I love real life.Day in a hurry, took all the joy and sadness, a lot of things, not enough time to recall, Chaoyang July, early June already covered confused. Season removed, landscape transformation, the so-called forever always far-fetched, time, not to be squandered, the true meaning of life is to enjoy the good in the flat, I Dimei fireworks, also read the leisure, with a touch of ink, painting a thin clear Huan, look lush green, covered with mottled wall. This July, I kept the book's swoosh; this July, I dream in Lijiang; this July, and has been well, not made sad.If you can do if a light breeze right woman, placed in the text soul, written imprint of life, write thin cool and clear Huan, occasionally write love, but never give love, keep a clear gel Bay, look for a parts of the peace, the joy and sorrow of all his writings, and text only affair has nothing to do with the other.Morning time, with a tranquil and contented Zen cloud water, eyes closed, the heart distant exile, Wind and Smoke curl in the mountains, such as Dai, ups and downs, indeed, like a thread, the ups and downs of life, with long Qingyuan . Flowers followed the road, facing the sun slowly forward, then the mind is calm, quiet as the lake, the water peach, flower with water, just like the fate of this world, do not ask why, regardless of come and go, only flowers need to remember Lu Qing, Yue possessor of the green heart, cool count. Sunlight penetration mist, alluding on the lake, the water green, clear, sparkling, on the beach, there are birds flying over from time to time, the sky blue and empty, with a quiet life after ups and downs, this time the heart is close to nature, without the slightest ripples, content with this quiet and peaceful. An end, wins the snow lotus, world clarity, years of silence, the heart is also safe.Time, very long. I know, I can stay in my mind there are limitations, not the majority, can only rely on these words to memory.Time, is very short. I understand, you can never forget so little, so I was in such a manner so as to leave some more.Youth, is very long. In life, shiny people, in fact, that a figure, how the passage of time, or the whole dazzling Love.Youth, is very short. In life, flickering days

Post comment

Nick *
Your name or nickname
Your contact information (optional, will not be shown)
Text *
Content of your comment
Calculate *
(* - required field)
STAT NO AD [Stat] [Admin] [STAT NO AD] [pub] [Mirror] Copyright © 2004-2016 Adam Sawicki
Copyright © 2004-2016 Adam Sawicki