Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- App.cpp
- */
- #include "pch.h"
- #include <agile.h>
- #include <dxgi1_4.h>
- #include <d3d11_3.h>
- #include <DirectXMath.h>
- using namespace Windows::ApplicationModel;
- using namespace Windows::ApplicationModel::Core;
- using namespace Windows::ApplicationModel::Activation;
- using namespace Windows::UI::Core;
- using namespace Windows::UI::Input;
- using namespace Windows::System;
- using namespace Windows::Foundation;
- using namespace Windows::Graphics::Display;
- using namespace Microsoft::WRL;
- using namespace DirectX;
- static float MOUSE_SCALE = 100.0f;
- static inline void ChkTrue(bool x)
- {
- assert(x);
- if (!x) abort();
- }
- static inline void ChkOk(HRESULT hr)
- {
- ChkTrue(hr == S_OK);
- }
- ref class AppView sealed : public IFrameworkView
- {
- public:
- // IFrameworkView Methods.
- virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
- virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
- virtual void Load(Platform::String^ entryPoint);
- virtual void Run();
- virtual void Uninitialize();
- private:
- // Event handlers.
- void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
- void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
- void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
- void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
- void OnDpiChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
- void OnOrientationChanged(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
- void OnDisplayContentsInvalidated(Windows::Graphics::Display::DisplayInformation^ sender, Platform::Object^ args);
- void OnPointerPressed(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs ^args);
- void OnPointerReleased(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs ^args);
- void OnPointerWheelChanged(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs ^args);
- void OnMouseMoved(Windows::Devices::Input::MouseDevice ^sender, Windows::Devices::Input::MouseEventArgs ^args);
- // Internal methods.
- void HandleDeviceLost();
- void CreateDeviceResources();
- void CreateWindowSizeDependentResources();
- DXGI_MODE_ROTATION ComputeDisplayRotation();
- float ConvertDipsToPixels(float dips);
- void UpdatePointerButtons(Windows::UI::Core::PointerEventArgs^ args);
- // Window state.
- bool m_windowClosed = false;
- bool m_windowVisible = true;
- // Cached window and display properties.
- Platform::Agile<Windows::UI::Core::CoreWindow> m_window;
- float m_dpi = -1.0f;
- // Direct3D objects.
- Microsoft::WRL::ComPtr<ID3D11Device3> m_device;
- Microsoft::WRL::ComPtr<ID3D11DeviceContext3> m_context;
- Microsoft::WRL::ComPtr<IDXGISwapChain3> m_swapChain;
- // Direct3D rendering objects. Required for 3D.
- Microsoft::WRL::ComPtr<ID3D11RenderTargetView1> m_renderTargetView;
- Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_depthStencilView;
- D3D11_VIEWPORT m_viewport = D3D11_VIEWPORT();
- // Cached device properties.
- D3D_FEATURE_LEVEL m_featureLevel = D3D_FEATURE_LEVEL_9_1;
- Windows::Foundation::Size m_renderTargetSize = Windows::Foundation::Size();
- Windows::Foundation::Size m_outputSize = Windows::Foundation::Size();
- Windows::Foundation::Size m_logicalSize = Windows::Foundation::Size();
- Windows::Graphics::Display::DisplayOrientations m_nativeOrientation = Windows::Graphics::Display::DisplayOrientations::None;
- Windows::Graphics::Display::DisplayOrientations m_currentOrientation = Windows::Graphics::Display::DisplayOrientations::None;
- // Transforms used for display orientation.
- DirectX::XMFLOAT4X4 m_orientationTransform;
- // Mouse state.
- float MouseDeltaX = 0.0f;
- float MouseDeltaY = 0.0f;
- float MouseDeltaWheel = 0.0f;
- bool MouseButtonL = false;
- bool MouseButtonM = false;
- bool MouseButtonR = false;
- // Previous pointer position. Used to compute deltas.
- Windows::UI::Core::CoreCursor^ _defaultCursor;
- Windows::UI::Core::CoreCursor^ _cursor;
- // TODO: Add application specific state here!
- };
- /**
- Startup view provider class.
- */
- ref class FrameworkViewSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
- {
- public:
- virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView() { return ref new AppView(); }
- private:
- };
- /**
- Application entry point.
- */
- [Platform::MTAThread]
- int main(Platform::Array<Platform::String^>^ args)
- {
- CoreApplication::Run(ref new FrameworkViewSource());
- return 0;
- }
- /**
- Initialize the view.
- */
- void AppView::Initialize(CoreApplicationView^ applicationView)
- {
- // TODO: Add application specific initialization code here!
- applicationView->Activated += ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &AppView::OnActivated);
- }
- /**
- Associate a CoreWindow with the view.
- */
- void AppView::SetWindow(CoreWindow^ window)
- {
- m_window = window;
- m_logicalSize = Windows::Foundation::Size(window->Bounds.Width, window->Bounds.Height);
- window->SizeChanged += ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &AppView::OnWindowSizeChanged);
- window->VisibilityChanged += ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &AppView::OnVisibilityChanged);
- window->Closed += ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &AppView::OnWindowClosed);
- window->PointerPressed += ref new Windows::Foundation::TypedEventHandler<Windows::UI::Core::CoreWindow ^, Windows::UI::Core::PointerEventArgs ^>(this, &AppView::OnPointerPressed);
- window->PointerReleased += ref new Windows::Foundation::TypedEventHandler<Windows::UI::Core::CoreWindow ^, Windows::UI::Core::PointerEventArgs ^>(this, &AppView::OnPointerReleased);
- window->PointerWheelChanged += ref new Windows::Foundation::TypedEventHandler<Windows::UI::Core::CoreWindow ^, Windows::UI::Core::PointerEventArgs ^>(this, &AppView::OnPointerWheelChanged);
- Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved += ref new Windows::Foundation::TypedEventHandler<Windows::Devices::Input::MouseDevice ^, Windows::Devices::Input::MouseEventArgs ^>(this, &AppView::OnMouseMoved);
- _defaultCursor = m_window->PointerCursor;
- _cursor = _defaultCursor;
- DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
- m_nativeOrientation = currentDisplayInformation->NativeOrientation;
- m_currentOrientation = currentDisplayInformation->CurrentOrientation;
- m_dpi = currentDisplayInformation->LogicalDpi;
- currentDisplayInformation->DpiChanged += ref new TypedEventHandler<DisplayInformation^, Object^>(this, &AppView::OnDpiChanged);
- currentDisplayInformation->OrientationChanged += ref new TypedEventHandler<DisplayInformation^, Object^>(this, &AppView::OnOrientationChanged);
- DisplayInformation::DisplayContentsInvalidated += ref new TypedEventHandler<DisplayInformation^, Object^>(this, &AppView::OnDisplayContentsInvalidated);
- // TODO: Add application specific SetWindow() code here!
- }
- /**
- Create the D3D swap chain, etc.
- */
- void AppView::Load(Platform::String^ entryPoint)
- {
- CreateDeviceResources();
- CreateWindowSizeDependentResources();
- // TODO: Add application specific Load() code here!
- }
- /**
- Run the app.
- */
- void AppView::Run()
- {
- while (!m_windowClosed)
- {
- if (m_windowVisible)
- {
- CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
- // Reset the viewport to target the whole screen.
- m_context->RSSetViewports(1, &m_viewport);
- // Reset render targets to the screen.
- ID3D11RenderTargetView *const targets[1] = { m_renderTargetView.Get() };
- m_context->OMSetRenderTargets(1, targets, m_depthStencilView.Get());
- // Clear the back buffer and depth stencil view.
- FLOAT clearColor[] = { 0.25f, 0.15f, 0.5f, 1 };
- m_context->ClearRenderTargetView(m_renderTargetView.Get(), clearColor);
- m_context->ClearDepthStencilView(m_depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
- // Get device rotation.
- DXGI_MODE_ROTATION swapChainRotation = DXGI_MODE_ROTATION_IDENTITY;
- m_swapChain->GetRotation(&swapChainRotation); // can fail (see docs) but ignore & just use default
- // TODO: Add application specific Run() code here!
- // NOTE: In particular, this is where your rendering call will happen.
- // Reset mouse look state for next frame.
- Windows::UI::Core::CoreWindow::GetForCurrentThread()->PointerCursor = _cursor;
- MouseDeltaX = 0.0f;
- MouseDeltaY = 0.0f;
- MouseDeltaWheel = 0.0f;
- // 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.
- DXGI_PRESENT_PARAMETERS parameters = { 0 };
- HRESULT hrPresent = m_swapChain->Present1(1, 0, ¶meters);
- // Discard the contents of the render target.
- // This is a valid operation only when the existing contents will be entirely
- // overwritten. If dirty or scroll rects are used, this call should be removed.
- m_context->DiscardView1(m_renderTargetView.Get(), nullptr, 0);
- // Discard the contents of the depth stencil.
- m_context->DiscardView1(m_depthStencilView.Get(), nullptr, 0);
- // If the device was removed either by a disconnection or a driver upgrade, we
- // must recreate all device resources.
- if (hrPresent == DXGI_ERROR_DEVICE_REMOVED ||
- hrPresent == DXGI_ERROR_DEVICE_RESET)
- {
- HandleDeviceLost();
- }
- else
- {
- ChkOk(hrPresent);
- }
- }
- else
- {
- CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
- }
- }
- }
- /**
- Uninitialize the view.
- */
- void AppView::Uninitialize()
- {
- // nothing!
- }
- /**
- Handle app view activation.
- */
- void AppView::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
- {
- CoreWindow::GetForCurrentThread()->Activate();
- }
- /**
- Handle window size change.
- */
- void AppView::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
- {
- Size logicalSize(sender->Bounds.Width, sender->Bounds.Height);
- if (m_logicalSize != logicalSize)
- {
- m_logicalSize = logicalSize;
- CreateWindowSizeDependentResources();
- }
- }
- /**
- Handle window visibility change.
- */
- void AppView::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
- {
- m_windowVisible = args->Visible;
- }
- /**
- Handle window close.
- */
- void AppView::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
- {
- m_windowClosed = true;
- }
- /**
- Handle DPI change.
- */
- void AppView::OnDpiChanged(DisplayInformation^ sender, Object^ args)
- {
- if (sender->LogicalDpi != m_dpi)
- {
- m_dpi = sender->LogicalDpi;
- // When the display DPI changes, the logical size of the window
- // (measured in Dips) also changes and needs to be updated.
- m_logicalSize = Windows::Foundation::Size(m_window->Bounds.Width, m_window->Bounds.Height);
- CreateWindowSizeDependentResources();
- }
- }
- /**
- Handle orientation change.
- */
- void AppView::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
- {
- if (m_currentOrientation != sender->CurrentOrientation)
- {
- m_currentOrientation = sender->CurrentOrientation;
- CreateWindowSizeDependentResources();
- }
- }
- /**
- */
- void AppView::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
- {
- // The D3D Device is no longer valid if the default adapter changed
- // since the device was created or if the device has been removed.
- // First, get the information for the default adapter from when the
- // device was created.
- ComPtr<IDXGIDevice3> dxgiDevice;
- ChkOk(m_device.As(&dxgiDevice));
- ComPtr<IDXGIAdapter> deviceAdapter;
- ChkOk(dxgiDevice->GetAdapter(&deviceAdapter));
- ComPtr<IDXGIFactory4> deviceFactory;
- ChkOk(deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory)));
- ComPtr<IDXGIAdapter1> previousDefaultAdapter;
- ChkOk(deviceFactory->EnumAdapters1(0, &previousDefaultAdapter));
- DXGI_ADAPTER_DESC1 previousDesc;
- ChkOk(previousDefaultAdapter->GetDesc1(&previousDesc));
- // Next, get the information for the current default adapter.
- ComPtr<IDXGIFactory4> currentFactory;
- ChkOk(CreateDXGIFactory1(IID_PPV_ARGS(¤tFactory)));
- ComPtr<IDXGIAdapter1> currentDefaultAdapter;
- ChkOk(currentFactory->EnumAdapters1(0, ¤tDefaultAdapter));
- DXGI_ADAPTER_DESC1 currentDesc;
- ChkOk(currentDefaultAdapter->GetDesc1(¤tDesc));
- // If the adapter LUIDs don't match, or if the device reports
- // that it has been removed, a new D3D device must be created.
- if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart ||
- previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart ||
- FAILED(m_device->GetDeviceRemovedReason()))
- {
- // Release references to resources related to the old device.
- dxgiDevice = nullptr;
- deviceAdapter = nullptr;
- deviceFactory = nullptr;
- previousDefaultAdapter = nullptr;
- // Create a new device and swap chain.
- HandleDeviceLost();
- }
- }
- /**
- Create the Direct3D device.
- */
- void AppView::CreateDeviceResources()
- {
- UINT creationFlags = 0;
- #if defined(_DEBUG)
- HRESULT hrSdkLayersCheck = D3D11CreateDevice(
- nullptr,
- D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
- 0,
- D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
- nullptr, // Any feature level will do.
- 0,
- D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
- nullptr, // No need to keep the D3D device reference.
- nullptr, // No need to know the feature level.
- nullptr // No need to keep the D3D device context reference.
- );
- if (SUCCEEDED(hrSdkLayersCheck))
- {
- // If the project is in a debug build, enable debugging via SDK Layers with this flag.
- creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
- }
- #endif
- // This array defines the set of DirectX hardware feature levels this app will support.
- // 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.
- static const D3D_FEATURE_LEVEL featureLevels[] =
- {
- D3D_FEATURE_LEVEL_12_1,
- D3D_FEATURE_LEVEL_12_0,
- D3D_FEATURE_LEVEL_11_1,
- D3D_FEATURE_LEVEL_11_0,
- D3D_FEATURE_LEVEL_10_1,
- D3D_FEATURE_LEVEL_10_0,
- D3D_FEATURE_LEVEL_9_3,
- D3D_FEATURE_LEVEL_9_2,
- D3D_FEATURE_LEVEL_9_1
- };
- // Create the Direct3D 11 API device object and a corresponding context.
- ComPtr<ID3D11Device> device;
- ComPtr<ID3D11DeviceContext> context;
- HRESULT hr = D3D11CreateDevice(
- nullptr, // Specify nullptr to use the default adapter.
- D3D_DRIVER_TYPE_HARDWARE, // Create a device using the hardware graphics driver.
- 0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
- creationFlags, // Set debug and Direct2D compatibility flags.
- featureLevels, // List of feature levels this app can support.
- ARRAYSIZE(featureLevels), // Size of the list above.
- D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
- &device, // Returns the Direct3D device created.
- &m_featureLevel, // Returns feature level of device created.
- &context // Returns the device immediate context.
- );
- if (FAILED(hr))
- {
- // Initialization failed, fall back to the WARP device.
- ChkOk(
- D3D11CreateDevice(
- nullptr,
- D3D_DRIVER_TYPE_WARP,
- 0,
- creationFlags,
- featureLevels,
- ARRAYSIZE(featureLevels),
- D3D11_SDK_VERSION,
- &device,
- &m_featureLevel,
- &context));
- }
- // Store pointers to the Direct3D 11.3 API device and immediate context.
- ChkOk(device.As(&m_device));
- ChkOk(context.As(&m_context));
- // Create the Direct2D device object and a corresponding context.
- ComPtr<IDXGIDevice3> dxgiDevice;
- ChkOk(m_device.As(&dxgiDevice));
- }
- /**
- This method determines the rotation between the display device's native
- orientation and the current display orientation.
- */
- DXGI_MODE_ROTATION AppView::ComputeDisplayRotation()
- {
- // Note: m_nativeOrientation can only be Landscape or Portrait even though
- // the DisplayOrientations enum has other values.
- switch (m_nativeOrientation)
- {
- case DisplayOrientations::Landscape:
- {
- switch (m_currentOrientation)
- {
- case DisplayOrientations::Landscape: return DXGI_MODE_ROTATION_IDENTITY;
- case DisplayOrientations::Portrait: return DXGI_MODE_ROTATION_ROTATE270;
- case DisplayOrientations::LandscapeFlipped: return DXGI_MODE_ROTATION_ROTATE180;
- case DisplayOrientations::PortraitFlipped: return DXGI_MODE_ROTATION_ROTATE90;
- }
- }
- break;
- case DisplayOrientations::Portrait:
- {
- switch (m_currentOrientation)
- {
- case DisplayOrientations::Landscape: return DXGI_MODE_ROTATION_ROTATE90;
- case DisplayOrientations::Portrait: return DXGI_MODE_ROTATION_IDENTITY;
- case DisplayOrientations::LandscapeFlipped: return DXGI_MODE_ROTATION_ROTATE270;
- case DisplayOrientations::PortraitFlipped: return DXGI_MODE_ROTATION_ROTATE180;
- }
- }
- break;
- }
- return DXGI_MODE_ROTATION_UNSPECIFIED;
- }
- /**
- Converts a length in device-independent pixels to a length in physical pixels.
- */
- float AppView::ConvertDipsToPixels(float dips)
- {
- static const float dipsPerInch = 96.0f;
- return floorf(dips * m_dpi / dipsPerInch + 0.5f); // Round to nearest integer.
- }
- /**
- These resources need to be recreated every time the window size is changed.
- */
- void AppView::CreateWindowSizeDependentResources()
- {
- // Clear the previous window size specific context.
- ID3D11RenderTargetView* nullViews[] = { nullptr };
- m_context->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
- m_renderTargetView = nullptr;
- m_depthStencilView = nullptr;
- m_context->Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr);
- // Calculate the necessary render target size in pixels.
- // The std::max calls make sure we don't pass zero to D3D.
- m_outputSize.Width = (std::max)(1.0f, ConvertDipsToPixels(m_logicalSize.Width));
- m_outputSize.Height = (std::max)(1.0f, ConvertDipsToPixels(m_logicalSize.Height));
- // The width and height of the swap chain must be based on the window's
- // natively-oriented width and height. If the window is not in the native
- // orientation, the dimensions must be reversed.
- DXGI_MODE_ROTATION displayRotation = ComputeDisplayRotation();
- bool swapDimensions = displayRotation == DXGI_MODE_ROTATION_ROTATE90 || displayRotation == DXGI_MODE_ROTATION_ROTATE270;
- m_renderTargetSize.Width = swapDimensions ? m_outputSize.Height : m_outputSize.Width;
- m_renderTargetSize.Height = swapDimensions ? m_outputSize.Width : m_outputSize.Height;
- if (m_swapChain != nullptr)
- {
- // The swap chain already exists, resize it.
- HRESULT hr = m_swapChain->ResizeBuffers(
- 2, // Double-buffered swap chain.
- lround(m_renderTargetSize.Width),
- lround(m_renderTargetSize.Height),
- DXGI_FORMAT_B8G8R8A8_UNORM,
- 0);
- if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
- {
- // If the device was removed for any reason, a new device
- // and swap chain will need to be created.
- HandleDeviceLost();
- // Everything is set up now. Do not continue execution of this
- // method. HandleDeviceLost will reenter this method and correctly
- // set up the new device.
- return;
- }
- else
- {
- ChkOk(hr);
- }
- }
- else
- {
- // Create a new swap chain using the same adapter as the existing device.
- DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
- swapChainDesc.Width = lround(m_renderTargetSize.Width); // Match the size of the window.
- swapChainDesc.Height = lround(m_renderTargetSize.Height);
- swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // This is the most common swap chain format.
- 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 minimize latency.
- swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // All Windows Store apps must use this SwapEffect.
- swapChainDesc.Flags = 0;
- swapChainDesc.Scaling = DXGI_SCALING_STRETCH;
- swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
- // This sequence obtains the DXGI factory that was used to create the Direct3D device above.
- ComPtr<IDXGIDevice3> dxgiDevice;
- ChkOk(m_device.As(&dxgiDevice));
- ComPtr<IDXGIAdapter> dxgiAdapter;
- ChkOk(dxgiDevice->GetAdapter(&dxgiAdapter));
- ComPtr<IDXGIFactory4> dxgiFactory;
- ChkOk(dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory)));
- ComPtr<IDXGISwapChain1> swapChain;
- ChkOk(
- dxgiFactory->CreateSwapChainForCoreWindow(
- m_device.Get(),
- reinterpret_cast<IUnknown*>(m_window.Get()),
- &swapChainDesc,
- nullptr,
- &swapChain));
- ChkOk(swapChain.As(&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 power consumption.
- ChkOk(dxgiDevice->SetMaximumFrameLatency(1));
- }
- // Set the proper orientation for the swap chain and
- // the transform for rendering to the rotated swap chain.
- ChkOk(m_swapChain->SetRotation(displayRotation));
- // 0-degree Z-rotation
- static const XMFLOAT4X4 Rotation0(
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- // 90-degree Z-rotation
- static const XMFLOAT4X4 Rotation90(
- 0.0f, 1.0f, 0.0f, 0.0f,
- -1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- // 180-degree Z-rotation
- static const XMFLOAT4X4 Rotation180(
- -1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, -1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- // 270-degree Z-rotation
- static const XMFLOAT4X4 Rotation270(
- 0.0f, -1.0f, 0.0f, 0.0f,
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f);
- switch (displayRotation)
- {
- case DXGI_MODE_ROTATION_IDENTITY: m_orientationTransform = Rotation0; break;
- case DXGI_MODE_ROTATION_ROTATE90: m_orientationTransform = Rotation270; break;
- case DXGI_MODE_ROTATION_ROTATE180: m_orientationTransform = Rotation180; break;
- case DXGI_MODE_ROTATION_ROTATE270: m_orientationTransform = Rotation90; break;
- default: ChkTrue(false);
- }
- // Create a render target view of the swap chain back buffer.
- ComPtr<ID3D11Texture2D1> backBuffer;
- ChkOk(m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer)));
- ChkOk(m_device->CreateRenderTargetView1(backBuffer.Get(), nullptr, &m_renderTargetView));
- // Create a depth stencil view for use with 3D rendering if needed.
- CD3D11_TEXTURE2D_DESC1 depthStencilDesc(
- DXGI_FORMAT_D24_UNORM_S8_UINT,
- lround(m_renderTargetSize.Width),
- lround(m_renderTargetSize.Height),
- 1, // This depth stencil view has only one texture.
- 1, // Use a single mipmap level.
- D3D11_BIND_DEPTH_STENCIL);
- ComPtr<ID3D11Texture2D1> depthStencil;
- ChkOk(m_device->CreateTexture2D1(&depthStencilDesc, nullptr, &depthStencil));
- CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
- ChkOk(m_device->CreateDepthStencilView(depthStencil.Get(), &depthStencilViewDesc, &m_depthStencilView));
- // Set the 3D rendering viewport to target the entire window.
- m_viewport = CD3D11_VIEWPORT(0.0f, 0.0f, m_renderTargetSize.Width, m_renderTargetSize.Height);
- m_context->RSSetViewports(1, &m_viewport);
- // TODO: Add application specific device resource creation here!
- }
- /**
- Recreate all device resources and set them back to the current state.
- */
- void AppView::HandleDeviceLost()
- {
- m_swapChain = nullptr;
- CreateDeviceResources();
- CreateWindowSizeDependentResources();
- }
- /**
- */
- void AppView::OnPointerPressed(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs ^args)
- {
- // NOTE: If implementing ImGui wrap this in the following condition
- // if (!ImGui::GetIO().WantCaptureMouse) { ... }
- // to prevent our mouse look behavior when an ImGui control has
- // captured the pointer.
- // This assumes we're implementing some kind of "mouse look" functionality,
- // i.e. if the pointer is pressed we're dragging the view direction around.
- // By settings _cursor to nullptr we will hide the mouse pointer (see the
- // AppView::Run method) and trigger calculation of mouse pointer deltas in
- // the AppView::OnMouseMoved method.
- UpdatePointerButtons(args);
- _cursor = nullptr;
- }
- /**
- */
- void AppView::OnPointerReleased(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs ^args)
- {
- UpdatePointerButtons(args);
- _cursor = _defaultCursor;
- }
- /**
- */
- void AppView::OnMouseMoved(Windows::Devices::Input::MouseDevice ^sender, Windows::Devices::Input::MouseEventArgs ^args)
- {
- if (_cursor == nullptr)
- {
- float dx = float(args->MouseDelta.X) / MOUSE_SCALE;
- float dy = float(args->MouseDelta.Y) / MOUSE_SCALE;
- MouseDeltaX = (std::max)(-1.0f, (std::min)(+1.0f, dx));
- MouseDeltaY = (std::max)(-1.0f, (std::min)(+1.0f, dy));
- }
- }
- /**
- */
- void AppView::OnPointerWheelChanged(Windows::UI::Core::CoreWindow ^sender, Windows::UI::Core::PointerEventArgs ^args)
- {
- auto d = args->CurrentPoint->Properties->MouseWheelDelta;
- auto nd = float(d) / float(WHEEL_DELTA * MOUSE_SCALE);
- MouseDeltaWheel = (std::max)(-1.0f, (std::min)(+1.0f, nd));
- }
- /**
- */
- void AppView::UpdatePointerButtons(Windows::UI::Core::PointerEventArgs^ args)
- {
- auto device = args->CurrentPoint->PointerDevice;
- if (device->PointerDeviceType == Windows::Devices::Input::PointerDeviceType::Mouse)
- {
- auto properties = args->CurrentPoint->Properties;
- MouseButtonL = properties->IsLeftButtonPressed;
- MouseButtonM = properties->IsMiddleButtonPressed;
- MouseButtonR = properties->IsRightButtonPressed;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement