5 Mixing SimpleMath and DirectXMath
Chuck Walbourn редактировал(а) эту страницу 2022-04-26 16:45:12 -07:00
Getting Started for DX11 Getting Started for DX12

This lesson discusses how to make use of more advanced math functions provided in the DirectXMath library using existing SimpleMath types.

Coordinate system

The SimpleMath wrapper assumes you are using right-handed coordinates, as does the remainder of the DirectX Tool Kit consistent with the default of XNA Game Studio. DirectXMath and Direct3D 11 generally, however, supports both right-handed and left-handed coordinates. If left-handed coordinates are desired, instead of using the handed Matrix methods, you use the DirectXMath LH equivalent function.

m_view = Matrix::CreateLookAt(Vector3(2.f, 2.f, 2.f),
    Vector3::Zero, Vector3::UnitY);
m_proj = Matrix::CreatePerspectiveFieldOfView(XM_PI / 4.f,
    float(backBufferWidth) / float(backBufferHeight), 0.1f, 10.f);

would instead become:

m_view = XMMatrixLookAtLH(Vector3(2.f, 2.f, 2.f),
    Vector3::Zero, Vector3::UnitY);
m_proj = XMMatrixPerspectiveFovLH( XM_PI / 4.f,
    float(backBufferWidth) / float(backBufferHeight), 0.1f, 10.f);

See SimpleMath for a complete list of Matrix methods that are 'handed'.

Many 'handed' DirectX Tool Kit functions take a bool parameter rhcoords that defaults to true. You should pass false when using left-handed view coordinates.

Right-hand Rule

Constants

A convenient way to build up constants with SimpleMath is to use the C++ constructers such as:

Vector3 a(10.f, -.5f, 2.5f);

This compiles fine, but at runtime this actually executes a little bit of code to build the structure up. For a vector like this where all the values are literals and known at compile time, a more efficient way to code them is to use DirectXMath's XMVECTORF32 and related types:

static const XMVECTORF32 s_a = { 10.f, -.5f, 2.5f, 0.f };

This becomes a vector laid out properly in data memory in your program ready for immediate use.

Options here include using:

  • XMVECTORF32 which is 4x floats
  • XMVECTORI32 which is 4x 32-bit ints
  • XMVECTORU32 which is 4x 32-bit unsigned ints
  • XMVECTORU8 which is 16x 8-bit unsigned ints

SimpleMath will freely convert all four of these data types into Vector2, Vector3, Vector4, Plane, Quaternion, or Color.

static const XMVECTORF32 s_lookat = { 2.f, 2.f, 2.f, 0.f };
m_view = Matrix::CreateLookAt( s_lookat, Vector3::Zero, Vector3::UnitY);

Fresnel term

Because of the free conversion of SimpleMath types, you can easily mix existing SimpleMath code with DirectXMath functions. For example, the XMFresnelTerm function doesn't have a SimpleMath equivalent:

Vector3 fresnel = XMFresnelTerm( Vector4( a1, a2, a3, a4 ),
    Vector4( ri1, ri2, ri3, ri4 ) );

PackedVector

DirectXMath includes a large collection of types and load/store methods in the DirectX::PackedVector namespace for converting to and from numerous specialized GPU types.

For example, if we want to create the initData for a texture in DXGI_FORMAT_R9G9B9E5_SHAREDEXP format:

std::unique_ptr<DirectX::PackedVector::XMFLOAT3SE]]> data(
    new DirectX::PackedVector::XMFLOAT3SE[width * height] );

for ( size_t h = 0; h < height; ++h )
{
    for( size_t w = 0; w < width; ++w  )
    {
        Vector3 pixel; // our data from somewhere
        XMStoreFloat3SE( &data[ w * h ], pixel );
    }
}

DirectXMath Library Internals

Next lesson: Adding the DirectX Tool Kit for Audio

Further reading

Introducing DirectXMath
DirectXMath 3.06
Known Issues: DirectXMath 3.06
Spherical Harmonics Math
XDSP.H: Digital Signal Processing helper functions
DirectXMath instruction extensions series