Quantcast
Channel: directxtk Wiki Rss Feed
Viewing all 874 articles
Browse latest View live

Updated Wiki: Adding the DirectX Tool Kit for Audio

$
0
0
This lesson covers adding DirectX Tool Kit for Audio to your project.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

NuGet package manager

If you used NuGet when Adding the DirectX Tool Kit, then you already have support for DirectX Tool Kit for Audio.. The id directxtk_desktop_2013 package is configured for Windows 7 and Windows Vista support, so it is making use of XAudio 2.7.

XAudio 2.7 requires the legacy DirectX SDK (June 2010). Due to some technical issues, it must be installed to the 'default' location of "C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)". To install the legacy DirectX SDK on your development system, see http://blogs.msdn.com/b/chuckw/archive/2010/06/15/10023137.aspx and be sure to read this article for a known issue with the installer http://blogs.msdn.com/b/chuckw/archive/2013/09/24/10246203.aspx.

Complete the steps in Adding the headers below including the additional configuration for XAudio 2.7.

The other platform NuGet packages do not require the legacy DirectX SDK as they always make use of XAudio 2.8 which is built into Windows 8.0 or later, Windows phone 8.x, and Xbox One.

Project-to-project references

If you used project-to-project references when Adding the DirectX Tool Kit, then you need to add an additional DirectX Tool Kit for Audio project to your solution. There are two choices depending on your platform target.

XAudio 2.7

XAudio 2.7 supports Windows Vista, Windows 7, and Windows 8.x. It is deployed by the legacy DirectX End User Runtime package and requires the legacy DirectX SDK (June 2010) to develop with. Due to some technical issues, it must be installed to the 'default' location of "C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)". To install the legacy DirectX SDK on your development system, see http://blogs.msdn.com/b/chuckw/archive/2010/06/15/10023137.aspx and be sure to read this article for a known issue with the installer http://blogs.msdn.com/b/chuckw/archive/2013/09/24/10246203.aspx.
  1. Right-click on your solution in the Solution Explorer, and select Add / Existing Project...
  2. Browse into the "DirectXTK\Audio" folder and select "DirectXTKAudio_Desktop_2013_DXSDK.vcxproj", click "Open"
  3. If Visual Studio presents a "Security Warning", select "OK". Optional: Uncheck "Ask me for every project in this solution" first.
  4. Right-click on your project in the Solution Explorer, and select Add / References...
  5. Select "Add New Reference..."
  6. Check "DirectXTKAudio_Desktop_2013_DXSDK.vcxproj" and select "OK"
  7. Select "OK"

AddReferenceDX.png

Complete the steps in Adding the headers below including the additional configuration for XAudio 2.7.

XAudio 2.8

XAudio 2.8 is built into Windows 8.0 or later, and everything needed is include with the OS and the Windows 8.1 SDK which is deployed with VS 2013.
  1. Right-click on your solution in the Solution Explorer, and select Add / Existing Project...
  2. Browse into the "DirectXTK\Audio" folder and select "DirectXTKAudio_Desktop_2013_Win8.vcxproj", click "Open"
  3. If Visual Studio presents a "Security Warning", select "OK". Optional: Uncheck "Ask me for every project in this solution" first.
  4. Right-click on your project in the Solution Explorer, and select Add / References...
  5. Select "Add New Reference..."
  6. Check "DirectXTKAudio_Desktop_2013_Win8.vcxproj" and select "OK"
  7. Select "OK"

AddReferenceWin8.png

Complete the steps in Adding the headers below including the additional configuration for XAudio 2.8.

The other platform DirectX Tool Kit vcxproj files already include DirectX Tool Kit for Audio as they always make use of XAudio 2.8 which is built into Windows 8.0 or later, Windows phone 8.x, and Xbox One.

Adding the headers

Now that we have the DirectX Tool Kit for Audio usable in your project, the next step is to include the library header into your project.

//// pch.h// Header for standard system include files.//

#pragma once

...

#include "Audio.h"

...

XAudio 2.7

If you are using XAudio 2.7 for Windows 7 and Windows Vista compatibility, we also need to add the DirectX SDK include and library paths to your project. First go to Project / Properties and select "VC++ Directories" on the left. Then set Configuration to "All Configurations" and Platform to "Win32" (note this is called "x86" in VS 2015). Add to the end of these paths:
  • Include Directories: ;$(DXSDK_DIR)Include
  • Library Directories: ;$(DXSDK_DIR)Lib\x86
Click "Apply".

settingsDXx86.png

Then set Configuration to "All Configurations" and Platform to "x64". Add to the end of these paths:
  • Include Directories: ;$(DXSDK_DIR)Include
  • Library Directories: ;$(DXSDK_DIR)Lib\x64
Click "Apply".

settingsDXx64.png

It is important that the legacy DirectX SDK paths be after the existing path since are making use of the Windows 8.1 / VS 2013. See http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx.

Troubleshooting: If you get a compilation error indicating you are missing "comdecl.h", then you have incorrectly configured your VC++ Directory include paths. If you get a link error indicating your are missing "x3daudio.lib" then you incorrectly configured your VC++ Directory library paths.

XAudio 2.8

If you are using XAudio 2.8, then your application should be built to require Windows 8.0 or later. In pch.h modify the following section:

#include <WinSDKVer.h>
#define _WIN32_WINNT 0x0602
#include <SDKDDKVer.h>

Troubleshooting: If you get a compilation error indicating you are missing "comdecl.h", then you have incorrectly configured the _WIN32_WINNT variable. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa383745.aspx.

Deployment

If you are using XAudio 2.7, then your application has a dependency on the DirectX End-User Runtime. See http://blogs.msdn.com/b/chuckw/archive/2010/09/08/not-so-direct-setup.aspx

If you are using XAudio 2.8, then your application has a dependency on Windows 8.0 or later.

Next lesson:Adding audio to your project

Further reading

DirectX Tool Kit docs Audio

http://blogs.msdn.com/b/chuckw/archive/2013/12/25/directx-tool-kit-for-audio.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx

Updated Wiki: Adding audio to your project

$
0
0
This lesson covers the basics of adding the use of audio engine to your project.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop, Adding the DirectX Tool Kit, and then Adding the DirectX Tool Kit for Audio which we will use for this lesson.

The basic game loop with the audio engine

In the Game.h file, add the following variable to the bottom of the Game class's private declarations:

std::unique_ptr<DirectX::AudioEngine> m_audEngine;

In Game.cpp, add to the end of Initialize:

AUDIO_ENGINE_FLAGS eflags = AudioEngine_Default;
#ifdef _DEBUG
eflags = eflags | AudioEngine_Debug;
#endif
m_audEngine.reset(new AudioEngine(eflags));

In Game.cpp, add to the TODO of Update:

if (!m_audEngine->Update())
{
    // more about this below...
}

In Game.cpp, add to the TODO of OnSuspending:

m_audEngine->Suspend();

In Game.cpp, add to the TODO of OnResuming:

m_audEngine->Resume();

In the Game.h file, add the following to the Game class public declarations:

~Game();

In Game.cpp, add after the constructor:

Game::~Game()
{
    if (m_audEngine)
    {
        m_audEngine->Suspend();
    }
}

Build and run. You won't hear anything yet, but we do have XAudio2 up and running.

Troubleshooting: If you get the link error 'unresolved external symbol' for CreateFX, X3DAudioInitialize, or X3DAudioCalculate, you may have incorrectly configured the x86 vs. x64 versions of the VC++ Directory library paths in the previous lesson.

Troubleshooting: When using the debug version of XAudio 2.7 on Windows Vista or Windows 7, you can get a break-point exception thrown even with a valid device. The debug output window message will be the following. You can safely ignore this and click "Continue".

################################################################################
### XAUDIO2: enginerendererconnection.cpp:334: 
### ASSERT FAILED: FramesToLeapTime(uOutputBufferFramesObtained, m_pOutputFormat, RoundUp) >= rtRequestedBufferDuration
################################################################################

Technical notes

We have an explicit destructor for Game that ensures the audio engine is suspended because of the multi-threaded nature of XAudio2 which directly uses data owned by the application for playback. This makes the code more robust as otherwise it would be very dependent on the order of destruction of DirectX Tool Kit for Audio objects in our Game class.

Silent mode

With graphics, your application can safely just fail to start up without a video card, but not every system has an audio device. Therefore to simplify audio coding, DirectX Tool Kit for Audio will successfully start even without an audio device being found. This is called 'silent mode'. You won't get callbacks, but creating objects in the library will succeed so you can avoid a lot of messy conditional testing code in your project.

Your application can detect this mode in two ways: First, after you first create the AudioEngine, you might want to check this:

if ( !m_audEngine->IsAudioDevicePresent() )
{
    // we are in 'silent mode'. 
}

You could use this to force the display of 'subtitles' for voice overs and the like.

The second way you can detect this is by Update returning false, which indicates that audio is not currently playing. This second case is a bit more complicated because there is another reason you might be not playing audio: the audio device you originally created went away!

if (!m_audEngine->Update())
{
    if (m_audEngine->IsCriticalError())
    {
        // We lost the audio device!
    }
}

Losing the audio device

The main reason you can encounter a 'critical error' with XAudio2 is that the currently connected WASAPI end-point has been removed from the system. With Windows, this can be caused by unplugging the speakers/headphones or device driver updates. With Windows phone, this is due to switching between headset and Bluetooth. With Xbox One, this doesn't happen with the default device, but could happen with 'headset' audio.

The application's response to this should be to try a single Reset to see if there is a new default device that is available. Otherwise, you'll go to being in 'silent mode'.

In the Game.h file, add the following variable to the bottom of the Game class's private declarations:

bool m_retryAudio;

In Initialize, modify the audio initialization to be:

AUDIO_ENGINE_FLAGS eflags = AudioEngine_Default;
#ifdef _DEBUG
eflags = eflags | AudioEngine_Debug;
#endif
m_audEngine.reset(new AudioEngine(eflags));
m_retryAudio = false;

In Update, modify the audio update to be:

if (m_retryAudio)
{
    m_retryAudio = false;
    if (m_audEngine->Reset())
    {
        // TODO: restart any looped sounds here
    }
}
elseif (!m_audEngine->Update())
{
    if (m_audEngine->IsCriticalError())
    {
        m_retryAudio = true;
    }
}

Detecting new audio devices

One last case you need to consider for Windows is if your application starts in 'silent mode' but then enables audio later (perhaps by plugging in a headset). Ideally, your 'silent' application should use the new device. You can also have a delay between when you lose an audio device and a new one becomes available. The solution to both these problems is to try calling Reset once when a new audio device becomes available on the system.

In the Game.h file, add the following method to public interface of the Game class:

void OnNewAudioDevice() { m_retryAudio = true; }

In the Main.cpp file after the other includes at the top, add:

#include <Dbt.h>

In Main.cpp, modify the wWinMain function as follows:

...
    // Register class and create window
    HDEVNOTIFY hNewAudio = nullptr;
    {
        // Register class
...
        // Create window
...
        g_game->Initialize( hwnd );

        // Listen for new audio devices
        DEV_BROADCAST_DEVICEINTERFACE filter = {0};
        filter.dbcc_size = sizeof( filter );
        filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
        filter.dbcc_classguid = KSCATEGORY_AUDIO;

        hNewAudio = RegisterDeviceNotification( hwnd, &filter,
            DEVICE_NOTIFY_WINDOW_HANDLE );
    }

    // Main message loop
...
    g_game.reset();

    if (hNewAudio)
        UnregisterDeviceNotification(hNewAudio);

    CoUninitialize();

    return (int) msg.wParam;
}

Lastly, in Main.cpp, add the following case to the switch statement in WndProc:

case WM_DEVICECHANGE:
    if ( wParam == DBT_DEVICEARRIVAL )
    {
        auto pDev = reinterpret_cast<PDEV_BROADCAST_HDR>( lParam );
        if( pDev )
        {
            if ( pDev->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE )
            {
                auto pInter = reinterpret_cast<const PDEV_BROADCAST_DEVICEINTERFACE>
                    ( pDev );
                if ( pInter->dbcc_classguid == KSCATEGORY_AUDIO )
                {
                    if (game)
                        game->OnNewAudioDevice();
                }
            }
        }
    }
    return 0;

Windows Store & Windows phone apps: Since there is no Win32 message loop for these applications, you'd make use of the WinRT class DeviceWatcher in Windows.Device.Enumeration namespace. See http://code.msdn.microsoft.com/windowsapps/Device-Enumeration-Sample-a6e45169.

Next lesson:Creating and playing sounds

Further reading

DirectX Tool Kit docs Audio, AudioEngine

http://blogs.msdn.com/b/chuckw/archive/2013/12/25/directx-tool-kit-for-audio.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/05/15/learning-xaudio2.aspx

Updated Wiki: Game controller input

$
0
0
This lesson will show how to read user input from game controllers.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Adding use of a gamepad

In the Game.h file, add the following variable to the bottom of the Game class's private declarations:

std::unique_ptr<DirectX::GamePad> m_gamePad;

In Game.cpp, add to the TODO of CreateDevice:

m_gamePad.reset(new GamePad());

In Game.cpp, add to the TODO of OnSuspending and OnDeactivated:

m_gamePad->Suspend();

In Game.cpp, add to the TODO of OnResuming and OnActivated:

m_gamePad->Resume();

In Game.cpp, add to the TODO of Update:

auto state = m_gamePad->GetState(0);

if (state.IsConnected())
{
    // TODO: Read controller 0 here
}

Build and run. The application does not display anything or respond to input, but if a Xbox 360 Common Controller or Xbox One controller is plugged into the PC, then it will be detected.

Detecting game controller button presses

Here we wire up the View button (know as the Back button on Xbox 360 Controllers) to exit the application.

In Game.cpp, modify the TODO section of Update:

auto state = m_gamePad->GetState(0);

if (state.IsConnected())
{
    if (state.IsViewPressed())
    {
        PostQuitMessage(0); // Win32 desktop API for exiting the application
    }
}

Build and run. The application exits when you press View / Back.

Using vibration

In Game.cpp, modify the TODO section of Update:

auto state = m_gamePad->GetState(0);

if (state.IsConnected())
{
    if (state.IsViewPressed())
    {
        PostQuitMessage(0);
    }
    else
    {
        float left = (state.IsAPressed()) ? 1.f : 0;
        float right = (state.IsBPressed()) ? 1.f : 0;

        m_gamePad->SetVibration(0, left, right);
    }
}

Build and run. If you press and hold A or B, you get vibration motors of the controller to activate.

Reading game controller position

In this version, we tie the left and right triggers to the vibration which provides an example of reading position information from a game controller.

In Game.cpp, modify the TODO section of Update:

if (state.IsConnected())
{
    if (state.IsViewPressed())
    {
        PostQuitMessage(0);
    }
    else
    {
        m_gamePad->SetVibration( 0, state.triggers.left, state.triggers.right );
    }

Build and run. Slowly depress the left and right triggers to feel the vibration motor change intensity.

Detecting single button presses

Because we are checking the button states each frame, you need to track the button state to track transitions like "the button just went down" rather than "the button is down now".

In the Game.h file, add the following variable to the bottom of the Game class's private declarations:

DirectX::GamePad::ButtonStateTracker m_buttons;

In Game.cpp, add to the TODO of OnResuming and OnActivated:

m_buttons.Reset();

In Game.cpp, modify the TODO section of Update:

if (state.IsConnected())
{
    if (state.IsViewPressed())
    {
        PostQuitMessage(0);
    }
    m_buttons.Update(state);
    if (m_buttons.a == GamePad::ButtonStateTracker::PRESSED)
    {
        // A was up last frame, it just went down this frame
    }
    if (m_buttons.b == GamePad::ButtonStateTracker::RELEASED)
    {
        // B was down last frame, it just went up this frame
    }
}

Next lessons:Using the SimpleMath library, Adding the DirectX Tool Kit for Audio

Further reading

DirectX Tool Kit docs GamePad

http://blogs.msdn.com/b/chuckw/archive/2014/09/05/directx-tool-kit-now-with-gamepads.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/04/26/xinput-and-windows-8-consumer-preview.aspx

Updated Wiki: Using the SimpleMath library

$
0
0
This lesson introduces the reader to the SimpleMath game and graphics math library.

Coordinate system

Consistent with the original XNA Game Framework C# math library, SimpleMath assumes a right-handed coordinate system, with the positive z-axis pointing toward the observer when the positive x-axis is pointing to the right, and the positive y-axis is pointing up.

Vectors

SimpleMath provides the Vector2, Vector3, and Vector4 classes for representing and manipulating vectors. A vector typically is used to represent a direction and magnitude.

Each vector class has methods for performing standard vector operations such as:
  • Dot product
  • Cross product
  • Normalization
  • Transformation
  • Linear, Cubic, Catmull-Rom, or Hermite spline interpolation.

Vector3 upVector( 0, 1.f, 0 );
Vector3 leftVector( 1.f, 0, 0 );
float dot = upVector.Dot( leftVector );

Matrices

SimpleMath provides a Matrix class for transformation of geometry. The Matrix class uses row-major order to address matrices, which means that the row is specified before the column when describing an element of a two-dimensional matrix. The Matrix class provides methods for performing standard matrix operations such as calculating the determinate or inverse of a matrix. There also are helper methods for creating scale, rotation, and translation matrices.

Matrix a(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
Matrix b(1, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 23, 42, 0, 1);
Matrix c = a * b;

Quaternions

The Quaternion structure to calculate the efficient rotation of a vector by a specified angle, and is particularly effective when interpolating between angles.

Quaternion a(0.707107f, 0, 0, 0.707107f);
Quaternion (0, 0.707107f, 0, 0.707107f);
Quaternion c = Quaternion::Slerp(a, b, 0.25f);

Bounding Volumes

The BoundingBox, BoudingOrientedBox, BoundingFrustum, BoundingSphere, Plane, and Ray classes provides for representing simplified versions of geometry for the purpose of efficient collision and hit testing. These classes have methods for checking for intersection and containment with each other

Precision and Performance

The SimpleMath types are single-precision. This means that the primitives and operations contained in this library use 32-bit floating-point numbers to achieve a balance between precision and efficiency when performing large numbers of calculations.

A 32-bit floating-point number ranges from –3.402823e38 to +3.402823e38. The 32 bits store the sign, mantissa, and exponent of the number that yields seven digits of floating-point precision. Some numbers—for example π, 1/3, or the square root of two—can be approximated only with seven digits of precision, so be aware of rounding errors when using a binary representation of a floating-point number.

Next lesson:Basic game math

Further reading

DirectX Tool Kit docs SimpleMath

http://blogs.msdn.com/b/shawnhar/archive/2013/01/08/simplemath-a-simplified-wrapper-for-directxmath.aspx

Updated Wiki: Version History

$
0
0
July 1, 2015
  • Added Keyboard, Mouse class
  • Support for loading pre-lit models with SDKMESH
  • GamePad implemented using Windows.Gaming.Input for Windows 10
  • DirectXTK for Audio updates for xWMA support with XAudio 2.9
  • Added FindGlyph and GetSpriteSheet methods to SpriteFont

March 27, 2015
  • Added projects for Windows apps Technical Preview
  • GamePad temporarily uses 'null' device for universal Windows application platform

February 25, 2015 (NuGet version 2015.2.25.1)
  • DirectXTK for Audio updates
    • breaking change pitch now defined as -1 to 1 with 0 as the default
    • One-shot Play method with volume, pitch, and pan
    • GetMasterVolume/SetMasterVolume method for AudioEngine
    • Fix for compact wavebank validation
    • Improved voice cleanup and shutdown
  • Minor code cleanup and C++11 =default/=delete usage

January 26, 2015 (NuGet version 2015.1.26.1)
  • GamePad class: emulate XInputEnable behavior for XInput 9.1.0
  • DirectXTK for Audio fix for Stop followed by Play doing a proper restart
  • DirectXTK for Audio fix when using XAudio 2.7 on a system with no audio device
  • Updates for Xbox One platform support
  • Minor code cleanup and C99 printf string conformance

November 24, 2014 (NuGet version 2014.11.24.1, 2014.11.24.2)
  • SimpleMath fix for Matrix operator !=
  • DirectXTK for Audio workaround for XAudio 2.7 on Windows 7 problem
  • Updates for Windows phone 8.1 platform support
  • Updates for Visual Studio 2015 Technical Preview
  • Minor code cleanup

October 28, 2014
  • Model support for loading from VBO files
  • Model render now sets samplers on slots 0,1 by default for dual-texture effects
  • Updates for Xbox One platform support
  • Minor code cleanup

September 5, 2014
  • GamePad class: gamepad controller helper using XInput on Windows, IGamepad for Xbox One
  • SimpleMath updates; Matrix billboard methods; breaking change: Matrix::Identity() -> Matrix::Identity
  • SpriteBatch new optional SetViewport method
  • SpriteFont fix for white-space character rendering optimization
  • DDSTextureLoader fix for auto-gen mipmaps for volume textures
  • Explicit calling-convention annotation for public headers
  • Updates for Xbox One platform support
  • Minor code and project cleanup

July 15, 2014 (NuGet version 2014.7.15.1)
  • DirectXTK for Audio and XWBTool fixes
  • Updates to Xbox One platform support

April 3, 2014
  • Windows phone 8.1 platform support

February 24, 2014
  • DirectXHelper: new utility header with MapGuard and public version of SetDebugObjectName template
  • DDSTextureLoader: Optional support for auto-gen mipmaps
  • DDSTextureLoader/ScreenGrab: support for Direct3D 11 video formats including legacy "YUY2" DDS files
  • GeometricPrimtive: Handedness fix for tetrahedron, octahedron, dodecahedron, and icosahedron
  • SpriteBatch::SetRotation(DXGI_MODE_ROTATION_UNSPECIFIED) to disable viewport matrix
  • XboxDDSTextureLoader: optional forceSRGB parameter

January 24, 2014
  • DirectXTK for Audio updated with voice management and optional mastering volume limiter
  • Added orientation rotation support to SpriteBatch
  • Fixed a resource leak with GetDefaultTexture() used by some Effects
  • Code cleanup (removed DXGI_1_2_FORMATS control define; d2d1.h workaround not needed; ScopedObject typedef removed)

December 24, 2013
  • DirectXTK for Audio
  • Xbox One platform support
  • MakeSpriteFont tool updated with more progress feedback when capturing large fonts
  • Minor updates for .SDKMESH Model loader
  • Fixed bug in .CMO Model loader when handling multiple textures
  • Improved debugging output

October 28, 2013
  • Updated for Visual Studio 2013 and Windows 8.1 SDK RTM
  • Added DGSLEffect, DGSLEffectFactory, VertexPositionNormalTangentColorTexture, and VertexPositionNormalTangentColorTextureSkinning
  • Model loading and effect factories support loading skinned models
  • MakeSpriteFont now has a smooth vs. sharp antialiasing option: /sharp
  • Model loading from CMOs now handles UV transforms for texture coordinates
  • A number of small fixes for EffectFactory
  • Minor code and project cleanup
  • Added NO_D3D11_DEBUG_NAME compilation define to control population of Direct3D debug layer names for debug builds

July 1, 2013
  • VS 2013 Preview projects added and updates for DirectXMath 3.05 vectorcall
  • Added use of sRGB WIC metadata for JPEG, PNG, and TIFF
  • SaveToWIC functions updated with new optional setCustomProps parameter and error check with optional targetFormat

May 30, 2013
  • Added more GeometricPrimitives: Cone, Tetrahedron, Octahedron, Dodecahedron, Icosahedron
  • Updated to support loading new metadata from DDS files (if present)
  • Fixed bug with loading of WIC 32bpp RGBE format images
  • Fixed bug when skipping mipmaps in a 1D or 2D array texture DDS file

February 22, 2013 (NuGet version 2.22.13.23)
  • Added SimpleMath header
  • Fixed bug that prevented properly overriding EffectFactory::CreateTexture
  • Fixed forceSRGB logic in DDSTextureLoader and WICTextureLoader
  • Break circular reference chains when using SpriteBatch with a setCustomShaders lambda
  • Updated projects with /fp:fast for all configs, /arch:SSE2 for Win32 configs
  • Sensibly named .pdb output files
  • Added WIC_USE_FACTORY_PROXY build option (uses WindowsCodecs.dll entrypoint rather than CoCreateInstance)

January 25, 2013
  • GeometricPrimitive support for left-handed coordinates and drawing with custom effects
  • Model, ModelMesh, and ModelMeshPart added with loading of rigid non-animating models from .CMO and .SDKMESH files
  • EffectFactory helper class added

December 11, 2012
  • Ex versions of DDSTextureLoader and WICTextureLoader
  • Removed use of ATL's CComPtr in favor of WRL's ComPtr for all platforms to support VS Express editions
  • Updated VS 2010 project for official 'property sheet' integration for Windows 8.0 SDK
  • Minor fix to CommonStates for Feature Level 9.1
  • Tweaked AlphaTestEffect.cpp to work around ARM NEON compiler codegen bug
  • Added dxguid.lib as a default library for Debug builds to resolve GUID link issues

November 15, 2012
  • Added support for WIC2 when available on Windows 8 and Windows 7 with KB 2670838
  • Cleaned up warning level 4 warnings

October 30, 2012
  • Added project files for Windows phone 8

October 12, 2012
  • Added PrimitiveBatch for drawing user primitives
  • Debug object names for all D3D resources (for PIX and debug layer leak reporting)

October 2, 2012
  • Added ScreenGrab module
  • Added CreateGeoSphere for drawing a geodesic sphere
  • Put DDSTextureLoader and WICTextureLoader into the DirectX C++ namespace

September 7, 2012
  • Renamed project files for better naming consistency
  • Updated WICTextureLoader for Windows 8 96bpp floating-point formats
  • Win32 desktop projects updated to use Windows Vista (0x0600) rather than Windows 7 (0x0601) APIs
  • Tweaked SpriteBatch.cpp to workaround ARM NEON compiler codegen bug

May 31, 2012
  • Updated Metro project for Visual Studio 2012 Release Candidate changes
  • Cleaned up x64 Debug configuration warnings and switched to use "_DEBUG" instead of "DEBUG"
  • Minor fix for DDSTextureLoader's retry fallback that can happen with 10level9 feature levels

May 2, 2012
  • Added SpriteFont implementation and the MakeSpriteFont utility

March 29, 2012
  • WICTextureLoader updated with Windows 8 WIC native pixel formats

March 6, 2012
  • Fix for too much temp memory used by WICTextureLoader
  • Add separate Visual Studio 11 projects for Desktop vs. Metro builds

March 5, 2012
  • Bug fix for SpriteBatch with batches > 2048

February 24, 2012
  • Original release

Updated Wiki: Simple rendering

$
0
0
Here we learn how to render a triangle and a grid in 3D.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Background

In order to do a draw operation with Direct3D 11, we need to provide the following objects and settings:
  • A vertex buffer containing the vertices of the elements to draw.
  • The input layout that describes the memory layout of the vertices in the vertex buffer.
  • A primitive topology setting that indicates how to interpret the individual vertices (as a point, a line, a triangle, etc.)
  • A compiled vertex shader program
  • A compiled pixel shader program
For this lesson, the BasicEffect object will provide the vertex and pixel shader programs, VertexPositionColor will provide the input layout, and PrimitiveBatch will provide the vertex buffer and primitive topology.

Note that since the input layout is the bridge between the vertex buffer data and the vertex shader program, this Direct3D object is created with information about both.

Drawing a triangle

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

std::unique_ptr<DirectX::BasicEffect> m_effect;
std::unique_ptr<DirectX::PrimitiveBatch<DirectX::VertexPositionColor>> m_batch;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;

In Game.cpp, add to the TODO of CreateDevice:

m_effect.reset(new BasicEffect(m_d3dDevice.Get()));
m_effect->SetVertexColorEnabled(true);

voidconst* shaderByteCode;
size_t byteCodeLength;

m_effect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);

DX::ThrowIfFailed(
        m_d3dDevice->CreateInputLayout(VertexPositionColor::InputElements,
            VertexPositionColor::InputElementCount,
            shaderByteCode, byteCodeLength,
            m_inputLayout.ReleaseAndGetAddressOf()));

m_batch.reset(new PrimitiveBatch<VertexPositionColor>(m_d3dContext.Get()));

In Game.cpp, add to the TODO of OnDeviceLost:

m_effect.reset();
m_batch.reset();
m_inputLayout.Reset();

In Game.cpp, add to the TODO of Render:

m_effect->Apply(m_d3dContext.Get());

m_d3dContext->IASetInputLayout(m_inputLayout.Get());

m_batch->Begin();

VertexPositionColor v1(Vector3(0.f, 0.5f, 0.5f), Colors::Yellow);
VertexPositionColor v2(Vector3(0.5f, -0.5f, 0.5f), Colors::Yellow);
VertexPositionColor v3(Vector3(-0.5f, -0.5f, 0.5f), Colors::Yellow);

m_batch->DrawTriangle(v1, v2, v3);

m_batch->End();

Build and run to see a simple yellow triangle rendered in 2D.

screenshotTriangle.png

The image above is drawn using device coordinates that are independent of the screen resolution and range from -1 to +1. Resizing the window will result in the same image scaled to the new window. If instead you want to draw using screen pixel coordinates (which match the coordinate system used by SpriteBatch), then:

In Game.cpp, add to the TODO of CreateResources:

Matrix proj = Matrix::CreateScale( 2.f/float(backBufferWidth),
    -2.f/float(backBufferHeight), 1.f)
   * Matrix::CreateTranslation( -1.f, 1.f, 0.f );
m_effect->SetProjection(proj);

In Game.cpp, modify the TODO of Render:

m_effect->Apply(m_d3dContext.Get());

m_d3dContext->IASetInputLayout(m_inputLayout.Get());

m_batch->Begin();

VertexPositionColor v1(Vector3(400.f, 150.f, 0.f), Colors::Yellow);
VertexPositionColor v2(Vector3(600.f, 450.f, 0.f), Colors::Yellow);
VertexPositionColor v3(Vector3(200.f, 450.f, 0.f), Colors::Yellow);

m_batch->DrawTriangle(v1, v2, v3);

m_batch->End();

Build and run to get the same image, but if you resize the window the triangle will not change in the second version.

Technical notes

  • The BasicEffect family of shader classes uses shader code built in to the DirectXTK.lib as static data so there's no need to compile shaders at runtime or to load data files from disk.
  • Internally, both SpriteBatch and PrimitiveBatch make use of a dynamic rather than static vertex buffer object which makes use of special memory shared between the CPU and GPU. Generally, we prefer when possible to use static vertex buffers as they can reside in the video memory directly that is only accessible by the GPU.

Drawing a grid

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

In Game.cpp, add to the TODO of CreateDevice:

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

m_effect->SetView(m_view);
m_effect->SetProjection(m_proj);

In Game.cpp, modify to the TODO of Render:

m_effect->SetWorld(m_world);

m_effect->Apply(m_d3dContext.Get());

m_d3dContext->IASetInputLayout(m_inputLayout.Get());

m_batch->Begin();

Vector3 xaxis(2.f, 0.f, 0.f);
Vector3 yaxis(0.f, 0.f, 2.f);
Vector3 origin = Vector3::Zero;

size_t divisions = 20;

for( size_t i = 0; i <= divisions; ++i )
{
    float fPercent = float(i) / float(divisions);
    fPercent = ( fPercent * 2.0f ) - 1.0f;

    Vector3 scale = xaxis * fPercent + origin;

    VertexPositionColor v1( scale - yaxis, Colors::White );
    VertexPositionColor v2( scale + yaxis, Colors::White );
    m_batch->DrawLine( v1, v2 );
}

for( size_t i = 0; i <= divisions; i++ )
{
    FLOAT fPercent = float(i) / float(divisions);
    fPercent = ( fPercent * 2.0f ) - 1.0f;

    Vector3 scale = yaxis * fPercent + origin;

    VertexPositionColor v1( scale - xaxis, Colors::White );
    VertexPositionColor v2( scale + xaxis, Colors::White );
    m_batch->DrawLine( v1, v2 );
}

m_batch->End();

Build and run to see a 3D grid.

screenshotGrid.png

Next lesson:3D shapes

Further reading

DirectX Tool Kit docs Effects, PrimitiveBatch, VertexTypes

Updated Wiki: Simple rendering

$
0
0
Here we learn how to render a triangle and a grid in 3D.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Background

In order to do a draw operation with Direct3D 11, we need to provide the following objects and settings:
  • A vertex buffer containing the vertices of the elements to draw.
  • The input layout that describes the memory layout of the vertices in the vertex buffer.
  • A primitive topology setting that indicates how to interpret the individual vertices (as a point, a line, a triangle, etc.)
  • A compiled vertex shader program
  • A compiled pixel shader program
For this lesson, the BasicEffect object will provide the vertex and pixel shader programs, VertexPositionColor will provide the input layout, and PrimitiveBatch will provide the vertex buffer and primitive topology.

Note that since the input layout is the bridge between the vertex buffer data and the vertex shader program, this Direct3D object is created with information about both.

Drawing a triangle

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

std::unique_ptr<DirectX::BasicEffect> m_effect;
std::unique_ptr<DirectX::PrimitiveBatch<DirectX::VertexPositionColor>> m_batch;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;

In Game.cpp, add to the TODO of CreateDevice:

m_effect.reset(new BasicEffect(m_d3dDevice.Get()));
m_effect->SetVertexColorEnabled(true);

voidconst* shaderByteCode;
size_t byteCodeLength;

m_effect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);

DX::ThrowIfFailed(
        m_d3dDevice->CreateInputLayout(VertexPositionColor::InputElements,
            VertexPositionColor::InputElementCount,
            shaderByteCode, byteCodeLength,
            m_inputLayout.ReleaseAndGetAddressOf()));

m_batch.reset(new PrimitiveBatch<VertexPositionColor>(m_d3dContext.Get()));

In Game.cpp, add to the TODO of OnDeviceLost:

m_effect.reset();
m_batch.reset();
m_inputLayout.Reset();

In Game.cpp, add to the TODO of Render:

m_effect->Apply(m_d3dContext.Get());

m_d3dContext->IASetInputLayout(m_inputLayout.Get());

m_batch->Begin();

VertexPositionColor v1(Vector3(0.f, 0.5f, 0.5f), Colors::Yellow);
VertexPositionColor v2(Vector3(0.5f, -0.5f, 0.5f), Colors::Yellow);
VertexPositionColor v3(Vector3(-0.5f, -0.5f, 0.5f), Colors::Yellow);

m_batch->DrawTriangle(v1, v2, v3);

m_batch->End();

Build and run to see a simple yellow triangle rendered in 2D.

screenshotTriangle.png

The image above is drawn using device coordinates that are independent of the screen resolution and range from -1 to +1. Resizing the window will result in the same image scaled to the new window. If instead you want to draw using screen pixel coordinates (which match the coordinate system used by SpriteBatch), then:

In Game.cpp, add to the TODO of CreateResources:

Matrix proj = Matrix::CreateScale( 2.f/float(backBufferWidth),
    -2.f/float(backBufferHeight), 1.f)
   * Matrix::CreateTranslation( -1.f, 1.f, 0.f );
m_effect->SetProjection(proj);

In Game.cpp, modify the TODO of Render:

m_effect->Apply(m_d3dContext.Get());

m_d3dContext->IASetInputLayout(m_inputLayout.Get());

m_batch->Begin();

VertexPositionColor v1(Vector3(400.f, 150.f, 0.f), Colors::Yellow);
VertexPositionColor v2(Vector3(600.f, 450.f, 0.f), Colors::Yellow);
VertexPositionColor v3(Vector3(200.f, 450.f, 0.f), Colors::Yellow);

m_batch->DrawTriangle(v1, v2, v3);

m_batch->End();

Build and run to get the same image, but if you resize the window the triangle will not change in the second version.

Technical notes

  • The BasicEffect family of shader classes uses shader code built in to the DirectXTK.lib as static data so there's no need to compile shaders at runtime or to load data files from disk.
  • Internally, both SpriteBatch and PrimitiveBatch make use of a dynamic rather than static vertex buffer object which makes use of special memory shared between the CPU and GPU. Generally, we prefer when possible to use static vertex buffers as they can reside in the video memory directly that is only accessible by the GPU.

Drawing a grid

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

In Game.cpp, add to the TODO of CreateDevice:

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

m_effect->SetView(m_view);
m_effect->SetProjection(m_proj);

In Game.cpp, modify to the TODO of Render:

m_effect->SetWorld(m_world);

m_effect->Apply(m_d3dContext.Get());

m_d3dContext->IASetInputLayout(m_inputLayout.Get());

m_batch->Begin();

Vector3 xaxis(2.f, 0.f, 0.f);
Vector3 yaxis(0.f, 0.f, 2.f);
Vector3 origin = Vector3::Zero;

size_t divisions = 20;

for( size_t i = 0; i <= divisions; ++i )
{
    float fPercent = float(i) / float(divisions);
    fPercent = ( fPercent * 2.0f ) - 1.0f;

    Vector3 scale = xaxis * fPercent + origin;

    VertexPositionColor v1( scale - yaxis, Colors::White );
    VertexPositionColor v2( scale + yaxis, Colors::White );
    m_batch->DrawLine( v1, v2 );
}

for( size_t i = 0; i <= divisions; i++ )
{
    float fPercent = float(i) / float(divisions);
    fPercent = ( fPercent * 2.0f ) - 1.0f;

    Vector3 scale = yaxis * fPercent + origin;

    VertexPositionColor v1( scale - xaxis, Colors::White );
    VertexPositionColor v2( scale + xaxis, Colors::White );
    m_batch->DrawLine( v1, v2 );
}

m_batch->End();

Build and run to see a 3D grid.

screenshotGrid.png

Next lesson:3D shapes

Further reading

DirectX Tool Kit docs Effects, PrimitiveBatch, VertexTypes

Updated Wiki: Using advanced shaders

$
0
0
In this lesson we learn about other built-in shader types and some of their uses.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Environment mapping

Start by saving wood.dds and cubemap.dds into your new project's directory, and then from the top menu select Project / Add Existing Item.... Select "wood.dds" and click "OK". Repeat for "cubemap.dds"

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;
std::unique_ptr<DirectX::CommonStates> m_states;
std::unique_ptr<DirectX::GeometricPrimitive> m_shape;
std::unique_ptr<DirectX::EnvironmentMapEffect> m_effect;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_texture;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_cubemap;

In Game.cpp, add to the TODO of CreateDevice:

m_states.reset(new CommonStates(m_d3dDevice.Get()));

m_effect.reset(new EnvironmentMapEffect(m_d3dDevice.Get()));
m_effect->EnableDefaultLighting();

m_shape = GeometricPrimitive::CreateTeapot(m_d3dContext.Get());
m_shape->CreateInputLayout(m_effect.get(),
    m_inputLayout.ReleaseAndGetAddressOf());

DX::ThrowIfFailed(
    CreateDDSTextureFromFile(m_d3dDevice.Get(), L"wood.dds", nullptr,
    m_texture.ReleaseAndGetAddressOf()));

m_effect->SetTexture(m_texture.Get());

DX::ThrowIfFailed(
    CreateDDSTextureFromFile(m_d3dDevice.Get(), L"cubemap.dds", nullptr,
    m_cubemap.ReleaseAndGetAddressOf()));

m_effect->SetEnvironmentMap(m_cubemap.Get());

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

m_effect->SetView(m_view);
m_effect->SetProjection(m_proj);

In Game.cpp, add to the TODO of OnDeviceLost:

m_states.reset();
m_shape.reset();
m_effect.reset();
m_inputLayout.Reset();
m_texture.Reset();
m_cubemap.Reset();

In Game.cpp, add to the TODO of Render:

m_effect->SetWorld(m_world);
m_shape->Draw(m_effect.get(), m_inputLayout.Get(), false, false, [=]{
    auto sampler = m_states->LinearWrap();
    m_d3dContext->PSSetSamplers( 1, 1, &sampler );
});

In Game.cpp, add to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Build and run to see the teapot rendered with a fancy material.

screenshotTeapot.png

In Game.cpp add the following to the TODO section of Update:

m_effect->SetFresnelFactor(cosf(time * 2.f));

Build and run to see the effect of animating the Fresnel factor.

screenshotTeapot2.png

Alpha-test

...

Next lesson:Applying lightmaps

Further reading

DirectX Tool Kit docs Effects

Updated Wiki: 3D shapes

$
0
0
This lesson draws simple shapes in 3D.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Background

In the previous lesson, we generated geometry with code using PrimitiveBatch to draw simple shapes. Here we make use of GeometricPrimitive which procedurally generates shapes like spheres, cubes, etc. These 3D shapes are more efficient to render because they make use of indexed primitives, and because they make use of a static rather than dynamic vertex buffer and index buffer.

Drawing a sphere

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;
std::unique_ptr<DirectX::GeometricPrimitive> m_shape;

In Game.cpp, add to the TODO of CreateDevice:

m_shape = GeometricPrimitive::CreateSphere(m_d3dContext.Get());

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

In Game.cpp, add to the TODO of OnDeviceLost:

m_shape.reset();

In Game.cpp, add to the TODO of Render:

m_shape->Draw(m_world, m_view, m_proj);

In Game.cpp, add to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Build and run, and you'll see a white lit sphere.

screenshotSphere.png

