I'm writing another game engine in C++11/VC11 which presently uses DirectX/Direct3D11 as rendering backend. In order to hide DirectX types from the public interface (and a possible later implementation of an OpenGL backend), I'm rolling a linear algebra library on my own, which - however - still uses DirectX Math internally for the time being. DirectX Math is more or less a bunch of typedefs around the C++ SIMD intrinsics (__m128 etc.). In order to keep the levels of indirection low and have the stuff as "atomic" and inlined as possible, I prefer to inherit from the DirectX Math types directly (XMVECTORF32 in this case) - i.e. I don't want to use it as a member variable:
struct vector4 : private DirectX::XMVECTORF32
MSDN gives following example for the correct initialization of the XMVECTORF32 structure:
XMVECTOR data;
XMVECTORF32 floatingVector = { 0.f, 0.f, 0.1f, 1.f };
data = floatingVector;
However, my attempts to initialize the XMVECTORF32 as a base structure are not understood by the compiler.
struct vector4 : private DirectX::XMVECTORF32 // not XMFLOAT4 due to possible conversation overhead
{
friend class matrix44;
inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
: DirectX::XMVECTORF32{v0, v1, v2, v3} // ERROR: ';' expected
{
}
};
Am I missing something? How to correctly perform the base initialization I am intending to do? Is there maybe some new C++11 initialization sugar to help me out?
------------ EDIT -----------
For some reasons, I was not seeing the obvious. After examining the definition of XMVECTORF32, it was clear that the underlying union-float-array "f" was accessible for me, so the initialization looks like this.
struct vector4 : private DirectX::XMVECTORF32
{
friend struct matrix44;
inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
{
f[0] = v0;
f[1] = v1;
f[2] = v2;
f[3] = v3;
}
};
No casts, no unions, no c arrays. With inlining, performance should be near optimum.
------------ EDIT 2 -----------
XMVECTORF32 is not meant for storing data. Therefore the vector must inherit from XMFLOAT4. Otherwise, this gives non-reproducible access violation exceptions, especially with optimizations turned on. Here is more background: http://www.asawicki.info/news_1429_xna_math_and_access_violation.html
My final code looks like this:
struct vector4 : private DirectX::XMFLOAT4
{
friend struct matrix44;
inline vector4(scalar v0, scalar v1, scalar v2, scalar v3)
: DirectX::XMFLOAT4(v0, v1, v2, v3)
{
}
inline scalar& v0() { return x; }
inline scalar& v1() { return y; }
inline scalar& v2() { return z; }
inline scalar& v3() { return w; }
};
The vector data must be loaded into an XMVECTOR using XMLoadFloat4 prior SIMD calculations - no way around it. Think of XMVECTOR like a register - not a memory location.