Added C# project & refactored names
51
Camera Renderer.sln
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.31702.278
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Camera Renderer CS", "Camera-Renderer_cs\Camera Renderer CS.csproj", "{33A294C7-3146-405C-BCCA-C4E36985D0D7}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|ARM = Debug|ARM
|
||||||
|
Debug|ARM64 = Debug|ARM64
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|ARM = Release|ARM
|
||||||
|
Release|ARM64 = Release|ARM64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|ARM.Build.0 = Debug|ARM
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|ARM64.Deploy.0 = Debug|ARM64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|x64.Deploy.0 = Debug|x64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Debug|x86.Deploy.0 = Debug|x86
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|ARM.ActiveCfg = Release|ARM
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|ARM.Build.0 = Release|ARM
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|ARM.Deploy.0 = Release|ARM
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|ARM64.Deploy.0 = Release|ARM64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|x64.Build.0 = Release|x64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|x64.Deploy.0 = Release|x64
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|x86.Build.0 = Release|x86
|
||||||
|
{33A294C7-3146-405C-BCCA-C4E36985D0D7}.Release|x86.Deploy.0 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {44D20E12-11F5-4631-9882-CF0DEE92FBED}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
7
Camera-Renderer_cpp/App.xaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<Application
|
||||||
|
x:Class="CameraDirect_cpp.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:CameraDirect_cpp">
|
||||||
|
|
||||||
|
</Application>
|
125
Camera-Renderer_cpp/App.xaml.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
//
|
||||||
|
// App.xaml.cpp
|
||||||
|
// Implementation of the App class.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "DirectXPage.xaml.h"
|
||||||
|
|
||||||
|
using namespace CameraDirect_cpp;
|
||||||
|
|
||||||
|
using namespace Platform;
|
||||||
|
using namespace Windows::ApplicationModel;
|
||||||
|
using namespace Windows::ApplicationModel::Activation;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
using namespace Windows::Foundation::Collections;
|
||||||
|
using namespace Windows::Storage;
|
||||||
|
using namespace Windows::UI::Xaml;
|
||||||
|
using namespace Windows::UI::Xaml::Controls;
|
||||||
|
using namespace Windows::UI::Xaml::Controls::Primitives;
|
||||||
|
using namespace Windows::UI::Xaml::Data;
|
||||||
|
using namespace Windows::UI::Xaml::Input;
|
||||||
|
using namespace Windows::UI::Xaml::Interop;
|
||||||
|
using namespace Windows::UI::Xaml::Media;
|
||||||
|
using namespace Windows::UI::Xaml::Navigation;
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the singleton application object. This is the first line of authored code
|
||||||
|
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||||
|
/// </summary>
|
||||||
|
App::App()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
|
||||||
|
Resuming += ref new EventHandler<Object^>(this, &App::OnResuming);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||||
|
/// will be used when the application is launched to open a specific file, to display
|
||||||
|
/// search results, and so forth.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="e">Details about the launch request and process.</param>
|
||||||
|
void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
|
||||||
|
{
|
||||||
|
#if _DEBUG
|
||||||
|
if (IsDebuggerPresent())
|
||||||
|
{
|
||||||
|
DebugSettings->EnableFrameRateCounter = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
|
||||||
|
|
||||||
|
// Do not repeat app initialization when the Window already has content,
|
||||||
|
// just ensure that the window is active
|
||||||
|
if (rootFrame == nullptr)
|
||||||
|
{
|
||||||
|
// Create a Frame to act as the navigation context and associate it with
|
||||||
|
// a SuspensionManager key
|
||||||
|
rootFrame = ref new Frame();
|
||||||
|
|
||||||
|
rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);
|
||||||
|
|
||||||
|
// Place the frame in the current Window
|
||||||
|
Window::Current->Content = rootFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rootFrame->Content == nullptr)
|
||||||
|
{
|
||||||
|
// When the navigation stack isn't restored navigate to the first page,
|
||||||
|
// configuring the new page by passing required information as a navigation
|
||||||
|
// parameter
|
||||||
|
rootFrame->Navigate(TypeName(DirectXPage::typeid), e->Arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_directXPage == nullptr)
|
||||||
|
{
|
||||||
|
m_directXPage = dynamic_cast<DirectXPage^>(rootFrame->Content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
|
||||||
|
{
|
||||||
|
m_directXPage->LoadInternalState(ApplicationData::Current->LocalSettings->Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the current window is active
|
||||||
|
Window::Current->Activate();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when application execution is being suspended. Application state is saved
|
||||||
|
/// without knowing whether the application will be terminated or resumed with the contents
|
||||||
|
/// of memory still intact.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The source of the suspend request.</param>
|
||||||
|
/// <param name="e">Details about the suspend request.</param>
|
||||||
|
void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
|
||||||
|
{
|
||||||
|
(void) sender; // Unused parameter
|
||||||
|
(void) e; // Unused parameter
|
||||||
|
|
||||||
|
m_directXPage->SaveInternalState(ApplicationData::Current->LocalSettings->Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when application execution is being resumed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The source of the resume request.</param>
|
||||||
|
/// <param name="args">Details about the resume request.</param>
|
||||||
|
void App::OnResuming(Object ^sender, Object ^args)
|
||||||
|
{
|
||||||
|
(void) sender; // Unused parameter
|
||||||
|
(void) args; // Unused parameter
|
||||||
|
|
||||||
|
m_directXPage->LoadInternalState(ApplicationData::Current->LocalSettings->Values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked when Navigation to a certain page fails
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">The Frame which failed navigation</param>
|
||||||
|
/// <param name="e">Details about the navigation failure</param>
|
||||||
|
void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
|
||||||
|
{
|
||||||
|
throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
|
||||||
|
}
|
||||||
|
|
28
Camera-Renderer_cpp/App.xaml.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// App.xaml.h
|
||||||
|
// Declaration of the App class.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "App.g.h"
|
||||||
|
#include "DirectXPage.xaml.h"
|
||||||
|
|
||||||
|
namespace CameraDirect_cpp
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides application-specific behavior to supplement the default Application class.
|
||||||
|
/// </summary>
|
||||||
|
ref class App sealed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
App();
|
||||||
|
virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
|
||||||
|
void OnResuming(Platform::Object ^sender, Platform::Object ^args);
|
||||||
|
void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
|
||||||
|
DirectXPage^ m_directXPage;
|
||||||
|
};
|
||||||
|
}
|
BIN
Camera-Renderer_cpp/Assets/LockScreenLogo.scale-200.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Camera-Renderer_cpp/Assets/SplashScreen.scale-200.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
Camera-Renderer_cpp/Assets/Square150x150Logo.scale-200.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
Camera-Renderer_cpp/Assets/Square44x44Logo.scale-200.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.2 KiB |
BIN
Camera-Renderer_cpp/Assets/StoreLogo.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Camera-Renderer_cpp/Assets/Wide310x150Logo.scale-200.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
319
Camera-Renderer_cpp/CameraDirect_cpp.vcxproj
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|ARM">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{e764711a-933e-4e87-a081-2c24b25f7699}</ProjectGuid>
|
||||||
|
<Keyword>DirectXXamlApp</Keyword>
|
||||||
|
<RootNamespace>CameraDirect_cpp</RootNamespace>
|
||||||
|
<DefaultLanguage>en-US</DefaultLanguage>
|
||||||
|
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||||
|
<AppContainerApplication>true</AppContainerApplication>
|
||||||
|
<ApplicationType>Windows Store</ApplicationType>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||||
|
<WindowsTargetPlatformMinVersion>10.0.17763.0</WindowsTargetPlatformMinVersion>
|
||||||
|
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
|
||||||
|
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ImageContentTask.props" />
|
||||||
|
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.props" />
|
||||||
|
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm; $(VCInstallDir)\lib\arm</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm64; $(VCInstallDir)\lib\arm64</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\arm64; $(VCInstallDir)\lib\arm64</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store; $(VCInstallDir)\lib</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>d2d1.lib; d3d11.lib; dxgi.lib; windowscodecs.lib; dwrite.lib; %(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories); $(VCInstallDir)\lib\store\amd64; $(VCInstallDir)\lib\amd64</AdditionalLibraryDirectories>
|
||||||
|
</Link>
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||||
|
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir);$(IntermediateOutputPath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Image Include="Assets\LockScreenLogo.scale-200.png" />
|
||||||
|
<Image Include="Assets\SplashScreen.scale-200.png" />
|
||||||
|
<Image Include="Assets\Square150x150Logo.scale-200.png" />
|
||||||
|
<Image Include="Assets\Square44x44Logo.scale-200.png" />
|
||||||
|
<Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||||
|
<Image Include="Assets\StoreLogo.png" />
|
||||||
|
<Image Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="App.xaml.h">
|
||||||
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Common\DeviceResources.h" />
|
||||||
|
<ClInclude Include="CameraDirect_cppMain.h" />
|
||||||
|
<ClInclude Include="DirectXPage.xaml.h">
|
||||||
|
<DependentUpon>DirectXPage.xaml</DependentUpon>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Common\DirectXHelper.h" />
|
||||||
|
<ClInclude Include="Common\StepTimer.h" />
|
||||||
|
<ClInclude Include="Content\Sample3DSceneRenderer.h" />
|
||||||
|
<ClInclude Include="Content\SampleFpsTextRenderer.h" />
|
||||||
|
<ClInclude Include="Content\ShaderStructures.h" />
|
||||||
|
<ClInclude Include="pch.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="App.xaml.cpp">
|
||||||
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Common\DeviceResources.cpp" />
|
||||||
|
<ClCompile Include="CameraDirect_cppMain.cpp" />
|
||||||
|
<ClCompile Include="DirectXPage.xaml.cpp">
|
||||||
|
<DependentUpon>DirectXPage.xaml</DependentUpon>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Content\SampleFpsTextRenderer.cpp" />
|
||||||
|
<ClCompile Include="Content\Sample3DSceneRenderer.cpp" />
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">Create</PrecompiledHeader>
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<AppxManifest Include="Package.appxmanifest">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</AppxManifest>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<FxCompile Include="Content\SamplePixelShader.hlsl">
|
||||||
|
<ShaderType>Pixel</ShaderType>
|
||||||
|
</FxCompile>
|
||||||
|
<FxCompile Include="Content\SampleVertexShader.hlsl">
|
||||||
|
<ShaderType>Vertex</ShaderType>
|
||||||
|
</FxCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ApplicationDefinition Include="App.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</ApplicationDefinition>
|
||||||
|
<Page Include="DirectXPage.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ImageContentTask.targets" />
|
||||||
|
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.targets" />
|
||||||
|
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.targets" />
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
66
Camera-Renderer_cpp/CameraDirect_cpp.vcxproj.filters
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Common">
|
||||||
|
<UniqueIdentifier>e764711a-933e-4e87-a081-2c24b25f7699</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Assets">
|
||||||
|
<UniqueIdentifier>9a29d315-3729-42f1-8e9a-441e0ca09644</UniqueIdentifier>
|
||||||
|
<Extensions>bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Content">
|
||||||
|
<UniqueIdentifier>e15b4174-702d-4f9c-b6c9-a413728a0086</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<ClInclude Include="Common\DirectXHelper.h">
|
||||||
|
<Filter>Common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Common\StepTimer.h">
|
||||||
|
<Filter>Common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Common\DeviceResources.h">
|
||||||
|
<Filter>Common</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClCompile Include="Common\DeviceResources.cpp">
|
||||||
|
<Filter>Common</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClInclude Include="Content\Sample3DSceneRenderer.h">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Content\SampleFpsTextRenderer.h">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Content\ShaderStructures.h">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClCompile Include="Content\Sample3DSceneRenderer.cpp">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Content\SampleFpsTextRenderer.cpp">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<FxCompile Include="Content\SamplePixelShader.hlsl">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</FxCompile>
|
||||||
|
<FxCompile Include="Content\SampleVertexShader.hlsl">
|
||||||
|
<Filter>Content</Filter>
|
||||||
|
</FxCompile>
|
||||||
|
<Image Include="Assets\LockScreenLogo.scale-200.png">
|
||||||
|
<Filter>Assets</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="Assets\SplashScreen.scale-200.png">
|
||||||
|
<Filter>Assets</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="Assets\Square150x150Logo.scale-200.png">
|
||||||
|
<Filter>Assets</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="Assets\Square44x44Logo.scale-200.png">
|
||||||
|
<Filter>Assets</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
|
||||||
|
<Filter>Assets</Filter>
|
||||||
|
</Image>
|
||||||
|
<Image Include="Assets\Wide310x150Logo.scale-200.png">
|
||||||
|
<Filter>Assets</Filter>
|
||||||
|
</Image>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
141
Camera-Renderer_cpp/CameraDirect_cppMain.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "CameraDirect_cppMain.h"
|
||||||
|
#include "Common\DirectXHelper.h"
|
||||||
|
|
||||||
|
using namespace CameraDirect_cpp;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
using namespace Windows::System::Threading;
|
||||||
|
using namespace Concurrency;
|
||||||
|
|
||||||
|
// Loads and initializes application assets when the application is loaded.
|
||||||
|
CameraDirect_cppMain::CameraDirect_cppMain(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
|
||||||
|
m_deviceResources(deviceResources), m_pointerLocationX(0.0f)
|
||||||
|
{
|
||||||
|
// Register to be notified if the Device is lost or recreated
|
||||||
|
m_deviceResources->RegisterDeviceNotify(this);
|
||||||
|
|
||||||
|
// TODO: Replace this with your app's content initialization.
|
||||||
|
m_sceneRenderer = std::unique_ptr<Sample3DSceneRenderer>(new Sample3DSceneRenderer(m_deviceResources));
|
||||||
|
|
||||||
|
m_fpsTextRenderer = std::unique_ptr<SampleFpsTextRenderer>(new SampleFpsTextRenderer(m_deviceResources));
|
||||||
|
|
||||||
|
// TODO: Change the timer settings if you want something other than the default variable timestep mode.
|
||||||
|
// e.g. for 60 FPS fixed timestep update logic, call:
|
||||||
|
/*
|
||||||
|
m_timer.SetFixedTimeStep(true);
|
||||||
|
m_timer.SetTargetElapsedSeconds(1.0 / 60);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraDirect_cppMain::~CameraDirect_cppMain()
|
||||||
|
{
|
||||||
|
// Deregister device notification
|
||||||
|
m_deviceResources->RegisterDeviceNotify(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates application state when the window size changes (e.g. device orientation change)
|
||||||
|
void CameraDirect_cppMain::CreateWindowSizeDependentResources()
|
||||||
|
{
|
||||||
|
// TODO: Replace this with the size-dependent initialization of your app's content.
|
||||||
|
m_sceneRenderer->CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraDirect_cppMain::StartRenderLoop()
|
||||||
|
{
|
||||||
|
// If the animation render loop is already running then do not start another thread.
|
||||||
|
if (m_renderLoopWorker != nullptr && m_renderLoopWorker->Status == AsyncStatus::Started)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a task that will be run on a background thread.
|
||||||
|
auto workItemHandler = ref new WorkItemHandler([this](IAsyncAction ^ action)
|
||||||
|
{
|
||||||
|
// Calculate the updated frame and render once per vertical blanking interval.
|
||||||
|
while (action->Status == AsyncStatus::Started)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_criticalSection);
|
||||||
|
Update();
|
||||||
|
if (Render())
|
||||||
|
{
|
||||||
|
m_deviceResources->Present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run task on a dedicated high priority background thread.
|
||||||
|
m_renderLoopWorker = ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::TimeSliced);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraDirect_cppMain::StopRenderLoop()
|
||||||
|
{
|
||||||
|
m_renderLoopWorker->Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the application state once per frame.
|
||||||
|
void CameraDirect_cppMain::Update()
|
||||||
|
{
|
||||||
|
ProcessInput();
|
||||||
|
|
||||||
|
// Update scene objects.
|
||||||
|
m_timer.Tick([&]()
|
||||||
|
{
|
||||||
|
// TODO: Replace this with your app's content update functions.
|
||||||
|
m_sceneRenderer->Update(m_timer);
|
||||||
|
m_fpsTextRenderer->Update(m_timer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process all input from the user before updating game state
|
||||||
|
void CameraDirect_cppMain::ProcessInput()
|
||||||
|
{
|
||||||
|
// TODO: Add per frame input handling here.
|
||||||
|
m_sceneRenderer->TrackingUpdate(m_pointerLocationX);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renders the current frame according to the current application state.
|
||||||
|
// Returns true if the frame was rendered and is ready to be displayed.
|
||||||
|
bool CameraDirect_cppMain::Render()
|
||||||
|
{
|
||||||
|
// Don't try to render anything before the first Update.
|
||||||
|
if (m_timer.GetFrameCount() == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||||
|
|
||||||
|
// Reset the viewport to target the whole screen.
|
||||||
|
auto viewport = m_deviceResources->GetScreenViewport();
|
||||||
|
context->RSSetViewports(1, &viewport);
|
||||||
|
|
||||||
|
// Reset render targets to the screen.
|
||||||
|
ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetView() };
|
||||||
|
context->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());
|
||||||
|
|
||||||
|
// Clear the back buffer and depth stencil view.
|
||||||
|
context->ClearRenderTargetView(m_deviceResources->GetBackBufferRenderTargetView(), DirectX::Colors::CornflowerBlue);
|
||||||
|
context->ClearDepthStencilView(m_deviceResources->GetDepthStencilView(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||||
|
|
||||||
|
// Render the scene objects.
|
||||||
|
// TODO: Replace this with your app's content rendering functions.
|
||||||
|
m_sceneRenderer->Render();
|
||||||
|
m_fpsTextRenderer->Render();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifies renderers that device resources need to be released.
|
||||||
|
void CameraDirect_cppMain::OnDeviceLost()
|
||||||
|
{
|
||||||
|
m_sceneRenderer->ReleaseDeviceDependentResources();
|
||||||
|
m_fpsTextRenderer->ReleaseDeviceDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notifies renderers that device resources may now be recreated.
|
||||||
|
void CameraDirect_cppMain::OnDeviceRestored()
|
||||||
|
{
|
||||||
|
m_sceneRenderer->CreateDeviceDependentResources();
|
||||||
|
m_fpsTextRenderer->CreateDeviceDependentResources();
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
50
Camera-Renderer_cpp/CameraDirect_cppMain.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common\StepTimer.h"
|
||||||
|
#include "Common\DeviceResources.h"
|
||||||
|
#include "Content\Sample3DSceneRenderer.h"
|
||||||
|
#include "Content\SampleFpsTextRenderer.h"
|
||||||
|
|
||||||
|
// Renders Direct2D and 3D content on the screen.
|
||||||
|
namespace CameraDirect_cpp
|
||||||
|
{
|
||||||
|
class CameraDirect_cppMain : public DX::IDeviceNotify
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CameraDirect_cppMain(const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||||
|
~CameraDirect_cppMain();
|
||||||
|
void CreateWindowSizeDependentResources();
|
||||||
|
void StartTracking() { m_sceneRenderer->StartTracking(); }
|
||||||
|
void TrackingUpdate(float positionX) { m_pointerLocationX = positionX; }
|
||||||
|
void StopTracking() { m_sceneRenderer->StopTracking(); }
|
||||||
|
bool IsTracking() { return m_sceneRenderer->IsTracking(); }
|
||||||
|
void StartRenderLoop();
|
||||||
|
void StopRenderLoop();
|
||||||
|
Concurrency::critical_section& GetCriticalSection() { return m_criticalSection; }
|
||||||
|
|
||||||
|
// IDeviceNotify
|
||||||
|
virtual void OnDeviceLost();
|
||||||
|
virtual void OnDeviceRestored();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ProcessInput();
|
||||||
|
void Update();
|
||||||
|
bool Render();
|
||||||
|
|
||||||
|
// Cached pointer to device resources.
|
||||||
|
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||||
|
|
||||||
|
// TODO: Replace with your own content renderers.
|
||||||
|
std::unique_ptr<Sample3DSceneRenderer> m_sceneRenderer;
|
||||||
|
std::unique_ptr<SampleFpsTextRenderer> m_fpsTextRenderer;
|
||||||
|
|
||||||
|
Windows::Foundation::IAsyncAction^ m_renderLoopWorker;
|
||||||
|
Concurrency::critical_section m_criticalSection;
|
||||||
|
|
||||||
|
// Rendering loop timer.
|
||||||
|
DX::StepTimer m_timer;
|
||||||
|
|
||||||
|
// Track current input pointer position.
|
||||||
|
float m_pointerLocationX;
|
||||||
|
};
|
||||||
|
}
|
748
Camera-Renderer_cpp/Common/DeviceResources.cpp
Normal file
@ -0,0 +1,748 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "DeviceResources.h"
|
||||||
|
#include "DirectXHelper.h"
|
||||||
|
#include <windows.ui.xaml.media.dxinterop.h>
|
||||||
|
|
||||||
|
using namespace D2D1;
|
||||||
|
using namespace DirectX;
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
using namespace Windows::Graphics::Display;
|
||||||
|
using namespace Windows::UI::Core;
|
||||||
|
using namespace Windows::UI::Xaml::Controls;
|
||||||
|
using namespace Platform;
|
||||||
|
|
||||||
|
namespace DisplayMetrics
|
||||||
|
{
|
||||||
|
// High resolution displays can require a lot of GPU and battery power to render.
|
||||||
|
// High resolution phones, for example, may suffer from poor battery life if
|
||||||
|
// games attempt to render at 60 frames per second at full fidelity.
|
||||||
|
// The decision to render at full fidelity across all platforms and form factors
|
||||||
|
// should be deliberate.
|
||||||
|
static const bool SupportHighResolutions = false;
|
||||||
|
|
||||||
|
// The default thresholds that define a "high resolution" display. If the thresholds
|
||||||
|
// are exceeded and SupportHighResolutions is false, the dimensions will be scaled
|
||||||
|
// by 50%.
|
||||||
|
static const float DpiThreshold = 192.0f; // 200% of standard desktop display.
|
||||||
|
static const float WidthThreshold = 1920.0f; // 1080p width.
|
||||||
|
static const float HeightThreshold = 1080.0f; // 1080p height.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constants used to calculate screen rotations.
|
||||||
|
namespace ScreenRotation
|
||||||
|
{
|
||||||
|
// 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
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constructor for DeviceResources.
|
||||||
|
DX::DeviceResources::DeviceResources() :
|
||||||
|
m_screenViewport(),
|
||||||
|
m_d3dFeatureLevel(D3D_FEATURE_LEVEL_9_1),
|
||||||
|
m_d3dRenderTargetSize(),
|
||||||
|
m_outputSize(),
|
||||||
|
m_logicalSize(),
|
||||||
|
m_nativeOrientation(DisplayOrientations::None),
|
||||||
|
m_currentOrientation(DisplayOrientations::None),
|
||||||
|
m_dpi(-1.0f),
|
||||||
|
m_effectiveDpi(-1.0f),
|
||||||
|
m_compositionScaleX(1.0f),
|
||||||
|
m_compositionScaleY(1.0f),
|
||||||
|
m_deviceNotify(nullptr)
|
||||||
|
{
|
||||||
|
CreateDeviceIndependentResources();
|
||||||
|
CreateDeviceResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configures resources that don't depend on the Direct3D device.
|
||||||
|
void DX::DeviceResources::CreateDeviceIndependentResources()
|
||||||
|
{
|
||||||
|
// Initialize Direct2D resources.
|
||||||
|
D2D1_FACTORY_OPTIONS options;
|
||||||
|
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
|
||||||
|
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
// If the project is in a debug build, enable Direct2D debugging via SDK Layers.
|
||||||
|
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialize the Direct2D Factory.
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
D2D1CreateFactory(
|
||||||
|
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||||
|
__uuidof(ID2D1Factory3),
|
||||||
|
&options,
|
||||||
|
&m_d2dFactory
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize the DirectWrite Factory.
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
DWriteCreateFactory(
|
||||||
|
DWRITE_FACTORY_TYPE_SHARED,
|
||||||
|
__uuidof(IDWriteFactory3),
|
||||||
|
&m_dwriteFactory
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize the Windows Imaging Component (WIC) Factory.
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
CoCreateInstance(
|
||||||
|
CLSID_WICImagingFactory2,
|
||||||
|
nullptr,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
IID_PPV_ARGS(&m_wicFactory)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configures the Direct3D device, and stores handles to it and the device context.
|
||||||
|
void DX::DeviceResources::CreateDeviceResources()
|
||||||
|
{
|
||||||
|
// This flag adds support for surfaces with a different color channel ordering
|
||||||
|
// than the API default. It is required for compatibility with Direct2D.
|
||||||
|
UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||||
|
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
if (DX::SdkLayersAvailable())
|
||||||
|
{
|
||||||
|
// 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.
|
||||||
|
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 Microsoft Store apps.
|
||||||
|
&device, // Returns the Direct3D device created.
|
||||||
|
&m_d3dFeatureLevel, // Returns feature level of device created.
|
||||||
|
&context // Returns the device immediate context.
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// If the initialization fails, fall back to the WARP device.
|
||||||
|
// For more information on WARP, see:
|
||||||
|
// https://go.microsoft.com/fwlink/?LinkId=286690
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
D3D11CreateDevice(
|
||||||
|
nullptr,
|
||||||
|
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||||
|
0,
|
||||||
|
creationFlags,
|
||||||
|
featureLevels,
|
||||||
|
ARRAYSIZE(featureLevels),
|
||||||
|
D3D11_SDK_VERSION,
|
||||||
|
&device,
|
||||||
|
&m_d3dFeatureLevel,
|
||||||
|
&context
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store pointers to the Direct3D 11.3 API device and immediate context.
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
device.As(&m_d3dDevice)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
context.As(&m_d3dContext)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create the Direct2D device object and a corresponding context.
|
||||||
|
ComPtr<IDXGIDevice3> dxgiDevice;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d3dDevice.As(&dxgiDevice)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d2dDevice->CreateDeviceContext(
|
||||||
|
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
|
||||||
|
&m_d2dContext
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These resources need to be recreated every time the window size is changed.
|
||||||
|
void DX::DeviceResources::CreateWindowSizeDependentResources()
|
||||||
|
{
|
||||||
|
// Clear the previous window size specific context.
|
||||||
|
ID3D11RenderTargetView* nullViews[] = {nullptr};
|
||||||
|
m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
|
||||||
|
m_d3dRenderTargetView = nullptr;
|
||||||
|
m_d2dContext->SetTarget(nullptr);
|
||||||
|
m_d2dTargetBitmap = nullptr;
|
||||||
|
m_d3dDepthStencilView = nullptr;
|
||||||
|
m_d3dContext->Flush1(D3D11_CONTEXT_TYPE_ALL, nullptr);
|
||||||
|
|
||||||
|
UpdateRenderTargetSize();
|
||||||
|
|
||||||
|
// 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_d3dRenderTargetSize.Width = swapDimensions ? m_outputSize.Height : m_outputSize.Width;
|
||||||
|
m_d3dRenderTargetSize.Height = swapDimensions ? m_outputSize.Width : m_outputSize.Height;
|
||||||
|
|
||||||
|
if (m_swapChain != nullptr)
|
||||||
|
{
|
||||||
|
// If the swap chain already exists, resize it.
|
||||||
|
HRESULT hr = m_swapChain->ResizeBuffers(
|
||||||
|
2, // Double-buffered swap chain.
|
||||||
|
lround(m_d3dRenderTargetSize.Width),
|
||||||
|
lround(m_d3dRenderTargetSize.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
|
||||||
|
{
|
||||||
|
DX::ThrowIfFailed(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Otherwise, create a new one using the same adapter as the existing Direct3D device.
|
||||||
|
DXGI_SCALING scaling = DisplayMetrics::SupportHighResolutions ? DXGI_SCALING_NONE : DXGI_SCALING_STRETCH;
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0};
|
||||||
|
|
||||||
|
swapChainDesc.Width = lround(m_d3dRenderTargetSize.Width); // Match the size of the window.
|
||||||
|
swapChainDesc.Height = lround(m_d3dRenderTargetSize.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 Microsoft Store apps must use _FLIP_ SwapEffects.
|
||||||
|
swapChainDesc.Flags = 0;
|
||||||
|
swapChainDesc.Scaling = scaling;
|
||||||
|
swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
|
||||||
|
|
||||||
|
// This sequence obtains the DXGI factory that was used to create the Direct3D device above.
|
||||||
|
ComPtr<IDXGIDevice3> dxgiDevice;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d3dDevice.As(&dxgiDevice)
|
||||||
|
);
|
||||||
|
|
||||||
|
ComPtr<IDXGIAdapter> dxgiAdapter;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
dxgiDevice->GetAdapter(&dxgiAdapter)
|
||||||
|
);
|
||||||
|
|
||||||
|
ComPtr<IDXGIFactory4> dxgiFactory;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory))
|
||||||
|
);
|
||||||
|
|
||||||
|
// When using XAML interop, the swap chain must be created for composition.
|
||||||
|
ComPtr<IDXGISwapChain1> swapChain;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
dxgiFactory->CreateSwapChainForComposition(
|
||||||
|
m_d3dDevice.Get(),
|
||||||
|
&swapChainDesc,
|
||||||
|
nullptr,
|
||||||
|
&swapChain
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
swapChain.As(&m_swapChain)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Associate swap chain with SwapChainPanel
|
||||||
|
// UI changes will need to be dispatched back to the UI thread
|
||||||
|
m_swapChainPanel->Dispatcher->RunAsync(CoreDispatcherPriority::High, ref new DispatchedHandler([=]()
|
||||||
|
{
|
||||||
|
// Get backing native interface for SwapChainPanel
|
||||||
|
ComPtr<ISwapChainPanelNative> panelNative;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
reinterpret_cast<IUnknown*>(m_swapChainPanel)->QueryInterface(IID_PPV_ARGS(&panelNative))
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
panelNative->SetSwapChain(m_swapChain.Get())
|
||||||
|
);
|
||||||
|
}, CallbackContext::Any));
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
dxgiDevice->SetMaximumFrameLatency(1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the proper orientation for the swap chain, and generate 2D and
|
||||||
|
// 3D matrix transformations for rendering to the rotated swap chain.
|
||||||
|
// Note the rotation angle for the 2D and 3D transforms are different.
|
||||||
|
// This is due to the difference in coordinate spaces. Additionally,
|
||||||
|
// the 3D matrix is specified explicitly to avoid rounding errors.
|
||||||
|
|
||||||
|
switch (displayRotation)
|
||||||
|
{
|
||||||
|
case DXGI_MODE_ROTATION_IDENTITY:
|
||||||
|
m_orientationTransform2D = Matrix3x2F::Identity();
|
||||||
|
m_orientationTransform3D = ScreenRotation::Rotation0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DXGI_MODE_ROTATION_ROTATE90:
|
||||||
|
m_orientationTransform2D =
|
||||||
|
Matrix3x2F::Rotation(90.0f) *
|
||||||
|
Matrix3x2F::Translation(m_logicalSize.Height, 0.0f);
|
||||||
|
m_orientationTransform3D = ScreenRotation::Rotation270;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DXGI_MODE_ROTATION_ROTATE180:
|
||||||
|
m_orientationTransform2D =
|
||||||
|
Matrix3x2F::Rotation(180.0f) *
|
||||||
|
Matrix3x2F::Translation(m_logicalSize.Width, m_logicalSize.Height);
|
||||||
|
m_orientationTransform3D = ScreenRotation::Rotation180;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DXGI_MODE_ROTATION_ROTATE270:
|
||||||
|
m_orientationTransform2D =
|
||||||
|
Matrix3x2F::Rotation(270.0f) *
|
||||||
|
Matrix3x2F::Translation(0.0f, m_logicalSize.Width);
|
||||||
|
m_orientationTransform3D = ScreenRotation::Rotation90;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw ref new FailureException();
|
||||||
|
}
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_swapChain->SetRotation(displayRotation)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Setup inverse scale on the swap chain
|
||||||
|
DXGI_MATRIX_3X2_F inverseScale = { 0 };
|
||||||
|
inverseScale._11 = 1.0f / m_effectiveCompositionScaleX;
|
||||||
|
inverseScale._22 = 1.0f / m_effectiveCompositionScaleY;
|
||||||
|
ComPtr<IDXGISwapChain2> spSwapChain2;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_swapChain.As<IDXGISwapChain2>(&spSwapChain2)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
spSwapChain2->SetMatrixTransform(&inverseScale)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create a render target view of the swap chain back buffer.
|
||||||
|
ComPtr<ID3D11Texture2D1> backBuffer;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBuffer))
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d3dDevice->CreateRenderTargetView1(
|
||||||
|
backBuffer.Get(),
|
||||||
|
nullptr,
|
||||||
|
&m_d3dRenderTargetView
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create a depth stencil view for use with 3D rendering if needed.
|
||||||
|
CD3D11_TEXTURE2D_DESC1 depthStencilDesc(
|
||||||
|
DXGI_FORMAT_D24_UNORM_S8_UINT,
|
||||||
|
lround(m_d3dRenderTargetSize.Width),
|
||||||
|
lround(m_d3dRenderTargetSize.Height),
|
||||||
|
1, // This depth stencil view has only one texture.
|
||||||
|
1, // Use a single mipmap level.
|
||||||
|
D3D11_BIND_DEPTH_STENCIL
|
||||||
|
);
|
||||||
|
|
||||||
|
ComPtr<ID3D11Texture2D1> depthStencil;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d3dDevice->CreateTexture2D1(
|
||||||
|
&depthStencilDesc,
|
||||||
|
nullptr,
|
||||||
|
&depthStencil
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d3dDevice->CreateDepthStencilView(
|
||||||
|
depthStencil.Get(),
|
||||||
|
&depthStencilViewDesc,
|
||||||
|
&m_d3dDepthStencilView
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set the 3D rendering viewport to target the entire window.
|
||||||
|
m_screenViewport = CD3D11_VIEWPORT(
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
m_d3dRenderTargetSize.Width,
|
||||||
|
m_d3dRenderTargetSize.Height
|
||||||
|
);
|
||||||
|
|
||||||
|
m_d3dContext->RSSetViewports(1, &m_screenViewport);
|
||||||
|
|
||||||
|
// Create a Direct2D target bitmap associated with the
|
||||||
|
// swap chain back buffer and set it as the current target.
|
||||||
|
D2D1_BITMAP_PROPERTIES1 bitmapProperties =
|
||||||
|
D2D1::BitmapProperties1(
|
||||||
|
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
|
||||||
|
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||||
|
m_dpi,
|
||||||
|
m_dpi
|
||||||
|
);
|
||||||
|
|
||||||
|
ComPtr<IDXGISurface2> dxgiBackBuffer;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_d2dContext->CreateBitmapFromDxgiSurface(
|
||||||
|
dxgiBackBuffer.Get(),
|
||||||
|
&bitmapProperties,
|
||||||
|
&m_d2dTargetBitmap
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());
|
||||||
|
m_d2dContext->SetDpi(m_effectiveDpi, m_effectiveDpi);
|
||||||
|
|
||||||
|
// Grayscale text anti-aliasing is recommended for all Microsoft Store apps.
|
||||||
|
m_d2dContext->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the dimensions of the render target and whether it will be scaled down.
|
||||||
|
void DX::DeviceResources::UpdateRenderTargetSize()
|
||||||
|
{
|
||||||
|
m_effectiveDpi = m_dpi;
|
||||||
|
m_effectiveCompositionScaleX = m_compositionScaleX;
|
||||||
|
m_effectiveCompositionScaleY = m_compositionScaleY;
|
||||||
|
|
||||||
|
// To improve battery life on high resolution devices, render to a smaller render target
|
||||||
|
// and allow the GPU to scale the output when it is presented.
|
||||||
|
if (!DisplayMetrics::SupportHighResolutions && m_dpi > DisplayMetrics::DpiThreshold)
|
||||||
|
{
|
||||||
|
float width = DX::ConvertDipsToPixels(m_logicalSize.Width, m_dpi);
|
||||||
|
float height = DX::ConvertDipsToPixels(m_logicalSize.Height, m_dpi);
|
||||||
|
|
||||||
|
// When the device is in portrait orientation, height > width. Compare the
|
||||||
|
// larger dimension against the width threshold and the smaller dimension
|
||||||
|
// against the height threshold.
|
||||||
|
if (max(width, height) > DisplayMetrics::WidthThreshold && min(width, height) > DisplayMetrics::HeightThreshold)
|
||||||
|
{
|
||||||
|
// To scale the app we change the effective DPI. Logical size does not change.
|
||||||
|
m_effectiveDpi /= 2.0f;
|
||||||
|
m_effectiveCompositionScaleX /= 2.0f;
|
||||||
|
m_effectiveCompositionScaleY /= 2.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the necessary render target size in pixels.
|
||||||
|
m_outputSize.Width = DX::ConvertDipsToPixels(m_logicalSize.Width, m_effectiveDpi);
|
||||||
|
m_outputSize.Height = DX::ConvertDipsToPixels(m_logicalSize.Height, m_effectiveDpi);
|
||||||
|
|
||||||
|
// Prevent zero size DirectX content from being created.
|
||||||
|
m_outputSize.Width = max(m_outputSize.Width, 1);
|
||||||
|
m_outputSize.Height = max(m_outputSize.Height, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called when the XAML control is created (or re-created).
|
||||||
|
void DX::DeviceResources::SetSwapChainPanel(SwapChainPanel^ panel)
|
||||||
|
{
|
||||||
|
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||||
|
|
||||||
|
m_swapChainPanel = panel;
|
||||||
|
m_logicalSize = Windows::Foundation::Size(static_cast<float>(panel->ActualWidth), static_cast<float>(panel->ActualHeight));
|
||||||
|
m_nativeOrientation = currentDisplayInformation->NativeOrientation;
|
||||||
|
m_currentOrientation = currentDisplayInformation->CurrentOrientation;
|
||||||
|
m_compositionScaleX = panel->CompositionScaleX;
|
||||||
|
m_compositionScaleY = panel->CompositionScaleY;
|
||||||
|
m_dpi = currentDisplayInformation->LogicalDpi;
|
||||||
|
m_d2dContext->SetDpi(m_dpi, m_dpi);
|
||||||
|
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called in the event handler for the SizeChanged event.
|
||||||
|
void DX::DeviceResources::SetLogicalSize(Windows::Foundation::Size logicalSize)
|
||||||
|
{
|
||||||
|
if (m_logicalSize != logicalSize)
|
||||||
|
{
|
||||||
|
m_logicalSize = logicalSize;
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called in the event handler for the DpiChanged event.
|
||||||
|
void DX::DeviceResources::SetDpi(float dpi)
|
||||||
|
{
|
||||||
|
if (dpi != m_dpi)
|
||||||
|
{
|
||||||
|
m_dpi = dpi;
|
||||||
|
m_d2dContext->SetDpi(m_dpi, m_dpi);
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called in the event handler for the OrientationChanged event.
|
||||||
|
void DX::DeviceResources::SetCurrentOrientation(DisplayOrientations currentOrientation)
|
||||||
|
{
|
||||||
|
if (m_currentOrientation != currentOrientation)
|
||||||
|
{
|
||||||
|
m_currentOrientation = currentOrientation;
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called in the event handler for the CompositionScaleChanged event.
|
||||||
|
void DX::DeviceResources::SetCompositionScale(float compositionScaleX, float compositionScaleY)
|
||||||
|
{
|
||||||
|
if (m_compositionScaleX != compositionScaleX ||
|
||||||
|
m_compositionScaleY != compositionScaleY)
|
||||||
|
{
|
||||||
|
m_compositionScaleX = compositionScaleX;
|
||||||
|
m_compositionScaleY = compositionScaleY;
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is called in the event handler for the DisplayContentsInvalidated event.
|
||||||
|
void DX::DeviceResources::ValidateDevice()
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));
|
||||||
|
|
||||||
|
ComPtr<IDXGIAdapter> deviceAdapter;
|
||||||
|
DX::ThrowIfFailed(dxgiDevice->GetAdapter(&deviceAdapter));
|
||||||
|
|
||||||
|
ComPtr<IDXGIFactory2> deviceFactory;
|
||||||
|
DX::ThrowIfFailed(deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory)));
|
||||||
|
|
||||||
|
ComPtr<IDXGIAdapter1> previousDefaultAdapter;
|
||||||
|
DX::ThrowIfFailed(deviceFactory->EnumAdapters1(0, &previousDefaultAdapter));
|
||||||
|
|
||||||
|
DXGI_ADAPTER_DESC1 previousDesc;
|
||||||
|
DX::ThrowIfFailed(previousDefaultAdapter->GetDesc1(&previousDesc));
|
||||||
|
|
||||||
|
// Next, get the information for the current default adapter.
|
||||||
|
|
||||||
|
ComPtr<IDXGIFactory4> currentFactory;
|
||||||
|
DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(¤tFactory)));
|
||||||
|
|
||||||
|
ComPtr<IDXGIAdapter1> currentDefaultAdapter;
|
||||||
|
DX::ThrowIfFailed(currentFactory->EnumAdapters1(0, ¤tDefaultAdapter));
|
||||||
|
|
||||||
|
DXGI_ADAPTER_DESC1 currentDesc;
|
||||||
|
DX::ThrowIfFailed(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_d3dDevice->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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate all device resources and set them back to the current state.
|
||||||
|
void DX::DeviceResources::HandleDeviceLost()
|
||||||
|
{
|
||||||
|
m_swapChain = nullptr;
|
||||||
|
|
||||||
|
if (m_deviceNotify != nullptr)
|
||||||
|
{
|
||||||
|
m_deviceNotify->OnDeviceLost();
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateDeviceResources();
|
||||||
|
m_d2dContext->SetDpi(m_dpi, m_dpi);
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
|
||||||
|
if (m_deviceNotify != nullptr)
|
||||||
|
{
|
||||||
|
m_deviceNotify->OnDeviceRestored();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register our DeviceNotify to be informed on device lost and creation.
|
||||||
|
void DX::DeviceResources::RegisterDeviceNotify(DX::IDeviceNotify* deviceNotify)
|
||||||
|
{
|
||||||
|
m_deviceNotify = deviceNotify;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call this method when the app suspends. It provides a hint to the driver that the app
|
||||||
|
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
|
||||||
|
void DX::DeviceResources::Trim()
|
||||||
|
{
|
||||||
|
ComPtr<IDXGIDevice3> dxgiDevice;
|
||||||
|
m_d3dDevice.As(&dxgiDevice);
|
||||||
|
|
||||||
|
dxgiDevice->Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Present the contents of the swap chain to the screen.
|
||||||
|
void DX::DeviceResources::Present()
|
||||||
|
{
|
||||||
|
// 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 hr = 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 modified.
|
||||||
|
m_d3dContext->DiscardView1(m_d3dRenderTargetView.Get(), nullptr, 0);
|
||||||
|
|
||||||
|
// Discard the contents of the depth stencil.
|
||||||
|
m_d3dContext->DiscardView1(m_d3dDepthStencilView.Get(), nullptr, 0);
|
||||||
|
|
||||||
|
// If the device was removed either by a disconnection or a driver upgrade, we
|
||||||
|
// must recreate all device resources.
|
||||||
|
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||||
|
{
|
||||||
|
HandleDeviceLost();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DX::ThrowIfFailed(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method determines the rotation between the display device's native orientation and the
|
||||||
|
// current display orientation.
|
||||||
|
DXGI_MODE_ROTATION DX::DeviceResources::ComputeDisplayRotation()
|
||||||
|
{
|
||||||
|
DXGI_MODE_ROTATION rotation = DXGI_MODE_ROTATION_UNSPECIFIED;
|
||||||
|
|
||||||
|
// Note: 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:
|
||||||
|
rotation = DXGI_MODE_ROTATION_IDENTITY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::Portrait:
|
||||||
|
rotation = DXGI_MODE_ROTATION_ROTATE270;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::LandscapeFlipped:
|
||||||
|
rotation = DXGI_MODE_ROTATION_ROTATE180;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::PortraitFlipped:
|
||||||
|
rotation = DXGI_MODE_ROTATION_ROTATE90;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::Portrait:
|
||||||
|
switch (m_currentOrientation)
|
||||||
|
{
|
||||||
|
case DisplayOrientations::Landscape:
|
||||||
|
rotation = DXGI_MODE_ROTATION_ROTATE90;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::Portrait:
|
||||||
|
rotation = DXGI_MODE_ROTATION_IDENTITY;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::LandscapeFlipped:
|
||||||
|
rotation = DXGI_MODE_ROTATION_ROTATE270;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DisplayOrientations::PortraitFlipped:
|
||||||
|
rotation = DXGI_MODE_ROTATION_ROTATE180;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rotation;
|
||||||
|
}
|
107
Camera-Renderer_cpp/Common/DeviceResources.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace DX
|
||||||
|
{
|
||||||
|
// Provides an interface for an application that owns DeviceResources to be notified of the device being lost or created.
|
||||||
|
interface IDeviceNotify
|
||||||
|
{
|
||||||
|
virtual void OnDeviceLost() = 0;
|
||||||
|
virtual void OnDeviceRestored() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Controls all the DirectX device resources.
|
||||||
|
class DeviceResources
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DeviceResources();
|
||||||
|
void SetSwapChainPanel(Windows::UI::Xaml::Controls::SwapChainPanel^ panel);
|
||||||
|
void SetLogicalSize(Windows::Foundation::Size logicalSize);
|
||||||
|
void SetCurrentOrientation(Windows::Graphics::Display::DisplayOrientations currentOrientation);
|
||||||
|
void SetDpi(float dpi);
|
||||||
|
void SetCompositionScale(float compositionScaleX, float compositionScaleY);
|
||||||
|
void ValidateDevice();
|
||||||
|
void HandleDeviceLost();
|
||||||
|
void RegisterDeviceNotify(IDeviceNotify* deviceNotify);
|
||||||
|
void Trim();
|
||||||
|
void Present();
|
||||||
|
|
||||||
|
// The size of the render target, in pixels.
|
||||||
|
Windows::Foundation::Size GetOutputSize() const { return m_outputSize; }
|
||||||
|
|
||||||
|
// The size of the render target, in dips.
|
||||||
|
Windows::Foundation::Size GetLogicalSize() const { return m_logicalSize; }
|
||||||
|
float GetDpi() const { return m_effectiveDpi; }
|
||||||
|
|
||||||
|
// D3D Accessors.
|
||||||
|
ID3D11Device3* GetD3DDevice() const { return m_d3dDevice.Get(); }
|
||||||
|
ID3D11DeviceContext3* GetD3DDeviceContext() const { return m_d3dContext.Get(); }
|
||||||
|
IDXGISwapChain3* GetSwapChain() const { return m_swapChain.Get(); }
|
||||||
|
D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return m_d3dFeatureLevel; }
|
||||||
|
ID3D11RenderTargetView1* GetBackBufferRenderTargetView() const { return m_d3dRenderTargetView.Get(); }
|
||||||
|
ID3D11DepthStencilView* GetDepthStencilView() const { return m_d3dDepthStencilView.Get(); }
|
||||||
|
D3D11_VIEWPORT GetScreenViewport() const { return m_screenViewport; }
|
||||||
|
DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
|
||||||
|
|
||||||
|
// D2D Accessors.
|
||||||
|
ID2D1Factory3* GetD2DFactory() const { return m_d2dFactory.Get(); }
|
||||||
|
ID2D1Device2* GetD2DDevice() const { return m_d2dDevice.Get(); }
|
||||||
|
ID2D1DeviceContext2* GetD2DDeviceContext() const { return m_d2dContext.Get(); }
|
||||||
|
ID2D1Bitmap1* GetD2DTargetBitmap() const { return m_d2dTargetBitmap.Get(); }
|
||||||
|
IDWriteFactory3* GetDWriteFactory() const { return m_dwriteFactory.Get(); }
|
||||||
|
IWICImagingFactory2* GetWicImagingFactory() const { return m_wicFactory.Get(); }
|
||||||
|
D2D1::Matrix3x2F GetOrientationTransform2D() const { return m_orientationTransform2D; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void CreateDeviceIndependentResources();
|
||||||
|
void CreateDeviceResources();
|
||||||
|
void CreateWindowSizeDependentResources();
|
||||||
|
void UpdateRenderTargetSize();
|
||||||
|
DXGI_MODE_ROTATION ComputeDisplayRotation();
|
||||||
|
|
||||||
|
// Direct3D objects.
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Device3> m_d3dDevice;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11DeviceContext3> m_d3dContext;
|
||||||
|
Microsoft::WRL::ComPtr<IDXGISwapChain3> m_swapChain;
|
||||||
|
|
||||||
|
// Direct3D rendering objects. Required for 3D.
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11RenderTargetView1> m_d3dRenderTargetView;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_d3dDepthStencilView;
|
||||||
|
D3D11_VIEWPORT m_screenViewport;
|
||||||
|
|
||||||
|
// Direct2D drawing components.
|
||||||
|
Microsoft::WRL::ComPtr<ID2D1Factory3> m_d2dFactory;
|
||||||
|
Microsoft::WRL::ComPtr<ID2D1Device2> m_d2dDevice;
|
||||||
|
Microsoft::WRL::ComPtr<ID2D1DeviceContext2> m_d2dContext;
|
||||||
|
Microsoft::WRL::ComPtr<ID2D1Bitmap1> m_d2dTargetBitmap;
|
||||||
|
|
||||||
|
// DirectWrite drawing components.
|
||||||
|
Microsoft::WRL::ComPtr<IDWriteFactory3> m_dwriteFactory;
|
||||||
|
Microsoft::WRL::ComPtr<IWICImagingFactory2> m_wicFactory;
|
||||||
|
|
||||||
|
// Cached reference to the XAML panel.
|
||||||
|
Windows::UI::Xaml::Controls::SwapChainPanel^ m_swapChainPanel;
|
||||||
|
|
||||||
|
// Cached device properties.
|
||||||
|
D3D_FEATURE_LEVEL m_d3dFeatureLevel;
|
||||||
|
Windows::Foundation::Size m_d3dRenderTargetSize;
|
||||||
|
Windows::Foundation::Size m_outputSize;
|
||||||
|
Windows::Foundation::Size m_logicalSize;
|
||||||
|
Windows::Graphics::Display::DisplayOrientations m_nativeOrientation;
|
||||||
|
Windows::Graphics::Display::DisplayOrientations m_currentOrientation;
|
||||||
|
float m_dpi;
|
||||||
|
float m_compositionScaleX;
|
||||||
|
float m_compositionScaleY;
|
||||||
|
|
||||||
|
// Variables that take into account whether the app supports high resolution screens or not.
|
||||||
|
float m_effectiveDpi;
|
||||||
|
float m_effectiveCompositionScaleX;
|
||||||
|
float m_effectiveCompositionScaleY;
|
||||||
|
|
||||||
|
// Transforms used for display orientation.
|
||||||
|
D2D1::Matrix3x2F m_orientationTransform2D;
|
||||||
|
DirectX::XMFLOAT4X4 m_orientationTransform3D;
|
||||||
|
|
||||||
|
// The IDeviceNotify can be held directly as it owns the DeviceResources.
|
||||||
|
IDeviceNotify* m_deviceNotify;
|
||||||
|
};
|
||||||
|
}
|
63
Camera-Renderer_cpp/Common/DirectXHelper.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ppltasks.h> // For create_task
|
||||||
|
|
||||||
|
namespace DX
|
||||||
|
{
|
||||||
|
inline void ThrowIfFailed(HRESULT hr)
|
||||||
|
{
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// Set a breakpoint on this line to catch Win32 API errors.
|
||||||
|
throw Platform::Exception::CreateException(hr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function that reads from a binary file asynchronously.
|
||||||
|
inline Concurrency::task<std::vector<byte>> ReadDataAsync(const std::wstring& filename)
|
||||||
|
{
|
||||||
|
using namespace Windows::Storage;
|
||||||
|
using namespace Concurrency;
|
||||||
|
|
||||||
|
auto folder = Windows::ApplicationModel::Package::Current->InstalledLocation;
|
||||||
|
|
||||||
|
return create_task(folder->GetFileAsync(Platform::StringReference(filename.c_str()))).then([] (StorageFile^ file)
|
||||||
|
{
|
||||||
|
return FileIO::ReadBufferAsync(file);
|
||||||
|
}).then([] (Streams::IBuffer^ fileBuffer) -> std::vector<byte>
|
||||||
|
{
|
||||||
|
std::vector<byte> returnBuffer;
|
||||||
|
returnBuffer.resize(fileBuffer->Length);
|
||||||
|
Streams::DataReader::FromBuffer(fileBuffer)->ReadBytes(Platform::ArrayReference<byte>(returnBuffer.data(), fileBuffer->Length));
|
||||||
|
return returnBuffer;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
|
||||||
|
inline float ConvertDipsToPixels(float dips, float dpi)
|
||||||
|
{
|
||||||
|
static const float dipsPerInch = 96.0f;
|
||||||
|
return floorf(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer.
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
// Check for SDK Layer support.
|
||||||
|
inline bool SdkLayersAvailable()
|
||||||
|
{
|
||||||
|
HRESULT hr = 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 Microsoft 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.
|
||||||
|
);
|
||||||
|
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
183
Camera-Renderer_cpp/Common/StepTimer.h
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
|
||||||
|
namespace DX
|
||||||
|
{
|
||||||
|
// Helper class for animation and simulation timing.
|
||||||
|
class StepTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StepTimer() :
|
||||||
|
m_elapsedTicks(0),
|
||||||
|
m_totalTicks(0),
|
||||||
|
m_leftOverTicks(0),
|
||||||
|
m_frameCount(0),
|
||||||
|
m_framesPerSecond(0),
|
||||||
|
m_framesThisSecond(0),
|
||||||
|
m_qpcSecondCounter(0),
|
||||||
|
m_isFixedTimeStep(false),
|
||||||
|
m_targetElapsedTicks(TicksPerSecond / 60)
|
||||||
|
{
|
||||||
|
if (!QueryPerformanceFrequency(&m_qpcFrequency))
|
||||||
|
{
|
||||||
|
throw ref new Platform::FailureException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!QueryPerformanceCounter(&m_qpcLastTime))
|
||||||
|
{
|
||||||
|
throw ref new Platform::FailureException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize max delta to 1/10 of a second.
|
||||||
|
m_qpcMaxDelta = m_qpcFrequency.QuadPart / 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get elapsed time since the previous Update call.
|
||||||
|
uint64 GetElapsedTicks() const { return m_elapsedTicks; }
|
||||||
|
double GetElapsedSeconds() const { return TicksToSeconds(m_elapsedTicks); }
|
||||||
|
|
||||||
|
// Get total time since the start of the program.
|
||||||
|
uint64 GetTotalTicks() const { return m_totalTicks; }
|
||||||
|
double GetTotalSeconds() const { return TicksToSeconds(m_totalTicks); }
|
||||||
|
|
||||||
|
// Get total number of updates since start of the program.
|
||||||
|
uint32 GetFrameCount() const { return m_frameCount; }
|
||||||
|
|
||||||
|
// Get the current framerate.
|
||||||
|
uint32 GetFramesPerSecond() const { return m_framesPerSecond; }
|
||||||
|
|
||||||
|
// Set whether to use fixed or variable timestep mode.
|
||||||
|
void SetFixedTimeStep(bool isFixedTimestep) { m_isFixedTimeStep = isFixedTimestep; }
|
||||||
|
|
||||||
|
// Set how often to call Update when in fixed timestep mode.
|
||||||
|
void SetTargetElapsedTicks(uint64 targetElapsed) { m_targetElapsedTicks = targetElapsed; }
|
||||||
|
void SetTargetElapsedSeconds(double targetElapsed) { m_targetElapsedTicks = SecondsToTicks(targetElapsed); }
|
||||||
|
|
||||||
|
// Integer format represents time using 10,000,000 ticks per second.
|
||||||
|
static const uint64 TicksPerSecond = 10000000;
|
||||||
|
|
||||||
|
static double TicksToSeconds(uint64 ticks) { return static_cast<double>(ticks) / TicksPerSecond; }
|
||||||
|
static uint64 SecondsToTicks(double seconds) { return static_cast<uint64>(seconds * TicksPerSecond); }
|
||||||
|
|
||||||
|
// After an intentional timing discontinuity (for instance a blocking IO operation)
|
||||||
|
// call this to avoid having the fixed timestep logic attempt a set of catch-up
|
||||||
|
// Update calls.
|
||||||
|
|
||||||
|
void ResetElapsedTime()
|
||||||
|
{
|
||||||
|
if (!QueryPerformanceCounter(&m_qpcLastTime))
|
||||||
|
{
|
||||||
|
throw ref new Platform::FailureException();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_leftOverTicks = 0;
|
||||||
|
m_framesPerSecond = 0;
|
||||||
|
m_framesThisSecond = 0;
|
||||||
|
m_qpcSecondCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update timer state, calling the specified Update function the appropriate number of times.
|
||||||
|
template<typename TUpdate>
|
||||||
|
void Tick(const TUpdate& update)
|
||||||
|
{
|
||||||
|
// Query the current time.
|
||||||
|
LARGE_INTEGER currentTime;
|
||||||
|
|
||||||
|
if (!QueryPerformanceCounter(¤tTime))
|
||||||
|
{
|
||||||
|
throw ref new Platform::FailureException();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 timeDelta = currentTime.QuadPart - m_qpcLastTime.QuadPart;
|
||||||
|
|
||||||
|
m_qpcLastTime = currentTime;
|
||||||
|
m_qpcSecondCounter += timeDelta;
|
||||||
|
|
||||||
|
// Clamp excessively large time deltas (e.g. after paused in the debugger).
|
||||||
|
if (timeDelta > m_qpcMaxDelta)
|
||||||
|
{
|
||||||
|
timeDelta = m_qpcMaxDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert QPC units into a canonical tick format. This cannot overflow due to the previous clamp.
|
||||||
|
timeDelta *= TicksPerSecond;
|
||||||
|
timeDelta /= m_qpcFrequency.QuadPart;
|
||||||
|
|
||||||
|
uint32 lastFrameCount = m_frameCount;
|
||||||
|
|
||||||
|
if (m_isFixedTimeStep)
|
||||||
|
{
|
||||||
|
// Fixed timestep update logic
|
||||||
|
|
||||||
|
// If the app is running very close to the target elapsed time (within 1/4 of a millisecond) just clamp
|
||||||
|
// the clock to exactly match the target value. This prevents tiny and irrelevant errors
|
||||||
|
// from accumulating over time. Without this clamping, a game that requested a 60 fps
|
||||||
|
// fixed update, running with vsync enabled on a 59.94 NTSC display, would eventually
|
||||||
|
// accumulate enough tiny errors that it would drop a frame. It is better to just round
|
||||||
|
// small deviations down to zero to leave things running smoothly.
|
||||||
|
|
||||||
|
if (abs(static_cast<int64>(timeDelta - m_targetElapsedTicks)) < TicksPerSecond / 4000)
|
||||||
|
{
|
||||||
|
timeDelta = m_targetElapsedTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_leftOverTicks += timeDelta;
|
||||||
|
|
||||||
|
while (m_leftOverTicks >= m_targetElapsedTicks)
|
||||||
|
{
|
||||||
|
m_elapsedTicks = m_targetElapsedTicks;
|
||||||
|
m_totalTicks += m_targetElapsedTicks;
|
||||||
|
m_leftOverTicks -= m_targetElapsedTicks;
|
||||||
|
m_frameCount++;
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Variable timestep update logic.
|
||||||
|
m_elapsedTicks = timeDelta;
|
||||||
|
m_totalTicks += timeDelta;
|
||||||
|
m_leftOverTicks = 0;
|
||||||
|
m_frameCount++;
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track the current framerate.
|
||||||
|
if (m_frameCount != lastFrameCount)
|
||||||
|
{
|
||||||
|
m_framesThisSecond++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_qpcSecondCounter >= static_cast<uint64>(m_qpcFrequency.QuadPart))
|
||||||
|
{
|
||||||
|
m_framesPerSecond = m_framesThisSecond;
|
||||||
|
m_framesThisSecond = 0;
|
||||||
|
m_qpcSecondCounter %= m_qpcFrequency.QuadPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Source timing data uses QPC units.
|
||||||
|
LARGE_INTEGER m_qpcFrequency;
|
||||||
|
LARGE_INTEGER m_qpcLastTime;
|
||||||
|
uint64 m_qpcMaxDelta;
|
||||||
|
|
||||||
|
// Derived timing data uses a canonical tick format.
|
||||||
|
uint64 m_elapsedTicks;
|
||||||
|
uint64 m_totalTicks;
|
||||||
|
uint64 m_leftOverTicks;
|
||||||
|
|
||||||
|
// Members for tracking the framerate.
|
||||||
|
uint32 m_frameCount;
|
||||||
|
uint32 m_framesPerSecond;
|
||||||
|
uint32 m_framesThisSecond;
|
||||||
|
uint64 m_qpcSecondCounter;
|
||||||
|
|
||||||
|
// Members for configuring fixed timestep mode.
|
||||||
|
bool m_isFixedTimeStep;
|
||||||
|
uint64 m_targetElapsedTicks;
|
||||||
|
};
|
||||||
|
}
|
324
Camera-Renderer_cpp/Content/Sample3DSceneRenderer.cpp
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "Sample3DSceneRenderer.h"
|
||||||
|
|
||||||
|
#include "..\Common\DirectXHelper.h"
|
||||||
|
|
||||||
|
using namespace CameraDirect_cpp;
|
||||||
|
|
||||||
|
using namespace DirectX;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
|
||||||
|
// Loads vertex and pixel shaders from files and instantiates the cube geometry.
|
||||||
|
Sample3DSceneRenderer::Sample3DSceneRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
|
||||||
|
m_loadingComplete(false),
|
||||||
|
m_degreesPerSecond(45),
|
||||||
|
m_indexCount(0),
|
||||||
|
m_tracking(false),
|
||||||
|
m_deviceResources(deviceResources)
|
||||||
|
{
|
||||||
|
CreateDeviceDependentResources();
|
||||||
|
CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initializes view parameters when the window size changes.
|
||||||
|
void Sample3DSceneRenderer::CreateWindowSizeDependentResources()
|
||||||
|
{
|
||||||
|
Size outputSize = m_deviceResources->GetOutputSize();
|
||||||
|
float aspectRatio = outputSize.Width / outputSize.Height;
|
||||||
|
float fovAngleY = 70.0f * XM_PI / 180.0f;
|
||||||
|
|
||||||
|
// This is a simple example of change that can be made when the app is in
|
||||||
|
// portrait or snapped view.
|
||||||
|
if (aspectRatio < 1.0f)
|
||||||
|
{
|
||||||
|
fovAngleY *= 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that the OrientationTransform3D matrix is post-multiplied here
|
||||||
|
// in order to correctly orient the scene to match the display orientation.
|
||||||
|
// This post-multiplication step is required for any draw calls that are
|
||||||
|
// made to the swap chain render target. For draw calls to other targets,
|
||||||
|
// this transform should not be applied.
|
||||||
|
|
||||||
|
// This sample makes use of a right-handed coordinate system using row-major matrices.
|
||||||
|
XMMATRIX perspectiveMatrix = XMMatrixPerspectiveFovRH(
|
||||||
|
fovAngleY,
|
||||||
|
aspectRatio,
|
||||||
|
0.01f,
|
||||||
|
100.0f
|
||||||
|
);
|
||||||
|
|
||||||
|
XMFLOAT4X4 orientation = m_deviceResources->GetOrientationTransform3D();
|
||||||
|
|
||||||
|
XMMATRIX orientationMatrix = XMLoadFloat4x4(&orientation);
|
||||||
|
|
||||||
|
XMStoreFloat4x4(
|
||||||
|
&m_constantBufferData.projection,
|
||||||
|
XMMatrixTranspose(perspectiveMatrix * orientationMatrix)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Eye is at (0,0.7,1.5), looking at point (0,-0.1,0) with the up-vector along the y-axis.
|
||||||
|
static const XMVECTORF32 eye = { 0.0f, 0.7f, 1.5f, 0.0f };
|
||||||
|
static const XMVECTORF32 at = { 0.0f, -0.1f, 0.0f, 0.0f };
|
||||||
|
static const XMVECTORF32 up = { 0.0f, 1.0f, 0.0f, 0.0f };
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called once per frame, rotates the cube and calculates the model and view matrices.
|
||||||
|
void Sample3DSceneRenderer::Update(DX::StepTimer const& timer)
|
||||||
|
{
|
||||||
|
if (!m_tracking)
|
||||||
|
{
|
||||||
|
// Convert degrees to radians, then convert seconds to rotation angle
|
||||||
|
float radiansPerSecond = XMConvertToRadians(m_degreesPerSecond);
|
||||||
|
double totalRotation = timer.GetTotalSeconds() * radiansPerSecond;
|
||||||
|
float radians = static_cast<float>(fmod(totalRotation, XM_2PI));
|
||||||
|
|
||||||
|
Rotate(radians);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate the 3D cube model a set amount of radians.
|
||||||
|
void Sample3DSceneRenderer::Rotate(float radians)
|
||||||
|
{
|
||||||
|
// Prepare to pass the updated model matrix to the shader
|
||||||
|
XMStoreFloat4x4(&m_constantBufferData.model, XMMatrixTranspose(XMMatrixRotationY(radians)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sample3DSceneRenderer::StartTracking()
|
||||||
|
{
|
||||||
|
m_tracking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// When tracking, the 3D cube can be rotated around its Y axis by tracking pointer position relative to the output screen width.
|
||||||
|
void Sample3DSceneRenderer::TrackingUpdate(float positionX)
|
||||||
|
{
|
||||||
|
if (m_tracking)
|
||||||
|
{
|
||||||
|
float radians = XM_2PI * 2.0f * positionX / m_deviceResources->GetOutputSize().Width;
|
||||||
|
Rotate(radians);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sample3DSceneRenderer::StopTracking()
|
||||||
|
{
|
||||||
|
m_tracking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renders one frame using the vertex and pixel shaders.
|
||||||
|
void Sample3DSceneRenderer::Render()
|
||||||
|
{
|
||||||
|
// Loading is asynchronous. Only draw geometry after it's loaded.
|
||||||
|
if (!m_loadingComplete)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto context = m_deviceResources->GetD3DDeviceContext();
|
||||||
|
|
||||||
|
// Prepare the constant buffer to send it to the graphics device.
|
||||||
|
context->UpdateSubresource1(
|
||||||
|
m_constantBuffer.Get(),
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&m_constantBufferData,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Each vertex is one instance of the VertexPositionColor struct.
|
||||||
|
UINT stride = sizeof(VertexPositionColor);
|
||||||
|
UINT offset = 0;
|
||||||
|
context->IASetVertexBuffers(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
m_vertexBuffer.GetAddressOf(),
|
||||||
|
&stride,
|
||||||
|
&offset
|
||||||
|
);
|
||||||
|
|
||||||
|
context->IASetIndexBuffer(
|
||||||
|
m_indexBuffer.Get(),
|
||||||
|
DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
|
||||||
|
context->IASetInputLayout(m_inputLayout.Get());
|
||||||
|
|
||||||
|
// Attach our vertex shader.
|
||||||
|
context->VSSetShader(
|
||||||
|
m_vertexShader.Get(),
|
||||||
|
nullptr,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send the constant buffer to the graphics device.
|
||||||
|
context->VSSetConstantBuffers1(
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
m_constantBuffer.GetAddressOf(),
|
||||||
|
nullptr,
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
|
|
||||||
|
// Attach our pixel shader.
|
||||||
|
context->PSSetShader(
|
||||||
|
m_pixelShader.Get(),
|
||||||
|
nullptr,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Draw the objects.
|
||||||
|
context->DrawIndexed(
|
||||||
|
m_indexCount,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sample3DSceneRenderer::CreateDeviceDependentResources()
|
||||||
|
{
|
||||||
|
// Load shaders asynchronously.
|
||||||
|
auto loadVSTask = DX::ReadDataAsync(L"SampleVertexShader.cso");
|
||||||
|
auto loadPSTask = DX::ReadDataAsync(L"SamplePixelShader.cso");
|
||||||
|
|
||||||
|
// After the vertex shader file is loaded, create the shader and input layout.
|
||||||
|
auto createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData) {
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD3DDevice()->CreateVertexShader(
|
||||||
|
&fileData[0],
|
||||||
|
fileData.size(),
|
||||||
|
nullptr,
|
||||||
|
&m_vertexShader
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
static const D3D11_INPUT_ELEMENT_DESC vertexDesc [] =
|
||||||
|
{
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD3DDevice()->CreateInputLayout(
|
||||||
|
vertexDesc,
|
||||||
|
ARRAYSIZE(vertexDesc),
|
||||||
|
&fileData[0],
|
||||||
|
fileData.size(),
|
||||||
|
&m_inputLayout
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// After the pixel shader file is loaded, create the shader and constant buffer.
|
||||||
|
auto createPSTask = loadPSTask.then([this](const std::vector<byte>& fileData) {
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD3DDevice()->CreatePixelShader(
|
||||||
|
&fileData[0],
|
||||||
|
fileData.size(),
|
||||||
|
nullptr,
|
||||||
|
&m_pixelShader
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
CD3D11_BUFFER_DESC constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer) , D3D11_BIND_CONSTANT_BUFFER);
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD3DDevice()->CreateBuffer(
|
||||||
|
&constantBufferDesc,
|
||||||
|
nullptr,
|
||||||
|
&m_constantBuffer
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Once both shaders are loaded, create the mesh.
|
||||||
|
auto createCubeTask = (createPSTask && createVSTask).then([this] () {
|
||||||
|
|
||||||
|
// Load mesh vertices. Each vertex has a position and a color.
|
||||||
|
static const VertexPositionColor cubeVertices[] =
|
||||||
|
{
|
||||||
|
{XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT3(0.0f, 0.0f, 0.0f)},
|
||||||
|
{XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT3(0.0f, 0.0f, 1.0f)},
|
||||||
|
{XMFLOAT3(-0.5f, 0.5f, -0.5f), XMFLOAT3(0.0f, 1.0f, 0.0f)},
|
||||||
|
{XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT3(0.0f, 1.0f, 1.0f)},
|
||||||
|
{XMFLOAT3( 0.5f, -0.5f, -0.5f), XMFLOAT3(1.0f, 0.0f, 0.0f)},
|
||||||
|
{XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT3(1.0f, 0.0f, 1.0f)},
|
||||||
|
{XMFLOAT3( 0.5f, 0.5f, -0.5f), XMFLOAT3(1.0f, 1.0f, 0.0f)},
|
||||||
|
{XMFLOAT3( 0.5f, 0.5f, 0.5f), XMFLOAT3(1.0f, 1.0f, 1.0f)},
|
||||||
|
};
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
|
||||||
|
vertexBufferData.pSysMem = cubeVertices;
|
||||||
|
vertexBufferData.SysMemPitch = 0;
|
||||||
|
vertexBufferData.SysMemSlicePitch = 0;
|
||||||
|
CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(cubeVertices), D3D11_BIND_VERTEX_BUFFER);
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD3DDevice()->CreateBuffer(
|
||||||
|
&vertexBufferDesc,
|
||||||
|
&vertexBufferData,
|
||||||
|
&m_vertexBuffer
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Load mesh indices. Each trio of indices represents
|
||||||
|
// a triangle to be rendered on the screen.
|
||||||
|
// For example: 0,2,1 means that the vertices with indexes
|
||||||
|
// 0, 2 and 1 from the vertex buffer compose the
|
||||||
|
// first triangle of this mesh.
|
||||||
|
static const unsigned short cubeIndices [] =
|
||||||
|
{
|
||||||
|
0,2,1, // -x
|
||||||
|
1,2,3,
|
||||||
|
|
||||||
|
4,5,6, // +x
|
||||||
|
5,7,6,
|
||||||
|
|
||||||
|
0,1,5, // -y
|
||||||
|
0,5,4,
|
||||||
|
|
||||||
|
2,6,7, // +y
|
||||||
|
2,7,3,
|
||||||
|
|
||||||
|
0,4,6, // -z
|
||||||
|
0,6,2,
|
||||||
|
|
||||||
|
1,3,7, // +z
|
||||||
|
1,7,5,
|
||||||
|
};
|
||||||
|
|
||||||
|
m_indexCount = ARRAYSIZE(cubeIndices);
|
||||||
|
|
||||||
|
D3D11_SUBRESOURCE_DATA indexBufferData = {0};
|
||||||
|
indexBufferData.pSysMem = cubeIndices;
|
||||||
|
indexBufferData.SysMemPitch = 0;
|
||||||
|
indexBufferData.SysMemSlicePitch = 0;
|
||||||
|
CD3D11_BUFFER_DESC indexBufferDesc(sizeof(cubeIndices), D3D11_BIND_INDEX_BUFFER);
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD3DDevice()->CreateBuffer(
|
||||||
|
&indexBufferDesc,
|
||||||
|
&indexBufferData,
|
||||||
|
&m_indexBuffer
|
||||||
|
)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Once the cube is loaded, the object is ready to be rendered.
|
||||||
|
createCubeTask.then([this] () {
|
||||||
|
m_loadingComplete = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sample3DSceneRenderer::ReleaseDeviceDependentResources()
|
||||||
|
{
|
||||||
|
m_loadingComplete = false;
|
||||||
|
m_vertexShader.Reset();
|
||||||
|
m_inputLayout.Reset();
|
||||||
|
m_pixelShader.Reset();
|
||||||
|
m_constantBuffer.Reset();
|
||||||
|
m_vertexBuffer.Reset();
|
||||||
|
m_indexBuffer.Reset();
|
||||||
|
}
|
50
Camera-Renderer_cpp/Content/Sample3DSceneRenderer.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "..\Common\DeviceResources.h"
|
||||||
|
#include "ShaderStructures.h"
|
||||||
|
#include "..\Common\StepTimer.h"
|
||||||
|
|
||||||
|
namespace CameraDirect_cpp
|
||||||
|
{
|
||||||
|
// This sample renderer instantiates a basic rendering pipeline.
|
||||||
|
class Sample3DSceneRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sample3DSceneRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||||
|
void CreateDeviceDependentResources();
|
||||||
|
void CreateWindowSizeDependentResources();
|
||||||
|
void ReleaseDeviceDependentResources();
|
||||||
|
void Update(DX::StepTimer const& timer);
|
||||||
|
void Render();
|
||||||
|
void StartTracking();
|
||||||
|
void TrackingUpdate(float positionX);
|
||||||
|
void StopTracking();
|
||||||
|
bool IsTracking() { return m_tracking; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Rotate(float radians);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Cached pointer to device resources.
|
||||||
|
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||||
|
|
||||||
|
// Direct3D resources for cube geometry.
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
|
||||||
|
Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
|
||||||
|
|
||||||
|
// System resources for cube geometry.
|
||||||
|
ModelViewProjectionConstantBuffer m_constantBufferData;
|
||||||
|
uint32 m_indexCount;
|
||||||
|
|
||||||
|
// Variables used with the rendering loop.
|
||||||
|
bool m_loadingComplete;
|
||||||
|
float m_degreesPerSecond;
|
||||||
|
bool m_tracking;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
122
Camera-Renderer_cpp/Content/SampleFpsTextRenderer.cpp
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "SampleFpsTextRenderer.h"
|
||||||
|
|
||||||
|
#include "Common/DirectXHelper.h"
|
||||||
|
|
||||||
|
using namespace CameraDirect_cpp;
|
||||||
|
using namespace Microsoft::WRL;
|
||||||
|
|
||||||
|
// Initializes D2D resources used for text rendering.
|
||||||
|
SampleFpsTextRenderer::SampleFpsTextRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources) :
|
||||||
|
m_text(L""),
|
||||||
|
m_deviceResources(deviceResources)
|
||||||
|
{
|
||||||
|
ZeroMemory(&m_textMetrics, sizeof(DWRITE_TEXT_METRICS));
|
||||||
|
|
||||||
|
// Create device independent resources
|
||||||
|
ComPtr<IDWriteTextFormat> textFormat;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetDWriteFactory()->CreateTextFormat(
|
||||||
|
L"Segoe UI",
|
||||||
|
nullptr,
|
||||||
|
DWRITE_FONT_WEIGHT_LIGHT,
|
||||||
|
DWRITE_FONT_STYLE_NORMAL,
|
||||||
|
DWRITE_FONT_STRETCH_NORMAL,
|
||||||
|
32.0f,
|
||||||
|
L"en-US",
|
||||||
|
&textFormat
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
textFormat.As(&m_textFormat)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_textFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_NEAR)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD2DFactory()->CreateDrawingStateBlock(&m_stateBlock)
|
||||||
|
);
|
||||||
|
|
||||||
|
CreateDeviceDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the text to be displayed.
|
||||||
|
void SampleFpsTextRenderer::Update(DX::StepTimer const& timer)
|
||||||
|
{
|
||||||
|
// Update display text.
|
||||||
|
uint32 fps = timer.GetFramesPerSecond();
|
||||||
|
|
||||||
|
m_text = (fps > 0) ? std::to_wstring(fps) + L" FPS" : L" - FPS";
|
||||||
|
|
||||||
|
ComPtr<IDWriteTextLayout> textLayout;
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetDWriteFactory()->CreateTextLayout(
|
||||||
|
m_text.c_str(),
|
||||||
|
(uint32) m_text.length(),
|
||||||
|
m_textFormat.Get(),
|
||||||
|
240.0f, // Max width of the input text.
|
||||||
|
50.0f, // Max height of the input text.
|
||||||
|
&textLayout
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
textLayout.As(&m_textLayout)
|
||||||
|
);
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_textLayout->GetMetrics(&m_textMetrics)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Renders a frame to the screen.
|
||||||
|
void SampleFpsTextRenderer::Render()
|
||||||
|
{
|
||||||
|
ID2D1DeviceContext* context = m_deviceResources->GetD2DDeviceContext();
|
||||||
|
Windows::Foundation::Size logicalSize = m_deviceResources->GetLogicalSize();
|
||||||
|
|
||||||
|
context->SaveDrawingState(m_stateBlock.Get());
|
||||||
|
context->BeginDraw();
|
||||||
|
|
||||||
|
// Position on the bottom right corner
|
||||||
|
D2D1::Matrix3x2F screenTranslation = D2D1::Matrix3x2F::Translation(
|
||||||
|
logicalSize.Width - m_textMetrics.layoutWidth,
|
||||||
|
logicalSize.Height - m_textMetrics.height
|
||||||
|
);
|
||||||
|
|
||||||
|
context->SetTransform(screenTranslation * m_deviceResources->GetOrientationTransform2D());
|
||||||
|
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_textFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_TRAILING)
|
||||||
|
);
|
||||||
|
|
||||||
|
context->DrawTextLayout(
|
||||||
|
D2D1::Point2F(0.f, 0.f),
|
||||||
|
m_textLayout.Get(),
|
||||||
|
m_whiteBrush.Get()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Ignore D2DERR_RECREATE_TARGET here. This error indicates that the device
|
||||||
|
// is lost. It will be handled during the next call to Present.
|
||||||
|
HRESULT hr = context->EndDraw();
|
||||||
|
if (hr != D2DERR_RECREATE_TARGET)
|
||||||
|
{
|
||||||
|
DX::ThrowIfFailed(hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
context->RestoreDrawingState(m_stateBlock.Get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleFpsTextRenderer::CreateDeviceDependentResources()
|
||||||
|
{
|
||||||
|
DX::ThrowIfFailed(
|
||||||
|
m_deviceResources->GetD2DDeviceContext()->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &m_whiteBrush)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
void SampleFpsTextRenderer::ReleaseDeviceDependentResources()
|
||||||
|
{
|
||||||
|
m_whiteBrush.Reset();
|
||||||
|
}
|
31
Camera-Renderer_cpp/Content/SampleFpsTextRenderer.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "..\Common\DeviceResources.h"
|
||||||
|
#include "..\Common\StepTimer.h"
|
||||||
|
|
||||||
|
namespace CameraDirect_cpp
|
||||||
|
{
|
||||||
|
// Renders the current FPS value in the bottom right corner of the screen using Direct2D and DirectWrite.
|
||||||
|
class SampleFpsTextRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SampleFpsTextRenderer(const std::shared_ptr<DX::DeviceResources>& deviceResources);
|
||||||
|
void CreateDeviceDependentResources();
|
||||||
|
void ReleaseDeviceDependentResources();
|
||||||
|
void Update(DX::StepTimer const& timer);
|
||||||
|
void Render();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Cached pointer to device resources.
|
||||||
|
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||||
|
|
||||||
|
// Resources related to text rendering.
|
||||||
|
std::wstring m_text;
|
||||||
|
DWRITE_TEXT_METRICS m_textMetrics;
|
||||||
|
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> m_whiteBrush;
|
||||||
|
Microsoft::WRL::ComPtr<ID2D1DrawingStateBlock1> m_stateBlock;
|
||||||
|
Microsoft::WRL::ComPtr<IDWriteTextLayout3> m_textLayout;
|
||||||
|
Microsoft::WRL::ComPtr<IDWriteTextFormat2> m_textFormat;
|
||||||
|
};
|
||||||
|
}
|
10
Camera-Renderer_cpp/Content/SamplePixelShader.hlsl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
struct PixelShaderInput
|
||||||
|
{
|
||||||
|
float4 pos : SV_POSITION;
|
||||||
|
float3 color : COLOR0;
|
||||||
|
};
|
||||||
|
|
||||||
|
float4 main(PixelShaderInput input) : SV_TARGET
|
||||||
|
{
|
||||||
|
return float4(input.color, 1.0f);
|
||||||
|
}
|
33
Camera-Renderer_cpp/Content/SampleVertexShader.hlsl
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
cbuffer ModelViewProjectionConstantBuffer : register(b0)
|
||||||
|
{
|
||||||
|
matrix model;
|
||||||
|
matrix view;
|
||||||
|
matrix projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexShaderInput
|
||||||
|
{
|
||||||
|
float3 pos : POSITION;
|
||||||
|
float3 color : COLOR0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PixelShaderInput
|
||||||
|
{
|
||||||
|
float4 pos : SV_POSITION;
|
||||||
|
float3 color : COLOR0;
|
||||||
|
};
|
||||||
|
|
||||||
|
PixelShaderInput main(VertexShaderInput input)
|
||||||
|
{
|
||||||
|
PixelShaderInput output;
|
||||||
|
float4 pos = float4(input.pos, 1.0f);
|
||||||
|
|
||||||
|
pos = mul(pos, model);
|
||||||
|
pos = mul(pos, view);
|
||||||
|
pos = mul(pos, projection);
|
||||||
|
output.pos = pos;
|
||||||
|
|
||||||
|
output.color = input.color;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
19
Camera-Renderer_cpp/Content/ShaderStructures.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace CameraDirect_cpp
|
||||||
|
{
|
||||||
|
// Constant buffer used to send MVP matrices to the vertex shader.
|
||||||
|
struct ModelViewProjectionConstantBuffer
|
||||||
|
{
|
||||||
|
DirectX::XMFLOAT4X4 model;
|
||||||
|
DirectX::XMFLOAT4X4 view;
|
||||||
|
DirectX::XMFLOAT4X4 projection;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used to send per-vertex data to the vertex shader.
|
||||||
|
struct VertexPositionColor
|
||||||
|
{
|
||||||
|
DirectX::XMFLOAT3 pos;
|
||||||
|
DirectX::XMFLOAT3 color;
|
||||||
|
};
|
||||||
|
}
|
39
Camera-Renderer_cpp/DirectXPage.xaml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<Page
|
||||||
|
x:Class="CameraDirect_cpp.DirectXPage"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:CameraDirect_cpp"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<SwapChainPanel x:Name="swapChainPanel" VerticalAlignment="Top" MinHeight="250">
|
||||||
|
|
||||||
|
</SwapChainPanel>
|
||||||
|
<Image x:Name="renderTarget" />
|
||||||
|
<StackPanel x:Name="SourceFlyout" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="20,30,20,20">
|
||||||
|
<StackPanel.Background>
|
||||||
|
<AcrylicBrush TintColor="#CC000000" TintOpacity="0.75"/>
|
||||||
|
</StackPanel.Background>
|
||||||
|
<TextBlock Text="Input Audio:" TextWrapping="Wrap" Margin="0,10,0,0" Foreground="White"/>
|
||||||
|
<ComboBox x:Name="audioComboBox" Width="120" MinWidth="300"/>
|
||||||
|
<TextBlock Text="Input Stream:" TextWrapping="Wrap" Margin="0,10,0,0" Foreground="White"/>
|
||||||
|
<ComboBox x:Name="videoComboBox" Width="120" MinWidth="300"/>
|
||||||
|
<Button x:Name="startStreamButton" Content="Start Stream" HorizontalContentAlignment="Center" HorizontalAlignment="Center" Margin="0,10,0,0" Background="#54FFFFFF"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Page.BottomAppBar>
|
||||||
|
<AppBar x:Name="bottomAppBar" Padding="10,0,10,0">
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
|
||||||
|
<AppBarButton AutomationProperties.Name="Sample Button"
|
||||||
|
AutomationProperties.AutomationId="SampleAppBarButton"
|
||||||
|
Click="AppBarButton_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
</AppBar>
|
||||||
|
</Page.BottomAppBar>
|
||||||
|
</Page>
|
196
Camera-Renderer_cpp/DirectXPage.xaml.cpp
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
//
|
||||||
|
// DirectXPage.xaml.cpp
|
||||||
|
// Implementation of the DirectXPage class.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
#include "DirectXPage.xaml.h"
|
||||||
|
|
||||||
|
using namespace CameraDirect_cpp;
|
||||||
|
|
||||||
|
using namespace Platform;
|
||||||
|
using namespace Windows::Foundation;
|
||||||
|
using namespace Windows::Foundation::Collections;
|
||||||
|
using namespace Windows::Graphics::Display;
|
||||||
|
using namespace Windows::System::Threading;
|
||||||
|
using namespace Windows::UI::Core;
|
||||||
|
using namespace Windows::UI::Input;
|
||||||
|
using namespace Windows::UI::Xaml;
|
||||||
|
using namespace Windows::UI::Xaml::Controls;
|
||||||
|
using namespace Windows::UI::Xaml::Controls::Primitives;
|
||||||
|
using namespace Windows::UI::Xaml::Data;
|
||||||
|
using namespace Windows::UI::Xaml::Input;
|
||||||
|
using namespace Windows::UI::Xaml::Media;
|
||||||
|
using namespace Windows::UI::Xaml::Navigation;
|
||||||
|
using namespace concurrency;
|
||||||
|
|
||||||
|
DirectXPage::DirectXPage():
|
||||||
|
m_windowVisible(true),
|
||||||
|
m_coreInput(nullptr)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
// Register event handlers for page lifecycle.
|
||||||
|
CoreWindow^ window = Window::Current->CoreWindow;
|
||||||
|
|
||||||
|
window->VisibilityChanged +=
|
||||||
|
ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &DirectXPage::OnVisibilityChanged);
|
||||||
|
|
||||||
|
DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
|
||||||
|
|
||||||
|
currentDisplayInformation->DpiChanged +=
|
||||||
|
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &DirectXPage::OnDpiChanged);
|
||||||
|
|
||||||
|
currentDisplayInformation->OrientationChanged +=
|
||||||
|
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &DirectXPage::OnOrientationChanged);
|
||||||
|
|
||||||
|
DisplayInformation::DisplayContentsInvalidated +=
|
||||||
|
ref new TypedEventHandler<DisplayInformation^, Object^>(this, &DirectXPage::OnDisplayContentsInvalidated);
|
||||||
|
|
||||||
|
swapChainPanel->CompositionScaleChanged +=
|
||||||
|
ref new TypedEventHandler<SwapChainPanel^, Object^>(this, &DirectXPage::OnCompositionScaleChanged);
|
||||||
|
|
||||||
|
swapChainPanel->SizeChanged +=
|
||||||
|
ref new SizeChangedEventHandler(this, &DirectXPage::OnSwapChainPanelSizeChanged);
|
||||||
|
|
||||||
|
// At this point we have access to the device.
|
||||||
|
// We can create the device-dependent resources.
|
||||||
|
m_deviceResources = std::make_shared<DX::DeviceResources>();
|
||||||
|
m_deviceResources->SetSwapChainPanel(swapChainPanel);
|
||||||
|
|
||||||
|
// Register our SwapChainPanel to get independent input pointer events
|
||||||
|
auto workItemHandler = ref new WorkItemHandler([this] (IAsyncAction ^)
|
||||||
|
{
|
||||||
|
// The CoreIndependentInputSource will raise pointer events for the specified device types on whichever thread it's created on.
|
||||||
|
m_coreInput = swapChainPanel->CreateCoreIndependentInputSource(
|
||||||
|
Windows::UI::Core::CoreInputDeviceTypes::Mouse |
|
||||||
|
Windows::UI::Core::CoreInputDeviceTypes::Touch |
|
||||||
|
Windows::UI::Core::CoreInputDeviceTypes::Pen
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register for pointer events, which will be raised on the background thread.
|
||||||
|
m_coreInput->PointerPressed += ref new TypedEventHandler<Object^, PointerEventArgs^>(this, &DirectXPage::OnPointerPressed);
|
||||||
|
m_coreInput->PointerMoved += ref new TypedEventHandler<Object^, PointerEventArgs^>(this, &DirectXPage::OnPointerMoved);
|
||||||
|
m_coreInput->PointerReleased += ref new TypedEventHandler<Object^, PointerEventArgs^>(this, &DirectXPage::OnPointerReleased);
|
||||||
|
|
||||||
|
// Begin processing input messages as they're delivered.
|
||||||
|
m_coreInput->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessUntilQuit);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run task on a dedicated high priority background thread.
|
||||||
|
m_inputLoopWorker = ThreadPool::RunAsync(workItemHandler, WorkItemPriority::High, WorkItemOptions::TimeSliced);
|
||||||
|
|
||||||
|
m_main = std::unique_ptr<CameraDirect_cppMain>(new CameraDirect_cppMain(m_deviceResources));
|
||||||
|
m_main->StartRenderLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectXPage::~DirectXPage()
|
||||||
|
{
|
||||||
|
// Stop rendering and processing events on destruction.
|
||||||
|
m_main->StopRenderLoop();
|
||||||
|
m_coreInput->Dispatcher->StopProcessEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Saves the current state of the app for suspend and terminate events.
|
||||||
|
void DirectXPage::SaveInternalState(IPropertySet^ state)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_main->GetCriticalSection());
|
||||||
|
m_deviceResources->Trim();
|
||||||
|
|
||||||
|
// Stop rendering when the app is suspended.
|
||||||
|
m_main->StopRenderLoop();
|
||||||
|
|
||||||
|
// Put code to save app state here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loads the current state of the app for resume events.
|
||||||
|
void DirectXPage::LoadInternalState(IPropertySet^ state)
|
||||||
|
{
|
||||||
|
// Put code to load app state here.
|
||||||
|
|
||||||
|
// Start rendering when the app is resumed.
|
||||||
|
m_main->StartRenderLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window event handlers.
|
||||||
|
|
||||||
|
void DirectXPage::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
|
||||||
|
{
|
||||||
|
m_windowVisible = args->Visible;
|
||||||
|
if (m_windowVisible)
|
||||||
|
{
|
||||||
|
m_main->StartRenderLoop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_main->StopRenderLoop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisplayInformation event handlers.
|
||||||
|
|
||||||
|
void DirectXPage::OnDpiChanged(DisplayInformation^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_main->GetCriticalSection());
|
||||||
|
// Note: The value for LogicalDpi retrieved here may not match the effective DPI of the app
|
||||||
|
// if it is being scaled for high resolution devices. Once the DPI is set on DeviceResources,
|
||||||
|
// you should always retrieve it using the GetDpi method.
|
||||||
|
// See DeviceResources.cpp for more details.
|
||||||
|
m_deviceResources->SetDpi(sender->LogicalDpi);
|
||||||
|
m_main->CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_main->GetCriticalSection());
|
||||||
|
m_deviceResources->SetCurrentOrientation(sender->CurrentOrientation);
|
||||||
|
m_main->CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_main->GetCriticalSection());
|
||||||
|
m_deviceResources->ValidateDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the app bar button is clicked.
|
||||||
|
void DirectXPage::AppBarButton_Click(Object^ sender, RoutedEventArgs^ e)
|
||||||
|
{
|
||||||
|
// Use the app bar if it is appropriate for your app. Design the app bar,
|
||||||
|
// then fill in event handlers (like this one).
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnPointerPressed(Object^ sender, PointerEventArgs^ e)
|
||||||
|
{
|
||||||
|
// When the pointer is pressed begin tracking the pointer movement.
|
||||||
|
m_main->StartTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnPointerMoved(Object^ sender, PointerEventArgs^ e)
|
||||||
|
{
|
||||||
|
// Update the pointer tracking code.
|
||||||
|
if (m_main->IsTracking())
|
||||||
|
{
|
||||||
|
m_main->TrackingUpdate(e->CurrentPoint->Position.X);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnPointerReleased(Object^ sender, PointerEventArgs^ e)
|
||||||
|
{
|
||||||
|
// Stop tracking pointer movement when the pointer is released.
|
||||||
|
m_main->StopTracking();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnCompositionScaleChanged(SwapChainPanel^ sender, Object^ args)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_main->GetCriticalSection());
|
||||||
|
m_deviceResources->SetCompositionScale(sender->CompositionScaleX, sender->CompositionScaleY);
|
||||||
|
m_main->CreateWindowSizeDependentResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectXPage::OnSwapChainPanelSizeChanged(Object^ sender, SizeChangedEventArgs^ e)
|
||||||
|
{
|
||||||
|
critical_section::scoped_lock lock(m_main->GetCriticalSection());
|
||||||
|
m_deviceResources->SetLogicalSize(e->NewSize);
|
||||||
|
m_main->CreateWindowSizeDependentResources();
|
||||||
|
}
|
59
Camera-Renderer_cpp/DirectXPage.xaml.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//
|
||||||
|
// DirectXPage.xaml.h
|
||||||
|
// Declaration of the DirectXPage class.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DirectXPage.g.h"
|
||||||
|
|
||||||
|
#include "Common\DeviceResources.h"
|
||||||
|
#include "CameraDirect_cppMain.h"
|
||||||
|
|
||||||
|
namespace CameraDirect_cpp
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A page that hosts a DirectX SwapChainPanel.
|
||||||
|
/// </summary>
|
||||||
|
public ref class DirectXPage sealed
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DirectXPage();
|
||||||
|
virtual ~DirectXPage();
|
||||||
|
|
||||||
|
void SaveInternalState(Windows::Foundation::Collections::IPropertySet^ state);
|
||||||
|
void LoadInternalState(Windows::Foundation::Collections::IPropertySet^ state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// XAML low-level rendering event handler.
|
||||||
|
void OnRendering(Platform::Object^ sender, Platform::Object^ args);
|
||||||
|
|
||||||
|
// Window event handlers.
|
||||||
|
void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
|
||||||
|
|
||||||
|
// DisplayInformation event handlers.
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Other event handlers.
|
||||||
|
void AppBarButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||||
|
void OnCompositionScaleChanged(Windows::UI::Xaml::Controls::SwapChainPanel^ sender, Object^ args);
|
||||||
|
void OnSwapChainPanelSizeChanged(Platform::Object^ sender, Windows::UI::Xaml::SizeChangedEventArgs^ e);
|
||||||
|
|
||||||
|
// Track our independent input on a background worker thread.
|
||||||
|
Windows::Foundation::IAsyncAction^ m_inputLoopWorker;
|
||||||
|
Windows::UI::Core::CoreIndependentInputSource^ m_coreInput;
|
||||||
|
|
||||||
|
// Independent input handling functions.
|
||||||
|
void OnPointerPressed(Platform::Object^ sender, Windows::UI::Core::PointerEventArgs^ e);
|
||||||
|
void OnPointerMoved(Platform::Object^ sender, Windows::UI::Core::PointerEventArgs^ e);
|
||||||
|
void OnPointerReleased(Platform::Object^ sender, Windows::UI::Core::PointerEventArgs^ e);
|
||||||
|
|
||||||
|
// Resources used to render the DirectX content in the XAML page background.
|
||||||
|
std::shared_ptr<DX::DeviceResources> m_deviceResources;
|
||||||
|
std::unique_ptr<CameraDirect_cppMain> m_main;
|
||||||
|
bool m_windowVisible;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
49
Camera-Renderer_cpp/Package.appxmanifest
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<Package
|
||||||
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||||
|
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
|
||||||
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||||
|
IgnorableNamespaces="uap mp">
|
||||||
|
|
||||||
|
<Identity
|
||||||
|
Name="7bc5f09c-b343-4491-af0f-5370254b2533"
|
||||||
|
Publisher="CN=Brych"
|
||||||
|
Version="1.0.0.0" />
|
||||||
|
|
||||||
|
<mp:PhoneIdentity PhoneProductId="7bc5f09c-b343-4491-af0f-5370254b2533" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||||
|
|
||||||
|
<Properties>
|
||||||
|
<DisplayName>CameraDirect_cpp</DisplayName>
|
||||||
|
<PublisherDisplayName>Brych</PublisherDisplayName>
|
||||||
|
<Logo>Assets\StoreLogo.png</Logo>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Dependencies>
|
||||||
|
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||||
|
</Dependencies>
|
||||||
|
|
||||||
|
<Resources>
|
||||||
|
<Resource Language="x-generate"/>
|
||||||
|
</Resources>
|
||||||
|
|
||||||
|
<Applications>
|
||||||
|
<Application Id="App"
|
||||||
|
Executable="$targetnametoken$.exe"
|
||||||
|
EntryPoint="CameraDirect_cpp.App">
|
||||||
|
<uap:VisualElements
|
||||||
|
DisplayName="CameraDirect_cpp"
|
||||||
|
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||||
|
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||||
|
Description="CameraDirect_cpp"
|
||||||
|
BackgroundColor="transparent">
|
||||||
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||||
|
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||||
|
</uap:VisualElements>
|
||||||
|
</Application>
|
||||||
|
</Applications>
|
||||||
|
|
||||||
|
<Capabilities>
|
||||||
|
<Capability Name="internetClient" />
|
||||||
|
</Capabilities>
|
||||||
|
</Package>
|
1
Camera-Renderer_cpp/pch.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "pch.h"
|
17
Camera-Renderer_cpp/pch.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <wrl.h>
|
||||||
|
#include <wrl/client.h>
|
||||||
|
#include <dxgi1_4.h>
|
||||||
|
#include <d3d11_3.h>
|
||||||
|
#include <d2d1_3.h>
|
||||||
|
#include <d2d1effects_2.h>
|
||||||
|
#include <dwrite_3.h>
|
||||||
|
#include <wincodec.h>
|
||||||
|
#include <DirectXColors.h>
|
||||||
|
#include <DirectXMath.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <agile.h>
|
||||||
|
#include <concrt.h>
|
||||||
|
#include <collection.h>
|
||||||
|
#include "App.xaml.h"
|
1
Camera-Renderer_cs
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit ab141dac9c1a811b032598de458b54d518fa0e71
|