OSDN Git Service

Release Preview 対応
[shooting3/shootinggame.git] / ShootingGame / DirectXBase.cpp
index 9ff707a..4225a75 100644 (file)
@@ -6,16 +6,18 @@
 //// Copyright (c) Microsoft Corporation. All rights reserved
 
 #include "pch.h"
-#include "DirectXBase.h" 
+#include "DirectXBase.h"
 
 using namespace Windows::UI::Core;
 using namespace Windows::Foundation;
 using namespace Microsoft::WRL;
+using namespace Windows::Graphics::Display;
 using namespace D2D1;
 
 // Constructor.
 DirectXBase::DirectXBase() :
-    m_dpi(-1.0f)
+    m_dpi(-1.0f),
+    m_numBuffers(2)
 {
 }
 
@@ -84,7 +86,7 @@ void DirectXBase::CreateDeviceResources()
     // Note the ordering should be preserved.
     // Don't forget to declare your application's minimum required feature level in its
     // description.  All applications are assumed to support 9.1 unless otherwise stated.
-    D3D_FEATURE_LEVEL featureLevels[] = 
+    D3D_FEATURE_LEVEL featureLevels[] =
     {
         D3D_FEATURE_LEVEL_11_1,
         D3D_FEATURE_LEVEL_11_0,
@@ -154,12 +156,12 @@ void DirectXBase::SetDpi(float dpi)
     {
         // Save the DPI of this display in our class.
         m_dpi = dpi;
-        
+
         // Update Direct2D's stored DPI.
         m_d2dContext->SetDpi(m_dpi, m_dpi);
 
-        // Often a DPI change implies a window size change. In some cases Windows will issues
-        // both a size changed event and a DPI changed event. In this case, the resulting bounds 
+        // Often a DPI change implies a window size change. In some cases Windows will issue
+        // both a size changed event and a DPI changed event. In this case, the resulting bounds
         // will not change, and the window resize code will only be executed once.
         UpdateForWindowSizeChange();
     }
@@ -168,6 +170,12 @@ void DirectXBase::SetDpi(float dpi)
 // This routine is called in the event handler for the view SizeChanged event.
 void DirectXBase::UpdateForWindowSizeChange()
 {
+    // Only handle window size changed if there is no pending DPI change.
+    if (m_dpi != DisplayProperties::LogicalDpi)
+    {
+        return;
+    }
+
     if (m_window->Bounds.Width  != m_windowBounds.Width ||
         m_window->Bounds.Height != m_windowBounds.Height)
     {
@@ -187,25 +195,24 @@ void DirectXBase::CreateWindowSizeDependentResources()
     m_windowBounds = m_window->Bounds;
 
     // If the swap chain already exists, resize it.
-    if(m_swapChain != nullptr)
+    if (m_swapChain != nullptr)
     {
         DX::ThrowIfFailed(
-            m_swapChain->ResizeBuffers(2, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0)
+            m_swapChain->ResizeBuffers(m_numBuffers, 0, 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0)
             );
     }
-    // Otherwise, create a new one.
-    else
+    else    // Otherwise, create a new one.
     {
         // Allocate a descriptor.
         DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
         swapChainDesc.Width = 0;                                     // use automatic sizing
         swapChainDesc.Height = 0;
         swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;           // this is the most common swapchain format
-        swapChainDesc.Stereo = false; 
+        swapChainDesc.Stereo = false;
         swapChainDesc.SampleDesc.Count = 1;                          // don't use multi-sampling
         swapChainDesc.SampleDesc.Quality = 0;
         swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
-        swapChainDesc.BufferCount = 2;                               // use double buffering to enable flip
+        swapChainDesc.BufferCount = m_numBuffers;                    // use multiple buffering to enable flip
         swapChainDesc.Scaling = DXGI_SCALING_NONE;
         swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all Metro style apps must use this SwapEffect
         swapChainDesc.Flags = 0;
@@ -213,7 +220,7 @@ void DirectXBase::CreateWindowSizeDependentResources()
         // Once the desired swap chain description is configured, it must be created on the same adapter as our D3D Device
 
         // First, retrieve the underlying DXGI Device from the D3D Device.
-        ComPtr<IDXGIDevice1>  dxgiDevice;
+        ComPtr<IDXGIDevice1> dxgiDevice;
         DX::ThrowIfFailed(
             m_d3dDevice.As(&dxgiDevice)
             );
@@ -231,23 +238,23 @@ void DirectXBase::CreateWindowSizeDependentResources()
             );
 
         // Obtain the final swap chain for this window from the DXGI factory.
+        CoreWindow^ window = m_window.Get();
         DX::ThrowIfFailed(
             dxgiFactory->CreateSwapChainForCoreWindow(
                 m_d3dDevice.Get(),
-                reinterpret_cast<IUnknown*>(m_window),
+                reinterpret_cast<IUnknown*>(window),
                 &swapChainDesc,
                 nullptr,    // allow on all displays
                 &m_swapChain
                 )
             );
 
-        // Ensure that DXGI does not queue more than one frame at a time. This both reduces 
-        // latency and ensures that the application will only render after each VSync, minimizing 
+        // Ensure that DXGI does not queue too many frames. This reduces latency and
+        // ensures that the application will only render after each VSync, minimizing
         // power consumption.
         DX::ThrowIfFailed(
-            dxgiDevice->SetMaximumFrameLatency(1)
+            dxgiDevice->SetMaximumFrameLatency(m_numBuffers - 1)
             );
-
     }
 
     // Obtain the backbuffer for this window which will be the final 3D rendertarget.
@@ -273,7 +280,7 @@ void DirectXBase::CreateWindowSizeDependentResources()
 
     // Create a descriptor for the depth/stencil buffer.
     CD3D11_TEXTURE2D_DESC depthStencilDesc(
-        DXGI_FORMAT_D24_UNORM_S8_UINT, 
+        DXGI_FORMAT_D24_UNORM_S8_UINT,
         backBufferDesc.Width,
         backBufferDesc.Height,
         1,
@@ -292,10 +299,11 @@ void DirectXBase::CreateWindowSizeDependentResources()
         );
 
     // Create a DepthStencil view on this surface to use on bind.
+    auto viewDesc = CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D);
     DX::ThrowIfFailed(
         m_d3dDevice->CreateDepthStencilView(
             depthStencil.Get(),
-            &CD3D11_DEPTH_STENCIL_VIEW_DESC(D3D11_DSV_DIMENSION_TEXTURE2D),
+            &viewDesc,
             &m_depthStencilView
             )
         );
@@ -311,10 +319,10 @@ void DirectXBase::CreateWindowSizeDependentResources()
     // Set the current viewport using the descriptor.
     m_d3dContext->RSSetViewports(1, &viewport);
 
-    // Now we set up the Direct2D render target bitmap linked to the swapchain. 
-    // Whenever we render to this bitmap, it will be directly rendered to the 
+    // Now we set up the Direct2D render target bitmap linked to the swapchain.
+    // Whenever we render to this bitmap, it will be directly rendered to the
     // swapchain associated with the window.
-    D2D1_BITMAP_PROPERTIES1 bitmapProperties = 
+    D2D1_BITMAP_PROPERTIES1 bitmapProperties =
         BitmapProperties1(
             D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
             PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
@@ -354,17 +362,17 @@ void DirectXBase::Present()
     parameters.pDirtyRects = nullptr;
     parameters.pScrollRect = nullptr;
     parameters.pScrollOffset = nullptr;
-    
+
     // The first argument instructs DXGI to block until VSync, putting the application
     // to sleep until the next VSync. This ensures we don't waste any cycles rendering
     // frames that will never be displayed to the screen.
     HRESULT hr = m_swapChain->Present1(1, 0, &parameters);
 
-    // If the device was removed either by a disconnect or a driver upgrade, we 
+    // If the device was removed either by a disconnect or a driver upgrade, we
     // must completely reinitialize the renderer.
     if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
     {
-        Initialize(m_window, m_dpi);
+        Initialize(m_window.Get(), m_dpi);
     }
     else
     {