Direct3D Rendering Cookbook
上QQ阅读APP看书,第一时间看更新

Creating device-dependent resources

In this recipe, we will see how the included sample framework deals with the initialization of device-dependent Direct3D resources and how our custom classes can make use of this throughout this book.

Getting ready

We continue from where we left off in the Using the sample rendering framework recipe.

How to do it…

We will review the base class's implementation of the CreateDeviceDependentResources function, and then look at how to implement overrides within the descending classes.

  1. The following protected virtual D3DApplicationBase.CreateDeviceDependentResources implementation is assigned as an event-handler to the DeviceManager.OnInitialize event.
    protected virtual void CreateDeviceDependentResources(DeviceManager deviceManager)
    {
        if (_swapChain != null)
        {
            // Release the swap chain
            RemoveAndDispose(ref _swapChain);
            // Force reinitialize size dependent resources
            SizeChanged(true);
        }
    }
  2. Within your class descending from D3DApplicationBase (or D3DApplicationDesktop and so on), be sure to call the base implementation, and then initialize the resources as required. The following code snippet shows how initializing a Direct3D shader resource might look like.
    public class D3DApp: Common.D3DApplicationDesktop
    {
      Texture2D myShaderResource;
    
    protected override  void  
      CreateDeviceDependentResources(
        DeviceManager deviceManager)
      {
        // Call base implementation
        base.CreateDeviceDependentResources(deviceManager);
        // Release existing resources
        RemoveAndDispose(ref myShaderResource);
    
        // Retrieve device reference
        var device = deviceManager.Direct3DDevice;
    
        // Create a shader resource view
        myShaderResource = ToDispose( 
           ShaderResourceView.FromFile(device, "Texture.png")); 
        ...
      }
    ...

How it works…

By handling the device manager's OnInitialize event our Direct3D applications descendent class is able to create its Direct3D device resources when the device is ready, or whenever the device instance is recreated.

The D3DApplicationBase base class provides the minimal code necessary to ensure that any existing swap chain is released and then recreated by triggering the D3DApplicationBase.OnSizeChanged event. Unless completely overriding the base implementation, it is important that our overrides call this base implementation.

After calling the base implementation, our own code needs to release any resources that may have been created previously by using the SharpDX.Component.RemoveAndDispose method. Then we retrieve the currently active Direct3D device from the device manager and continue to create any necessary resources.

With this approach it is important to ensure that any resources that wrap a native COM object are passed to ToDispose, so that they are correctly registered to be released when our class instance is disposed.

Tip

SharpDX classes that wrap COM objects all descend from SharpDX.ComObject. This class provides access to the native pointer and also a number of helpful variations on the native IUnknown interface's QueryInterface method.