Drawing other built-in shapes

In Game.cpp modify the TODO of CreateDevice:

m_shape = GeometricPrimitive::CreateTorus(m_d3dContext.Get());

Build and run to see a torus instead of a sphere.

screenshotTorus.png

You can try out other shapes like a cube, cone, cylinder, dodecahedron, or the classic teapot.

m_shape = GeometricPrimitive::CreateCube(m_d3dContext.Get());

m_shape = GeometricPrimitive::CreateCone(m_d3dContext.Get());

m_shape = GeometricPrimitive::CreateCylinder(m_d3dContext.Get());

m_shape = GeometricPrimitive::CreateDodecahedron(m_d3dContext.Get());

m_shape = GeometricPrimitive::CreateTeapot(m_d3dContext.Get());

Adding textures to 3D shapes

Start by saving earth.bmp into your new project's directory, and then from the top menu select Project / Add Existing Item.... Select "earth.bmp" and click "OK".

In the Game.h file, add the following variable to the bottom of the Game class's private declarations:

Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_texture;

In Game.cpp, add to the TODO of CreateDevice:

DX::ThrowIfFailed(
    CreateWICTextureFromFile(m_d3dDevice.Get(), L"earth.bmp", nullptr,
    m_texture.ReleaseAndGetAddressOf()));

In Game.cpp, add to the TODO of OnDeviceLost:

m_texture.Reset();

In Game.cpp modify the TODO of CreateDevice:

m_shape = GeometricPrimitive::CreateSphere(m_d3dContext.Get());

In Game.cpp, modify to the TODO of Render:

m_shape->Draw(m_world, m_view, m_proj, Colors::White, m_texture.Get());

In Game.cpp, modify to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationY(time);

Build and you'll see planet earth spinning.

screenshotEarth1.png

Using custom lighting and effects

By default the geometric primitive renderer uses a simple BasicEffect with default lighting settings. To get more control over the rendering, you can use your own effect.

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

std::unique_ptr<DirectX::BasicEffect> m_effect;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;

In Game.cpp modify the TODO of CreateDevice:

m_effect.reset(new BasicEffect(m_d3dDevice.Get()));
m_effect->SetTextureEnabled(true);
m_effect->SetPerPixelLighting(true);
m_effect->SetLightingEnabled(true);
m_effect->SetLightEnabled(0, true);
m_effect->SetLightDiffuseColor(0, Colors::White);
m_effect->SetLightDirection(0, -Vector3::UnitZ);

m_shape = GeometricPrimitive::CreateSphere(m_d3dContext.Get());
m_shape->CreateInputLayout(m_effect.get(),
    m_inputLayout.ReleaseAndGetAddressOf());

DX::ThrowIfFailed(
    CreateWICTextureFromFile(m_d3dDevice.Get(), L"earth.bmp", nullptr,
    m_texture.ReleaseAndGetAddressOf()));

m_effect->SetTexture(m_texture.Get());

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

m_effect->SetView(m_view);
m_effect->SetProjection(m_proj);

In Game.cpp, add to the TODO of OnDeviceLost:

m_effect.reset();
m_inputLayout.Reset();

In Game.cpp, modify to the TODO of Render:

m_effect->SetWorld(m_world);
m_shape->Draw(m_effect.get(), m_inputLayout.Get());

Build and run to see earth with more 'space-like' lighting.

screenshotEarth2.png

Next lesson:Rendering a model

Further reading

DirectX Tool Kit docs Effects, GeometricPrimitive

Updated Wiki: Rendering a model

$
0
0
This lesson loads and draws models in 3D.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Creating a model

Source assets for models are often stored in Autodesk FBX, Wavefront OBJ, or similar formats. A build process is used to convert them to a more run-time friendly format that is easier to load and render.

Visual Studio has a built-in system for converting a Wavefront OBJ or Autodesk FBX as part of the build process to a CMO, which you can read about here - http://msdn.microsoft.com/en-us/library/hh972446.aspx.

For this tutorial, we will instead make of use of the DirectXMesh (http://go.microsoft.com/fwlink/?LinkID=324981) meshconvert command-line tool. Start by saving cup._obj, cup.mtl, and cup.jpg into your new project's directory, and then from the top menu select Project / Add Existing Item.... Select "cup.jpg" and click "OK".
  1. Download the "Meshconvert.zip" from the DirectXMesh CodePlex site and extract the EXE into your project's folder.
  2. Open a command-prompt and then change to your project's folder. http://windows.microsoft.com/en-us/windows/command-prompt-faq
  3. Run the following command-line
meshconvert cup._obj -cmo -nodds -fliptc -y

Then from the top menu in Visual Studio select Project / Add Existing Item.... Select cup.cmo and click "OK".

Technical notes

  • The switch "-cmo" selects the Visual Studio Compiled Mesh Object runtime format as the output. The meshconver command-line tool also supports "-sdkmesh" and "-vbo". https://directxmesh.codeplex.com/wikipage?title=Geometry%20formats
  • The switch "-nodds" causes any texture file name references in the material information of the source file to stay in their original file format (such as .png or .jpg). Otherwise, it assumes you will be converting all the needed texture files to a .dds instead.
  • The switch "-fliptc" flips the direction of the texture coordinates. Since SimpleMath and these tutorials assume we are using right-handed viewing coordinates and the model was created using left-handed viewing coordinates we have to flip them to get the text in the texture to appear correctly.
  • The switch "-y" indicates that it is ok to overwrite the output file in case you run it multiple times.

Drawing a model

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

std::unique_ptr<DirectX::CommonStates> m_states;
std::unique_ptr<DirectX::IEffectFactory> m_fxFactory;
std::unique_ptr<DirectX::Model> m_model;

In Game.cpp, add to the TODO of CreateDevice:

m_states.reset(new CommonStates(m_d3dDevice.Get()));

m_fxFactory.reset(new EffectFactory(m_d3dDevice.Get()));

m_model = Model::CreateFromCMO(m_d3dDevice.Get(), L"cup.cmo", *m_fxFactory);

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

In Game.cpp, add to the TODO of OnDeviceLost:

m_states.reset();
m_fxFactory.reset();
m_model.reset();

In Game.cpp, add to the TODO of Render:

m_model->Draw(m_d3dContext.Get(), *m_states, m_world, m_view, m_proj);

In Game.cpp, add to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Build and run and you will see our cup model rendered with default lighting:

screenshotCup.png

Troubleshooting: If you get a runtime exception, then you may have the "cup.jpg" or "cup.cmo" in the wrong folder, have modified the "Working Directory" in the "Debugging" configuration settings, or otherwise changed the expected paths at runtime of the application. You should set a break-point on Model::CreateFromCMO and step into the code to find the exact problem.

Updating effects settings in a model

The Model class creates effects automatically for the loaded materials which are set to default lighting parameters. To update them, you use the Model::UpdateEffects method. Because the effects system is flexible, we must first enable C++ Run-Time Type Information (RTTI) in order to safely discover the various interfaces supported at runtime. From the drop-down menu, select Project / Properties. Set to "All Configurations" / "All Platforms". On the left-hand tree view select C/C++ / Language. Then set "Enable Run-Time Type Information" to "Yes". Click "OK".

settingsRTTI.png

In Game.cpp, add to the TODO of CreateDevice:

m_model->UpdateEffects([](IEffect* effect)
{
    auto lights = dynamic_cast<IEffectLights*>(effect);
    if (lights)
    {
        lights->SetLightingEnabled(true);
        lights->SetPerPixelLighting(true);
        lights->SetLightEnabled(0, true);
        lights->SetLightDiffuseColor(0, Colors::Gold);
        lights->SetLightEnabled(1, false);
        lights->SetLightEnabled(2, false);
    }

    auto fog = dynamic_cast<IEffectFog*>(effect);
    if (fog)
    {
        fog->SetFogEnabled(true);
        fog->SetFogColor(Colors::CornflowerBlue);
        fog->SetFogStart(3.f);
        fog->SetFogEnd(4.f);
    }
});

Build and run to get our cup with a colored light and fogging enabled.

screenshotCupFog.png

Technical notes

Here we've made use to two C++ concepts:
  1. The dynamic_cast operator allows us to safely determine if an effect in the model supports lighting and/or fog using the C++ run-time type checking. If the IEffect instance does not support the desired interface, the cast returns a nullptr and our code will skip those settings.
  2. This also used a lambda function (aka anonymous function) of the form [](IEffect* effect){ ... } which is a new C++11 syntax. We could have used a C-style call-back function, but this syntax is more direct.

Using DGSL shaders for the model

For this lesson, we made use of EffectFactory which will create either BasicEffect or SkinnedEffect instances depending on the content of the loaded model file. With CMOs and the built-in Visual Studio 3D pipeline, you can instead make use of DGSLEffect by changing EffectFactory to DGSLEffectFactory.

In Game.cpp in the TODO section of CreateDevice, change

m_fxFactory.reset(new EffectFactory(m_d3dDevice.Get()));

to

m_fxFactory.reset(new DGSLEffectFactory(m_d3dDevice.Get()));

Note: This is why we used the abstract interface IEffectFactory rather than using std::unique_ptr<EffectFactory> in Game.h so that the variable could refer to either type of factory.

Build and run. If you still have the UpdateEffects code in place, you'll see the fog no longer appears although the light is colored.

screenShotCupNoFog.png

The lack of fog is because our "cup.cmo" makes use of the default built-in DGSL shaders lambert and phong which do not implement fog. The DGSLEffectFactory allows you to use Model and the Effect interface with the more complex custom DGSL shaders supported by the Visual Studio CMO pipeline where you use a visual editor to build pixel shaders.

http://msdn.microsoft.com/en-us/library/hh873117.aspx

Next lesson:Using skinned models

Further reading

DirectX Tool Kit docs EffectFactory, Effects, Model

Updated Wiki: Creating custom shaders with DGSL

$
0
0
This lesson covers creating custom shaders with the Visual Studio DGSL Shader Designer and using them with DirectX Tool Kit.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Creating custom shaders using DGSL

One approach to creating your own shader is to use a visual designer tool, such as Visual Studio's DGSL Shader Designer. In this tool, the vertex shader is 'fixed' and the visual tool is used to create the pixel shader. The result of the designer tool is a compiled shader in a .DGSL.CSO file that can be loaded at runtime. The resulting shaders can be complex and use up to 8 textures at once, perform tangent-space lighting, and many other complex effects.

To use these with DirectX Tool Kit, you can manually create DGSLEffect instances and use them with PrimitiveBatch. You can also load them automatically from a CMO using Model when you provide the DGSLEffectFactory rather than the standard EffectFactory as we demonstrated in Rendering a model.

Rendering a sphere with our effect

Save the files MyDGSLShader.dgsl, billard15.dds, envmap.dds, ReadData.h, and dgslsphere.inc to your new project's folder. Using to the top menu and select Project / Add Existing Item.... Select "MyDGSLShader.dgsl" and hit "OK". Repeat for each file.

Right click on your project in the Solution Explorer. Select Build Dependencies / Build Customizations.... Check "ShaderGraphContentTask..." and hit "Ok".

settingsBCS.png

Right-click on the "MyDGSLShader.dgsl" file in the Solution Explorer, select Properties.... Set Item Type to "Shader Graph Content Pipeline".

settingsDGSL.png

In pch.h add after the other #include statements:

#include "ReadData.h"

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;
std::unique_ptr<DirectX::CommonStates> m_states;
std::unique_ptr<DirectX::DGSLEffect> m_effect;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_shapeVB;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_shapeIB;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_texture;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_texture2;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;

In Game.cpp after the using namespace statements, add:

namespace
{
#include "dgslsphere.inc"
}

In Game.cpp modify in CreateDevice:

staticconst D3D_FEATURE_LEVEL featureLevels [] =
{
    // TODO: Modify for supported Direct3D feature levels (see code below related to 11.1 fallback handling)
    D3D_FEATURE_LEVEL_11_1,
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
};

In Game.cpp, add to the TODO of CreateDevice:

m_states.reset(new CommonStates(m_d3dDevice.Get()));

// Create DGSL Effectauto blob = DX::ReadData( L"MyDGSLShader.cso" );
DX::ThrowIfFailed(m_d3dDevice->CreatePixelShader(&blob.front(), blob.size(), nullptr,
    m_pixelShader.ReleaseAndGetAddressOf()));

m_effect.reset(new DGSLEffect(m_d3dDevice.Get(), m_pixelShader.Get()));
m_effect->SetTextureEnabled(true);
m_effect->SetVertexColorEnabled(true);

DX::ThrowIfFailed(
    CreateDDSTextureFromFile(m_d3dDevice.Get(), L"billard15.dds", nullptr,
    m_texture.ReleaseAndGetAddressOf()));

m_effect->SetTexture(m_texture.Get());

DX::ThrowIfFailed(
    CreateDDSTextureFromFile(m_d3dDevice.Get(), L"envmap.dds", nullptr,
    m_texture2.ReleaseAndGetAddressOf()));

m_effect->SetTexture(1, m_texture2.Get());
m_effect->EnableDefaultLighting();

voidconst* shaderByteCode;
size_t byteCodeLength;

m_effect->GetVertexShaderBytecode(&shaderByteCode, &byteCodeLength);

DX::ThrowIfFailed( m_d3dDevice->CreateInputLayout(
    VertexPositionNormalTangentColorTexture::InputElements, 
    VertexPositionNormalTangentColorTexture::InputElementCount,
    shaderByteCode, byteCodeLength, m_inputLayout.ReleaseAndGetAddressOf()));

// Create sphere geometry with DGSL vertex data
{
    D3D11_BUFFER_DESC desc = { 0 };
    desc.ByteWidth = sizeof(g_sphereVB);
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

    D3D11_SUBRESOURCE_DATA initData = { 0 };
    initData.pSysMem = g_sphereVB;
        
    DX::ThrowIfFailed( m_d3dDevice->CreateBuffer( &desc, &initData,
        m_shapeVB.ReleaseAndGetAddressOf() ) );
}

{
    D3D11_BUFFER_DESC desc = { 0 };
    desc.ByteWidth = sizeof(g_sphereIB);
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_INDEX_BUFFER;

    D3D11_SUBRESOURCE_DATA initData = { 0 };
    initData.pSysMem = g_sphereIB;
        
    DX::ThrowIfFailed( m_d3dDevice->CreateBuffer( &desc, &initData,
        m_shapeIB.ReleaseAndGetAddressOf() ) );
}

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

m_effect->SetViewport( float(backBufferWidth), float(backBufferHeight) );

m_effect->SetView(m_view);
m_effect->SetProjection(m_proj);

In Game.cpp, add to the TODO of OnDeviceLost:

m_states.reset();
m_effect.reset();
m_shapeVB.Reset();
m_shapeIB.Reset();
m_inputLayout.Reset();
m_texture.Reset();
m_texture2.Reset();
m_pixelShader.Reset();

In Game.cpp, add to the TODO of Render:

m_effect->Apply( m_d3dContext.Get() );

auto sampler = m_states->LinearWrap();
m_d3dContext->PSSetSamplers( 0, 1, &sampler );

m_d3dContext->RSSetState( m_states->CullClockwise() );

m_d3dContext->IASetIndexBuffer( m_shapeIB.Get(), DXGI_FORMAT_R16_UINT, 0 );
    
m_d3dContext->IASetInputLayout( m_inputLayout.Get() );

UINT stride = sizeof(VertexPositionNormalTangentColorTexture);
UINT offset = 0;
m_d3dContext->IASetVertexBuffers(0, 1, m_shapeVB.GetAddressOf(), &stride, &offset);

m_d3dContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

m_d3dContext->DrawIndexed( _countof(g_sphereIB), 0, 0 );

In Game.cpp, add to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_effect->SetTime(time);

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

m_effect->SetWorld(m_world);

Build and run to see the sphere.

screenshotBall.png

Troubleshooting: If you get a runtime exception, then you may have the "billard15.dds" or "envmap.dds" in the wrong folder, have modified the "Working Directory" in the "Debugging" configuration settings, or otherwise changed the expected paths at runtime of the application. You should set a break-point on CreateDDSTextureFromFile and step into the code to find the exact problem. If you get an exception from DX::ReadData, then you may not have the "MyDGSLShader.dgsl" file building correctly.

Technical notes

We are not able to use a GeometricPrimitive because the DGSL rendering pipeline requires per-vertex tangent information. Therefore, we load a custom vertex buffer/index buffer for this lesson that uses the VertexPositionNormalTangentColorTexture vertex structure with the tangent information. This vertex information is always included with CMO models.

While the example DGSL here doesn't require it, this lesson shows setting the extra DGSL variables for time and viewport size in the Update and CreateResources methods.

Limitations

The main limitation of using the DGSL tool is that it creates only Shader Model 4.0 Pixel Shaders, which requires Direct3D feature level 10.0 or greater. This is why we removed the 9.x feature levels from CreateDevice above.

To support Windows phone, you need feature level 9.3, and to target Surface RT you need feature level 9.1. There is a workaround which is to manually export the DGSL shader to an HLSL file, then compile it using FXC with either the ps_4_0_level_9_1 or ps_4_0_level_9_3 shader profile. It is quite likely you'll need to manually simplify the HLSL shader to successfully get it to compile. DGSLEffectFactory implements this workaround by looking for a 'base-name' equivalent of the .DGSL.CSO file as a .CSO file when on feature level 9.x devices.

http://msdn.microsoft.com/en-us/library/hh667618.aspx

Next lesson:Writing custom shaders

Further reading

DirectX Tool Kit docs Effects

http://msdn.microsoft.com/en-us/library/hh972446.aspx

http://msdn.microsoft.com/en-us/library/hh873117.aspx

http://aka.ms/vs3dkitwin

Updated Wiki: Rendering a model

$
0
0
This lesson loads and draws models in 3D.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Creating a model

Source assets for models are often stored in Autodesk FBX, Wavefront OBJ, or similar formats. A build process is used to convert them to a more run-time friendly format that is easier to load and render.

Visual Studio has a built-in system for converting a Wavefront OBJ or Autodesk FBX as part of the build process to a CMO, which you can read about here - http://msdn.microsoft.com/en-us/library/hh972446.aspx.

For this tutorial, we will instead make of use of the DirectXMesh (http://go.microsoft.com/fwlink/?LinkID=324981) meshconvert command-line tool. Start by saving cup._obj, cup.mtl, and cup.jpg into your new project's directory, and then from the top menu select Project / Add Existing Item.... Select "cup.jpg" and click "OK".
  1. Download the "Meshconvert.zip" from the DirectXMesh CodePlex site and extract the EXE into your project's folder.
  2. Open a command-prompt and then change to your project's folder. http://windows.microsoft.com/en-us/windows/command-prompt-faq
  3. Run the following command-line
meshconvert cup._obj -cmo -nodds -fliptc -y

Then from the top menu in Visual Studio select Project / Add Existing Item.... Select cup.cmo and click "OK".

Technical notes

  • The switch "-cmo" selects the Visual Studio Compiled Mesh Object runtime format as the output. The meshconver command-line tool also supports "-sdkmesh" and "-vbo". https://directxmesh.codeplex.com/wikipage?title=Geometry%20formats
  • The switch "-nodds" causes any texture file name references in the material information of the source file to stay in their original file format (such as .png or .jpg). Otherwise, it assumes you will be converting all the needed texture files to a .dds instead.
  • The switch "-fliptc" flips the direction of the texture coordinates. Since SimpleMath and these tutorials assume we are using right-handed viewing coordinates and the model was created using left-handed viewing coordinates we have to flip them to get the text in the texture to appear correctly.
  • The switch "-y" indicates that it is ok to overwrite the output file in case you run it multiple times.

Drawing a model

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

std::unique_ptr<DirectX::CommonStates> m_states;
std::unique_ptr<DirectX::IEffectFactory> m_fxFactory;
std::unique_ptr<DirectX::Model> m_model;

In Game.cpp, add to the TODO of CreateDevice:

m_states.reset(new CommonStates(m_d3dDevice.Get()));

m_fxFactory.reset(new EffectFactory(m_d3dDevice.Get()));

m_model = Model::CreateFromCMO(m_d3dDevice.Get(), L"cup.cmo", *m_fxFactory);

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

In Game.cpp, add to the TODO of OnDeviceLost:

m_states.reset();
m_fxFactory.reset();
m_model.reset();

In Game.cpp, add to the TODO of Render:

m_model->Draw(m_d3dContext.Get(), *m_states, m_world, m_view, m_proj);

In Game.cpp, add to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Build and run and you will see our cup model rendered with default lighting:

screenshotCup.png

Troubleshooting: If you get a runtime exception, then you may have the "cup.jpg" or "cup.cmo" in the wrong folder, have modified the "Working Directory" in the "Debugging" configuration settings, or otherwise changed the expected paths at runtime of the application. You should set a break-point on Model::CreateFromCMO and step into the code to find the exact problem.

Updating effects settings in a model

The Model class creates effects automatically for the loaded materials which are set to default lighting parameters. To update them, you use the Model::UpdateEffects method. Because the effects system is flexible, we must first enable C++ Run-Time Type Information (RTTI) in order to safely discover the various interfaces supported at runtime. From the drop-down menu, select Project / Properties. Set to "All Configurations" / "All Platforms". On the left-hand tree view select C/C++ / Language. Then set "Enable Run-Time Type Information" to "Yes". Click "OK".

settingsRTTI.png

In Game.cpp, add to the TODO of CreateDevice:

m_model->UpdateEffects([](IEffect* effect)
{
    auto lights = dynamic_cast<IEffectLights*>(effect);
    if (lights)
    {
        lights->SetLightingEnabled(true);
        lights->SetPerPixelLighting(true);
        lights->SetLightEnabled(0, true);
        lights->SetLightDiffuseColor(0, Colors::Gold);
        lights->SetLightEnabled(1, false);
        lights->SetLightEnabled(2, false);
    }

    auto fog = dynamic_cast<IEffectFog*>(effect);
    if (fog)
    {
        fog->SetFogEnabled(true);
        fog->SetFogColor(Colors::CornflowerBlue);
        fog->SetFogStart(3.f);
        fog->SetFogEnd(4.f);
    }
});

Build and run to get our cup with a colored light and fogging enabled.

screenshotCupFog.png

Technical notes

Here we've made use to two C++ concepts:
  1. The dynamic_cast operator allows us to safely determine if an effect in the model supports lighting and/or fog using the C++ run-time type checking. If the IEffect instance does not support the desired interface, the cast returns a nullptr and our code will skip those settings.
  2. This also used a lambda function (aka anonymous function) of the form [](IEffect* effect){ ... } which is a new C++11 syntax. We could have used a C-style call-back function, but this syntax is more direct.

Using DGSL shaders for the model

For this lesson, we made use of EffectFactory which will create BasicEffect, DualTextureEffect, or SkinnedEffect instances depending on the content of the loaded model file. With CMOs and the built-in Visual Studio 3D pipeline, you can instead make use of DGSLEffect by changing EffectFactory to DGSLEffectFactory.

In Game.cpp in the TODO section of CreateDevice, change

m_fxFactory.reset(new EffectFactory(m_d3dDevice.Get()));

to

m_fxFactory.reset(new DGSLEffectFactory(m_d3dDevice.Get()));

Note: This is why we used the abstract interface IEffectFactory rather than using std::unique_ptr<EffectFactory> in Game.h so that the variable could refer to either type of factory.

Build and run. If you still have the UpdateEffects code in place, you'll see the fog no longer appears although the light is colored.

screenShotCupNoFog.png

The lack of fog is because our "cup.cmo" makes use of the default built-in DGSL shaders lambert and phong which do not implement fog. The DGSLEffectFactory allows you to use Model and the Effect interface with the more complex custom DGSL shaders supported by the Visual Studio CMO pipeline where you use a visual editor to build pixel shaders.

http://msdn.microsoft.com/en-us/library/hh873117.aspx

Next lesson:Using skinned models

Further reading

DirectX Tool Kit docs EffectFactory, Effects, Model

Updated Wiki: Rendering a model

$
0
0
This lesson loads and draws models in 3D.

Setup

First create a new project using the instructions from the first two lessons: The basic game loop and
Adding the DirectX Tool Kit which we will use for this lesson.

Creating a model

Source assets for models are often stored in Autodesk FBX, Wavefront OBJ, or similar formats. A build process is used to convert them to a more run-time friendly format that is easier to load and render.

Visual Studio has a built-in system for converting a Wavefront OBJ or Autodesk FBX as part of the build process to a CMO, which you can read about here - http://msdn.microsoft.com/en-us/library/hh972446.aspx.

For this tutorial, we will instead make of use of the DirectXMesh (http://go.microsoft.com/fwlink/?LinkID=324981) meshconvert command-line tool. Start by saving cup._obj, cup.mtl, and cup.jpg into your new project's directory, and then from the top menu select Project / Add Existing Item.... Select "cup.jpg" and click "OK".
  1. Download the "Meshconvert.zip" from the DirectXMesh CodePlex site and extract the EXE into your project's folder.
  2. Open a command-prompt and then change to your project's folder. http://windows.microsoft.com/en-us/windows/command-prompt-faq
  3. Run the following command-line
meshconvert cup._obj -cmo -nodds -fliptc -y

Then from the top menu in Visual Studio select Project / Add Existing Item.... Select cup.cmo and click "OK".

Technical notes

  • The switch "-cmo" selects the Visual Studio Compiled Mesh Object runtime format as the output. The meshconver command-line tool also supports "-sdkmesh" and "-vbo". https://directxmesh.codeplex.com/wikipage?title=Geometry%20formats
  • The switch "-nodds" causes any texture file name references in the material information of the source file to stay in their original file format (such as .png or .jpg). Otherwise, it assumes you will be converting all the needed texture files to a .dds instead.
  • The switch "-fliptc" flips the direction of the texture coordinates. Since SimpleMath and these tutorials assume we are using right-handed viewing coordinates and the model was created using left-handed viewing coordinates we have to flip them to get the text in the texture to appear correctly.
  • The switch "-y" indicates that it is ok to overwrite the output file in case you run it multiple times.

Drawing a model

In the Game.h file, add the following variables to the bottom of the Game class's private declarations:

DirectX::SimpleMath::Matrix m_world;
DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

std::unique_ptr<DirectX::CommonStates> m_states;
std::unique_ptr<DirectX::IEffectFactory> m_fxFactory;
std::unique_ptr<DirectX::Model> m_model;

In Game.cpp, add to the TODO of CreateDevice:

m_states.reset(new CommonStates(m_d3dDevice.Get()));

m_fxFactory.reset(new EffectFactory(m_d3dDevice.Get()));

m_model = Model::CreateFromCMO(m_d3dDevice.Get(), L"cup.cmo", *m_fxFactory);

m_world = Matrix::Identity;

In Game.cpp, add to the TODO of CreateResources:

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

In Game.cpp, add to the TODO of OnDeviceLost:

m_states.reset();
m_fxFactory.reset();
m_model.reset();

In Game.cpp, add to the TODO of Render:

m_model->Draw(m_d3dContext.Get(), *m_states, m_world, m_view, m_proj);

In Game.cpp, add to the TODO of Update:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Build and run and you will see our cup model rendered with default lighting:

screenshotCup.png

Troubleshooting: If you get a runtime exception, then you may have the "cup.jpg" or "cup.cmo" in the wrong folder, have modified the "Working Directory" in the "Debugging" configuration settings, or otherwise changed the expected paths at runtime of the application. You should set a break-point on Model::CreateFromCMO and step into the code to find the exact problem.

Updating effects settings in a model

The Model class creates effects automatically for the loaded materials which are set to default lighting parameters. To update them, you use the Model::UpdateEffects method. Because the effects system is flexible, we must first enable C++ Run-Time Type Information (RTTI) in order to safely discover the various interfaces supported at runtime. From the drop-down menu, select Project / Properties. Set to "All Configurations" / "All Platforms". On the left-hand tree view select C/C++ / Language. Then set "Enable Run-Time Type Information" to "Yes". Click "OK".

settingsRTTI.png

In Game.cpp, add to the TODO of CreateDevice:

m_model->UpdateEffects([](IEffect* effect)
{
    auto lights = dynamic_cast<IEffectLights*>(effect);
    if (lights)
    {
        lights->SetLightingEnabled(true);
        lights->SetPerPixelLighting(true);
        lights->SetLightEnabled(0, true);
        lights->SetLightDiffuseColor(0, Colors::Gold);
        lights->SetLightEnabled(1, false);
        lights->SetLightEnabled(2, false);
    }

    auto fog = dynamic_cast<IEffectFog*>(effect);
    if (fog)
    {
        fog->SetFogEnabled(true);
        fog->SetFogColor(Colors::CornflowerBlue);
        fog->SetFogStart(3.f);
        fog->SetFogEnd(4.f);
    }
});

Build and run to get our cup with a colored light and fogging enabled.

screenshotCupFog.png

Technical notes

Here we've made use to two C++ concepts:
  1. The dynamic_cast operator allows us to safely determine if an effect in the model supports lighting and/or fog using the C++ run-time type checking. If the IEffect instance does not support the desired interface, the cast returns a nullptr and our code will skip those settings.
  2. This also used a lambda function (aka anonymous function) of the form [](IEffect* effect){ ... } which is a new C++11 syntax. We could have used a C-style call-back function, but this syntax is more direct.

Using DGSL shaders for the model

For this lesson, we made use of EffectFactory which will create BasicEffect, DualTextureEffect, or SkinnedEffect instances depending on the content of the loaded model file. With CMOs and the built-in Visual Studio 3D pipeline, you can instead make use of DGSLEffect by changing EffectFactory to DGSLEffectFactory.

In Game.cpp in the TODO section of CreateDevice, change

m_fxFactory.reset(new EffectFactory(m_d3dDevice.Get()));

to

m_fxFactory.reset(new DGSLEffectFactory(m_d3dDevice.Get()));

Note: This is why we used the abstract interface IEffectFactory rather than using std::unique_ptr<EffectFactory> in Game.h so that the variable could refer to either type of factory.

Build and run. If you still have the UpdateEffects code in place, you'll see the fog no longer appears although the light is colored since DGSLEffect does not support the fog interface.

screenShotCupNoFog.png

The lack of fog is because our "cup.cmo" makes use of the default built-in DGSL shaders lambert and phong which do not implement fog. The DGSLEffectFactory allows you to use Model and the Effect interface with the more complex custom DGSL shaders supported by the Visual Studio CMO pipeline where you use a visual editor to build pixel shaders.

http://msdn.microsoft.com/en-us/library/hh873117.aspx

Next lesson:Using skinned models

Further reading

DirectX Tool Kit docs EffectFactory, Effects, Model

Updated Wiki: Basic game math

$
0
0
This lesson will cover the basics of 3D transformations for graphics.

Positioning the camera

We've already used a simple camera setup in the 3D shapes lesson.

In the Game class we added variables for the projection matrix and the view matrix:

DirectX::SimpleMath::Matrix m_view;
DirectX::SimpleMath::Matrix m_proj;

In the CreateResources method, we used the backbuffer size to create a simple perspective view:

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

The m_proj matrix is created as a perspective camera using an field-of-view of PI/4 radians (which is 45 degrees), the aspect ratio of the backbuffer, the near-plane distance of 0.1 and a far-plane distance of 10.

The m_view matrix Is created as a view looking from the position (2,2,2) looking at the position (0,0,0) with an up vector of (0,1,0).

These two matrices handle transforming objects positioned in world coordinates and transforming them to view coordinates and then to screen coordinates.

Positioning an object

The 3D shapes lesson also provides an example of positioning an object.

In the Game class we added a variable for the world matrix for our 3D shape:

DirectX::SimpleMath::Matrix m_world;

We initially set it to the identity in CreateDevice:

m_world = Matrix::Identity

Then in Update we set the matrix to a rotation about the Z-axis based on time:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationZ(cosf(time) * 2.f);

Then later in the lesson we made it into a rotation about the Y-axes based on time:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationY(time);

The m_world matrix transforms the object's local (also known as model) coordinates into world coordinates.

Composing transformations

The power of affine transformation is that you can compose them by multiplying them together. In our 3D shapes lesson, we can modify the Update: to get more interesting motion for the planet earth.

For example if you modified Update as follows

float time = float(timer.GetTotalSeconds());

Vector3 pos = Vector3::Lerp(Vector3::Zero, Vector3::One, cos(time));
m_world = Matrix::CreateRotationY(time) * Matrix::CreateTranslation(pos);

Build and run to see the earth spinning and moving away and towards the camera.

If you flipped the order of the matrix multiply, you'll get much different results:

float time = float(timer.GetTotalSeconds());

Vector3 pos = Vector3::Lerp(Vector3::Zero, Vector3::One, cos(time));
m_world = Matrix::CreateTranslation( pos ) * Matrix::CreateRotationY( time);

Build and run to see the planet earth moving in a more complex pattern.

Transforming a point

For performance, the majority of the 3D transformations we use in rendering at computed on the GPU using vertex shaders based on the matrices we provide for world, view, and projection. There are times, however, when we want to compute a transformation on the CPU (such as doing collision detection or visibility culling). To transform a point using our variables above we should first concatenate our matrices into a single matrix that combines the transformations.

Matrix matrix = m_world * m_view * m_proj;

Vector3 point; // Our input from somewhere

Vector3 newPoint = Vector3::Transform( point, matrix );

Note: In our example we are only transforming a single point which means we are doing 3 matrix multiplies and 1 vector-matrix multiply. For a single point it might have been better to do 3 vector-matrix multiplies, but for most usage cases we are likely to transform more than just a single point. Ideally we'd use the array version of Transform to transform many points at once.

Moving the camera

We can animate the camera's position as well as the object's. In the 3D shapes lesson, we will change Update as follows:

float time = float(timer.GetTotalSeconds());

m_world = Matrix::CreateRotationY(time);

Vector3 cameraPos = Vector3::Lerp(Vector3(2.f, 2.f, 2.f),
    Vector3(2.f, 0.f, 2.f), cos(time));
m_view = Matrix::CreateLookAt(cameraPos, Vector3::Zero, Vector3::UnitY);
m_effect->SetView(m_view);

Build and run to see the camera moving up and down while still looking at the planet earth as the center of focus.

Next lesson:Collision detection

Further reading

DirectX Tool Kit docs SimpleMath

http://en.wikipedia.org/wiki/Radian

http://en.wikipedia.org/wiki/Graphical_projection

Updated Wiki: Mixing SimpleMath and DirectXMath

$
0
0
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.

http://en.wikipedia.org/wiki/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:

staticconst 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.

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

https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.utilities.xmfresnelterm.aspx

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

https://msdn.microsoft.com/en-us/library/windows/desktop/ee418728.aspx

Next lesson:Adding the DirectX Tool Kit for Audio

Further reading

http://blogs.msdn.com/b/chuckw/archive/2012/03/27/introducing-directxmath.aspx

http://blogs.msdn.com/b/chuckw/archive/2013/10/24/directxmath-3-06.aspx

http://blogs.msdn.com/b/chuckw/archive/2014/12/12/known-issues-directxmath-3-06.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/07/28/spherical-harmonics-math.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/05/01/xdsp-h.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/09/11/directxmath-sse-sse2-and-arm-neon.aspx

Updated Wiki: Getting Started

$
0
0
NEWS: This project is now hosted on GitHubhttps://github.com/Microsoft/DirectXTK. This site is being maintained for now, but please move to using GitHub.

This is the Getting Started tutorial for DirectX Tool Kit which introduces the reader to programming Direct3D 11 in C++.

Background

This tutorial assumes the reader is familiar with the basics of C++ programming using Microsoft Visual C++, including writing code, building applications, and basic debugging. Coding conventions here will make use of C++11 language features such as auto, simple lambdas (aka anonymous functions), and the standard smart-pointer std::unique_ptr, but will generally be otherwise 'core' C++ (i.e. language features supported in Visual C++ 2010).
This tutorial does not assume prior experience with Direct3D, but the reader should be familiar with the basic graphics concepts for DirectX or OpenGL. That said, you can get a long way using DirectX Tool Kit without much in the way of graphics experience.

One thing that many C++ developers, particularly game developers, may not be all that familiar with is "C++ Exception Handling". This is distinct from "Structured Exception Handling" (SEH) which some developers have seen in the past, and can leave an unfavorable impression of C++ EH. On both ARM and x64 native platforms, C++ EH is very efficient, although the x86 32-bit implementation does have some quirks. In any case, DirectX Tool Kit uses C++ Exception Handling for most error conditions, just as the Standard Template Library (STL) does and the default behavior of the new operator. Note that Direct3D 11 and DirectX Tool Kit are not "WinRT" APIs, so we do not make use of the new C++/CX language extensions. DirectX Tool Kit is a 'pure' C++ library, which is why it's not directly usable by Visual Basic, C# or HTML+JavaScript applications.

Audience

These tutorials are written with game development in mind as the target application since games are an excellent fit for the 'immersive DirectX app' model. Keep in mind, however, that the majority of the functionality in the DirectX Tool Kit is applicable to DirectX graphics programming in general for both game and non-game applications.

Software Setup

For learning purposes, these instructions are going to focus on the following setup:
  • Visual Studio 2013 Community, Professional, Premium, or Ultimate (Update 4)
  • Windows 7 or Windows 8.x
We will be using a Win32 desktop application project template in order to support developers using Windows 7, but all these techniques and APIs apply to Windows Store apps, Windows phone 8.x, "Universal apps" for Windows 8.1 & Windows Phone 8.1, and Xbox One as well.

Tutorials

The basic game loop
Adding the DirectX Tool Kit

Graphics

Sprites and textures
More tricks with sprites
Drawing text
Simple rendering
3D shapes
Rendering a model
Using skinned models
Using advanced shaders
Applying lightmaps
Creating custom shaders with DGSL
Writing custom shaders

Input

Game controller input

Math

Using the SimpleMath library
Basic game math
Collision detection
Picking
Mixing SimpleMath and DirectXMath

Audio

Adding the DirectX Tool Kit for Audio
Adding audio to your project
Creating and playing sounds
Using positional audio

Resources

http://blogs.msdn.com/b/chuckw/archive/2014/04/07/book-recommendations.aspx

http://blogs.msdn.com/b/chuckw/archive/2011/07/11/getting-started-with-direct3d-11.aspx

http://blogs.msdn.com/b/chuckw/archive/2012/09/17/dual-use-coding-techniques-for-games.aspx

Updated Wiki: DirectXTK

$
0
0
NEWS: This project is now hosted on GitHubhttps://github.com/Microsoft/DirectXTK. This site is being maintained for now, but please move to using GitHub.

Headers

Public headers are in the Inc folder of the distribution package.

Namespace

All the functions in the library are in the DirectX C++ namespace.

Note: The Xbox One exclusive application XBoxDDSTextureLoader functions are in the Xbox C++ namespace

Modules

Tools

MakeSpriteFont - builds .spritefont data files for use with SpriteFont class
XWBTool - builds .xwb XACT-style wave banks for use with WaveBank class

Building

This code is designed to build with Visual Studio 2010 or later. It requires the Windows 8.x SDK for functionality such as the DirectXMath library and the DXGI 1.2 headers. Visual Studio 2012 or later already include the Windows 8.x SDK, but Visual Studio 2010 users must install the standalone Windows 8.1 SDK http://go.microsoft.com/fwlink/?LinkID=323507. Details on using the Windows 8.1 SDK with VS 2010 are described on the Visual C++ Team Blog http://blogs.msdn.com/b/vcblog/archive/2012/11/23/using-the-windows-8-sdk-with-visual-studio-2010-configuring-multiple-projects.aspx and the required .props files are included in the DirectX Tool Kit package.

These components are designed to work without requiring any content from the DirectX SDK. For details, see "Where is the DirectX SDK"? http://msdn.microsoft.com/en-us/library/ee663275.aspx and "Where is the DirectX SDK (2013 Edition)?" http://blogs.msdn.com/b/chuckw/archive/2013/07/01/where-is-the-directx-sdk-2013-edition.aspx

HLSL shaders

The distribution package comes with a set of Src\Shader\*.inc files containing the compiled HLSL shaders which are included into the DirectXTK static library. They can be rebuilt if using a newer HLSL FXC.EXE or if the .fx or .hlsl files in the library are modified.

Open a Developer Command Prompt (installed with Visual Studio), and change to the directory containing CompileShaders.cmd (i.e. ...\DirectXTK\Src\Shaders)
http://windows.microsoft.com/en-us/windows/command-prompt-faq

Enter the following command-line after changing to the appropriate directory:
CompileShaders

Then rebuild the DirectXTK library to update with the latest version of the shaders.

Xbox One XDK

Xbox One exclusive application developers using the Xbox One XDK need to generate the Src\Shaders\Compiled\XboxOne*.inc files to build the library as they are not included in the distribution package. They should be generated with the matching FXC compiler from the Xbox One XDK. While they will continue to work if outdated, a mismatch will cause runtime compilation overhead that would otherwise be avoided.

Open a Xbox One XDK Command Prompt, and change to the directory containing CompileShaders.cmd (i.e. ...\DirectXTK\Src\Shaders)
http://windows.microsoft.com/en-us/windows/command-prompt-faq

Enter the following command-line after changing to the appropriate directory:
CompileShaders xbox

Then build the Xbox One XDK version of the DirectXTK library.

Adding to a VS solution

Using project-to-project references

In your application's solution, right-click on the Solution and use "Add \ Existing Project..." to add the appropriate .vcxproj file to your solution.
  • DirectXTK_Windows10 is for universal Windows apps building with VS 2015 targeting Windows 10
  • DirectXTK_Windows81 is for Windows Store C++ apps building with VS 2013 targeting Windows 8.1 / RT 8.1
  • DirectXTK_Windows8 is for Windows Store C++ apps building with VS 2012 targeting Windows 8 / RT
  • DirectXTK_WindowsPhone81 is for Windows phone 8.1 C++ apps building with VS 2013 Update 2 or later.
  • DirectXTK_XAMLSilverlight_WindowsPhone81 is for Windows phone Silverlight 8.1 C++ apps building with VS 2013 Update 2 or later.
  • DirectXTK_WindowsPhone8 is for Windows phone 8 C++ apps building with VS 2012 or VS 2013 and the Windows Phone 8.0 SDK
  • DirectXTK_Desktop_2015 is for Windows desktop C++ applications building with VS 2015
  • DirectXTK_Desktop_2013 is for Windows desktop C++ applications building with the VS 2013 Express for Desktop, VS 2013 Community, VS 2013 Professional or higher
  • DirectXTK_Desktop_2012 is for Windows desktop C++ applications building with VS 2012 Express for Desktop, VS 2012 Professional or higher
  • DirectXTK_Desktop_2010 is for Windows desktop C++ applications building with VS 2010 using the Windows 8.1 SDK
  • DirectXTK_XboxOneXDK is for Xbox One exclusive C++ applications building with VS 2012 using the Xbox One XDK
  • DirectXTK_XboxOneADK is for Xbox One hub apps C++ building with VS 2012 using the Xbox One ADK
In your application's project, right-click on the Project and use "References...", then "Add New Reference...", and then check the DirectXTK project name and click OK. For a Windows Store app, Windows phone, or Xbox One solution, you need to set Reference Assembly Output to false since DirectXTK is a static C++ library and not a WinRT component.

settingsROA.PNG

In your application's project settings, on the "C++ / General" page set Configuration to "All Configurations", set Platform to "All Platforms", and then add the relative path to DirectXTK\inc;--assuming you have the DirectXTK folder in the same directory as your sln file, it should be $(SolutionDir)\DirectXTK\inc;--to the Additional Include Directories properties. Click Apply.

settingsAID.PNG

When using VS 2010 with the Windows 8.x SDK, or when using VS 2012 with the Windows 8.1 SDK, you'll need to apply the correct .props files to your projects as well as use the correct DirectXTK project. http://blogs.msdn.com/b/vcblog/archive/2012/11/23/using-the-windows-8-sdk-with-visual-studio-2010-configuring-multiple-projects.aspx

See Audio for additional information when setting up Windows desktop projects to use DirectXTK for Audio.

http://blogs.msdn.com/b/vcblog/archive/2010/05/03/flexible-project-to-project-references.aspx

Using NuGet package manager

Alternatively you can use NuGet to install one of the DirectX Tool Kit packages. Use Project / Manage NuGet Packages... then select "Online" and search for "DirectX Tool Kit".
  • Use Id: directxtk_desktop_2013 for Windows desktop C++ applications building with the VS 2013 Express for Desktop, VS 2013 Community, VS 2013 Professional or higher
  • Use Id: directxtk_windowsstore_8_1 for Windows Store C++ apps building with VS 2013 targeting Windows 8.1 / RT 8.1
  • Use Id: directxtk_windowsphone_8_1 for Windows phone 8.1 C++ apps or Windows phone Silverlight 8.1 C++ apps building with VS 2013 Update 2 or later.
  • Use Id: directxtk_windowsphone_8 for Windows phone 8 C++ apps building with VS 2012 or VS 2013 and the Windows Phone 8.0 SDK.
You should use the NuGet interface to check for updates if you have an older version installed.

https://www.nuget.org/packages/directxtk_desktop_2013/
https://www.nuget.org/packages/directxtk_windowsstore_8_1/
https://www.nuget.org/packages/directxtk_windowsphone_8_1/
https://www.nuget.org/packages/directxtk_windowsphone_8/

Related tutorial:Adding the DirectX Tool Kit

Content pipeline

To use the Visual Studio 2012 or later graphics assets tools in the build system, be sure to add them to your project. http://msdn.microsoft.com/en-us/library/hh972446.aspx

The graphics assets tools are not present in the Express editions of Visual Studio 2012. They are present in the Visual Studio 2013 Express for Windows and Community editions, but not in VS 2013 Express for Windows Desktop.

Note: When adding .spritefont, .sdkmesh, or .xwb files to your Windows Store app or Windows phone app project, you need to manually set the file properties to "Content: Yes" for all configurations to have these files included in your AppX package. .dds files and other image file formats are automatically detected as a media file and are included as content by default.

Error handling

DirectXTK makes use of C++ exception handling which should be enabled by the application via the /EHsc compiler switch. In Visual Studio, this is set in the project settings under "C++ / Code Generation" with Enable C++ Exceptions set to "Yes (/EHsc)" for all configurations.

http://msdn.microsoft.com/en-us/library/4t3saedz.aspx
http://msdn.microsoft.com/en-us/library/d14azbfh.aspx
http://blogs.msdn.com/b/chuckw/archive/2012/09/17/dual-use-coding-techniques-for-games.aspx
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

Smart-pointers and reference counting

DirectXTK encourages and makes use of a number of smart-pointers to simplify resource lifetime tracking.
  • std::unique_ptr - A smart-pointer that has exactly one 'owner' of the memory
  • std::shared_ptr - A smart-pointer that tracks memory use with reference counting
  • Microsoft::WRL::ComPtr - A COM smart-pointer for reference count management very similar to ATL's CComPtr
http://msdn.microsoft.com/en-us/library/hh279674.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ff485846.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ff485839.aspx#smartptr
http://msdn.microsoft.com/en-us/library/windows/desktop/bb205070.aspx

Implementation notes

DirectXTK's implementation makes extensive use of the pImpl idiom. This keeps the public headers slim and minimizes inter-module dependencies.

// SpriteBatch.h public headerclass SpriteBatch
{
public:
    ...

private:
    // Private implementation.class Impl;

    std::unique_ptr<Impl> pImpl;

    // Prevent copying.
    SpriteBatch(SpriteBatch const&);
    SpriteBatch& operator= (SpriteBatch const&);
};

This also allows use to allocate the pImpl class internally using _aligned_malloc(x,16); so that we can use the DIrectXMath aligned XMVECTOR and XMMATRIX types directly in the implementation.

http://en.wikipedia.org/wiki/Opaque_pointer

Updated Wiki: Version History

$
0
0
NEWS: This project is now hosted on GitHubhttps://github.com/Microsoft/DirectXTK. This site is being maintained for now, but please move to using GitHub.

July 1, 2015
  • Added Keyboard, Mouse class
  • Support for loading pre-lit models with SDKMESH
  • GamePad implemented using Windows.Gaming.Input for Windows 10
  • DirectXTK for Audio updates for xWMA support with XAudio 2.9
  • Added FindGlyph and GetSpriteSheet methods to SpriteFont

March 27, 2015
  • Added projects for Windows apps Technical Preview
  • GamePad temporarily uses 'null' device for universal Windows application platform

February 25, 2015 (NuGet version 2015.2.25.1)
  • DirectXTK for Audio updates
    • breaking change pitch now defined as -1 to 1 with 0 as the default
    • One-shot Play method with volume, pitch, and pan
    • GetMasterVolume/SetMasterVolume method for AudioEngine
    • Fix for compact wavebank validation
    • Improved voice cleanup and shutdown
  • Minor code cleanup and C++11 =default/=delete usage

January 26, 2015 (NuGet version 2015.1.26.1)
  • GamePad class: emulate XInputEnable behavior for XInput 9.1.0
  • DirectXTK for Audio fix for Stop followed by Play doing a proper restart
  • DirectXTK for Audio fix when using XAudio 2.7 on a system with no audio device
  • Updates for Xbox One platform support
  • Minor code cleanup and C99 printf string conformance

November 24, 2014 (NuGet version 2014.11.24.1, 2014.11.24.2)
  • SimpleMath fix for Matrix operator !=
  • DirectXTK for Audio workaround for XAudio 2.7 on Windows 7 problem
  • Updates for Windows phone 8.1 platform support
  • Updates for Visual Studio 2015 Technical Preview
  • Minor code cleanup

October 28, 2014
  • Model support for loading from VBO files
  • Model render now sets samplers on slots 0,1 by default for dual-texture effects
  • Updates for Xbox One platform support
  • Minor code cleanup

September 5, 2014
  • GamePad class: gamepad controller helper using XInput on Windows, IGamepad for Xbox One
  • SimpleMath updates; Matrix billboard methods; breaking change: Matrix::Identity() -> Matrix::Identity
  • SpriteBatch new optional SetViewport method
  • SpriteFont fix for white-space character rendering optimization
  • DDSTextureLoader fix for auto-gen mipmaps for volume textures
  • Explicit calling-convention annotation for public headers
  • Updates for Xbox One platform support
  • Minor code and project cleanup

July 15, 2014 (NuGet version 2014.7.15.1)
  • DirectXTK for Audio and XWBTool fixes
  • Updates to Xbox One platform support

April 3, 2014
  • Windows phone 8.1 platform support

February 24, 2014
  • DirectXHelper: new utility header with MapGuard and public version of SetDebugObjectName template
  • DDSTextureLoader: Optional support for auto-gen mipmaps
  • DDSTextureLoader/ScreenGrab: support for Direct3D 11 video formats including legacy "YUY2" DDS files
  • GeometricPrimtive: Handedness fix for tetrahedron, octahedron, dodecahedron, and icosahedron
  • SpriteBatch::SetRotation(DXGI_MODE_ROTATION_UNSPECIFIED) to disable viewport matrix
  • XboxDDSTextureLoader: optional forceSRGB parameter

January 24, 2014
  • DirectXTK for Audio updated with voice management and optional mastering volume limiter
  • Added orientation rotation support to SpriteBatch
  • Fixed a resource leak with GetDefaultTexture() used by some Effects
  • Code cleanup (removed DXGI_1_2_FORMATS control define; d2d1.h workaround not needed; ScopedObject typedef removed)

December 24, 2013
  • DirectXTK for Audio
  • Xbox One platform support
  • MakeSpriteFont tool updated with more progress feedback when capturing large fonts
  • Minor updates for .SDKMESH Model loader
  • Fixed bug in .CMO Model loader when handling multiple textures
  • Improved debugging output

October 28, 2013
  • Updated for Visual Studio 2013 and Windows 8.1 SDK RTM
  • Added DGSLEffect, DGSLEffectFactory, VertexPositionNormalTangentColorTexture, and VertexPositionNormalTangentColorTextureSkinning
  • Model loading and effect factories support loading skinned models
  • MakeSpriteFont now has a smooth vs. sharp antialiasing option: /sharp
  • Model loading from CMOs now handles UV transforms for texture coordinates
  • A number of small fixes for EffectFactory
  • Minor code and project cleanup
  • Added NO_D3D11_DEBUG_NAME compilation define to control population of Direct3D debug layer names for debug builds

July 1, 2013
  • VS 2013 Preview projects added and updates for DirectXMath 3.05 vectorcall
  • Added use of sRGB WIC metadata for JPEG, PNG, and TIFF
  • SaveToWIC functions updated with new optional setCustomProps parameter and error check with optional targetFormat

May 30, 2013
  • Added more GeometricPrimitives: Cone, Tetrahedron, Octahedron, Dodecahedron, Icosahedron
  • Updated to support loading new metadata from DDS files (if present)
  • Fixed bug with loading of WIC 32bpp RGBE format images
  • Fixed bug when skipping mipmaps in a 1D or 2D array texture DDS file

February 22, 2013 (NuGet version 2.22.13.23)
  • Added SimpleMath header
  • Fixed bug that prevented properly overriding EffectFactory::CreateTexture
  • Fixed forceSRGB logic in DDSTextureLoader and WICTextureLoader
  • Break circular reference chains when using SpriteBatch with a setCustomShaders lambda
  • Updated projects with /fp:fast for all configs, /arch:SSE2 for Win32 configs
  • Sensibly named .pdb output files
  • Added WIC_USE_FACTORY_PROXY build option (uses WindowsCodecs.dll entrypoint rather than CoCreateInstance)

January 25, 2013
  • GeometricPrimitive support for left-handed coordinates and drawing with custom effects
  • Model, ModelMesh, and ModelMeshPart added with loading of rigid non-animating models from .CMO and .SDKMESH files
  • EffectFactory helper class added

December 11, 2012
  • Ex versions of DDSTextureLoader and WICTextureLoader
  • Removed use of ATL's CComPtr in favor of WRL's ComPtr for all platforms to support VS Express editions
  • Updated VS 2010 project for official 'property sheet' integration for Windows 8.0 SDK
  • Minor fix to CommonStates for Feature Level 9.1
  • Tweaked AlphaTestEffect.cpp to work around ARM NEON compiler codegen bug
  • Added dxguid.lib as a default library for Debug builds to resolve GUID link issues

November 15, 2012
  • Added support for WIC2 when available on Windows 8 and Windows 7 with KB 2670838
  • Cleaned up warning level 4 warnings

October 30, 2012
  • Added project files for Windows phone 8

October 12, 2012
  • Added PrimitiveBatch for drawing user primitives
  • Debug object names for all D3D resources (for PIX and debug layer leak reporting)

October 2, 2012
  • Added ScreenGrab module
  • Added CreateGeoSphere for drawing a geodesic sphere
  • Put DDSTextureLoader and WICTextureLoader into the DirectX C++ namespace

September 7, 2012
  • Renamed project files for better naming consistency
  • Updated WICTextureLoader for Windows 8 96bpp floating-point formats
  • Win32 desktop projects updated to use Windows Vista (0x0600) rather than Windows 7 (0x0601) APIs
  • Tweaked SpriteBatch.cpp to workaround ARM NEON compiler codegen bug

May 31, 2012
  • Updated Metro project for Visual Studio 2012 Release Candidate changes
  • Cleaned up x64 Debug configuration warnings and switched to use "_DEBUG" instead of "DEBUG"
  • Minor fix for DDSTextureLoader's retry fallback that can happen with 10level9 feature levels

May 2, 2012
  • Added SpriteFont implementation and the MakeSpriteFont utility

March 29, 2012
  • WICTextureLoader updated with Windows 8 WIC native pixel formats

March 6, 2012
  • Fix for too much temp memory used by WICTextureLoader
  • Add separate Visual Studio 11 projects for Desktop vs. Metro builds

March 5, 2012
  • Bug fix for SpriteBatch with batches > 2048

February 24, 2012
  • Original release

Updated Wiki: Audio

$
0
0
NEWS: This project is now hosted on GitHubhttps://github.com/Microsoft/DirectXTK. This site is being maintained for now, but please move to using GitHub.

The DirectXTK for Audio components implement a low-level audio API similar to XNA Game Studio's Microsoft.Xna.Framework.Audio. This consists of the following classes all declared in the Audio.h header (in the Inc folder of the distribution):
  • AudioEngine - This class represents an XAudio2 audio graph, device, and mastering voice.
  • SoundEffect - A container class for sound resources which can be loaded from .wav files.
  • SoundEffectInstance - Provides a single playing, paused, or stopped instance of a sound
  • DynamicSoundEffectInstance - SoundEffectInstance where the application provides the audio data on demand
  • WaveBank - A container class for sound resources packaged into an XACT-style .xwb wave bank.
  • AudioListener, AudioEmitter - Utility classes used with SoundEffectInstance::Apply3D.
Note: DirectXTK for Audio uses XAudio 2. It does not make use of the legacy XACT Engine, XACT Cue, or XACT SoundBank.

Related tutorials:Adding the DirectX Tool Kit for Audio, Adding audio to your project, Creating and playing sounds, Using positional audio

Header

#include <Audio.h>

Initialization

The first step in using DirectXTK for Audio is to create the AudioEngine, which creates an XAudio2 interface, an XAudio2 mastering voice, and other global resources.

// This is only needed in Windows desktop apps
CoInitializeEx( nullptr, COINIT_MULTITHREADED );

AUDIO_ENGINE_FLAGS eflags = AudioEngine_Default;
#ifdef _DEBUG
eflags = eflags | AudioEngine_Debug;
#endif
std::unique_ptr<AudioEngine> audEngine( new AudioEngine( eflags ) );

Per-frame processing

The application should call Update () every frame to allow for per-frame engine updates, such as one-shot voice management. This could also be done in a worker thread rather than on the main rendering thread.

if ( !audEngine->Update() )
{
    // No audio device is activeif ( audEngine->IsCriticalError() )
    {
        ...
    }    
}

Update() returns false if no audio is actually playing (either due to there being no audio device on the system at the time AudioEngine was created, or because XAudio2 encountered a Critical Error--typically due to speakers being unplugged). Calls to various DirectXTK for Audio methods can still be made in this state but no actual audio processing will take place. See AudioEngine for more information.

Loading and a playing a looping sound

Creating SoundEffectInstances allows full control over the playback, and are provided with a dedicated XAudio2 source voice. This allows control of playback, looping, volume control, panning, and pitch-shifting.

std::unique_ptr<SoundEffect> soundEffect( new SoundEffect( audEngine.get(), L"Sound.wav" ) );
auto effect = soundEffect->CreateInstance();

...

effect->Play( true );

Playing one-shots

A common way to play sounds is to trigger them in a 'fire-and-forget' mode. This is done by calling SoundEffect::Play() rather than creating a SoundEffectInstance. These use XAudio2 source voices managed by AudioEngine, are cleaned up automatically when they finish playing, and can overlap in time. One-shot sounds cannot be looped or have positional 3D effects.

std::unique_ptr<SoundEffect> soundEffect( new SoundEffect( audEngine.get(), L"Explosion.wav" ) );
soundEffect->Play();

...

soundEffect->Play();

Applying 3D audio effects to a sound

DirectXTK for Audio supports positional 3D audio with optional environmental reverb effects using X3DAudio.

AUDIO_ENGINE_FLAGS eflags =  AudioEngine_EnvironmentalReverb
            | AudioEngine_ReverbUseFilters;
#ifdef _DEBUG
eflags = eflags | AudioEngine_Debug;
#endif
std::unique_ptr<AudioEngine> audEngine( new AudioEngine( eflags ) );
audEngine->SetReverb( Reverb_ConcertHall );

...

std::unique_ptr<SoundEffect> soundEffect( new SoundEffect( audEngine.get(), L"Sound.wav" ) );
auto effect = soundEffect->CreateInstance( SoundEffectInstance_Use3D | SoundEffectInstance_ReverbUseFilters );

...

effect->Play(true);

...

AudioListener listener;
listener.SetPosition( ... );

AudioEmitter emitter;
emitter.SetPosition( ... );

effect->Apply3D( listener, emitter );

Note: A C++ exception is thrown if you call Apply3D for a SoundEffectInstance that was not created with SoundEffectInstance_Use3D

Using wave banks

Rather than loading individual .wav files, a more efficient method is to package them into a "wave bank". This allows for more efficient loading and memory organization. DirectXTK for Audio's WaveBank class can be used to play one-shots or to create SoundEffectInstances from 'in-memory' wave banks.

std::unique_ptr<WaveBank> wb( new WaveBank( audEngine.get(), L"wavebank.xwb" ) );

A SoundEffectInstance can be created from a wavebank referencing a particular wave in the bank:

auto effect = wb->CreateInstance( 10 );
if ( !effect )
    // Error (invalid index for wave bank)

...

effect->Play( true );

One-shot sounds can also be played directly from the wave bank.

wb->Play( 2 );
wb->Play( 6 );

XACT3-style "wave banks" can be created by using the XWBTool command-line tool, or they can be authored using XACT3 in the DirectX SDK. Note that the XWBTool will not perform any format conversions or compression, so more full-featured options are better handled with the XACT3 GUI or XACTBLD, or it can be used on .wav files already compressed by adpcmencode.exe, xwmaencode.exe, xma2encode.exe, etc.

xwbtool -o wavebank.xwb Sound.wav Explosion.wav Music.wav

DirectXTK for Audio does not make use of the XACT engine, nor does it make use of XACT "sound banks" .xsb or "cues". We only use .xwb wave banks as a method for packing .wav data.

Voice management

Each instance of a SoundEffectInstance will allocate it's own source voice when played, which won't be released until it is destroyed. Each time a one-shot sound is played from a SoundEffect or a WaveBank, a voice will be created or a previously used one-shot voice will be reused if possible.

See AudioEngine for more information.

Platform support

Windows 8.x, Windows 10, Windows phone 8.x, and Xbox One all include XAudio 2.8 or later. Therefore, the standard DirectXTK.lib includes DirectXTK for Audio for all these platforms:
  • DirectXTK_Windows10
  • DirectXTK_Windows81
  • DirectXTK_Windows8
  • DirectXTK_WindowsPhone81
  • DirectXTK_XAMLSilverlight_WindowsPhone81
  • DirectXTK_WindowsPhone8
  • DirectXTK_XboxOneXDK
  • DirectXTK_XboxOneADK
For Windows desktop applications targeting Windows 8.x or later, you can make use of XAudio 2.8. The DirectXTKAudioWin8.lib contains the XAudio 2.8 version of DirectXTK for Audio, while DirectXTK.lib for Windows desktop contains only the math/graphics components. To support Windows desktop applications on Windows 7 and Windows Vista, we must make use XAudio 2.7, the legacy DirectX SDK, and the legacy DirectX End-User Runtime Redistribution packages (aka DirectSetup). The DirectXTKAudioDX.lib is the XAudio 2.7 version of DirectXTK for Audio.

DirectXTK_Desktop_2015, DirectXTK_Desktop_2013, DirectXTK_Desktop_2012, and DirectXTK_Desktop_2010 do not include DirectXTK for Audio. To add DirectXTK for Audio support for a Windows desktop application, you must also add one of the following projects from the Audio folder of the distribution to your solution and Add a Reference to it (see DirectXTK for more details).

When targeting Windows 8.x or later:
  • DirectXTKAudio_Desktop_2012_Win8 - DirectXTK for Audio using VS 2012 and XAudio 2.8
  • DirectXTKAudio_Desktop_2013_Win8 - DirectXTK for Audio using VS 2013 and XAudio 2.8
  • DirectXTKAudio_Desktop_2015_Win8 - DirectXTK for Audio using VS 2015 and XAudio 2.8

When targeting Windows Vista, Windows 7, or Windows 8.x:
  • DirectXTKAudio_Desktop_2010_DXSDK - DirectXTK for Audio project for VS 2010 + Windows 8.1 SDK + legacy DirectXTK using XAudio 2.7
  • DirectXTKAudio_Desktop_2012_DXSDK - DirectXTK for Audio project for VS 2012 + Windows 8.0 SDK + legacy DirectXTK using XAudio 2.7
  • DirectXTKAudio_Desktop_2013_DXSDK - DirectXTK for Audio project for VS 2013 + Windows 8.1 SDK + legacy DirectXTK using XAudio 2.7
VS 2010 Note: We only support DirectXTK for Audio with the legacy DirectX SDK due to some issues with using the VS 2010 toolset and with Windows 8.x SDK WinRT headers.

http://msdn.microsoft.com/en-us/library/windows/desktop/ee415802.aspx
http://support.microsoft.com/kb/2728613
http://msdn.microsoft.com/en-us/library/windows/desktop/ee663275.aspx

DirectXTK makes use of the latest Direct3D 11.1 headers available in the Windows 8.x SDK, and there are a number of file conflicts between the Windows 8.x SDK and the legacy DirectX SDK. Therefore, when building for down-level support with XAudio 2.7, Audio.h explicitly includes the DirectX SDK version of XAudio2 headers with a full path name. These reflect the default install locations, and if you have installed it elsewhere you will need to update this header. The *_DXSDK.vcxproj files use the DXSDK_DIR environment variable, so only the Audio.h references need updating for an alternative location.

// Using XAudio 2.7 requires the DirectX SDK
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\comdecl.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\xaudio2.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\xaudio2fx.h>
#pragma warning(push)
#pragma warning( disable : 4005 )
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\x3daudio.h>

Content Pipeline

Note: When adding .xwb files to your Windows Store app or Windows phone app project, you need to manually set the file properties to "Content: Yes" for all configurations to have these files included in your AppX package. .wav files are automatically detected as a media file and are included as content by default.

Threading model

The DirectXTK for Audio methods assume it is always called from a single thread. This is generally either the main thread or a worker thread dedicated to audio processing. The XAudio2 engine itself makes use of lock-free mechanism to make it 'thread-safe'.

Note that IVoiceNotify::OnBufferEnd is called from XAudio2's thread, so the callback must be very fast and use thread-safe operations.

Further reading

http://blogs.msdn.com/b/chuckw/archive/2012/05/15/learning-xaudio2.aspx
http://blogs.msdn.com/b/chuckw/archive/2012/04/02/xaudio2-and-windows-8-consumer-preview.aspx
http://xbox.create.msdn.com/en-US/education/catalog/utility/soundlab

Updated Wiki: Mouse

$
0
0
NEWS: This project is now hosted on GitHubhttps://github.com/Microsoft/DirectXTK. This site is being maintained for now, but please move to using GitHub https://github.com/Microsoft/DirectXTK/wiki/DirectXTK

This is a helper for simplified mouse tracking modeled after the XNA C# Mouse class.

Header

#include <Mouse.h>

Initialization

Mouse is a singleton.

std::unique_ptr<Mouse> mouse( new Mouse );
For exception safety, it is recommended you make use of the C++ RAII pattern and use a std::unique_ptr.

Integration

For Windows desktop applications, the application needs to make the appropriate calls during the main WndProc message processing:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_MOUSEMOVE:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP:
    case WM_MOUSEWHEEL:
    case WM_XBUTTONDOWN:
    case WM_XBUTTONUP:
        Mouse::ProcessMessage(message, wParam, lParam);
        break;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}

For universal Windows apps or Windows Store apps, you need to call SetWindow and SetDpi in the appropriate places.

void App::SetWindow(CoreWindow^ window)
{
    mouse->SetWindow(window);
}

void App::OnDpiChanged(DisplayInformation^ sender, Object^ args)
{
    mouse->SetDpi(sender->LogicalDpi);
}

Basic use

GetState queries the current state of the mouse.

auto state = mouse->GetState();

if ( state.leftButton )
   // Left button is down

XMFLOAT2 mousePosInPixels( float(m.x), float(m.y) );
// This is the absolute position of the mouse relative// to the upper-left corner of the window

Button state tracker

A common pattern is to trigger an action when a mouse button is pressed or released, but you don't want to trigger the action every single frame if the button is held down for more than a single frame. This helper class simplifies this.

std::unique_ptr<Mouse::ButtonStateTracker> tracker( new Mouse::ButtonStateTracker );

...

auto state = mouse->GetState();
tracker->Update( state );

if ( tracker->rightButton == Mouse::ButtonStateTracker::PRESSED )
    // Take an action when Right mouse button is first pressed, but don't do// it again until the button is released and then pressed again

When resuming from a pause or suspend, be sure to call Reset on the tracker object to clear the state history.

Remark

The mouse scroll wheel value is accumulated. To reset the value to 0, use ResetScrollWheelValue.

Threading model

The Mouse class should be thread-safe with the exception of the ProcessMessage which should only be called in your windows message loop.

Platform notes

The Xbox One platform doesn't support pointer or mouse input devices.

For Windows Store, universal Windows apps, and Windows phone touch/pointer devices are captured as mouse movement.

Viewing all 874 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>