summaryrefslogtreecommitdiffstats
path: root/unityplugin/UnityEmulator
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2017-11-13 04:14:15 +0000
committerEgor Yusov <egor.yusov@gmail.com>2017-11-13 04:14:15 +0000
commit1b2530749ea3dc4937cdd7aa37e5a144e6d10183 (patch)
treede2a77d6c8ce8a33c2b3070c66549f429e43a017 /unityplugin/UnityEmulator
parentUpdated submodules (diff)
downloadDiligentEngine-1b2530749ea3dc4937cdd7aa37e5a144e6d10183.tar.gz
DiligentEngine-1b2530749ea3dc4937cdd7aa37e5a144e6d10183.zip
Updated to version 2.1
Diffstat (limited to 'unityplugin/UnityEmulator')
-rw-r--r--unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems32
-rw-r--r--unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems.filters16
-rw-r--r--unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj200
-rw-r--r--unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj.filters2
-rw-r--r--unityplugin/UnityEmulator/build/Win32/UnityEmulator-Debug.vgdbsettings76
-rw-r--r--unityplugin/UnityEmulator/build/Win32/UnityEmulator-Release.vgdbsettings76
-rw-r--r--unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj265
-rw-r--r--unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj.filters65
-rw-r--r--unityplugin/UnityEmulator/build/Win32/jni/Android.mk46
-rw-r--r--unityplugin/UnityEmulator/build/Win32/jni/Application.mk7
-rw-r--r--unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems45
-rw-r--r--unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems.filters81
-rw-r--r--unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.props40
-rw-r--r--unityplugin/UnityEmulator/include/DiligentGraphicsAdapter.h50
-rw-r--r--unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D11.h41
-rw-r--r--unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D12.h44
-rw-r--r--unityplugin/UnityEmulator/include/DiligentGraphicsAdapterGL.h46
-rw-r--r--unityplugin/UnityEmulator/include/ResourceStateTransitionHandler.h31
-rw-r--r--unityplugin/UnityEmulator/include/UnityGraphicsD3D11Emulator.h29
-rw-r--r--unityplugin/UnityEmulator/include/UnityGraphicsD3D12Emulator.h32
-rw-r--r--unityplugin/UnityEmulator/include/UnityGraphicsEmulator.h41
-rw-r--r--unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h42
-rw-r--r--unityplugin/UnityEmulator/include/UnitySceneBase.h74
-rw-r--r--unityplugin/UnityEmulator/src/Android/AndroidMainImpl.cpp565
-rw-r--r--unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorApplication.java47
-rw-r--r--unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorNativeActivity.java164
-rw-r--r--unityplugin/UnityEmulator/src/Android/Java/helper/NDKHelper.java203
-rw-r--r--unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp326
-rw-r--r--unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h91
-rw-r--r--unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D11.cpp127
-rw-r--r--unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp254
-rw-r--r--unityplugin/UnityEmulator/src/DiligentGraphicsAdapterGL.cpp103
-rw-r--r--unityplugin/UnityEmulator/src/UWP/App.cpp252
-rw-r--r--unityplugin/UnityEmulator/src/UWP/App.h75
-rw-r--r--unityplugin/UnityEmulator/src/UWP/DeviceResources.cpp459
-rw-r--r--unityplugin/UnityEmulator/src/UWP/DeviceResources.h71
-rw-r--r--unityplugin/UnityEmulator/src/UWP/DirectXHelper.h58
-rw-r--r--unityplugin/UnityEmulator/src/UWP/StepTimer.h183
-rw-r--r--unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.cpp209
-rw-r--r--unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.h70
-rw-r--r--unityplugin/UnityEmulator/src/UWP/pch2.h20
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsD3D11Emulator.cpp370
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsD3D11Impl.h39
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp558
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h84
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsEmulator.cpp90
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp87
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.cpp189
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h37
-rw-r--r--unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h11
-rw-r--r--unityplugin/UnityEmulator/src/Windows/WinMain.cpp344
51 files changed, 6467 insertions, 0 deletions
diff --git a/unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems b/unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems
new file mode 100644
index 0000000..a0d4048
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <ItemsProjectGuid>{FBE96ADC-7C36-45B2-BE6D-F173413EB1C6}</ItemsProjectGuid>
+ <ItemsRootNamespace>AtmosphereSample</ItemsRootNamespace>
+ <ItemsProjectName>UnityEmulatorUWP.Shared</ItemsProjectName>
+ <SharedGUID>2c11e612-847b-48ac-a5dd-fd953e773442</SharedGUID>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectCapability Include="SourceItemsFromImports" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UWP\App.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UWP\DeviceResources.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UWP\UnityEmulatorAppMain.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\App.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\DeviceResources.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\DirectXHelper.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\pch2.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\UnityEmulatorAppMain.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\StepTimer.h" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems.filters b/unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems.filters
new file mode 100644
index 0000000..6763a1b
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/UWP.Shared/UnityEmulatorUWP.Shared.vcxitems.filters
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UWP\App.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UWP\DeviceResources.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UWP\UnityEmulatorAppMain.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\App.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\pch2.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\DeviceResources.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\DirectXHelper.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\StepTimer.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UWP\UnityEmulatorAppMain.h" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj b/unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj
new file mode 100644
index 0000000..074fade
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{17597734-2FBF-481F-99D4-3315B70FE3E2}</ProjectGuid>
+ <Keyword>StaticLibrary</Keyword>
+ <RootNamespace>UnityEmulator</RootNamespace>
+ <DefaultLanguage>en-US</DefaultLanguage>
+ <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+ <AppContainerApplication>true</AppContainerApplication>
+ <ApplicationType>Windows Store</ApplicationType>
+ <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
+ <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
+ <ApplicationTypeRevision>10.0</ApplicationTypeRevision>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <PlatformToolset>v140</PlatformToolset>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ <Import Project="..\Windows.Shared\UnityEmulator.Shared.vcxitems" Label="Shared" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\UWP\UWP_Win32Dbg.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\UWP\UWP_Win32Rel.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\UWP\UWP_ArmDbg.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\UWP\UWP_ArmRel.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\UWP\UWP_X64Dbg.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\UWP\UWP_X64Rel.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <GenerateManifest>false</GenerateManifest>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <GenerateManifest>false</GenerateManifest>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <GenerateManifest>false</GenerateManifest>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|arm'">
+ <ClCompile>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|arm'">
+ <ClCompile>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <CompileAsWinRT>false</CompileAsWinRT>
+ <SDLCheck>true</SDLCheck>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+ <GenerateWindowsMetadata>false</GenerateWindowsMetadata>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj.filters b/unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj.filters
new file mode 100644
index 0000000..c31757e
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/UWP/UnityEmulator.vcxproj.filters
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" /> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Win32/UnityEmulator-Debug.vgdbsettings b/unityplugin/UnityEmulator/build/Win32/UnityEmulator-Debug.vgdbsettings
new file mode 100644
index 0000000..3f5b24b
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Win32/UnityEmulator-Debug.vgdbsettings
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <ConfigurationName>Debug</ConfigurationName>
+ <Project xsi:type="com.visualgdb.project.android">
+ <CustomSourceDirectories>
+ <Directories />
+ <PathStyle>MinGWWindowsSlash</PathStyle>
+ </CustomSourceDirectories>
+ <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath>
+ </Project>
+ <Build xsi:type="com.visualgdb.build.android">
+ <AndroidPlatform>android-19</AndroidPlatform>
+ <IsDebugConfiguration>true</IsDebugConfiguration>
+ <JNIOnlyBuild>true</JNIOnlyBuild>
+ <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean>
+ <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean>
+ <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest>
+ <CustomActions />
+ </Build>
+ <Debug xsi:type="com.visualgdb.debug.android">
+ <AdditionalStartupCommands />
+ <AdditionalGDBSettings>
+ <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications>
+ <ForceSingleThreadedMode>false</ForceSingleThreadedMode>
+ <PendingBreakpointsSupported>true</PendingBreakpointsSupported>
+ <DisableChildRanges>false</DisableChildRanges>
+ <UseAppleExtensions>false</UseAppleExtensions>
+ <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning>
+ <MakeLogFile>false</MakeLogFile>
+ <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping>
+ <UseRelativePathsOnly>false</UseRelativePathsOnly>
+ <ExitAction>KillApp</ExitAction>
+ <Features>
+ <DisableAutoDetection>false</DisableAutoDetection>
+ <UseFrameParameter>false</UseFrameParameter>
+ <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported>
+ <ListLocalsSupported>false</ListLocalsSupported>
+ <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable>
+ <ThreadInfoSupported>false</ThreadInfoSupported>
+ <PendingBreakpointsSupported>false</PendingBreakpointsSupported>
+ <SupportTargetCommand>false</SupportTargetCommand>
+ </Features>
+ <DisableDisassembly>false</DisableDisassembly>
+ <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand>
+ <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry>
+ <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat>
+ </AdditionalGDBSettings>
+ <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" />
+ <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC>
+ <UseDefaultInstallDir>false</UseDefaultInstallDir>
+ <RemotePort>5039</RemotePort>
+ <LocalPort>5039</LocalPort>
+ <GDBServerStartupTimeout>10000</GDBServerStartupTimeout>
+ <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay>
+ <DoubleSlashWorkaround>false</DoubleSlashWorkaround>
+ <AlreadyRunningDecision>Ask</AlreadyRunningDecision>
+ <ShowLogCat>true</ShowLogCat>
+ <EnableThreadNameWatcher>true</EnableThreadNameWatcher>
+ </Debug>
+ <CustomBuild>
+ <PreBuildActions />
+ <PostBuildActions />
+ <PreCleanActions />
+ <PostCleanActions />
+ </CustomBuild>
+ <CustomDebug>
+ <PreDebugActions />
+ <PostDebugActions />
+ <BreakMode>Default</BreakMode>
+ </CustomDebug>
+ <CustomShortcuts>
+ <Shortcuts />
+ <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting>
+ </CustomShortcuts>
+ <UserDefinedVariables />
+</VisualGDBProjectSettings2> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Win32/UnityEmulator-Release.vgdbsettings b/unityplugin/UnityEmulator/build/Win32/UnityEmulator-Release.vgdbsettings
new file mode 100644
index 0000000..669691f
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Win32/UnityEmulator-Release.vgdbsettings
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<VisualGDBProjectSettings2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <ConfigurationName>Release</ConfigurationName>
+ <Project xsi:type="com.visualgdb.project.android">
+ <CustomSourceDirectories>
+ <Directories />
+ <PathStyle>MinGWWindowsSlash</PathStyle>
+ </CustomSourceDirectories>
+ <AndroidProjectPath>$(ProjectDir)</AndroidProjectPath>
+ </Project>
+ <Build xsi:type="com.visualgdb.build.android">
+ <AndroidPlatform>android-19</AndroidPlatform>
+ <IsDebugConfiguration>false</IsDebugConfiguration>
+ <JNIOnlyBuild>true</JNIOnlyBuild>
+ <AdditionalDirectoriesToDeleteOnClean>bin;obj</AdditionalDirectoriesToDeleteOnClean>
+ <DeleteANTFilesOnClean>false</DeleteANTFilesOnClean>
+ <DoNotEditAndroidManifest>false</DoNotEditAndroidManifest>
+ <CustomActions />
+ </Build>
+ <Debug xsi:type="com.visualgdb.debug.android">
+ <AdditionalStartupCommands />
+ <AdditionalGDBSettings>
+ <FilterSpuriousStoppedNotifications>false</FilterSpuriousStoppedNotifications>
+ <ForceSingleThreadedMode>false</ForceSingleThreadedMode>
+ <PendingBreakpointsSupported>true</PendingBreakpointsSupported>
+ <DisableChildRanges>false</DisableChildRanges>
+ <UseAppleExtensions>false</UseAppleExtensions>
+ <CanAcceptCommandsWhileRunning>false</CanAcceptCommandsWhileRunning>
+ <MakeLogFile>false</MakeLogFile>
+ <IgnoreModuleEventsWhileStepping>true</IgnoreModuleEventsWhileStepping>
+ <UseRelativePathsOnly>false</UseRelativePathsOnly>
+ <ExitAction>KillApp</ExitAction>
+ <Features>
+ <DisableAutoDetection>false</DisableAutoDetection>
+ <UseFrameParameter>false</UseFrameParameter>
+ <SimpleValuesFlagSupported>false</SimpleValuesFlagSupported>
+ <ListLocalsSupported>false</ListLocalsSupported>
+ <ByteLevelMemoryCommandsAvailable>false</ByteLevelMemoryCommandsAvailable>
+ <ThreadInfoSupported>false</ThreadInfoSupported>
+ <PendingBreakpointsSupported>false</PendingBreakpointsSupported>
+ <SupportTargetCommand>false</SupportTargetCommand>
+ </Features>
+ <DisableDisassembly>false</DisableDisassembly>
+ <ExamineMemoryWithXCommand>false</ExamineMemoryWithXCommand>
+ <StepIntoNewInstanceEntry>main</StepIntoNewInstanceEntry>
+ <ExamineRegistersInRawFormat>true</ExamineRegistersInRawFormat>
+ </AdditionalGDBSettings>
+ <LaunchGDBSettings xsi:type="GDBLaunchParametersAndroid" />
+ <GenerateCtrlBreakInsteadOfCtrlC>false</GenerateCtrlBreakInsteadOfCtrlC>
+ <UseDefaultInstallDir>false</UseDefaultInstallDir>
+ <RemotePort>5039</RemotePort>
+ <LocalPort>5039</LocalPort>
+ <GDBServerStartupTimeout>10000</GDBServerStartupTimeout>
+ <AdditionalGDBServerStartupDelay>0</AdditionalGDBServerStartupDelay>
+ <DoubleSlashWorkaround>false</DoubleSlashWorkaround>
+ <AlreadyRunningDecision>Ask</AlreadyRunningDecision>
+ <ShowLogCat>true</ShowLogCat>
+ <EnableThreadNameWatcher>true</EnableThreadNameWatcher>
+ </Debug>
+ <CustomBuild>
+ <PreBuildActions />
+ <PostBuildActions />
+ <PreCleanActions />
+ <PostCleanActions />
+ </CustomBuild>
+ <CustomDebug>
+ <PreDebugActions />
+ <PostDebugActions />
+ <BreakMode>Default</BreakMode>
+ </CustomDebug>
+ <CustomShortcuts>
+ <Shortcuts />
+ <ShowMessageAfterExecuting>true</ShowMessageAfterExecuting>
+ </CustomShortcuts>
+ <UserDefinedVariables />
+</VisualGDBProjectSettings2> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj b/unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj
new file mode 100644
index 0000000..d3dd0b6
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|ARM">
+ <Configuration>Debug</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|ARM">
+ <Configuration>Release</Configuration>
+ <Platform>ARM</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{F40021AC-6D7B-4828-81C4-2D04F946A88E}</ProjectGuid>
+ <RootNamespace>UnityEmulator</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.10240.0</WindowsTargetPlatformVersion>
+ <ProjectName>UnityEmulator</ProjectName>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <PlatformToolset>v120</PlatformToolset>
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <PlatformToolset>v120</PlatformToolset>
+ <ConfigurationType>Makefile</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ <Import Project="..\Windows.Shared\UnityEmulator.Shared.vcxitems" Label="Shared" Condition="Exists('..\WindowsStore\UnityEmulator.Shared\UnityEmulator.Shared.vcxitems')" />
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ <Import Project="..\Windows.Shared\UnityEmulator.Shared.vcxitems" Label="Shared" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\Windows\Win32d.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\Windows\Win64d.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </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" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\Windows\Win32r.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="..\..\..\..\diligentcore\Shared\build\Windows\Win64r.props" />
+ <Import Project="..\Windows.Shared\UnityEmulator.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <Import Project="..\..\..\..\diligentcore\Shared\build\Windows\Android32d.props" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <Import Project="..\..\..\..\diligentcore\Shared\build\Windows\Android32r.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
+ <NMakeForcedIncludes>$(ProjectDir)..\..\..\..\Common\Android\gcc_Debug.h;$(NMakeForcedIncludes)</NMakeForcedIncludes>
+ <NMakeOutput>
+ </NMakeOutput>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
+ <NMakeForcedIncludes>$(ProjectDir)..\..\..\..\Common\Android\gcc_Release.h;$(NMakeForcedIncludes)</NMakeForcedIncludes>
+ <NMakeOutput>
+ </NMakeOutput>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_WINDOWS;PLATFORM_WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Message>Copying D3DCompiler_47.dll to $(TargetDir)...</Message>
+ <Command>copy "$(VC_ExecutablePath_x86_x86)\D3Dcompiler_47.dll" "$(TargetDir)"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_WINDOWS;PLATFORM_WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Message>Copying D3DCompiler_47.dll to $(TargetDir)...</Message>
+ <Command>copy "$(VC_ExecutablePath_x64_x64)\D3Dcompiler_47.dll" "$(TargetDir)"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_WINDOWS;PLATFORM_WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Message>Copying D3DCompiler_47.dll to $(TargetDir)...</Message>
+ <Command>copy "$(VC_ExecutablePath_x86_x86)\D3Dcompiler_47.dll" "$(TargetDir)"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>_WINDOWS;PLATFORM_WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <SubSystem>Windows</SubSystem>
+ </Link>
+ <PostBuildEvent>
+ <Message>Copying D3DCompiler_47.dll to $(TargetDir)...</Message>
+ <Command>copy "$(VC_ExecutablePath_x64_x64)\D3Dcompiler_47.dll" "$(TargetDir)"</Command>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\Android\AndroidMainImpl.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\src\Android\UnityGraphicsGLESAndroid_Impl.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\src\DiligentGraphicsAdapterGL.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\src\UnityGraphicsEmulator.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\src\UnityGraphicsGLCoreES_Emulator.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+ </ClCompile>
+ <ClCompile Include="..\..\src\Windows\WinMain.cpp">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">true</ExcludedFromBuild>
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\..\diligentcore\Common\build\Win32\Common.vcxproj">
+ <Project>{7380f7e6-315f-4b4e-92eb-e6aeee865298}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\External\glew\build\Win32\glew_static.vcxproj">
+ <Project>{664e6f0d-6784-4760-9565-d54f8eb1edf4}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\Graphics\GraphicsEngineD3D11\build\Win32\GraphicsEngineD3D11.vcxproj">
+ <Project>{fe289cc7-15d6-4a76-b9cb-f61cab3192c9}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\Graphics\GraphicsEngineD3D12\build\Win32\GraphicsEngineD3D12.vcxproj">
+ <Project>{fff8071a-db82-485b-adc3-f0b675296869}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\Graphics\GraphicsEngineOpenGL\build\Win32\GraphicsEngineOpenGL.vcxproj">
+ <Project>{15e346d3-fde6-4b29-88b7-fca14dada501}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\Graphics\GraphicsEngine\build\Win32\GraphicsEngine.vcxproj">
+ <Project>{052dd700-477c-4512-a7f4-b05ebef5c80e}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\Platforms\Basic\build\Win32\BasicPlatform.vcxproj">
+ <Project>{8ada5f93-7a38-4ad8-b8f5-1ffd4d4f630c}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\..\..\..\diligentcore\Platforms\Win32\build\Win32\WindowsPlatform.vcxproj">
+ <Project>{58f32677-436b-412a-bbf8-2b1310d82cd8}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\src\Android\Java\helper\NDKHelper.java" />
+ <None Include="..\..\src\Android\Java\UnityEmulator\UnityEmulatorNativeActivity.java" />
+ <None Include="..\..\src\Android\Java\UnityEmulator\UnityEmulatorApplication.java" />
+ <None Include="jni\Android.mk" />
+ <None Include="jni\Application.mk" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\Android\UnityGraphicsGLESAndroid_Impl.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj.filters b/unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj.filters
new file mode 100644
index 0000000..6952802
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Win32/UnityEmulator.vcxproj.filters
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Android">
+ <UniqueIdentifier>{154722cc-8c82-4869-8e51-fb073a87f966}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Android\Java">
+ <UniqueIdentifier>{fe07d990-c5ac-488d-b7df-b3c66018d0b3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Android\jni">
+ <UniqueIdentifier>{31c218a8-0b04-4224-97ad-909aeff5c135}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Android\src">
+ <UniqueIdentifier>{90e91db8-8be2-446b-abee-0365b7dc18a8}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Windows">
+ <UniqueIdentifier>{e9f1e7cd-5112-4fb6-854a-3ebfd5efa88b}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Windows\src">
+ <UniqueIdentifier>{f1774749-d1e5-4b2c-9f8d-df8ef690d4b5}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\Windows\WinMain.cpp">
+ <Filter>Windows\src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\Android\AndroidMainImpl.cpp">
+ <Filter>Android\src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\Android\UnityGraphicsGLESAndroid_Impl.cpp">
+ <Filter>Android\src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\UnityGraphicsGLCoreES_Emulator.cpp">
+ <Filter>Android\src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\DiligentGraphicsAdapterGL.cpp">
+ <Filter>Android\src</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\src\UnityGraphicsEmulator.cpp">
+ <Filter>Android\src</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\src\Android\Java\helper\NDKHelper.java">
+ <Filter>Android\Java</Filter>
+ </None>
+ <None Include="jni\Android.mk">
+ <Filter>Android\jni</Filter>
+ </None>
+ <None Include="jni\Application.mk">
+ <Filter>Android\jni</Filter>
+ </None>
+ <None Include="..\..\src\Android\Java\UnityEmulator\UnityEmulatorNativeActivity.java">
+ <Filter>Android\Java</Filter>
+ </None>
+ <None Include="..\..\src\Android\Java\UnityEmulator\UnityEmulatorApplication.java">
+ <Filter>Android\Java</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\src\Android\UnityGraphicsGLESAndroid_Impl.h">
+ <Filter>Android\src</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Win32/jni/Android.mk b/unityplugin/UnityEmulator/build/Win32/jni/Android.mk
new file mode 100644
index 0000000..45466e4
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Win32/jni/Android.mk
@@ -0,0 +1,46 @@
+
+DEPENDENCY_PATH := $(call my-dir)
+LOCAL_PATH := $(abspath $(DEPENDENCY_PATH))
+
+include $(CLEAR_VARS)
+# Project configuration
+LOCAL_MODULE := UnityEmulator
+LOCAL_CFLAGS := -std=c++11 -DENGINE_DLL
+LOCAL_CPP_FEATURES := exceptions
+
+LOCAL_STATIC_LIBRARIES := cpufeatures android_native_app_glue ndk_helper
+
+# Include paths
+PROJECT_ROOT := $(LOCAL_PATH)/../../..
+ENGINE_ROOT := $(PROJECT_ROOT)/../..
+CORE_ROOT := $(ENGINE_ROOT)/diligentcore
+TOOLS_ROOT := $(ENGINE_ROOT)/diligenttools
+# include directories for static libraries are declared in corresponding LOCAL_EXPORT_C_INCLUDES sections
+LOCAL_C_INCLUDES += $(PROJECT_ROOT)/include
+LOCAL_C_INCLUDES += $(PROJECT_ROOT)/src
+LOCAL_C_INCLUDES += $(PROJECT_ROOT)/../GhostCubePlugin/PluginSource/src/Unity
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Common/include
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Common/interface
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Platforms/interface
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Graphics/GraphicsEngine/interface
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Graphics/GraphicsEngine/include
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Graphics/GraphicsEngineD3DBase/include
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Graphics/GraphicsEngineOpenGL/interface
+LOCAL_C_INCLUDES += $(CORE_ROOT)/Graphics/HLSL2GLSLConverterLib/interface
+LOCAL_C_INCLUDES += $(TOOLS_ROOT)/Graphics/GraphicsTools/include
+
+# Source files
+#VisualGDBAndroid: AutoUpdateSourcesInNextLine
+LOCAL_SRC_FILES := ../../../src/Android/AndroidMainImpl.cpp ../../../src/Android/UnityGraphicsGLESAndroid_Impl.cpp ../../../src/DiligentGraphicsAdapterGL.cpp ../../../src/UnityGraphicsEmulator.cpp ../../../src/UnityGraphicsGLCoreES_Emulator.cpp ../../../src/Windows/WinMain.cpp
+
+# Build instructions
+#VisualGDBAndroid: VSExcludeListLocation
+VISUALGDB_VS_EXCLUDED_FILES_Release := ../../../Src/Win32/WinMain.cpp
+VISUALGDB_VS_EXCLUDED_FILES_Debug := ../../../src/Windows/WinMain.cpp
+LOCAL_SRC_FILES := $(filter-out $(VISUALGDB_VS_EXCLUDED_FILES_$(VGDB_VSCONFIG)),$(LOCAL_SRC_FILES))
+
+include $(BUILD_STATIC_LIBRARY)
+
+$(call import-module,android/ndk_helper)
+$(call import-module,android/native_app_glue)
+$(call import-module,android/cpufeatures)
diff --git a/unityplugin/UnityEmulator/build/Win32/jni/Application.mk b/unityplugin/UnityEmulator/build/Win32/jni/Application.mk
new file mode 100644
index 0000000..e8ef4b4
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Win32/jni/Application.mk
@@ -0,0 +1,7 @@
+# Generated by VisualGDB
+
+DEPENDENCY_PATH := $(call my-dir)
+LOCAL_PATH := $(abspath $(DEPENDENCY_PATH))
+include $(LOCAL_PATH)/../../../../../diligentcore/Common/make/AppCommon.mk
+
+APP_MODULES := UnityEmulator \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems b/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems
new file mode 100644
index 0000000..37e73bc
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <ItemsProjectGuid>{ae83b976-c8ca-4621-9269-bf47c5789018}</ItemsProjectGuid>
+ <ItemsRootNamespace>AtmosphereSample</ItemsRootNamespace>
+ <ItemsProjectName>UnityEmulator.Shared</ItemsProjectName>
+ <SharedGUID>2c11e612-847b-48ac-a5dd-fd953e773442</SharedGUID>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$(MSBuildThisFileDirectory)</AdditionalIncludeDirectories>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ProjectCapability Include="SourceItemsFromImports" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapter.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapterD3D11.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapterD3D12.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapterGL.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ResourceStateTransitionHandler.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsD3D11Emulator.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsD3D12Emulator.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsEmulator.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsGLCoreES_Emulator.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnitySceneBase.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D11Impl.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D12Impl.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGLCore_Impl.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGL_Impl.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D11Emulator.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D12Emulator.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsEmulator.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGLCoreES_Emulator.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DiligentGraphicsAdapterD3D11.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DiligentGraphicsAdapterD3D12.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DiligentGraphicsAdapterGL.cpp" />
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGLCore_Impl.cpp" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems.filters b/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems.filters
new file mode 100644
index 0000000..4fb2f8d
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.Shared.vcxitems.filters
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="src">
+ <UniqueIdentifier>{74468132-c052-44c1-9407-963d145244d1}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="include">
+ <UniqueIdentifier>{58f43661-c9a6-48e2-bfaa-818a394b2c36}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnitySceneBase.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapter.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapterD3D11.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapterD3D12.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\DiligentGraphicsAdapterGL.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D11Impl.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D12Impl.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\ResourceStateTransitionHandler.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsD3D11Emulator.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsD3D12Emulator.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsEmulator.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGLCore_Impl.h">
+ <Filter>src</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\include\UnityGraphicsGLCoreES_Emulator.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ <ClInclude Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGL_Impl.h">
+ <Filter>include</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D11Emulator.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsEmulator.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsD3D12Emulator.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DiligentGraphicsAdapterD3D11.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DiligentGraphicsAdapterD3D12.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\DiligentGraphicsAdapterGL.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGLCore_Impl.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ <ClCompile Include="$(MSBuildThisFileDirectory)..\..\src\UnityGraphicsGLCoreES_Emulator.cpp">
+ <Filter>src</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.props b/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.props
new file mode 100644
index 0000000..915b946
--- /dev/null
+++ b/unityplugin/UnityEmulator/build/Windows.Shared/UnityEmulator.props
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ImportGroup Label="PropertySheets" />
+ <PropertyGroup Label="UserMacros">
+ <ProjectRoot>..\..</ProjectRoot>
+ <AssetsPath>$(ProjectRoot)\build\assets</AssetsPath>
+ <EngineRoot>$(ProjectRoot)\..\..</EngineRoot>
+ <CoreRoot>$(EngineRoot)\diligentcore</CoreRoot>
+ <ToolsRoot>$(EngineRoot)\diligenttools</ToolsRoot>
+ </PropertyGroup>
+ <PropertyGroup>
+ <IncludePath>$(ProjectRoot)\include;$(CoreRoot)\Graphics\GraphicsEngine\interface;$(CoreRoot)\Graphics\GraphicsEngine\include;$(CoreRoot)\Graphics\GraphicsEngineD3D11\interface;$(CoreRoot)\Graphics\GraphicsEngineD3D12\interface;$(CoreRoot)\Graphics\GraphicsEngineD3DBase\include;$(CoreRoot)\Graphics\GraphicsEngineOpenGL\interface;$(CoreRoot)\Graphics\HLSL2GLSLConverterLib\interface;$(CoreRoot)\Common\include;$(CoreRoot)\Common\interface;$(CoreRoot)\Platforms\interface;$(CoreRoot)\Graphics\GraphicsTools\include;$(ToolsRoot)\TextureLoader\interface;$(AssetsPath)\shaders;$(ProjectRoot)\..\GhostCubePlugin\PluginSource\src\Unity;$(ProjectRoot)\src;$(ProjectRoot)\src\UWP;$(CoreRoot)\External\glew\include\GL;$(IncludePath)</IncludePath>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <PostBuildEvent />
+ <Link>
+ <AdditionalDependencies>d3d11.lib;d3d12.lib;d3dcompiler.lib;opengl32.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <BuildMacro Include="ProjectRoot">
+ <Value>$(ProjectRoot)</Value>
+ </BuildMacro>
+ <BuildMacro Include="AssetsPath">
+ <Value>$(AssetsPath)</Value>
+ </BuildMacro>
+ <BuildMacro Include="EngineRoot">
+ <Value>$(EngineRoot)</Value>
+ </BuildMacro>
+ <BuildMacro Include="CoreRoot">
+ <Value>$(CoreRoot)</Value>
+ </BuildMacro>
+ <BuildMacro Include="ToolsRoot">
+ <Value>$(ToolsRoot)</Value>
+ </BuildMacro>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/include/DiligentGraphicsAdapter.h b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapter.h
new file mode 100644
index 0000000..5af252c
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapter.h
@@ -0,0 +1,50 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+#pragma once
+
+#include "RenderDevice.h"
+#include "DeviceContext.h"
+#include "RefCntAutoPtr.h"
+
+class DiligentGraphicsAdapter
+{
+public:
+ virtual ~DiligentGraphicsAdapter() = 0;
+
+ virtual void BeginFrame() = 0;
+ virtual void EndFrame() = 0;
+ virtual void PreSwapChainResize() {}
+ virtual void PostSwapChainResize() {}
+
+ Diligent::IRenderDevice* GetDevice() { return m_pDevice; }
+ Diligent::IDeviceContext* GetContext() { return m_pDeviceCtx; }
+ Diligent::ISwapChain* GetSwapChain() { return m_pProxySwapChain; }
+ virtual bool UsesReverseZ() = 0;
+
+protected:
+ Diligent::RefCntAutoPtr<Diligent::IRenderDevice> m_pDevice;
+ Diligent::RefCntAutoPtr<Diligent::IDeviceContext> m_pDeviceCtx;
+ Diligent::RefCntAutoPtr<Diligent::ISwapChain> m_pProxySwapChain;
+};
+
+inline DiligentGraphicsAdapter::~DiligentGraphicsAdapter() {}
diff --git a/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D11.h b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D11.h
new file mode 100644
index 0000000..3e5d64f
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D11.h
@@ -0,0 +1,41 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+#pragma once
+
+#include "DiligentGraphicsAdapter.h"
+
+class DiligentGraphicsAdapterD3D11 : public DiligentGraphicsAdapter
+{
+public:
+ virtual ~DiligentGraphicsAdapterD3D11()override {}
+
+ DiligentGraphicsAdapterD3D11(const class UnityGraphicsD3D11Emulator& UnityGraphicsD3D11)noexcept;
+ void InitProxySwapChain();
+
+ virtual void BeginFrame()override final;
+ virtual void EndFrame()override final;
+ virtual bool UsesReverseZ()override final;
+
+private:
+ const UnityGraphicsD3D11Emulator& m_UnityGraphicsD3D11;
+};
diff --git a/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D12.h b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D12.h
new file mode 100644
index 0000000..a9f3cd7
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterD3D12.h
@@ -0,0 +1,44 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+#pragma once
+
+#include "DiligentGraphicsAdapter.h"
+
+class DiligentGraphicsAdapterD3D12 : public DiligentGraphicsAdapter
+{
+public:
+ virtual ~DiligentGraphicsAdapterD3D12()override {}
+
+ DiligentGraphicsAdapterD3D12(class UnityGraphicsD3D12Emulator& UnityGraphicsD3D12)noexcept;
+ void InitProxySwapChain();
+
+ virtual void BeginFrame()override final;
+ virtual void EndFrame()override final;
+ virtual void PreSwapChainResize()override final;
+ virtual void PostSwapChainResize()override final;
+ virtual bool UsesReverseZ()override final;
+
+private:
+ UnityGraphicsD3D12Emulator& m_UnityGraphicsD3D12;
+
+};
diff --git a/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterGL.h b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterGL.h
new file mode 100644
index 0000000..28770cb
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/DiligentGraphicsAdapterGL.h
@@ -0,0 +1,46 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+#pragma once
+
+#include "PlatformDefinitions.h"
+
+#if OPENGL_SUPPORTED
+
+#include "DiligentGraphicsAdapter.h"
+
+class DiligentGraphicsAdapterGL : public DiligentGraphicsAdapter
+{
+public:
+ virtual ~DiligentGraphicsAdapterGL()override {}
+
+ DiligentGraphicsAdapterGL(const class UnityGraphicsGLCoreES_Emulator& UnityGraphicsGL)noexcept;
+
+ virtual void BeginFrame()override final;
+ virtual void EndFrame()override final;
+ virtual bool UsesReverseZ()override final;
+
+private:
+ const UnityGraphicsGLCoreES_Emulator& m_UnityGraphicsGL;
+};
+
+#endif // OPENGL_SUPPORTED \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/include/ResourceStateTransitionHandler.h b/unityplugin/UnityEmulator/include/ResourceStateTransitionHandler.h
new file mode 100644
index 0000000..ba1feea
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/ResourceStateTransitionHandler.h
@@ -0,0 +1,31 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+#pragma once
+
+struct UnityGraphicsD3D12ResourceState;
+class IResourceStateTransitionHandler
+{
+public:
+ virtual ~IResourceStateTransitionHandler(){}
+ virtual void TransitionResources(int stateCount, UnityGraphicsD3D12ResourceState* states){}
+};
diff --git a/unityplugin/UnityEmulator/include/UnityGraphicsD3D11Emulator.h b/unityplugin/UnityEmulator/include/UnityGraphicsD3D11Emulator.h
new file mode 100644
index 0000000..5907591
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/UnityGraphicsD3D11Emulator.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <memory>
+#include "UnityGraphicsEmulator.h"
+
+class UnityGraphicsD3D11Impl;
+class UnityGraphicsD3D11Emulator : public UnityGraphicsEmulator
+{
+public:
+ static UnityGraphicsD3D11Emulator& GetInstance();
+ void CreateD3D11DeviceAndContext();
+ void CreateSwapChain(void *pNativeWndHandle, unsigned int Width, unsigned int Height);
+
+ virtual void Present()override final;
+ virtual void Release()override final;
+ virtual void BeginFrame()override final;
+ virtual void EndFrame()override final;
+ virtual void ResizeSwapChain(unsigned int Width, unsigned int Height)override final;
+ virtual bool UsesReverseZ()const override final { return true; }
+ virtual IUnityInterface* GetUnityGraphicsAPIInterface()override final;
+ static UnityGraphicsD3D11Impl* GetGraphicsImpl();
+ virtual UnityGfxRenderer GetUnityGfxRenderer()override final;
+ virtual bool SwapChainInitialized()override final;
+ void* GetD3D11Device();
+
+private:
+ UnityGraphicsD3D11Emulator();
+ static std::unique_ptr<UnityGraphicsD3D11Impl> m_GraphicsImpl;
+};
diff --git a/unityplugin/UnityEmulator/include/UnityGraphicsD3D12Emulator.h b/unityplugin/UnityEmulator/include/UnityGraphicsD3D12Emulator.h
new file mode 100644
index 0000000..b668e39
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/UnityGraphicsD3D12Emulator.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <memory>
+#include "UnityGraphicsEmulator.h"
+
+class UnityGraphicsD3D12Impl;
+class IResourceStateTransitionHandler;
+
+class UnityGraphicsD3D12Emulator : public UnityGraphicsEmulator
+{
+public:
+ static UnityGraphicsD3D12Emulator& GetInstance();
+ void CreateD3D12DeviceAndCommandQueue();
+ void CreateSwapChain(void *pNativeWndHandle, unsigned int Width, unsigned int Height);
+ void SetTransitionHandler(IResourceStateTransitionHandler *pTransitionHandler);
+
+ virtual void Present()override final;
+ virtual void Release()override final;
+ virtual void BeginFrame()override final;
+ virtual void EndFrame()override final;
+ virtual void ResizeSwapChain(unsigned int Width, unsigned int Height)override final;
+ virtual bool UsesReverseZ()const override final { return true; }
+ virtual IUnityInterface* GetUnityGraphicsAPIInterface()override final;
+ static UnityGraphicsD3D12Impl* GetGraphicsImpl();
+ virtual UnityGfxRenderer GetUnityGfxRenderer()override final;
+ virtual bool SwapChainInitialized()override final;
+ void* GetD3D12Device();
+
+private:
+ UnityGraphicsD3D12Emulator();
+ static std::unique_ptr<UnityGraphicsD3D12Impl> m_GraphicsImpl;
+};
diff --git a/unityplugin/UnityEmulator/include/UnityGraphicsEmulator.h b/unityplugin/UnityEmulator/include/UnityGraphicsEmulator.h
new file mode 100644
index 0000000..d362836
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/UnityGraphicsEmulator.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <vector>
+
+#include "IUnityInterface.h"
+#include "IUnityGraphics.h"
+
+
+class UnityGraphicsEmulator
+{
+public:
+ UnityGraphicsEmulator();
+ virtual void Release() = 0;
+ virtual void Present() = 0;
+ virtual void BeginFrame() = 0;
+ virtual void EndFrame() = 0;
+ virtual void ResizeSwapChain(unsigned int Width, unsigned int Height) = 0;
+ virtual bool SwapChainInitialized() = 0;
+ virtual bool UsesReverseZ()const { return false; }
+ virtual IUnityInterface* GetUnityGraphicsAPIInterface() = 0;
+ IUnityInterfaces &GeUnityInterfaces();
+
+ static UnityGraphicsEmulator& GetInstance() { return *m_Instance; }
+ void RegisterInterface(const UnityInterfaceGUID &guid, IUnityInterface* ptr);
+ IUnityInterface* GetInterface(const UnityInterfaceGUID &guid);
+ virtual UnityGfxRenderer GetUnityGfxRenderer() = 0;
+
+ void RegisterDeviceEventCallback(IUnityGraphicsDeviceEventCallback callback);
+ void UnregisterDeviceEventCallback(IUnityGraphicsDeviceEventCallback callback);
+ void InvokeDeviceEventCallback(UnityGfxDeviceEventType eventType);
+
+private:
+ UnityGraphicsEmulator(const UnityGraphicsEmulator&) = delete;
+ UnityGraphicsEmulator(UnityGraphicsEmulator&&) = delete;
+ UnityGraphicsEmulator& operator = (const UnityGraphicsEmulator&) = delete;
+ UnityGraphicsEmulator& operator = (UnityGraphicsEmulator&&) = delete;
+
+ std::vector< std::pair<UnityInterfaceGUID, IUnityInterface*> > m_Interfaces;
+ static UnityGraphicsEmulator *m_Instance;
+ std::vector<IUnityGraphicsDeviceEventCallback> m_DeviceEventCallbacks;
+};
diff --git a/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h b/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h
new file mode 100644
index 0000000..cc69f93
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "PlatformDefinitions.h"
+
+#if OPENGL_SUPPORTED
+
+#include <memory>
+#include "UnityGraphicsEmulator.h"
+
+#if defined(PLATFORM_ANDROID)
+ class UnityGraphicsGLESAndroid_Impl;
+ using UnityGraphicsGL_Impl = UnityGraphicsGLESAndroid_Impl;
+#elif defined( PLATFORM_WIN32 ) || defined( PLATFORM_UNIVERSAL_WINDOWS )
+ class UnityGraphicsGLCore_Impl;
+ using UnityGraphicsGL_Impl = UnityGraphicsGLCore_Impl;
+#else
+# error Unknown Platform
+#endif
+
+
+class UnityGraphicsGLCoreES_Emulator : public UnityGraphicsEmulator
+{
+public:
+ static UnityGraphicsGLCoreES_Emulator& GetInstance();
+ void InitGLContext(void *pNativeWndHandle, int MajorVersion, int MinorVersion);
+
+ virtual void Present()override final;
+ virtual void Release()override final;
+ virtual void BeginFrame()override final;
+ virtual void EndFrame()override final;
+ virtual void ResizeSwapChain(unsigned int Width, unsigned int Height)override final;
+ virtual IUnityInterface* GetUnityGraphicsAPIInterface()override final;
+ static UnityGraphicsGL_Impl* GetGraphicsImpl();
+ virtual UnityGfxRenderer GetUnityGfxRenderer()override final;
+ virtual bool SwapChainInitialized()override final;
+
+private:
+ UnityGraphicsGLCoreES_Emulator();
+ static std::unique_ptr<UnityGraphicsGL_Impl> m_GraphicsImpl;
+};
+
+#endif // OPENGL_SUPPORTED \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/include/UnitySceneBase.h b/unityplugin/UnityEmulator/include/UnitySceneBase.h
new file mode 100644
index 0000000..81ff6c1
--- /dev/null
+++ b/unityplugin/UnityEmulator/include/UnitySceneBase.h
@@ -0,0 +1,74 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+#pragma once
+
+#include "RenderDevice.h"
+#include "DeviceContext.h"
+#include "RefCntAutoPtr.h"
+#include "IUnityGraphics.h"
+#include "DiligentGraphicsAdapter.h"
+#include "ResourceStateTransitionHandler.h"
+
+typedef void* (*TLoadPluginFunction)(const char *FunctionName);
+
+class UnitySceneBase
+{
+public:
+ virtual ~UnitySceneBase() = 0;
+
+ virtual void OnPluginLoad(TLoadPluginFunction LoadPluginFunctionCallback) = 0;
+
+ virtual void OnPluginUnload() = 0;
+
+ virtual void OnGraphicsInitialized() = 0;
+
+ virtual void OnWindowResize(int NewWidth, int NewHeight)
+ {
+ m_WindowWidth = NewWidth;
+ m_WindowHeight = NewHeight;
+ }
+
+ virtual const char* GetSceneName() = 0;
+
+ virtual const char* GetPluginName() = 0;
+
+ virtual void Render(UnityRenderingEvent RenderEventFunc, double CurrTime, double ElapsedTime) = 0;
+
+ void SetDiligentGraphicsAdapter(DiligentGraphicsAdapter *DiligentGraphics)
+ {
+ m_DiligentGraphics = DiligentGraphics;
+ }
+
+ IResourceStateTransitionHandler* GetStateTransitionHandler() { return m_pStateTransitionHandler.get(); }
+
+protected:
+ DiligentGraphicsAdapter* m_DiligentGraphics;
+ std::unique_ptr<IResourceStateTransitionHandler> m_pStateTransitionHandler;
+
+ int m_WindowWidth = 640;
+ int m_WindowHeight = 480;
+};
+
+inline UnitySceneBase::~UnitySceneBase() {}
+
+extern UnitySceneBase* CreateScene();
diff --git a/unityplugin/UnityEmulator/src/Android/AndroidMainImpl.cpp b/unityplugin/UnityEmulator/src/Android/AndroidMainImpl.cpp
new file mode 100644
index 0000000..6943301
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Android/AndroidMainImpl.cpp
@@ -0,0 +1,565 @@
+ /* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+//--------------------------------------------------------------------------------
+// Include files
+//--------------------------------------------------------------------------------
+#include <jni.h>
+#include <errno.h>
+
+#include <android/sensor.h>
+#include <android/log.h>
+#include <android_native_app_glue.h>
+#include <android/native_window_jni.h>
+#include <cpu-features.h>
+#include <memory>
+
+#include "NDKHelper.h"
+
+#include "Timer.h"
+
+#include "IUnityInterface.h"
+#include "UnityGraphicsGLESAndroid_Impl.h"
+#include "UnityGraphicsGLCoreES_Emulator.h"
+#include "DiligentGraphicsAdapterGL.h"
+#include "UnitySceneBase.h"
+#include "StringTools.h"
+#include "Errors.h"
+
+//-------------------------------------------------------------------------
+//Preprocessor
+//-------------------------------------------------------------------------
+#define HELPER_CLASS_NAME "com/sample/helper/NDKHelper" //Class name of helper function
+//-------------------------------------------------------------------------
+//Shared state for our app.
+//-------------------------------------------------------------------------
+
+extern "C"
+{
+ void __attribute__((visibility("default"))) UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces);
+ void __attribute__((visibility("default"))) UNITY_INTERFACE_API UnityPluginUnload();
+ UnityRenderingEvent __attribute__((visibility("default"))) UNITY_INTERFACE_API GetRenderEventFunc();
+}
+
+void* LoadPluginFunction(const char* FunctionName);
+
+bool LoadPlugin()
+{
+ // Do nothing. Android automagically sets function pointers
+ return true;
+}
+
+
+struct android_app;
+class Engine
+{
+ bool initialized_resources_;
+ bool has_focus_;
+
+ ndk_helper::DoubletapDetector doubletap_detector_;
+ ndk_helper::PinchDetector pinch_detector_;
+ ndk_helper::DragDetector drag_detector_;
+ ndk_helper::PerfMonitor monitor_;
+
+ //ndk_helper::TapCamera tap_camera_;
+
+ android_app* app_;
+
+ ASensorManager* sensor_manager_;
+ const ASensor* accelerometer_sensor_;
+ ASensorEventQueue* sensor_event_queue_;
+
+ void UpdateFPS( float fFPS );
+ void ShowUI();
+ //void TransformPosition( ndk_helper::Vec2& vec );
+
+ std::unique_ptr<DiligentGraphicsAdapter> diligent_graphics_;
+ std::unique_ptr<UnitySceneBase> scene_;
+ UnityGraphicsGLCoreES_Emulator *unity_graphics_gles_emulator_ = nullptr;
+ UnityRenderingEvent render_event_func_ = nullptr;
+
+public:
+ static void HandleCmd( struct android_app* app,
+ int32_t cmd );
+ static int32_t HandleInput( android_app* app,
+ AInputEvent* event );
+
+ Engine();
+ ~Engine();
+ void SetState( android_app* state );
+ int InitDisplay();
+ void LoadResources();
+ void UnloadResources();
+ void DrawFrame();
+ void TermDisplay();
+ void TrimMemory();
+ bool IsReady();
+ void UnloadPlugin();
+
+ void UpdatePosition( AInputEvent* event,
+ int32_t iIndex,
+ float& fX,
+ float& fY );
+
+ void InitSensors();
+ void ProcessSensors( int32_t id );
+ void SuspendSensors();
+ void ResumeSensors();
+};
+
+//-------------------------------------------------------------------------
+//Ctor
+//-------------------------------------------------------------------------
+Engine::Engine() :
+ initialized_resources_( false ),
+ has_focus_( false ),
+ app_( NULL ),
+ sensor_manager_( NULL ),
+ accelerometer_sensor_( NULL ),
+ sensor_event_queue_( NULL ),
+ scene_(CreateScene())
+{
+ if (!LoadPlugin())
+ {
+ LOG_ERROR_AND_THROW("Failed to load native plugin");
+ }
+ scene_->OnPluginLoad(LoadPluginFunction);
+ render_event_func_ = GetRenderEventFunc();
+}
+
+void Engine::UnloadPlugin()
+{
+ unity_graphics_gles_emulator_->InvokeDeviceEventCallback(kUnityGfxDeviceEventShutdown);
+ UnityPluginUnload();
+}
+
+//-------------------------------------------------------------------------
+//Dtor
+//-------------------------------------------------------------------------
+Engine::~Engine()
+{
+ scene_->OnPluginUnload();
+ scene_.reset();
+ UnloadPlugin();
+ diligent_graphics_.reset();
+ unity_graphics_gles_emulator_->Release();
+}
+
+/**
+* Load resources
+*/
+void Engine::LoadResources()
+{
+ scene_->OnGraphicsInitialized();
+
+ //renderer_.Init();
+ //renderer_.Bind( &tap_camera_ );
+}
+
+/**
+* Unload resources
+*/
+void Engine::UnloadResources()
+{
+ //renderer_.Unload();
+}
+
+/**
+* Initialize an EGL context for the current display.
+*/
+int Engine::InitDisplay()
+{
+ if( !initialized_resources_ )
+ {
+ // Init graphics resources
+ auto &GraphicsGLCoreES_Emulator = UnityGraphicsGLCoreES_Emulator::GetInstance();
+ GraphicsGLCoreES_Emulator.InitGLContext(app_->window, 3, 1);
+ unity_graphics_gles_emulator_ = &GraphicsGLCoreES_Emulator;
+ diligent_graphics_.reset(new DiligentGraphicsAdapterGL(GraphicsGLCoreES_Emulator));
+
+ scene_->SetDiligentGraphicsAdapter(diligent_graphics_.get());
+
+ LoadResources();
+ initialized_resources_ = true;
+ }
+ else
+ {
+ // initialize OpenGL ES and EGL
+ if( EGL_SUCCESS != unity_graphics_gles_emulator_->GetGraphicsImpl()->Resume( app_->window ) )
+ {
+ UnloadResources();
+ LoadResources();
+ }
+ }
+
+ UnityPluginLoad(&unity_graphics_gles_emulator_->GeUnityInterfaces());
+
+ ShowUI();
+
+
+ auto *graphics_impl = unity_graphics_gles_emulator_->GetGraphicsImpl();
+ auto width = graphics_impl->GetBackBufferWidth();
+ auto height = graphics_impl->GetBackBufferHeight();
+
+ scene_->OnWindowResize(width, height);
+
+ //tap_camera_.SetFlip( 1.f, -1.f, -1.f );
+ //tap_camera_.SetPinchTransformFactor( 2.f, 2.f, 8.f );
+
+ return 0;
+}
+
+/**
+* Just the current frame in the display.
+*/
+void Engine::DrawFrame()
+{
+ float fFPS;
+ if( monitor_.Update( fFPS ) )
+ {
+ UpdateFPS( fFPS );
+ }
+
+ unity_graphics_gles_emulator_->BeginFrame();
+ diligent_graphics_->BeginFrame();
+
+ static Diligent::Timer timer;
+ static double prev_time = timer.GetElapsedTime();
+ auto curr_time = timer.GetElapsedTime();
+ auto elapsed_time = curr_time - prev_time;
+ prev_time = curr_time;
+
+ scene_->Render(render_event_func_, curr_time, elapsed_time);
+
+ diligent_graphics_->EndFrame();
+ unity_graphics_gles_emulator_->EndFrame();
+
+ unity_graphics_gles_emulator_->Present();
+ //if( EGL_SUCCESS != pRenderDevice_->Present() )
+ //{
+ // UnloadResources();
+ // LoadResources();
+ //}
+}
+
+/**
+* Tear down the EGL context currently associated with the display.
+*/
+void Engine::TermDisplay()
+{
+ unity_graphics_gles_emulator_->GetGraphicsImpl()->Suspend();
+}
+
+void Engine::TrimMemory()
+{
+ LOGI( "Trimming memory" );
+ unity_graphics_gles_emulator_->GetGraphicsImpl()->Invalidate();
+}
+
+/**
+* Process the next input event.
+*/
+int32_t Engine::HandleInput( android_app* app,
+ AInputEvent* event )
+{
+ Engine* eng = (Engine*)app->userData;
+ if( AInputEvent_getType( event ) == AINPUT_EVENT_TYPE_MOTION )
+ {
+ ndk_helper::GESTURE_STATE doubleTapState = eng->doubletap_detector_.Detect( event );
+ ndk_helper::GESTURE_STATE dragState = eng->drag_detector_.Detect( event );
+ ndk_helper::GESTURE_STATE pinchState = eng->pinch_detector_.Detect( event );
+
+ //Double tap detector has a priority over other detectors
+ if( doubleTapState == ndk_helper::GESTURE_STATE_ACTION )
+ {
+ //Detect double tap
+ //eng->tap_camera_.Reset( true );
+ }
+ else
+ {
+ //Handle drag state
+ if( dragState & ndk_helper::GESTURE_STATE_START )
+ {
+ //Otherwise, start dragging
+ ndk_helper::Vec2 v;
+ eng->drag_detector_.GetPointer( v );
+ float fX = 0, fY = 0;
+ v.Value(fX, fY);
+
+ //eng->TransformPosition( v );
+ //eng->tap_camera_.BeginDrag( v );
+ }
+ else if( dragState & ndk_helper::GESTURE_STATE_MOVE )
+ {
+ ndk_helper::Vec2 v;
+ eng->drag_detector_.GetPointer( v );
+ float fX = 0, fY = 0;
+ v.Value(fX, fY);
+
+ //eng->TransformPosition( v );
+ //eng->tap_camera_.Drag( v );
+ }
+ else if( dragState & ndk_helper::GESTURE_STATE_END )
+ {
+ //eng->tap_camera_.EndDrag();
+ }
+
+ //Handle pinch state
+ if( pinchState & ndk_helper::GESTURE_STATE_START )
+ {
+ //Start new pinch
+ ndk_helper::Vec2 v1;
+ ndk_helper::Vec2 v2;
+ eng->pinch_detector_.GetPointers( v1, v2 );
+ //eng->TransformPosition( v1 );
+ //eng->TransformPosition( v2 );
+ //eng->tap_camera_.BeginPinch( v1, v2 );
+ }
+ else if( pinchState & ndk_helper::GESTURE_STATE_MOVE )
+ {
+ //Multi touch
+ //Start new pinch
+ ndk_helper::Vec2 v1;
+ ndk_helper::Vec2 v2;
+ eng->pinch_detector_.GetPointers( v1, v2 );
+ //eng->TransformPosition( v1 );
+ //eng->TransformPosition( v2 );
+ //eng->tap_camera_.Pinch( v1, v2 );
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+/**
+* Process the next main command.
+*/
+void Engine::HandleCmd( struct android_app* app,
+ int32_t cmd )
+{
+ Engine* eng = (Engine*)app->userData;
+ switch( cmd )
+ {
+ case APP_CMD_SAVE_STATE:
+ break;
+ case APP_CMD_INIT_WINDOW:
+ // The window is being shown, get it ready.
+ if( app->window != NULL )
+ {
+ eng->InitDisplay();
+ eng->DrawFrame();
+ }
+ break;
+ case APP_CMD_TERM_WINDOW:
+ // The window is being hidden or closed, clean it up.
+ eng->TermDisplay();
+ eng->has_focus_ = false;
+ break;
+ case APP_CMD_STOP:
+ break;
+ case APP_CMD_GAINED_FOCUS:
+ eng->ResumeSensors();
+ //Start animation
+ eng->has_focus_ = true;
+ break;
+ case APP_CMD_LOST_FOCUS:
+ eng->SuspendSensors();
+ // Also stop animating.
+ eng->has_focus_ = false;
+ eng->DrawFrame();
+ break;
+ case APP_CMD_LOW_MEMORY:
+ //Free up GL resources
+ eng->TrimMemory();
+ break;
+ }
+}
+
+//-------------------------------------------------------------------------
+//Sensor handlers
+//-------------------------------------------------------------------------
+void Engine::InitSensors()
+{
+ sensor_manager_ = ASensorManager_getInstance();
+ accelerometer_sensor_ = ASensorManager_getDefaultSensor( sensor_manager_,
+ ASENSOR_TYPE_ACCELEROMETER );
+ sensor_event_queue_ = ASensorManager_createEventQueue( sensor_manager_, app_->looper,
+ LOOPER_ID_USER, NULL, NULL );
+}
+
+void Engine::ProcessSensors( int32_t id )
+{
+ // If a sensor has data, process it now.
+ if( id == LOOPER_ID_USER )
+ {
+ if( accelerometer_sensor_ != NULL )
+ {
+ ASensorEvent event;
+ while( ASensorEventQueue_getEvents( sensor_event_queue_, &event, 1 ) > 0 )
+ {
+ }
+ }
+ }
+}
+
+void Engine::ResumeSensors()
+{
+ // When our app gains focus, we start monitoring the accelerometer.
+ if( accelerometer_sensor_ != NULL )
+ {
+ ASensorEventQueue_enableSensor( sensor_event_queue_, accelerometer_sensor_ );
+ // We'd like to get 60 events per second (in us).
+ ASensorEventQueue_setEventRate( sensor_event_queue_, accelerometer_sensor_,
+ (1000L / 60) * 1000 );
+ }
+}
+
+void Engine::SuspendSensors()
+{
+ // When our app loses focus, we stop monitoring the accelerometer.
+ // This is to avoid consuming battery while not being used.
+ if( accelerometer_sensor_ != NULL )
+ {
+ ASensorEventQueue_disableSensor( sensor_event_queue_, accelerometer_sensor_ );
+ }
+}
+
+//-------------------------------------------------------------------------
+//Misc
+//-------------------------------------------------------------------------
+void Engine::SetState( android_app* state )
+{
+ app_ = state;
+ doubletap_detector_.SetConfiguration( app_->config );
+ drag_detector_.SetConfiguration( app_->config );
+ pinch_detector_.SetConfiguration( app_->config );
+}
+
+bool Engine::IsReady()
+{
+ if( has_focus_ )
+ return true;
+
+ return false;
+}
+
+//void Engine::TransformPosition( ndk_helper::Vec2& vec )
+//{
+// vec = ndk_helper::Vec2( 2.0f, 2.0f ) * vec
+// / ndk_helper::Vec2( pDeviceContext_->GetMainBackBufferDesc().Width, pDeviceContext_->GetMainBackBufferDesc().Height )
+// - ndk_helper::Vec2( 1.f, 1.f );
+//}
+
+void Engine::ShowUI()
+{
+ JNIEnv *jni;
+ app_->activity->vm->AttachCurrentThread( &jni, NULL );
+
+ //Default class retrieval
+ jclass clazz = jni->GetObjectClass( app_->activity->clazz );
+ jmethodID methodID = jni->GetMethodID( clazz, "showUI", "()V" );
+ jni->CallVoidMethod( app_->activity->clazz, methodID );
+
+ app_->activity->vm->DetachCurrentThread();
+ return;
+}
+
+void Engine::UpdateFPS( float fFPS )
+{
+ JNIEnv *jni;
+ app_->activity->vm->AttachCurrentThread( &jni, NULL );
+
+ //Default class retrieval
+ jclass clazz = jni->GetObjectClass( app_->activity->clazz );
+ jmethodID methodID = jni->GetMethodID( clazz, "updateFPS", "(F)V" );
+ jni->CallVoidMethod( app_->activity->clazz, methodID, fFPS );
+
+ app_->activity->vm->DetachCurrentThread();
+ return;
+}
+
+Engine g_engine;
+
+/**
+* This is the main entry point of a native application that is using
+* android_native_app_glue. It runs in its own thread, with its own
+* event loop for receiving input events and doing other things.
+*/
+
+// The actual android_main() must be defined in the application project
+void android_main_impl( android_app* state )
+{
+ app_dummy();
+
+ g_engine.SetState( state );
+
+ //Init helper functions
+ ndk_helper::JNIHelper::Init( state->activity, HELPER_CLASS_NAME );
+
+ state->userData = &g_engine;
+ state->onAppCmd = Engine::HandleCmd;
+ state->onInputEvent = Engine::HandleInput;
+
+#ifdef USE_NDK_PROFILER
+ monstartup( "libEngineSandbox.so" );
+#endif
+
+ // Prepare to monitor accelerometer
+ g_engine.InitSensors();
+
+ // loop waiting for stuff to do.
+ while( 1 )
+ {
+ // Read all pending events.
+ int id;
+ int events;
+ android_poll_source* source;
+
+ // If not animating, we will block forever waiting for events.
+ // If animating, we loop until all events are read, then continue
+ // to draw the next frame of animation.
+ while( (id = ALooper_pollAll( g_engine.IsReady() ? 0 : -1, NULL, &events, (void**)&source )) >= 0 )
+ {
+ // Process this event.
+ if( source != NULL )
+ source->process( state, source );
+
+ g_engine.ProcessSensors( id );
+
+ // Check if we are exiting.
+ if( state->destroyRequested != 0 )
+ {
+ g_engine.TermDisplay();
+ return;
+ }
+ }
+
+ if( g_engine.IsReady() )
+ {
+ // Drawing is throttled to the screen update rate, so there
+ // is no need to do timing here.
+ g_engine.DrawFrame();
+ }
+ }
+}
diff --git a/unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorApplication.java b/unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorApplication.java
new file mode 100644
index 0000000..249f291
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorApplication.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.DiligentGrpahics.UnityEmulator;
+
+import javax.microedition.khronos.opengles.GL10;
+
+import android.app.Application;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.opengl.GLUtils;
+import android.util.Log;
+import android.widget.Toast;
+
+public class UnityEmulatorApplication extends Application {
+ public void onCreate(){
+ Log.w("native-activity", "onCreate");
+
+ final PackageManager pm = getApplicationContext().getPackageManager();
+ ApplicationInfo ai;
+ try {
+ ai = pm.getApplicationInfo( this.getPackageName(), 0);
+ } catch (final NameNotFoundException e) {
+ ai = null;
+ }
+ final String applicationName = (String) (ai != null ? pm.getApplicationLabel(ai) : "(unknown)");
+ Toast.makeText(this, applicationName, Toast.LENGTH_SHORT).show();
+ }
+}
diff --git a/unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorNativeActivity.java b/unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorNativeActivity.java
new file mode 100644
index 0000000..e30e106
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Android/Java/UnityEmulator/UnityEmulatorNativeActivity.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.DiligentGrpahics.UnityEmulator;
+
+import android.app.NativeActivity;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup.MarginLayoutParams;
+import android.view.WindowManager.LayoutParams;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+import android.util.Log;
+
+public class UnityEmulatorNativeActivity extends NativeActivity {
+
+ static
+ {
+ try{
+ System.loadLibrary("GraphicsEngineOpenGL");
+ Log.i("native-activity", "Loaded GraphicsEngineOpenGL library\n");
+ } catch (UnsatisfiedLinkError e) {
+ Log.e("native-activity", "Failed to load GraphicsEngineOpenGL library\n" + e);
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String pluginName = getString(R.string.plugin_name);
+ try{
+ System.loadLibrary(pluginName);
+ Log.i("native-activity", "Loaded " + pluginName + " plugin\n");
+ } catch (UnsatisfiedLinkError e) {
+ Log.e("native-activity", "Failed to load " + pluginName + " plugin\n" + e);
+ }
+
+ //Hide toolbar
+ int SDK_INT = android.os.Build.VERSION.SDK_INT;
+ if(SDK_INT >= 19)
+ {
+ setImmersiveSticky();
+
+ View decorView = getWindow().getDecorView();
+ decorView.setOnSystemUiVisibilityChangeListener
+ (new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int visibility) {
+ setImmersiveSticky();
+ }
+ });
+ }
+ }
+
+ protected void onResume() {
+ super.onResume();
+
+ //Hide toolbar
+ int SDK_INT = android.os.Build.VERSION.SDK_INT;
+ if(SDK_INT >= 11 && SDK_INT < 14)
+ {
+ getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+ }
+ else if(SDK_INT >= 14 && SDK_INT < 19)
+ {
+ getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LOW_PROFILE);
+ }
+ else if(SDK_INT >= 19)
+ {
+ setImmersiveSticky();
+ }
+
+ }
+ // Our popup window, you will call it from your C/C++ code later
+
+ void setImmersiveSticky() {
+ View decorView = getWindow().getDecorView();
+ decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
+ | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
+ }
+
+ UnityEmulatorNativeActivity _activity;
+ PopupWindow _popupWindow;
+ TextView _label;
+
+ public void showUI()
+ {
+ if( _popupWindow != null )
+ return;
+
+ _activity = this;
+
+ this.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ LayoutInflater layoutInflater
+ = (LayoutInflater)getBaseContext()
+ .getSystemService(LAYOUT_INFLATER_SERVICE);
+ View popupView = layoutInflater.inflate(R.layout.widgets, null);
+ _popupWindow = new PopupWindow(
+ popupView,
+ LayoutParams.WRAP_CONTENT,
+ LayoutParams.WRAP_CONTENT);
+
+ LinearLayout mainLayout = new LinearLayout(_activity);
+ MarginLayoutParams params = new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+ params.setMargins(0, 0, 0, 0);
+ _activity.setContentView(mainLayout, params);
+
+ // Show our UI over NativeActivity window
+ _popupWindow.showAtLocation(mainLayout, Gravity.TOP | Gravity.LEFT, 10, 10);
+ _popupWindow.update();
+
+ _label = (TextView)popupView.findViewById(R.id.textViewFPS);
+
+ }});
+ }
+
+ protected void onPause()
+ {
+ super.onPause();
+ if (_popupWindow != null) {
+ _popupWindow.dismiss();
+ _popupWindow = null;
+ }
+ }
+
+ public void updateFPS(final float fFPS)
+ {
+ if( _label == null )
+ return;
+
+ _activity = this;
+ this.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ _label.setText(String.format("%2.2f FPS", fFPS));
+
+ }});
+ }
+}
+
+
diff --git a/unityplugin/UnityEmulator/src/Android/Java/helper/NDKHelper.java b/unityplugin/UnityEmulator/src/Android/Java/helper/NDKHelper.java
new file mode 100644
index 0000000..3385a5d
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Android/Java/helper/NDKHelper.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sample.helper;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import javax.microedition.khronos.opengles.GL10;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.opengl.GLUtils;
+import android.util.Log;
+
+public class NDKHelper
+{
+ private static Context context;
+
+ public static void setContext(Context c)
+ {
+ Log.i("NDKHelper", "setContext:" + c);
+ context = c;
+ }
+
+ //
+ // Load Bitmap
+ // Java helper is useful decoding PNG, TIFF etc rather than linking libPng
+ // etc separately
+ //
+ private int nextPOT(int i)
+ {
+ int pot = 1;
+ while (pot < i)
+ pot <<= 1;
+ return pot;
+ }
+
+ private Bitmap scaleBitmap(Bitmap bitmapToScale, float newWidth, float newHeight)
+ {
+ if (bitmapToScale == null)
+ return null;
+ // get the original width and height
+ int width = bitmapToScale.getWidth();
+ int height = bitmapToScale.getHeight();
+ // create a matrix for the manipulation
+ Matrix matrix = new Matrix();
+
+ // resize the bit map
+ matrix.postScale(newWidth / width, newHeight / height);
+
+ // recreate the new Bitmap and set it back
+ return Bitmap.createBitmap(bitmapToScale, 0, 0, bitmapToScale.getWidth(),
+ bitmapToScale.getHeight(), matrix, true);
+ }
+
+ public boolean loadTexture(String path)
+ {
+ Bitmap bitmap = null;
+ try
+ {
+ String str = path;
+ if (!path.startsWith("/"))
+ {
+ str = "/" + path;
+ }
+
+ File file = new File(context.getExternalFilesDir(null), str);
+ if (file.canRead())
+ {
+ bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
+ } else
+ {
+ bitmap = BitmapFactory.decodeStream(context.getResources().getAssets()
+ .open(path));
+ }
+ // Matrix matrix = new Matrix();
+ // // resize the bit map
+ // matrix.postScale(-1F, 1F);
+ //
+ // // recreate the new Bitmap and set it back
+ // bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
+ // bitmap.getHeight(), matrix, true);
+
+ } catch (Exception e)
+ {
+ Log.w("NDKHelper", "Coundn't load a file:" + path);
+ return false;
+ }
+
+ if (bitmap != null)
+ {
+ GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
+ }
+ return true;
+
+ }
+
+ public Bitmap openBitmap(String path, boolean iScalePOT)
+ {
+ Bitmap bitmap = null;
+ try
+ {
+ bitmap = BitmapFactory.decodeStream(context.getResources().getAssets()
+ .open(path));
+ if (iScalePOT)
+ {
+ int originalWidth = getBitmapWidth(bitmap);
+ int originalHeight = getBitmapHeight(bitmap);
+ int width = nextPOT(originalWidth);
+ int height = nextPOT(originalHeight);
+ if (originalWidth != width || originalHeight != height)
+ {
+ // Scale it
+ bitmap = scaleBitmap(bitmap, width, height);
+ }
+ }
+
+ } catch (Exception e)
+ {
+ Log.w("NDKHelper", "Coundn't load a file:" + path);
+ }
+
+ return bitmap;
+ }
+
+ public int getBitmapWidth(Bitmap bmp)
+ {
+ return bmp.getWidth();
+ }
+
+ public int getBitmapHeight(Bitmap bmp)
+ {
+ return bmp.getHeight();
+ }
+
+ public void getBitmapPixels(Bitmap bmp, int[] pixels)
+ {
+ int w = bmp.getWidth();
+ int h = bmp.getHeight();
+ bmp.getPixels(pixels, 0, w, 0, 0, w, h);
+ }
+
+ public void closeBitmap(Bitmap bmp)
+ {
+ bmp.recycle();
+ }
+
+ public static String getNativeLibraryDirectory(Context appContext)
+ {
+ ApplicationInfo ai = context.getApplicationInfo();
+
+ Log.w("NDKHelper", "ai.nativeLibraryDir:" + ai.nativeLibraryDir);
+
+ if ((ai.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0
+ || (ai.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
+ {
+ return ai.nativeLibraryDir;
+ }
+ return "/system/lib/";
+ }
+
+ public int getNativeAudioBufferSize()
+ {
+ int SDK_INT = android.os.Build.VERSION.SDK_INT;
+ if (SDK_INT >= 17)
+ {
+ AudioManager am = (AudioManager) context
+ .getSystemService(Context.AUDIO_SERVICE);
+ String framesPerBuffer = am
+ .getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
+ return Integer.parseInt(framesPerBuffer);
+ } else
+ {
+ return 0;
+ }
+ }
+
+ public int getNativeAudioSampleRate()
+ {
+ return AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM);
+
+ }
+
+}
diff --git a/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp
new file mode 100644
index 0000000..176d501
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp
@@ -0,0 +1,326 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include "UnityGraphicsGLESAndroid_Impl.h"
+#include "Errors.h"
+
+#ifndef EGL_CONTEXT_MINOR_VERSION_KHR
+# define EGL_CONTEXT_MINOR_VERSION_KHR 0x30FB
+#endif
+
+#ifndef EGL_CONTEXT_MAJOR_VERSION_KHR
+# define EGL_CONTEXT_MAJOR_VERSION_KHR EGL_CONTEXT_CLIENT_VERSION
+#endif
+
+#ifndef GL_FRAMEBUFFER_SRGB
+# define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+
+bool UnityGraphicsGLESAndroid_Impl::InitEGLSurface()
+{
+ display_ = eglGetDisplay( EGL_DEFAULT_DISPLAY );
+ if( display_ == EGL_NO_DISPLAY )
+ {
+ LOG_ERROR_AND_THROW( "No EGL display found" );
+ }
+
+ auto success = eglInitialize( display_, 0, 0 );
+ if( !success )
+ {
+ LOG_ERROR_AND_THROW( "Failed to initialise EGL" );
+ }
+
+ /*
+ * Here specify the attributes of the desired configuration.
+ * Below, we select an EGLConfig with at least 8 bits per color
+ * component compatible with on-screen windows
+ */
+ const EGLint attribs[] =
+ {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ //EGL_COLORSPACE, EGL_COLORSPACE_sRGB, // does not work
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 24,
+ //EGL_SAMPLE_BUFFERS , 1,
+ //EGL_SAMPLES , 4,
+ EGL_NONE
+ };
+ color_size_ = 8;
+ depth_size_ = 24;
+
+ // Get a list of EGL frame buffer configurations that match specified attributes
+ EGLint num_configs;
+ success = eglChooseConfig( display_, attribs, &config_, 1, &num_configs );
+ if( !success )
+ {
+ LOG_ERROR_AND_THROW( "Failed to choose config" );
+ }
+
+ if( !num_configs )
+ {
+ //Fall back to 16bit depth buffer
+ const EGLint attribs[] =
+ {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //Request opengl ES2.0
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 16,
+ EGL_NONE
+ };
+ success = eglChooseConfig( display_, attribs, &config_, 1, &num_configs );
+ if( !success )
+ {
+ LOG_ERROR_AND_THROW( "Failed to choose 16-bit depth config" );
+ }
+
+ depth_size_ = 16;
+ }
+
+ if( !num_configs )
+ {
+ LOG_ERROR_AND_THROW( "Unable to retrieve EGL config" );
+ }
+
+ surface_ = eglCreateWindowSurface( display_, config_, window_, NULL );
+ if( surface_ == EGL_NO_SURFACE )
+ {
+ LOG_ERROR_AND_THROW( "Failed to create EGLSurface" );
+ }
+
+ screen_width_ = 0;
+ screen_height_ = 0;
+ eglQuerySurface( display_, surface_, EGL_WIDTH, &screen_width_ );
+ eglQuerySurface( display_, surface_, EGL_HEIGHT, &screen_height_ );
+
+ /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+ * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
+ * As soon as we picked a EGLConfig, we can safely reconfigure the
+ * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
+ EGLint format;
+ eglGetConfigAttrib( display_, config_, EGL_NATIVE_VISUAL_ID, &format );
+ ANativeWindow_setBuffersGeometry( window_, 0, 0, format );
+
+ return true;
+}
+
+bool UnityGraphicsGLESAndroid_Impl::InitEGLContext()
+{
+ const EGLint context_attribs[] =
+ {
+ EGL_CONTEXT_CLIENT_VERSION, major_version_,
+ EGL_CONTEXT_MINOR_VERSION_KHR, minor_version_,
+ EGL_NONE
+ };
+
+ LOG_INFO_MESSAGE( "contextAttribs: ", context_attribs[0], ' ', context_attribs[1], '\n' );
+ LOG_INFO_MESSAGE( "contextAttribs: ", context_attribs[2], ' ', context_attribs[3], '\n' );
+
+ context_ = eglCreateContext( display_, config_, NULL, context_attribs );
+ if( context_ == EGL_NO_CONTEXT )
+ {
+ LOG_ERROR_AND_THROW( "Failed to create EUnityGraphicsGLESAndroid_Impl" );
+ }
+
+ if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_FALSE )
+ {
+ LOG_ERROR_AND_THROW( "Unable to eglMakeCurrent" );
+ }
+
+ context_valid_ = true;
+ return true;
+}
+
+void UnityGraphicsGLESAndroid_Impl::InitGLES()
+{
+ if( gles_initialized_ )
+ return;
+
+ // When GL_FRAMEBUFFER_SRGB is enabled, and if the destination image is in the sRGB colorspace
+ // then OpenGL will assume the shader's output is in the linear RGB colorspace. It will therefore
+ // convert the output from linear RGB to sRGB.
+ // Any writes to images that are not in the sRGB format should not be affected.
+ // Thus this setting should be just set once and left that way
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ if( glGetError() != GL_NO_ERROR )
+ LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers");
+
+ gles_initialized_ = true;
+}
+
+void UnityGraphicsGLESAndroid_Impl::InitGLContext(void *native_wnd_handle, int major_version, int minor_version)
+{
+ major_version_ = major_version;
+ minor_version_ = minor_version;
+ Init(reinterpret_cast<ANativeWindow*>(native_wnd_handle));
+}
+
+bool UnityGraphicsGLESAndroid_Impl::Init( ANativeWindow* window )
+{
+ if( egl_context_initialized_ )
+ return true;
+
+ //
+ //Initialize EGL
+ //
+ window_ = window;
+ InitEGLSurface();
+ InitEGLContext();
+ InitGLES();
+
+ egl_context_initialized_ = true;
+
+ return true;
+}
+
+UnityGraphicsGLESAndroid_Impl::~UnityGraphicsGLESAndroid_Impl()
+{
+ Terminate();
+}
+
+void UnityGraphicsGLESAndroid_Impl::ResizeSwapchain(int new_width, int new_height)
+{
+ screen_width_ = new_width;
+ screen_height_ = new_height;
+ // Nothing more needs to be done in GLES
+}
+
+void UnityGraphicsGLESAndroid_Impl::SwapBuffers()
+{
+ bool b = eglSwapBuffers( display_, surface_ );
+ if( !b )
+ {
+ EGLint err = eglGetError();
+ if( err == EGL_BAD_SURFACE )
+ {
+ //Recreate surface
+ InitEGLSurface();
+ //return EGL_SUCCESS; //Still consider UnityGraphicsGLESAndroid_Impl is valid
+ }
+ else if( err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT )
+ {
+ //Context has been lost!!
+ context_valid_ = false;
+ Terminate();
+ InitEGLContext();
+ }
+ //return err;
+ }
+ //return EGL_SUCCESS;
+}
+
+void UnityGraphicsGLESAndroid_Impl::Terminate()
+{
+ if( display_ != EGL_NO_DISPLAY )
+ {
+ eglMakeCurrent( display_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
+ if( context_ != EGL_NO_CONTEXT )
+ {
+ eglDestroyContext( display_, context_ );
+ }
+
+ if( surface_ != EGL_NO_SURFACE )
+ {
+ eglDestroySurface( display_, surface_ );
+ }
+ eglTerminate( display_ );
+ }
+
+ display_ = EGL_NO_DISPLAY;
+ context_ = EGL_NO_CONTEXT;
+ surface_ = EGL_NO_SURFACE;
+ context_valid_ = false;
+}
+
+
+EGLint UnityGraphicsGLESAndroid_Impl::Resume( ANativeWindow* window )
+{
+ if( egl_context_initialized_ == false )
+ {
+ Init( window );
+ return EGL_SUCCESS;
+ }
+
+
+ //Create surface
+ window_ = window;
+ surface_ = eglCreateWindowSurface( display_, config_, window_, NULL );
+ int32_t new_screen_width = 0;
+ int32_t new_screen_height = 0;
+ eglQuerySurface( display_, surface_, EGL_WIDTH, &new_screen_width );
+ eglQuerySurface( display_, surface_, EGL_HEIGHT, &new_screen_height );
+
+ if( new_screen_width != screen_width_ || new_screen_height != screen_height_ )
+ {
+ screen_width_ = new_screen_width;
+ screen_height_ = new_screen_height;
+ //Screen resized
+ LOG_INFO_MESSAGE( "Screen resized\n" );
+ }
+
+ if( eglMakeCurrent( display_, surface_, surface_, context_ ) == EGL_TRUE )
+ return EGL_SUCCESS;
+
+ EGLint err = eglGetError();
+ LOG_WARNING_MESSAGE( "Unable to eglMakeCurrent ", err, '\n' );
+
+ if( err == EGL_CONTEXT_LOST )
+ {
+ //Recreate context
+ LOG_INFO_MESSAGE( "Re-creating egl context\n" );
+ InitEGLContext();
+ }
+ else
+ {
+ //Recreate surface
+ Terminate();
+ InitEGLSurface();
+ InitEGLContext();
+ }
+
+ return err;
+
+}
+
+void UnityGraphicsGLESAndroid_Impl::Suspend()
+{
+ if( surface_ != EGL_NO_SURFACE )
+ {
+ eglDestroySurface( display_, surface_ );
+ surface_ = EGL_NO_SURFACE;
+ }
+}
+
+bool UnityGraphicsGLESAndroid_Impl::Invalidate()
+{
+ Terminate();
+
+ egl_context_initialized_ = false;
+ return true;
+}
diff --git a/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h
new file mode 100644
index 0000000..1ea7df1
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h
@@ -0,0 +1,91 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+
+#include <EGL/egl.h>
+#include <android/native_window.h>
+
+class UnityGraphicsGLESAndroid_Impl
+{
+public:
+ void InitGLContext(void *native_wnd_handle, int major_version, int minor_version);
+ ~UnityGraphicsGLESAndroid_Impl();
+
+ bool Init(ANativeWindow* window);
+
+ void ResizeSwapchain(int NewWidth, int NewHeight);
+
+ void SwapBuffers();
+
+ int GetBackBufferWidth()const { return screen_width_; }
+ int GetBackBufferHeight()const { return screen_height_; }
+ GLenum GetBackBufferFormat()const { return GL_RGBA8; }
+ GLenum GetDepthBufferFormat()const
+ {
+ if (depth_size_ == 32)
+ GL_DEPTH_COMPONENT32F;
+ else if (depth_size_ == 24)
+ return GL_DEPTH_COMPONENT24;
+ else if(depth_size_ == 16)
+ return GL_DEPTH_COMPONENT16;
+ else
+ return 0;
+ }
+ EGLContext GetContext() { return context_; }
+
+ bool Invalidate();
+
+ void Suspend();
+ EGLint Resume( ANativeWindow* window );
+
+private:
+ //EGL configurations
+ ANativeWindow* window_ = nullptr;
+ EGLDisplay display_ = EGL_NO_DISPLAY;
+ EGLSurface surface_ = EGL_NO_SURFACE;
+ EGLContext context_ = EGL_NO_CONTEXT;
+ EGLConfig config_;
+
+ //Screen parameters
+ int32_t color_size_ = 0;
+ int32_t depth_size_ = 0;
+ int32_t major_version_ = 0;
+ int32_t minor_version_ = 0;
+
+ //Flags
+ bool gles_initialized_ = false;
+ bool egl_context_initialized_ = false;
+ bool es3_supported_ = false;
+ float gl_version_ = 0;
+ bool context_valid_ = false;
+
+ int screen_width_ = 0;
+ int screen_height_ = 0;
+
+ void InitGLES();
+ void Terminate();
+ bool InitEGLSurface();
+ bool InitEGLContext();
+};
diff --git a/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D11.cpp b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D11.cpp
new file mode 100644
index 0000000..4b02965
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D11.cpp
@@ -0,0 +1,127 @@
+#include <d3d11.h>
+#include <dxgi1_2.h>
+
+#include "DiligentGraphicsAdapterD3D11.h"
+#include "UnityGraphicsD3D11Emulator.h"
+#include "RenderDeviceFactoryD3D11.h"
+#include "SwapChainBase.h"
+#include "SwapChainD3D11.h"
+#include "DefaultRawMemoryAllocator.h"
+#include "UnityGraphicsD3D11Impl.h"
+#include "DXGITypeConversions.h"
+
+using namespace Diligent;
+
+namespace
+{
+
+class ProxySwapChainD3D11 : public SwapChainBase<ISwapChainD3D11>
+{
+public:
+ using TBase = SwapChainBase<ISwapChainD3D11>;
+
+ ProxySwapChainD3D11( IReferenceCounters *pRefCounters,
+ IRenderDevice *pDevice,
+ IDeviceContext *pDeviceContext,
+ const SwapChainDesc& SCDesc ) :
+ TBase(pRefCounters, pDevice, pDeviceContext,SCDesc)
+ {}
+
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_SwapChainD3D11, TBase)
+
+ virtual IDXGISwapChain *GetDXGISwapChain()override final
+ {
+ UNEXPECTED("DXGI swap chain cannot be requested through the proxy swap chain")
+ return nullptr;
+ }
+
+ virtual ID3D11RenderTargetView *GetRTV()override final{ return m_pRTV; }
+
+ virtual ID3D11DepthStencilView *GetDSV()override final { return m_pDSV; }
+
+ virtual void Present()override final
+ {
+ UNEXPECTED("Present is not expected to be called directly")
+ }
+
+ virtual void Resize(Uint32 NewWidth, Uint32 NewHeight)override final
+ {
+ TBase::Resize(NewWidth, NewHeight, 0);
+ }
+
+ void SetSwapChainAttribs(ID3D11RenderTargetView *pRTV, ID3D11DepthStencilView *pDSV, Uint32 Width, Uint32 Height)
+ {
+ TBase::Resize(Width, Height, 0);
+ m_pRTV = pRTV;
+ m_pDSV = pDSV;
+ }
+
+ void ResetSwapChainAttribs()
+ {
+ m_pRTV = nullptr;
+ m_pDSV = nullptr;
+ }
+
+private:
+ ID3D11RenderTargetView *m_pRTV = nullptr;
+ ID3D11DepthStencilView *m_pDSV = nullptr;
+};
+
+}
+
+DiligentGraphicsAdapterD3D11::DiligentGraphicsAdapterD3D11(const UnityGraphicsD3D11Emulator& UnityGraphicsD3D11)noexcept :
+ m_UnityGraphicsD3D11(UnityGraphicsD3D11)
+{
+ auto *GraphicsD3D11Impl = m_UnityGraphicsD3D11.GetGraphicsImpl();
+ ID3D11Device *pd3d11Device = GraphicsD3D11Impl->GetD3D11Device();
+ ID3D11DeviceContext *pd3d11Context = GraphicsD3D11Impl->GetD3D11Context();
+ auto *pFactoryD3d11 = GetEngineFactoryD3D11();
+ EngineD3D11Attribs Attribs;
+ pFactoryD3d11->AttachToD3D11Device(pd3d11Device, pd3d11Context, Attribs, &m_pDevice, &m_pDeviceCtx, 0);
+}
+
+void DiligentGraphicsAdapterD3D11::InitProxySwapChain()
+{
+ auto *GraphicsD3D11Impl = m_UnityGraphicsD3D11.GetGraphicsImpl();
+ D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
+ GraphicsD3D11Impl->GetRTV()->GetDesc(&RTVDesc);
+ D3D11_DEPTH_STENCIL_VIEW_DESC DSVDesc;
+ GraphicsD3D11Impl->GetDSV()->GetDesc(&DSVDesc);
+
+ SwapChainDesc SCDesc;
+ SCDesc.ColorBufferFormat = DXGI_FormatToTexFormat(RTVDesc.Format);
+ SCDesc.DepthBufferFormat = DXGI_FormatToTexFormat(DSVDesc.Format);
+ SCDesc.Width = GraphicsD3D11Impl->GetBackBufferWidth();
+ SCDesc.Height = GraphicsD3D11Impl->GetBackBufferHeight();
+ // These fields are irrelevant
+ SCDesc.SamplesCount = 0;
+ SCDesc.BufferCount = 0;
+
+ auto &DefaultAllocator = DefaultRawMemoryAllocator::GetAllocator();
+ auto pProxySwapChainD3D11 = NEW_RC_OBJ(DefaultAllocator, "ProxySwapChainD3D11 instance", ProxySwapChainD3D11)(m_pDevice, m_pDeviceCtx, SCDesc);
+ pProxySwapChainD3D11->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(static_cast<ISwapChain**>(&m_pProxySwapChain)));
+
+ m_pDeviceCtx->SetSwapChain(m_pProxySwapChain);
+}
+
+void DiligentGraphicsAdapterD3D11::BeginFrame()
+{
+ auto *UnityGraphicsD3D11Impl = m_UnityGraphicsD3D11.GetGraphicsImpl();
+ auto *pRTV = UnityGraphicsD3D11Impl->GetRTV();
+ auto *pDSV = UnityGraphicsD3D11Impl->GetDSV();
+ auto Width = UnityGraphicsD3D11Impl->GetBackBufferWidth();
+ auto Height = UnityGraphicsD3D11Impl->GetBackBufferHeight();
+ VERIFY_EXPR(pRTV != nullptr && pDSV != nullptr && Width != 0 && Height != 0);
+ ValidatedCast<ProxySwapChainD3D11>(m_pProxySwapChain.RawPtr())->SetSwapChainAttribs(pRTV, pDSV, Width, Height);
+}
+
+void DiligentGraphicsAdapterD3D11::EndFrame()
+{
+ ValidatedCast<ProxySwapChainD3D11>(m_pProxySwapChain.RawPtr())->ResetSwapChainAttribs();
+ m_pDeviceCtx->InvalidateState();
+}
+
+bool DiligentGraphicsAdapterD3D11::UsesReverseZ()
+{
+ return m_UnityGraphicsD3D11.UsesReverseZ();
+} \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp
new file mode 100644
index 0000000..9aea25d
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D12.cpp
@@ -0,0 +1,254 @@
+
+#define NOMINMAX
+#include <D3D12.h>
+#include <dxgi1_4.h>
+#include <atlbase.h>
+#include "UnityGraphicsD3D12Impl.h"
+#include "DiligentGraphicsAdapterD3D12.h"
+#include "UnityGraphicsD3D12Emulator.h"
+#include "SwapChainD3D12.h"
+#include "TextureD3D12.h"
+#include "RenderDeviceD3D12.h"
+#include "DeviceContextD3D12.h"
+#include "CommandQueueD3D12.h"
+#include "RenderDeviceFactoryD3D12.h"
+#include "SwapChainBase.h"
+#include "DefaultRawMemoryAllocator.h"
+#include "DXGITypeConversions.h"
+
+using namespace Diligent;
+
+namespace
+{
+
+class ProxyCommandQueueD3D12 : public ObjectBase<ICommandQueueD3D12>
+{
+public:
+ using TBase = ObjectBase<ICommandQueueD3D12>;
+ ProxyCommandQueueD3D12(IReferenceCounters *pRefCounters, UnityGraphicsD3D12Impl& GraphicsD3D12Impl) :
+ TBase(pRefCounters),
+ m_GraphicsD3D12Impl(GraphicsD3D12Impl)
+ {
+ }
+
+ ~ProxyCommandQueueD3D12()
+ {
+ }
+
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_CommandQueueD3D12, TBase )
+
+ // Returns the fence value that will be signaled next time
+ virtual UINT64 GetNextFenceValue()override final
+ {
+ return m_GraphicsD3D12Impl.GetNextFenceValue();
+ }
+
+ // Executes a given command list
+ virtual UINT64 ExecuteCommandList(ID3D12GraphicsCommandList* commandList)override final
+ {
+ return m_GraphicsD3D12Impl.ExecuteCommandList(commandList);
+ }
+
+ // Returns D3D12 command queue. May return null if queue is anavailable
+ virtual ID3D12CommandQueue* GetD3D12CommandQueue()
+ {
+ return nullptr;
+ }
+
+ /// Returns value of the last completed fence
+ virtual Uint64 GetCompletedFenceValue()
+ {
+ return m_GraphicsD3D12Impl.GetCompletedFenceValue();
+ }
+
+ /// Blocks execution until all pending GPU commands are complete
+ virtual void IdleGPU()
+ {
+ m_GraphicsD3D12Impl.IdleGPU();
+ }
+
+private:
+ UnityGraphicsD3D12Impl& m_GraphicsD3D12Impl;
+};
+
+
+class ProxySwapChainD3D12 : public SwapChainBase<ISwapChainD3D12>
+{
+public:
+ using TBase = SwapChainBase<ISwapChainD3D12>;
+
+ ProxySwapChainD3D12( IReferenceCounters *pRefCounters,
+ IRenderDevice *pDevice,
+ IDeviceContext *pDeviceContext,
+ const SwapChainDesc& SCDesc ) :
+ TBase(pRefCounters, pDevice, pDeviceContext,SCDesc)
+ {
+ }
+
+ IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_SwapChainD3D12, TBase)
+
+ virtual IDXGISwapChain *GetDXGISwapChain()override final
+ {
+ UNEXPECTED("DXGI swap chain cannot be requested through the proxy swap chain")
+ return nullptr;
+ }
+
+ virtual ITextureViewD3D12* GetCurrentBackBufferRTV()
+ {
+ return m_RTVs[m_CurrentBackBufferIndex];
+ }
+
+ virtual ITextureViewD3D12* GetDepthBufferDSV()
+ {
+ return m_DSV;
+ }
+
+ virtual void Present()override final
+ {
+ UNEXPECTED("Present is not expected to be called directly")
+ }
+
+ virtual void Resize(Uint32 NewWidth, Uint32 NewHeight)override final
+ {
+ TBase::Resize(NewWidth, NewHeight, 0);
+ }
+
+ void ReleaseBuffers()
+ {
+ m_BackBuffers.clear();
+ m_RTVs.clear();
+ m_DepthBuffer.Release();
+ m_DSV.Release();
+ }
+
+ void SetBackBufferIndex(Uint32 BackBufferIndex) { m_CurrentBackBufferIndex = BackBufferIndex; }
+
+ void CreateBuffers(IDXGISwapChain3 *pDXGISwapChain, ID3D12Resource *pd3d12DepthBuffer)
+ {
+ DXGI_SWAP_CHAIN_DESC1 SwapChainDesc;
+ pDXGISwapChain->GetDesc1(&SwapChainDesc);
+ m_SwapChainDesc.BufferCount = SwapChainDesc.BufferCount;
+ m_SwapChainDesc.SamplesCount = SwapChainDesc.SampleDesc.Count;
+ m_SwapChainDesc.Width = SwapChainDesc.Width;
+ m_SwapChainDesc.Height = SwapChainDesc.Height;
+ m_SwapChainDesc.ColorBufferFormat = DXGI_FormatToTexFormat(SwapChainDesc.Format);
+ const auto DepthBufferDesc = pd3d12DepthBuffer->GetDesc();
+ m_SwapChainDesc.DepthBufferFormat = DXGI_FormatToTexFormat(DepthBufferDesc.Format);
+
+ RefCntAutoPtr<IRenderDeviceD3D12> pRenderDeviceD3D12(m_pRenderDevice, IID_RenderDeviceD3D12);
+
+ m_BackBuffers.reserve(m_SwapChainDesc.BufferCount);
+ m_RTVs.reserve(m_SwapChainDesc.BufferCount);
+ for(Uint32 backbuff = 0; backbuff < m_SwapChainDesc.BufferCount; ++backbuff)
+ {
+ CComPtr<ID3D12Resource> pd3d12BackBuffer;
+ auto hr = pDXGISwapChain->GetBuffer(backbuff, __uuidof(pd3d12BackBuffer), reinterpret_cast<void**>( static_cast<ID3D12Resource**>(&pd3d12BackBuffer) ));
+ if(FAILED(hr))
+ LOG_ERROR_AND_THROW("Failed to get back buffer ", backbuff," from the swap chain");
+ RefCntAutoPtr<ITexture> pBackBuffer;
+ pRenderDeviceD3D12->CreateTextureFromD3DResource(pd3d12BackBuffer, &pBackBuffer);
+ m_BackBuffers.emplace_back( RefCntAutoPtr<ITextureD3D12>(pBackBuffer, IID_TextureD3D12) );
+ TextureViewDesc TexViewDesc;
+ TexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET;
+ TexViewDesc.Format = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ RefCntAutoPtr<ITextureView> pRTV;
+ pBackBuffer->CreateView(TexViewDesc, &pRTV);
+ m_RTVs.emplace_back(RefCntAutoPtr<ITextureViewD3D12>(pRTV, IID_TextureViewD3D12));
+ }
+
+ RefCntAutoPtr<ITexture> pDepthBuffer;
+ pRenderDeviceD3D12->CreateTextureFromD3DResource(pd3d12DepthBuffer, &pDepthBuffer);
+ m_DepthBuffer = RefCntAutoPtr<ITextureD3D12>(pDepthBuffer, IID_TextureD3D12);
+ auto *pDSV = m_DepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL);
+ m_DSV = RefCntAutoPtr<ITextureViewD3D12>(pDSV, IID_TextureViewD3D12);
+ }
+
+ ITextureD3D12* GetCurrentBackBuffer() { return m_BackBuffers[m_CurrentBackBufferIndex]; }
+ ITextureD3D12* GetDepthBuffer() { return m_DepthBuffer; }
+
+private:
+ std::vector<RefCntAutoPtr<ITextureD3D12>> m_BackBuffers;
+ std::vector<RefCntAutoPtr<ITextureViewD3D12>> m_RTVs;
+ RefCntAutoPtr<ITextureD3D12> m_DepthBuffer;
+ RefCntAutoPtr<ITextureViewD3D12> m_DSV;
+ Uint32 m_CurrentBackBufferIndex = 0;
+};
+
+}
+
+
+DiligentGraphicsAdapterD3D12::DiligentGraphicsAdapterD3D12(UnityGraphicsD3D12Emulator& UnityGraphicsD3D12)noexcept :
+ m_UnityGraphicsD3D12(UnityGraphicsD3D12)
+{
+ auto *GraphicsImpl = UnityGraphicsD3D12.GetGraphicsImpl();
+ auto *d3d12Device = GraphicsImpl->GetD3D12Device();
+
+ auto &DefaultAllocator = DefaultRawMemoryAllocator::GetAllocator();
+ auto CmdQueue = NEW_RC_OBJ(DefaultAllocator, "UnityCommandQueueImpl instance", ProxyCommandQueueD3D12)(*GraphicsImpl);
+
+ auto *pFactoryD3D12 = GetEngineFactoryD3D12();
+ EngineD3D12Attribs Attribs;
+ pFactoryD3D12->AttachToD3D12Device(d3d12Device, CmdQueue, Attribs, &m_pDevice, &m_pDeviceCtx, 0);
+}
+
+void DiligentGraphicsAdapterD3D12::InitProxySwapChain()
+{
+ auto *GraphicsImpl = m_UnityGraphicsD3D12.GetGraphicsImpl();
+ auto &DefaultAllocator = DefaultRawMemoryAllocator::GetAllocator();
+ SwapChainDesc SCDesc;
+ auto ProxySwapChain = NEW_RC_OBJ(DefaultAllocator, "UnityCommandQueueImpl instance", ProxySwapChainD3D12)(m_pDevice, m_pDeviceCtx, SCDesc);
+ ProxySwapChain->CreateBuffers(GraphicsImpl->GetDXGISwapChain(), GraphicsImpl->GetDepthBuffer());
+ m_pProxySwapChain = ProxySwapChain;
+ m_pDeviceCtx->SetSwapChain(ProxySwapChain);
+}
+
+void DiligentGraphicsAdapterD3D12::PreSwapChainResize()
+{
+ auto *pProxySwapChainD3D12 = ValidatedCast<ProxySwapChainD3D12>(m_pProxySwapChain.RawPtr());
+ auto *pDeviceD3D12 = ValidatedCast<IRenderDeviceD3D12>(m_pDevice.RawPtr());
+ pProxySwapChainD3D12->ReleaseBuffers();
+ auto *GraphicsImpl = m_UnityGraphicsD3D12.GetGraphicsImpl();
+ pDeviceD3D12->FinishFrame();
+ // We must idle GPU
+ GraphicsImpl->IdleGPU();
+ // And call FinishFrame() to release references to swap chain resources
+ pDeviceD3D12->FinishFrame();
+}
+
+void DiligentGraphicsAdapterD3D12::PostSwapChainResize()
+{
+ auto *GraphicsImpl = m_UnityGraphicsD3D12.GetGraphicsImpl();
+ auto *pProxySwapChainD3D12 = ValidatedCast<ProxySwapChainD3D12>(m_pProxySwapChain.RawPtr());
+ pProxySwapChainD3D12->CreateBuffers(GraphicsImpl->GetDXGISwapChain(), GraphicsImpl->GetDepthBuffer());
+}
+
+void DiligentGraphicsAdapterD3D12::BeginFrame()
+{
+ auto *GraphicsImpl = m_UnityGraphicsD3D12.GetGraphicsImpl();
+ auto *pProxySwapChainD3D12 = ValidatedCast<ProxySwapChainD3D12>(m_pProxySwapChain.RawPtr());
+ pProxySwapChainD3D12->SetBackBufferIndex(GraphicsImpl->GetCurrentBackBufferIndex());
+ // Unity graphics emulator transitions render target to D3D12_RESOURCE_STATE_RENDER_TARGET,
+ // and depth buffer to D3D12_RESOURCE_STATE_DEPTH_WRITE state
+ pProxySwapChainD3D12->GetCurrentBackBuffer()->SetD3D12ResourceState(D3D12_RESOURCE_STATE_RENDER_TARGET);
+ pProxySwapChainD3D12->GetDepthBuffer()->SetD3D12ResourceState(D3D12_RESOURCE_STATE_DEPTH_WRITE);
+}
+
+void DiligentGraphicsAdapterD3D12::EndFrame()
+{
+ // Unity graphics emulator expects render target to be D3D12_RESOURCE_STATE_RENDER_TARGET,
+ // and depth buffer to be in D3D12_RESOURCE_STATE_DEPTH_WRITE state
+ auto *pCtxD3D12 = ValidatedCast<IDeviceContextD3D12>(m_pDeviceCtx.RawPtr());
+ auto *pProxySwapChainD3D12 = ValidatedCast<ProxySwapChainD3D12>(m_pProxySwapChain.RawPtr());
+ auto *pCurrentBackBuffer = pProxySwapChainD3D12->GetCurrentBackBuffer();
+ auto *pDepthBuffer = pProxySwapChainD3D12->GetDepthBuffer();
+ pCtxD3D12->TransitionTextureState(pCurrentBackBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET);
+ pCtxD3D12->TransitionTextureState(pDepthBuffer, D3D12_RESOURCE_STATE_DEPTH_WRITE);
+ m_pDeviceCtx->Flush();
+ m_pDeviceCtx->InvalidateState();
+ ValidatedCast<IRenderDeviceD3D12>(m_pDevice.RawPtr())->FinishFrame();
+}
+
+bool DiligentGraphicsAdapterD3D12::UsesReverseZ()
+{
+ return m_UnityGraphicsD3D12.UsesReverseZ();
+}
diff --git a/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterGL.cpp b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterGL.cpp
new file mode 100644
index 0000000..4b5ecb1
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterGL.cpp
@@ -0,0 +1,103 @@
+#include "DiligentGraphicsAdapterGL.h"
+
+#if OPENGL_SUPPORTED
+
+#include "UnityGraphicsGLCoreES_Emulator.h"
+#include "RenderDeviceFactoryOpenGL.h"
+#include "SwapChainBase.h"
+#include "DefaultRawMemoryAllocator.h"
+#include "UnityGraphicsGL_Impl.h"
+
+using namespace Diligent;
+
+namespace
+{
+
+class ProxySwapChainGL : public SwapChainBase<ISwapChain>
+{
+public:
+ using TBase = SwapChainBase<ISwapChain>;
+
+ ProxySwapChainGL( IReferenceCounters *pRefCounters,
+ IRenderDevice *pDevice,
+ IDeviceContext *pDeviceContext,
+ const SwapChainDesc& SCDesc ) :
+ TBase(pRefCounters, pDevice, pDeviceContext,SCDesc)
+ {}
+
+ virtual void Present()override final
+ {
+ UNEXPECTED("Present is not expected to be called directly")
+ }
+
+ virtual void Resize(Uint32 NewWidth, Uint32 NewHeight)override final
+ {
+ TBase::Resize(NewWidth, NewHeight, 0);
+ }
+};
+
+}
+
+DiligentGraphicsAdapterGL::DiligentGraphicsAdapterGL(const UnityGraphicsGLCoreES_Emulator& UnityGraphicsGL)noexcept :
+ m_UnityGraphicsGL(UnityGraphicsGL)
+{
+ auto *UnityGraphicsGLImpl = UnityGraphicsGL.GetGraphicsImpl();
+
+ auto *pFactoryGL = GetEngineFactoryOpenGL();
+ EngineCreationAttribs Attribs;
+ pFactoryGL->AttachToActiveGLContext(Attribs, &m_pDevice, &m_pDeviceCtx);
+
+ auto BackBufferGLFormat = UnityGraphicsGLImpl->GetBackBufferFormat();
+ auto DepthBufferGLFormat = UnityGraphicsGLImpl->GetDepthBufferFormat();
+
+ SwapChainDesc SCDesc;
+ if(BackBufferGLFormat == GL_RGBA8)
+ SCDesc.ColorBufferFormat = TEX_FORMAT_RGBA8_UNORM_SRGB;
+ else
+ {
+ UNEXPECTED("Unexpected back buffer format")
+ }
+
+ if (DepthBufferGLFormat == GL_DEPTH_COMPONENT32F)
+ SCDesc.DepthBufferFormat = TEX_FORMAT_D32_FLOAT;
+ else if (DepthBufferGLFormat == GL_DEPTH_COMPONENT24)
+ SCDesc.DepthBufferFormat = TEX_FORMAT_D24_UNORM_S8_UINT;
+ else if (DepthBufferGLFormat == GL_DEPTH_COMPONENT16)
+ SCDesc.DepthBufferFormat = TEX_FORMAT_D16_UNORM;
+ else
+ {
+ UNEXPECTED("Unexpected depth buffer format")
+ }
+
+ SCDesc.Width = UnityGraphicsGLImpl->GetBackBufferWidth();
+ SCDesc.Height = UnityGraphicsGLImpl->GetBackBufferHeight();
+ // These fields are irrelevant
+ SCDesc.SamplesCount = 0;
+ SCDesc.BufferCount = 0;
+
+ auto &DefaultAllocator = DefaultRawMemoryAllocator::GetAllocator();
+ auto pProxySwapChainGL = NEW_RC_OBJ(DefaultAllocator, "ProxySwapChainGL instance", ProxySwapChainGL)(m_pDevice, m_pDeviceCtx, SCDesc);
+ pProxySwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(static_cast<ISwapChain**>(&m_pProxySwapChain)));
+
+ m_pDeviceCtx->SetSwapChain(m_pProxySwapChain);
+}
+
+void DiligentGraphicsAdapterGL::BeginFrame()
+{
+ auto *UnityGraphicsGLImpl = m_UnityGraphicsGL.GetGraphicsImpl();
+ Uint32 Width = UnityGraphicsGLImpl->GetBackBufferWidth();
+ Uint32 Height = UnityGraphicsGLImpl->GetBackBufferHeight();
+ ValidatedCast<ProxySwapChainGL>(m_pProxySwapChain.RawPtr())->Resize(Width, Height);
+}
+
+void DiligentGraphicsAdapterGL::EndFrame()
+{
+ m_pDeviceCtx->InvalidateState();
+}
+
+bool DiligentGraphicsAdapterGL::UsesReverseZ()
+{
+ return m_UnityGraphicsGL.UsesReverseZ();
+}
+
+#endif // OPENGL_SUPPORTED \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/src/UWP/App.cpp b/unityplugin/UnityEmulator/src/UWP/App.cpp
new file mode 100644
index 0000000..7bd098f
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/App.cpp
@@ -0,0 +1,252 @@
+/* Copyright 2015-2016 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include "pch2.h"
+#include "App.h"
+
+#include <ppltasks.h>
+
+using namespace UnityEmulatorApp;
+
+using namespace concurrency;
+using namespace Windows::ApplicationModel;
+using namespace Windows::ApplicationModel::Core;
+using namespace Windows::ApplicationModel::Activation;
+using namespace Windows::UI::Core;
+using namespace Windows::UI::Input;
+using namespace Windows::System;
+using namespace Windows::Foundation;
+using namespace Windows::Graphics::Display;
+
+using Microsoft::WRL::ComPtr;
+
+
+// The main function is only used to initialize our IFrameworkView class.
+[Platform::MTAThread]
+int main(Platform::Array<Platform::String^>^)
+{
+ auto direct3DApplicationSource = ref new Direct3DApplicationSource();
+ CoreApplication::Run(direct3DApplicationSource);
+ return 0;
+}
+
+IFrameworkView^ Direct3DApplicationSource::CreateView()
+{
+ return ref new App();
+}
+
+App::App() :
+ m_windowClosed(false),
+ m_windowVisible(true)
+{
+}
+
+// The first method called when the IFrameworkView is being created.
+void App::Initialize(CoreApplicationView^ applicationView)
+{
+ // Register event handlers for app lifecycle. This example includes Activated, so that we
+ // can make the CoreWindow active and start rendering on the window.
+ applicationView->Activated +=
+ ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &App::OnActivated);
+
+ CoreApplication::Suspending +=
+ ref new EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);
+
+ CoreApplication::Resuming +=
+ ref new EventHandler<Platform::Object^>(this, &App::OnResuming);
+}
+
+// Called when the CoreWindow object is created (or re-created).
+void App::SetWindow(CoreWindow^ window)
+{
+ window->SizeChanged +=
+ ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &App::OnWindowSizeChanged);
+
+ window->VisibilityChanged +=
+ ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
+
+ window->Closed +=
+ ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
+
+ DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
+
+ currentDisplayInformation->DpiChanged +=
+ ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDpiChanged);
+
+ currentDisplayInformation->OrientationChanged +=
+ ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnOrientationChanged);
+
+ DisplayInformation::DisplayContentsInvalidated +=
+ ref new TypedEventHandler<DisplayInformation^, Object^>(this, &App::OnDisplayContentsInvalidated);
+}
+
+// Initializes scene resources, or loads a previously saved app state.
+void App::Load(Platform::String^ entryPoint)
+{
+ if (m_main == nullptr)
+ {
+ m_main = std::unique_ptr<UnityEmulatorAppMain>(new UnityEmulatorAppMain());
+ }
+}
+
+// This method is called after the window becomes active.
+void App::Run()
+{
+ while (!m_windowClosed)
+ {
+ if (m_windowVisible)
+ {
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
+
+ //auto commandQueue = GetDeviceResources()->GetCommandQueue();
+ //PIXBeginEvent(commandQueue, 0, L"Update");
+ {
+ m_main->Update();
+ }
+ //PIXEndEvent(commandQueue);
+
+ //PIXBeginEvent(commandQueue, 0, L"Render");
+ {
+ GetDeviceResources()->BeginFrame();
+
+ m_main->Render();
+
+ GetDeviceResources()->EndFrame();
+ GetDeviceResources()->Present();
+ }
+ //PIXEndEvent(commandQueue);
+ }
+ else
+ {
+ CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
+ }
+ }
+}
+
+// Required for IFrameworkView.
+// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView
+// class is torn down while the app is in the foreground.
+void App::Uninitialize()
+{
+}
+
+// Application lifecycle event handlers.
+
+void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
+{
+ // Run() won't start until the CoreWindow is activated.
+ CoreWindow::GetForCurrentThread()->Activate();
+}
+
+void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
+{
+ // Save app state asynchronously after requesting a deferral. Holding a deferral
+ // indicates that the application is busy performing suspending operations. Be
+ // aware that a deferral may not be held indefinitely. After about five seconds,
+ // the app will be forced to exit.
+ SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
+
+ create_task([this, deferral]()
+ {
+ m_main->OnSuspending();
+ deferral->Complete();
+ });
+}
+
+void App::OnResuming(Platform::Object^ sender, Platform::Object^ args)
+{
+ // Restore any data or state that was unloaded on suspend. By default, data
+ // and state are persisted when resuming from suspend. Note that this event
+ // does not occur if the app was previously terminated.
+
+ m_main->OnResuming();
+}
+
+// Window event handlers.
+
+void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
+{
+ GetDeviceResources()->SetLogicalSize(Size(sender->Bounds.Width, sender->Bounds.Height));
+ m_main->OnWindowSizeChanged();
+}
+
+void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
+{
+ m_windowVisible = args->Visible;
+}
+
+void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
+{
+ m_windowClosed = true;
+}
+
+// DisplayInformation event handlers.
+
+void App::OnDpiChanged(DisplayInformation^ sender, Object^ args)
+{
+ // 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.
+ GetDeviceResources()->SetDpi(sender->LogicalDpi);
+ m_main->OnWindowSizeChanged();
+}
+
+void App::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
+{
+ GetDeviceResources()->SetCurrentOrientation(sender->CurrentOrientation);
+ m_main->OnWindowSizeChanged();
+}
+
+void App::OnDisplayContentsInvalidated(DisplayInformation^ sender, Object^ args)
+{
+ GetDeviceResources()->ValidateDevice();
+}
+
+std::shared_ptr<DX::DeviceResources> App::GetDeviceResources()
+{
+ if (m_deviceResources != nullptr && m_deviceResources->IsDeviceRemoved())
+ {
+ // All references to the existing D3D device must be released before a new device
+ // can be created.
+
+ m_deviceResources = nullptr;
+ m_main->OnDeviceRemoved();
+
+#if defined(_DEBUG)
+ ComPtr<IDXGIDebug1> dxgiDebug;
+ if (SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
+ {
+ dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
+ }
+#endif
+ }
+
+ if (m_deviceResources == nullptr)
+ {
+ m_deviceResources = std::make_shared<DX::DeviceResources>();
+ m_deviceResources->SetWindow(CoreWindow::GetForCurrentThread());
+ m_main->CreateRenderers(m_deviceResources);
+ }
+ return m_deviceResources;
+}
diff --git a/unityplugin/UnityEmulator/src/UWP/App.h b/unityplugin/UnityEmulator/src/UWP/App.h
new file mode 100644
index 0000000..e762e8f
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/App.h
@@ -0,0 +1,75 @@
+/* Copyright 2015-2016 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#pragma once
+
+#include "pch.h"
+#include "DeviceResources.h"
+#include "UnityEmulatorAppMain.h"
+
+namespace UnityEmulatorApp
+{
+ // Main entry point for our app. Connects the app with the Windows shell and handles application lifecycle events.
+ ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
+ {
+ public:
+ App();
+
+ // IFrameworkView methods.
+ virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
+ virtual void SetWindow(Windows::UI::Core::CoreWindow^ window);
+ virtual void Load(Platform::String^ entryPoint);
+ virtual void Run();
+ virtual void Uninitialize();
+
+ protected:
+ // Application lifecycle event handlers.
+ void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args);
+ void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ args);
+ void OnResuming(Platform::Object^ sender, Platform::Object^ args);
+
+ // Window event handlers.
+ void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args);
+ void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args);
+ void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args);
+
+ // 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);
+
+ private:
+ std::shared_ptr<DX::DeviceResources> GetDeviceResources();
+
+ std::shared_ptr<DX::DeviceResources> m_deviceResources;
+ std::unique_ptr<UnityEmulatorAppMain> m_main;
+ bool m_windowClosed;
+ bool m_windowVisible;
+ };
+}
+
+ref class Direct3DApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
+{
+public:
+ virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
+};
diff --git a/unityplugin/UnityEmulator/src/UWP/DeviceResources.cpp b/unityplugin/UnityEmulator/src/UWP/DeviceResources.cpp
new file mode 100644
index 0000000..c38b510
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/DeviceResources.cpp
@@ -0,0 +1,459 @@
+#include "pch2.h"
+#include "DeviceResources.h"
+#include "DirectXHelper.h"
+
+#include "IUnityInterface.h"
+#include "UnityGraphicsD3D11Emulator.h"
+#include "UnityGraphicsD3D12Emulator.h"
+#include "DiligentGraphicsAdapterD3D11.h"
+#include "DiligentGraphicsAdapterD3D12.h"
+#include "ValidatedCast.h"
+
+#include "UnitySceneBase.h"
+#include "StringTools.h"
+#include "Errors.h"
+
+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;
+using namespace Diligent;
+
+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_d3dRenderTargetSize(),
+ m_outputSize(),
+ m_logicalSize(),
+ m_nativeOrientation(DisplayOrientations::None),
+ m_currentOrientation(DisplayOrientations::None),
+ m_dpi(-1.0f),
+ m_deviceRemoved(false)
+{
+ CreateDeviceResources();
+}
+
+// Configures the Direct3D device, and stores handles to it and the device context.
+void DX::DeviceResources::CreateDeviceResources()
+{
+ switch (m_DeviceType)
+ {
+ case DeviceType::D3D11:
+ {
+ auto &GraphicsD3D11Emulator = UnityGraphicsD3D11Emulator::GetInstance();
+ GraphicsD3D11Emulator.CreateD3D11DeviceAndContext();
+ m_UnityGraphicsEmulator = &GraphicsD3D11Emulator;
+ m_DiligentGraphics.reset(new DiligentGraphicsAdapterD3D11(GraphicsD3D11Emulator));
+ }
+ break;
+
+ case DeviceType::D3D12:
+ {
+ auto &GraphicsD3D12Emulator = UnityGraphicsD3D12Emulator::GetInstance();
+ GraphicsD3D12Emulator.CreateD3D12DeviceAndCommandQueue();
+ m_UnityGraphicsEmulator = &GraphicsD3D12Emulator;
+ m_DiligentGraphics.reset(new DiligentGraphicsAdapterD3D12(GraphicsD3D12Emulator));
+ }
+ break;
+
+ default:
+ LOG_ERROR_AND_THROW("Unsupported device type");
+ }
+}
+
+DX::DeviceResources::~DeviceResources()
+{
+ m_DiligentGraphics.reset();
+ m_UnityGraphicsEmulator->Release();
+}
+
+// These resources need to be recreated every time the window size is changed.
+void DX::DeviceResources::CreateWindowSizeDependentResources()
+{
+ 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;
+ auto fWidth = swapDimensions ? m_outputSize.Height : m_outputSize.Width;
+ auto fHeight = swapDimensions ? m_outputSize.Width : m_outputSize.Height;
+
+ UINT backBufferWidth = lround(fWidth);
+ UINT backBufferHeight = lround(fHeight);
+
+ if (m_UnityGraphicsEmulator->SwapChainInitialized())
+ {
+ m_DiligentGraphics->PreSwapChainResize();
+ // If the swap chain already exists, resize it.
+ m_UnityGraphicsEmulator->ResizeSwapChain(backBufferWidth, backBufferHeight);
+
+ m_DiligentGraphics->PostSwapChainResize();
+
+#if 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.
+ m_deviceRemoved = true;
+
+ // Do not continue execution of this method. DeviceResources will be destroyed and re-created.
+ return;
+ }
+ else
+ {
+ DX::ThrowIfFailed(hr);
+ }
+#endif
+ }
+ else
+ {
+ auto NativeWndHandle = reinterpret_cast<IUnknown*>(m_window.Get());
+ switch (m_DeviceType)
+ {
+ case DeviceType::D3D11:
+ {
+ auto &GraphicsD3D11Emulator = UnityGraphicsD3D11Emulator::GetInstance();
+ GraphicsD3D11Emulator.CreateSwapChain(NativeWndHandle, backBufferWidth, backBufferHeight);
+ ValidatedCast<DiligentGraphicsAdapterD3D11>(m_DiligentGraphics.get())->InitProxySwapChain();
+ }
+ break;
+
+ case DeviceType::D3D12:
+ {
+ auto &GraphicsD3D12Emulator = UnityGraphicsD3D12Emulator::GetInstance();
+ GraphicsD3D12Emulator.CreateSwapChain(NativeWndHandle, backBufferWidth, backBufferHeight);
+ ValidatedCast<DiligentGraphicsAdapterD3D12>(m_DiligentGraphics.get())->InitProxySwapChain();
+ }
+ break;
+
+ default:
+ UNEXPECTED("Unsupported device type");
+ }
+ }
+
+ // Set the proper orientation for the swap chain, and generate
+ // 3D matrix transformations for rendering to the rotated swap chain.
+ // The 3D matrix is specified explicitly to avoid rounding errors.
+
+ switch (displayRotation)
+ {
+ case DXGI_MODE_ROTATION_IDENTITY:
+ m_orientationTransform3D = ScreenRotation::Rotation0;
+ break;
+
+ case DXGI_MODE_ROTATION_ROTATE90:
+ m_orientationTransform3D = ScreenRotation::Rotation270;
+ break;
+
+ case DXGI_MODE_ROTATION_ROTATE180:
+ m_orientationTransform3D = ScreenRotation::Rotation180;
+ break;
+
+ case DXGI_MODE_ROTATION_ROTATE270:
+ m_orientationTransform3D = ScreenRotation::Rotation90;
+ break;
+
+ default:
+ throw ref new FailureException();
+ }
+#if 0
+ DX::ThrowIfFailed(
+ m_swapChain->SetRotation(displayRotation)
+ );
+#endif
+
+
+}
+
+// Determine the dimensions of the render target and whether it will be scaled down.
+void DX::DeviceResources::UpdateRenderTargetSize()
+{
+ m_effectiveDpi = m_dpi;
+
+ // 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;
+ }
+ }
+
+ // 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 CoreWindow is created (or re-created).
+void DX::DeviceResources::SetWindow(CoreWindow^ window)
+{
+ DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView();
+
+ m_window = window;
+ m_logicalSize = Windows::Foundation::Size(window->Bounds.Width, window->Bounds.Height);
+ m_nativeOrientation = currentDisplayInformation->NativeOrientation;
+ m_currentOrientation = currentDisplayInformation->CurrentOrientation;
+ m_dpi = currentDisplayInformation->LogicalDpi;
+
+ 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;
+
+ // When the display DPI changes, the logical size of the window (measured in Dips) also changes and needs to be updated.
+ m_logicalSize = Windows::Foundation::Size(m_window->Bounds.Width, m_window->Bounds.Height);
+
+ CreateWindowSizeDependentResources();
+ }
+}
+
+// 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 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.
+
+ ComPtr<IDXGIDevice3> dxgiDevice;
+ ComPtr<ID3D11Device> d3d11Device;
+ ComPtr<ID3D12Device> d3d12Device;
+
+ if (m_DeviceType == DeviceType::D3D11)
+ {
+ auto &GraphicsD3D11Emulator = UnityGraphicsD3D11Emulator::GetInstance();
+ d3d11Device = reinterpret_cast<ID3D11Device*>(GraphicsD3D11Emulator.GetGraphicsImpl());
+ DX::ThrowIfFailed(d3d11Device.As(&dxgiDevice));
+ }
+ else if (m_DeviceType == DeviceType::D3D12)
+ {
+ auto &GraphicsD3D12Emulator = UnityGraphicsD3D12Emulator::GetInstance();
+ d3d12Device = reinterpret_cast<ID3D12Device*>(GraphicsD3D12Emulator.GetGraphicsImpl());
+ DX::ThrowIfFailed(d3d12Device.As(&dxgiDevice));
+ }
+
+ ComPtr<IDXGIAdapter> deviceAdapter;
+ DX::ThrowIfFailed(dxgiDevice->GetAdapter(&deviceAdapter));
+
+ ComPtr<IDXGIFactory2> deviceFactory;
+ DX::ThrowIfFailed(deviceAdapter->GetParent(IID_PPV_ARGS(&deviceFactory)));
+
+ // First, get the LUID for the default adapter from when the device was created.
+
+ DXGI_ADAPTER_DESC previousDesc;
+ {
+ ComPtr<IDXGIAdapter1> previousDefaultAdapter;
+ DX::ThrowIfFailed(deviceFactory->EnumAdapters1(0, &previousDefaultAdapter));
+
+ DX::ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
+ }
+
+ // Next, get the information for the current default adapter.
+
+ DXGI_ADAPTER_DESC currentDesc;
+ {
+ ComPtr<IDXGIFactory4> currentDxgiFactory;
+ DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&currentDxgiFactory)));
+
+ ComPtr<IDXGIAdapter1> currentDefaultAdapter;
+ DX::ThrowIfFailed(currentDxgiFactory->EnumAdapters1(0, &currentDefaultAdapter));
+
+ DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(&currentDesc));
+ }
+
+ // 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 ||
+ d3d11Device && FAILED(d3d11Device->GetDeviceRemovedReason()) ||
+ d3d12Device && FAILED(d3d12Device->GetDeviceRemovedReason()))
+ {
+ m_deviceRemoved = true;
+ }
+}
+
+void DX::DeviceResources::SetResourceStateTransitionHandler(IResourceStateTransitionHandler *pHandler)
+{
+ if (GetDeviceType() == DeviceType::D3D12)
+ {
+ UnityGraphicsD3D12Emulator::GetInstance().SetTransitionHandler(pHandler);
+ }
+}
+
+void DX::DeviceResources::BeginFrame()
+{
+ m_UnityGraphicsEmulator->BeginFrame();
+ m_DiligentGraphics->BeginFrame();
+}
+
+void DX::DeviceResources::EndFrame()
+{
+ m_DiligentGraphics->EndFrame();
+ m_UnityGraphicsEmulator->EndFrame();
+}
+
+// Present the contents of the swap chain to the screen.
+void DX::DeviceResources::Present()
+{
+ m_UnityGraphicsEmulator->Present();
+
+ //// 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)
+ //{
+ // m_deviceRemoved = true;
+ //}
+ //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;
+}
diff --git a/unityplugin/UnityEmulator/src/UWP/DeviceResources.h b/unityplugin/UnityEmulator/src/UWP/DeviceResources.h
new file mode 100644
index 0000000..c91b055
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/DeviceResources.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include "UnityGraphicsEmulator.h"
+#include "DiligentGraphicsAdapter.h"
+#include "ResourceStateTransitionHandler.h"
+
+namespace DX
+{
+ // Controls all the DirectX device resources.
+ class DeviceResources
+ {
+ public:
+ DeviceResources();
+ ~DeviceResources();
+ void SetWindow(Windows::UI::Core::CoreWindow^ window);
+ void SetLogicalSize(Windows::Foundation::Size logicalSize);
+ void SetCurrentOrientation(Windows::Graphics::Display::DisplayOrientations currentOrientation);
+ void SetDpi(float dpi);
+ void ValidateDevice();
+ void BeginFrame();
+ void Present();
+ void EndFrame();
+ DiligentGraphicsAdapter* GetDiligentGraphicsAdapter() { return m_DiligentGraphics.get(); }
+ UnityGraphicsEmulator* GetUnityGraphicsEmulator() { return m_UnityGraphicsEmulator;}
+
+ Diligent::DeviceType GetDeviceType()const {return m_DeviceType;}
+
+ // 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; }
+ bool IsDeviceRemoved() const { return m_deviceRemoved; }
+ void SetResourceStateTransitionHandler(IResourceStateTransitionHandler *pHandler);
+ // D3D Accessors.
+ DirectX::XMFLOAT4X4 GetOrientationTransform3D() const { return m_orientationTransform3D; }
+
+ private:
+ void CreateDeviceResources();
+ void CreateWindowSizeDependentResources();
+ void UpdateRenderTargetSize();
+ DXGI_MODE_ROTATION ComputeDisplayRotation();
+
+ bool m_deviceRemoved = false;
+
+ UnityGraphicsEmulator* m_UnityGraphicsEmulator = nullptr;
+
+ std::unique_ptr<DiligentGraphicsAdapter> m_DiligentGraphics;
+
+ // Cached reference to the Window.
+ Platform::Agile<Windows::UI::Core::CoreWindow> m_window;
+
+ // Cached device properties.
+ 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;
+
+ // This is the DPI that will be reported back to the app. It takes into account whether the app supports high resolution screens or not.
+ float m_effectiveDpi;
+
+ // Transforms used for display orientation.
+ DirectX::XMFLOAT4X4 m_orientationTransform3D;
+
+ Diligent::DeviceType m_DeviceType = Diligent::DeviceType::D3D12;
+ };
+}
diff --git a/unityplugin/UnityEmulator/src/UWP/DirectXHelper.h b/unityplugin/UnityEmulator/src/UWP/DirectXHelper.h
new file mode 100644
index 0000000..958b355
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/DirectXHelper.h
@@ -0,0 +1,58 @@
+#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.
+ }
+
+ // Assign a name to the object to aid with debugging.
+#if defined(_DEBUG)
+ inline void SetName(ID3D12Object* pObject, LPCWSTR name)
+ {
+ pObject->SetName(name);
+ }
+#else
+ inline void SetName(ID3D12Object*, LPCWSTR)
+ {
+ }
+#endif
+}
+
+// Naming helper function for ComPtr<T>.
+// Assigns the name of the variable as the name of the object.
+#define NAME_D3D12_OBJECT(x) DX::SetName(x.Get(), L#x)
diff --git a/unityplugin/UnityEmulator/src/UWP/StepTimer.h b/unityplugin/UnityEmulator/src/UWP/StepTimer.h
new file mode 100644
index 0000000..286710c
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/StepTimer.h
@@ -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(&currentTime))
+ {
+ 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;
+ };
+}
diff --git a/unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.cpp b/unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.cpp
new file mode 100644
index 0000000..ea19b7c
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.cpp
@@ -0,0 +1,209 @@
+/* Copyright 2015-2016 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include "pch2.h"
+#include "UnityEmulatorAppMain.h"
+#include "DirectXHelper.h"
+#include "StringTools.h"
+#include "Errors.h"
+
+using namespace UnityEmulatorApp;
+using namespace Windows::Foundation;
+using namespace Windows::System::Threading;
+using namespace Concurrency;
+using namespace Diligent;
+
+// The DirectX 12 Application template is documented at http://go.microsoft.com/fwlink/?LinkID=613670&clcid=0x409
+
+HMODULE UnityEmulatorAppMain::m_DLLHandle;
+UnityEmulatorAppMain::TUnityPluginLoad UnityEmulatorAppMain::UnityPluginLoad;
+UnityEmulatorAppMain::TUnityPluginUnload UnityEmulatorAppMain::UnityPluginUnload;
+UnityEmulatorAppMain::TGetRenderEventFunc UnityEmulatorAppMain::GetRenderEventFunc;
+UnityRenderingEvent UnityEmulatorAppMain::RenderEventFunc;
+
+void* UnityEmulatorAppMain::LoadPluginFunction(const char* FunctionName)
+{
+ auto Func = GetProcAddress(m_DLLHandle, FunctionName);
+ VERIFY( Func != nullptr, "Failed to import plugin function \"", FunctionName, "\"." );
+ return Func;
+}
+
+
+bool UnityEmulatorAppMain::LoadPlugin(const char* LibPath)
+{
+ auto wLibPath = WidenString(LibPath);
+ m_DLLHandle = LoadPackagedLibrary( wLibPath.c_str(), 0);
+ if( m_DLLHandle == NULL )
+ {
+ LOG_ERROR_MESSAGE( "Failed to load ", LibPath, " library." );
+ return false;
+ }
+
+ UnityPluginLoad = reinterpret_cast<TUnityPluginLoad>( GetProcAddress(m_DLLHandle, "UnityPluginLoad") );
+ UnityPluginUnload = reinterpret_cast<TUnityPluginUnload>( GetProcAddress(m_DLLHandle, "UnityPluginUnload") );
+ GetRenderEventFunc = reinterpret_cast<TGetRenderEventFunc>( GetProcAddress(m_DLLHandle, "GetRenderEventFunc") );
+ if( UnityPluginLoad == nullptr || UnityPluginUnload == nullptr || GetRenderEventFunc == nullptr )
+ {
+ LOG_ERROR_MESSAGE( "Failed to import plugin functions from ", LibPath, " library." );
+ FreeLibrary( m_DLLHandle );
+ return false;
+ }
+
+ return true;
+}
+
+
+// Loads and initializes application assets when the application is loaded.
+UnityEmulatorAppMain::UnityEmulatorAppMain() :
+ m_scene(CreateScene())
+{
+#if defined(PLATFORM_UNIVERSAL_WINDOWS)
+ FileSystem::SetWorkingDirectory("assets");
+#endif
+
+ std::string LibName = "Assets\\";
+ LibName.append(m_scene->GetPluginName());
+
+#if _WIN64
+# if _M_ARM >= 7
+ LibName += "_arm";
+# else
+ LibName += "_64";
+# endif
+#else
+# if _M_ARM >= 7
+ LibName += "_arm";
+# else
+ LibName += "_32";
+# endif
+#endif
+
+#ifdef _DEBUG
+ LibName += "d";
+#else
+ LibName += "r";
+#endif
+
+ LibName.append(".dll");
+ if (!LoadPlugin(LibName.c_str()))
+ throw std::runtime_error("Failed to load plugin");
+
+ m_scene->OnPluginLoad(LoadPluginFunction);
+
+ // 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);
+}
+
+void UnityEmulatorAppMain::UnloadPlugin()
+{
+ m_deviceResources->GetUnityGraphicsEmulator()->InvokeDeviceEventCallback(kUnityGfxDeviceEventShutdown);
+ UnityPluginUnload();
+ FreeLibrary(m_DLLHandle);
+ m_DLLHandle = NULL;
+}
+
+
+UnityEmulatorAppMain::~UnityEmulatorAppMain()
+{
+ m_scene->OnPluginUnload();
+ m_scene.reset();
+ UnloadPlugin();
+}
+
+// Creates and initializes the renderers.
+void UnityEmulatorAppMain::CreateRenderers(const std::shared_ptr<DX::DeviceResources>& deviceResources)
+{
+ m_deviceResources = deviceResources;
+ m_scene->SetDiligentGraphicsAdapter(m_deviceResources->GetDiligentGraphicsAdapter());
+ m_scene->OnGraphicsInitialized();
+ m_deviceResources->SetResourceStateTransitionHandler(m_scene->GetStateTransitionHandler());
+ UnityPluginLoad(&m_deviceResources->GetUnityGraphicsEmulator()->GeUnityInterfaces());
+ RenderEventFunc = GetRenderEventFunc();
+
+ OnWindowSizeChanged();
+}
+
+// Updates the application state once per frame.
+void UnityEmulatorAppMain::Update()
+{
+ // Update scene objects.
+ m_timer.Tick([&]()
+ {
+
+ });
+}
+
+// Renders the current frame according to the current application state.
+// Returns true if the frame was rendered and is ready to be displayed.
+bool UnityEmulatorAppMain::Render()
+{
+ // Don't try to render anything before the first Update.
+ if (m_timer.GetFrameCount() == 0)
+ {
+ return false;
+ }
+
+ float CurrTime = static_cast<float>(m_timer.GetTotalSeconds());
+ float ElapsedTime = static_cast<float>(m_timer.GetElapsedSeconds());
+ m_scene->Render(RenderEventFunc, CurrTime, ElapsedTime);
+
+ return true;
+}
+
+// Updates application state when the window's size changes (e.g. device orientation change)
+void UnityEmulatorAppMain::OnWindowSizeChanged()
+{
+ auto Size = m_deviceResources->GetOutputSize();
+ m_scene->OnWindowResize(static_cast<int>(Size.Width), static_cast<int>(Size.Height));
+}
+
+// Notifies the app that it is being suspended.
+void UnityEmulatorAppMain::OnSuspending()
+{
+ // TODO: Replace this with your app's suspending logic.
+
+ // Process lifetime management may terminate suspended apps at any time, so it is
+ // good practice to save any state that will allow the app to restart where it left off.
+
+ //m_sceneRenderer->SaveState();
+
+ // If your application uses video memory allocations that are easy to re-create,
+ // consider releasing that memory to make it available to other applications.
+}
+
+// Notifes the app that it is no longer suspended.
+void UnityEmulatorAppMain::OnResuming()
+{
+ // TODO: Replace this with your app's resuming logic.
+}
+
+// Notifies renderers that device resources need to be released.
+void UnityEmulatorAppMain::OnDeviceRemoved()
+{
+ // TODO: Save any necessary application or renderer state and release the renderer
+ // and its resources which are no longer valid.
+ //m_sceneRenderer->SaveState();
+ //m_pSample = nullptr;
+}
diff --git a/unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.h b/unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.h
new file mode 100644
index 0000000..e722907
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/UnityEmulatorAppMain.h
@@ -0,0 +1,70 @@
+
+/* Copyright 2015-2016 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#pragma once
+
+#include "StepTimer.h"
+#include "DeviceResources.h"
+#include "UnitySceneBase.h"
+#include "IUnityInterface.h"
+
+namespace UnityEmulatorApp
+{
+ class UnityEmulatorAppMain
+ {
+ public:
+ UnityEmulatorAppMain();
+ ~UnityEmulatorAppMain();
+ void CreateRenderers(const std::shared_ptr<DX::DeviceResources>& deviceResources);
+ void Update();
+ bool Render();
+
+ void OnWindowSizeChanged();
+ void OnSuspending();
+ void OnResuming();
+ void OnDeviceRemoved();
+
+ private:
+ using TUnityPluginLoad = void (UNITY_INTERFACE_API *)(IUnityInterfaces* unityInterfaces);
+ using TUnityPluginUnload = void (UNITY_INTERFACE_API *)();
+ using TGetRenderEventFunc = UnityRenderingEvent(UNITY_INTERFACE_API *)();
+
+ static HMODULE m_DLLHandle;
+ static TUnityPluginLoad UnityPluginLoad;
+ static TUnityPluginUnload UnityPluginUnload;
+ static TGetRenderEventFunc GetRenderEventFunc;
+ static UnityRenderingEvent RenderEventFunc;
+ static void* LoadPluginFunction(const char* FunctionName);
+
+ static bool LoadPlugin(const char* LibName);
+ void UnloadPlugin();
+
+ // Cached pointer to device resources.
+ std::shared_ptr<DX::DeviceResources> m_deviceResources;
+ std::unique_ptr<UnitySceneBase> m_scene;
+
+ // Rendering loop timer.
+ DX::StepTimer m_timer;
+ };
+}
diff --git a/unityplugin/UnityEmulator/src/UWP/pch2.h b/unityplugin/UnityEmulator/src/UWP/pch2.h
new file mode 100644
index 0000000..b90e80e
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UWP/pch2.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#define NOMINIMAX
+
+#include <wrl.h>
+#include <wrl/client.h>
+#include <dxgi1_4.h>
+#include <d3d12.h>
+#include <d3d11.h>
+#include <pix.h>
+#include <DirectXColors.h>
+#include <DirectXMath.h>
+#include <memory>
+#include <vector>
+#include <agile.h>
+#include <concrt.h>
+
+#if defined(_DEBUG)
+#include <dxgidebug.h>
+#endif
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsD3D11Emulator.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsD3D11Emulator.cpp
new file mode 100644
index 0000000..f6dc7e2
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsD3D11Emulator.cpp
@@ -0,0 +1,370 @@
+
+#include <stdexcept>
+
+#include "UnityGraphicsD3D11Impl.h"
+
+#include "UnityGraphicsD3D11Emulator.h"
+#include "IUnityGraphicsD3D11.h"
+#include "DebugUtilities.h"
+#include "Errors.h"
+
+
+#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 Windows Store apps.
+ nullptr, // No need to keep the D3D device reference.
+ nullptr, // No need to know the feature level.
+ nullptr // No need to keep the D3D device context reference.
+ );
+
+ return SUCCEEDED(hr);
+}
+#endif
+
+void UnityGraphicsD3D11Impl::CreateDeviceAndContext()
+{
+ // This flag adds support for surfaces with a different color channel ordering
+ // than the API default. It is required for compatibility with Direct2D.
+ // D3D11_CREATE_DEVICE_BGRA_SUPPORT;
+ UINT creationFlags = 0;
+
+#if defined(_DEBUG)
+ if (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[] =
+ {
+#ifdef PLATFORM_UNIVERSAL_WINDOWS
+ D3D_FEATURE_LEVEL_11_1,
+#endif
+ 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.
+ D3D_FEATURE_LEVEL d3dFeatureLevel = D3D_FEATURE_LEVEL_11_0;
+ HRESULT hr = D3D11CreateDevice(
+ nullptr, // Specify nullptr to use the default adapter.
+ D3D_DRIVER_TYPE_HARDWARE, // Create a device using the hardware graphics driver.
+ 0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
+ creationFlags, // Set debug and Direct2D compatibility flags.
+ featureLevels, // List of feature levels this app can support.
+ ARRAYSIZE(featureLevels), // Size of the list above.
+ D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Store apps.
+ &m_d3d11Device, // Returns the Direct3D device created.
+ &d3dFeatureLevel, // Returns feature level of device created.
+ &m_d3d11Context // Returns the device immediate context.
+ );
+
+ if (FAILED(hr))
+ {
+ // If the initialization fails, fall back to the WARP device.
+ // For more information on WARP, see:
+ // http://go.microsoft.com/fwlink/?LinkId=286690
+ hr = D3D11CreateDevice(
+ nullptr,
+ D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
+ 0,
+ creationFlags,
+ featureLevels,
+ ARRAYSIZE(featureLevels),
+ D3D11_SDK_VERSION,
+ &m_d3d11Device,
+ &d3dFeatureLevel,
+ &m_d3d11Context
+ );
+ throw std::runtime_error("Failed to create D3D11 native device and immediate context");
+ return;
+ }
+}
+
+void UnityGraphicsD3D11Impl::CreateSwapChain(void* pNativeWndHandle, unsigned int Width, unsigned int Height)
+{
+ m_BackBufferWidth = 0;
+ m_BackBufferHeight = 0;
+
+#ifdef PLATFORM_WIN32
+ auto hWnd = reinterpret_cast<HWND>(pNativeWndHandle);
+ RECT rc;
+ GetClientRect( hWnd, &rc );
+ VERIFY_EXPR(Width = rc.right - rc.left);
+ VERIFY_EXPR(Height = rc.bottom - rc.top);
+#endif
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = m_BackBufferWidth = Width;
+ swapChainDesc.Height = m_BackBufferHeight = Height;
+ // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats:
+ // - DXGI_FORMAT_R16G16B16A16_FLOAT
+ // - DXGI_FORMAT_B8G8R8A8_UNORM
+ // - DXGI_FORMAT_R8G8B8A8_UNORM
+ // - DXGI_FORMAT_R10G10B10A2_UNORM
+ // If RGBA8_UNORM_SRGB swap chain is required, we will create RGBA8_UNORM swap chain, but
+ // create RGBA8_UNORM_SRGB render target view
+ swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.Scaling = DXGI_SCALING_NONE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used
+ swapChainDesc.Flags = 0;
+
+ CComPtr<IDXGISwapChain1> pSwapChain1;
+
+#if defined( PLATFORM_WIN32 )
+ // This sequence obtains the DXGI factory that was used to create the Direct3D device above.
+ CComPtr<IDXGIDevice> pDXGIDevice;
+ m_d3d11Device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast<void**>( static_cast<IDXGIDevice**>(&pDXGIDevice) ) );
+ CComPtr<IDXGIAdapter> pDXGIAdapter;
+ pDXGIDevice->GetAdapter(&pDXGIAdapter);
+ CComPtr<IDXGIFactory2> pDXGIFactory;
+ pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>( static_cast<IDXGIFactory2**>(&pDXGIFactory) ));
+
+ auto hr = pDXGIFactory->CreateSwapChainForHwnd(m_d3d11Device, hWnd, &swapChainDesc, nullptr, nullptr, &pSwapChain1);
+ if(FAILED(hr))
+ throw std::runtime_error( "Failed to create DXGI swap chain" );
+
+#elif defined( PLATFORM_UNIVERSAL_WINDOWS )
+
+ CComPtr<IDXGIDevice3> pDXGIDevice;
+ m_d3d11Device->QueryInterface(__uuidof(IDXGIDevice3), reinterpret_cast<void**>(static_cast<IDXGIDevice3**>(&pDXGIDevice)));
+ CComPtr<IDXGIAdapter> pDXGIAdapter;
+ pDXGIDevice->GetAdapter(&pDXGIAdapter);
+ CComPtr<IDXGIFactory2> pDXGIFactory;
+ pDXGIAdapter->GetParent(__uuidof(pDXGIFactory), reinterpret_cast<void**>(static_cast<IDXGIFactory2**>(&pDXGIFactory)));
+
+ HRESULT hr = pDXGIFactory->CreateSwapChainForCoreWindow(
+ m_d3d11Device,
+ reinterpret_cast<IUnknown*>(pNativeWndHandle),
+ &swapChainDesc,
+ nullptr,
+ &pSwapChain1);
+ if(FAILED(hr))
+ throw std::runtime_error( "Failed to create DXGI swap chain" );
+
+ // 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.
+ pDXGIDevice->SetMaximumFrameLatency( 1 );
+
+#endif
+
+ pSwapChain1->QueryInterface( __uuidof(m_SwapChain), reinterpret_cast<void**>(static_cast<IDXGISwapChain**>(&m_SwapChain)) );
+
+ CreateRTVandDSV();
+}
+
+void UnityGraphicsD3D11Impl::CreateRTVandDSV()
+{
+ m_BackBufferRTV.Release();
+ m_DepthBufferDSV.Release();
+
+ // Create a render target view
+ CComPtr<ID3D11Texture2D> pBackBuffer;
+ auto hr = m_SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(static_cast<ID3D11Texture2D**>(&pBackBuffer)));
+ VERIFY_EXPR(SUCCEEDED(hr));
+
+ D3D11_RENDER_TARGET_VIEW_DESC RTVDesc = {};
+ RTVDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ // We need to explicitly specify RTV format, as we may need to create RGBA8_UNORM_SRGB RTV for
+ // a RGBA8_UNORM swap chain
+ RTVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ RTVDesc.Texture2D.MipSlice = 0;
+ hr = m_d3d11Device->CreateRenderTargetView(pBackBuffer, &RTVDesc, &m_BackBufferRTV);
+ VERIFY_EXPR(SUCCEEDED(hr));
+
+ DXGI_SWAP_CHAIN_DESC SwapChainDesc;
+ m_SwapChain->GetDesc(&SwapChainDesc);
+ // Create depth buffer
+ D3D11_TEXTURE2D_DESC DepthBufferDesc;
+ DepthBufferDesc.Width = m_BackBufferWidth;
+ DepthBufferDesc.Height = m_BackBufferHeight;
+ DepthBufferDesc.MipLevels = 1;
+ DepthBufferDesc.ArraySize = 1;
+ auto DepthFormat = DXGI_FORMAT_D32_FLOAT;
+ DepthBufferDesc.Format = DepthFormat;
+ DepthBufferDesc.SampleDesc.Count = 1;
+ DepthBufferDesc.SampleDesc.Quality = 0;
+ DepthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
+ DepthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+ DepthBufferDesc.CPUAccessFlags = 0;
+ DepthBufferDesc.MiscFlags = 0;
+ CComPtr<ID3D11Texture2D> ptex2DDepthBuffer;
+ hr = m_d3d11Device->CreateTexture2D(&DepthBufferDesc, NULL, &ptex2DDepthBuffer);
+ VERIFY_EXPR(SUCCEEDED(hr));
+
+ // Create DSV
+ m_d3d11Device->CreateDepthStencilView(ptex2DDepthBuffer, NULL, &m_DepthBufferDSV);
+ VERIFY_EXPR(SUCCEEDED(hr));
+
+ ID3D11RenderTargetView *DefaultRTV[] = { GetRTV() };
+ m_d3d11Context->OMSetRenderTargets(1, DefaultRTV, GetDSV());
+}
+
+
+void UnityGraphicsD3D11Impl::Present()
+{
+ UINT SyncInterval = 1; // 0
+#ifdef PLATFORM_UNIVERSAL_WINDOWS
+ SyncInterval = 1; // Interval 0 is not supported on Windows Phone
+#endif
+
+ ID3D11RenderTargetView *NullTRV[] = { nullptr };
+ m_d3d11Context->OMSetRenderTargets(1, NullTRV, nullptr);
+
+ m_SwapChain->Present( SyncInterval, 0 );
+ // A successful Present call for DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL SwapChains unbinds
+ // backbuffer 0 from all GPU writeable bind points.
+ // We need to rebind all render targets to make sure that
+ // the back buffer is not unbound
+}
+
+void UnityGraphicsD3D11Impl::ResizeSwapChain( UINT NewWidth, UINT NewHeight )
+{
+ if (NewWidth == 0 || NewHeight == 0)
+ return;
+
+ ID3D11RenderTargetView *NullTRV[] = { nullptr };
+ m_d3d11Context->OMSetRenderTargets(1, NullTRV, nullptr);
+ // Swap chain cannot be resized until all references are released
+ m_BackBufferRTV.Release();
+ m_DepthBufferDSV.Release();
+ try
+ {
+ m_BackBufferWidth = NewWidth;
+ m_BackBufferHeight = NewHeight;
+ DXGI_SWAP_CHAIN_DESC SCDes;
+ memset( &SCDes, 0, sizeof( SCDes ) );
+ m_SwapChain->GetDesc( &SCDes );
+ auto hr = m_SwapChain->ResizeBuffers(SCDes.BufferCount, m_BackBufferWidth, m_BackBufferHeight, SCDes.BufferDesc.Format,
+ SCDes.Flags);
+ if(FAILED(hr))
+ throw std::runtime_error("Failed to resize the DXGI swap chain");
+
+
+ CreateRTVandDSV();
+ }
+ catch( const std::runtime_error & )
+ {
+ LOG_ERROR( "Failed to resize the swap chain" );
+ }
+}
+
+
+std::unique_ptr<UnityGraphicsD3D11Impl> UnityGraphicsD3D11Emulator::m_GraphicsImpl;
+
+UnityGraphicsD3D11Emulator::UnityGraphicsD3D11Emulator()
+{
+ VERIFY(!m_GraphicsImpl, "Another emulator has already been initialized");
+ m_GraphicsImpl.reset( new UnityGraphicsD3D11Impl );
+ GeUnityInterfaces().RegisterInterface(IUnityGraphicsD3D11_GUID, GetUnityGraphicsAPIInterface());
+}
+
+UnityGraphicsD3D11Emulator& UnityGraphicsD3D11Emulator::GetInstance()
+{
+ static UnityGraphicsD3D11Emulator TheInstance;
+ return TheInstance;
+}
+
+void UnityGraphicsD3D11Emulator::CreateD3D11DeviceAndContext()
+{
+ m_GraphicsImpl->CreateDeviceAndContext();
+}
+
+void UnityGraphicsD3D11Emulator::CreateSwapChain(void *pNativeWndHandle, unsigned int Width, unsigned int Height)
+{
+ m_GraphicsImpl->CreateSwapChain(pNativeWndHandle, Width, Height);
+}
+
+void UnityGraphicsD3D11Emulator::Present()
+{
+ m_GraphicsImpl->Present();
+}
+
+void UnityGraphicsD3D11Emulator::Release()
+{
+ m_GraphicsImpl.reset();
+}
+
+void UnityGraphicsD3D11Emulator::ResizeSwapChain(unsigned int Width, unsigned int Height)
+{
+ m_GraphicsImpl->ResizeSwapChain(Width, Height);
+}
+
+bool UnityGraphicsD3D11Emulator::SwapChainInitialized()
+{
+ return m_GraphicsImpl->GetSwapChain() != nullptr;
+}
+
+void* UnityGraphicsD3D11Emulator::GetD3D11Device()
+{
+ return m_GraphicsImpl->GetD3D11Device();
+}
+
+static ID3D11Device* UNITY_INTERFACE_API UnityGraphicsD3D11_GetDevice()
+{
+ auto *GraphicsImpl = UnityGraphicsD3D11Emulator::GetGraphicsImpl();
+ return GraphicsImpl != nullptr ? GraphicsImpl->GetD3D11Device() : nullptr;
+}
+
+UnityGraphicsD3D11Impl* UnityGraphicsD3D11Emulator::GetGraphicsImpl()
+{
+ return m_GraphicsImpl.get();
+}
+
+IUnityInterface* UnityGraphicsD3D11Emulator::GetUnityGraphicsAPIInterface()
+{
+ static IUnityGraphicsD3D11 UnityGraphicsD3D11;
+ UnityGraphicsD3D11.GetDevice = UnityGraphicsD3D11_GetDevice;
+ return &UnityGraphicsD3D11;
+}
+
+UnityGfxRenderer UnityGraphicsD3D11Emulator::GetUnityGfxRenderer()
+{
+ return kUnityGfxRendererD3D11;
+}
+
+void UnityGraphicsD3D11Emulator::BeginFrame()
+{
+ auto d3d11Ctx = m_GraphicsImpl->GetD3D11Context();
+ ID3D11RenderTargetView *DefaultRTV[] = { m_GraphicsImpl->GetRTV() };
+ d3d11Ctx->OMSetRenderTargets(1, DefaultRTV, m_GraphicsImpl->GetDSV());
+ D3D11_VIEWPORT Viewport;
+ Viewport.TopLeftX = 0;
+ Viewport.TopLeftY = 0;
+ Viewport.Width = static_cast<float>( m_GraphicsImpl->GetBackBufferWidth() );
+ Viewport.Height = static_cast<float>( m_GraphicsImpl->GetBackBufferHeight() );
+ Viewport.MinDepth = 0;
+ Viewport.MaxDepth = 1;
+ d3d11Ctx->RSSetViewports(1, &Viewport);
+ float ClearColor[] = { 0, 0, 0.5f, 1 };
+ d3d11Ctx->ClearRenderTargetView(DefaultRTV[0], ClearColor);
+ d3d11Ctx->ClearDepthStencilView(m_GraphicsImpl->GetDSV(), D3D11_CLEAR_DEPTH, UsesReverseZ() ? 0.f : 1.f, 0);
+}
+
+void UnityGraphicsD3D11Emulator::EndFrame()
+{
+}
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsD3D11Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsD3D11Impl.h
new file mode 100644
index 0000000..183522f
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsD3D11Impl.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#if defined(PLATFORM_WIN32)
+ #include <d3d11.h>
+#elif defined(PLATFORM_UNIVERSAL_WINDOWS)
+ #include <d3d11_2.h>
+#endif
+
+#include <dxgi1_2.h>
+#include <atlbase.h>
+
+#include <memory>
+
+class UnityGraphicsD3D11Impl
+{
+public:
+ void CreateDeviceAndContext();
+ void CreateSwapChain(void* pNativeWndHandle, unsigned int Width, unsigned int Height);
+ void CreateRTVandDSV();
+ void Present();
+ void ResizeSwapChain(UINT NewWidth, UINT NewHeight);
+
+
+ ID3D11Device* GetD3D11Device() { return m_d3d11Device; }
+ ID3D11DeviceContext* GetD3D11Context() { return m_d3d11Context; }
+ ID3D11RenderTargetView* GetRTV() { return m_BackBufferRTV; }
+ ID3D11DepthStencilView* GetDSV() { return m_DepthBufferDSV; }
+ UINT GetBackBufferWidth()const { return m_BackBufferWidth; }
+ UINT GetBackBufferHeight()const { return m_BackBufferHeight; }
+ IDXGISwapChain* GetSwapChain(){ return m_SwapChain; }
+
+private:
+ UINT m_BackBufferWidth = 0, m_BackBufferHeight = 0;
+ CComPtr<ID3D11Device> m_d3d11Device;
+ CComPtr<ID3D11DeviceContext> m_d3d11Context;
+ CComPtr<IDXGISwapChain> m_SwapChain;
+ CComPtr<ID3D11RenderTargetView> m_BackBufferRTV;
+ CComPtr<ID3D11DepthStencilView> m_DepthBufferDSV;
+};
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp
new file mode 100644
index 0000000..45b7332
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Emulator.cpp
@@ -0,0 +1,558 @@
+
+#include "UnityGraphicsD3D12Impl.h"
+#include "UnityGraphicsD3D12Emulator.h"
+#include "IUnityGraphicsD3D12.h"
+#include "DebugUtilities.h"
+#include "Errors.h"
+
+UnityGraphicsD3D12Impl::UnityGraphicsD3D12Impl() :
+ m_WaitForGPUEventHandle( CreateEvent(nullptr, false, false, nullptr) )
+{
+ VERIFY_EXPR(m_WaitForGPUEventHandle != INVALID_HANDLE_VALUE);
+}
+
+UnityGraphicsD3D12Impl::~UnityGraphicsD3D12Impl()
+{
+ IdleGPU();
+ CloseHandle(m_WaitForGPUEventHandle);
+}
+
+static void GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter)
+{
+ CComPtr<IDXGIAdapter1> adapter;
+ *ppAdapter = nullptr;
+
+ for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex)
+ {
+ DXGI_ADAPTER_DESC1 desc;
+ adapter->GetDesc1(&desc);
+
+ if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
+ {
+ // Don't select the Basic Render Driver adapter.
+ // If you want a software adapter, pass in "/warp" on the command line.
+ continue;
+ }
+
+ // Check to see if the adapter supports Direct3D 12, but don't create the
+ // actual device yet.
+ if (SUCCEEDED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
+ {
+ break;
+ }
+ }
+
+ *ppAdapter = adapter.Detach();
+}
+
+
+void UnityGraphicsD3D12Impl::CreateDeviceAndCommandQueue()
+{
+#if defined(_DEBUG)
+ // Enable the D3D12 debug layer.
+ {
+ CComPtr<ID3D12Debug> debugController;
+ if (SUCCEEDED(D3D12GetDebugInterface(__uuidof(debugController), reinterpret_cast<void**>(static_cast<ID3D12Debug**>(&debugController)) )))
+ {
+ debugController->EnableDebugLayer();
+ }
+ }
+#endif
+
+ CComPtr<IDXGIFactory4> factory;
+ HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory4**>(&factory)) );
+ if(FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create DXGI factory")
+
+ CComPtr<IDXGIAdapter1> hardwareAdapter;
+ GetHardwareAdapter(factory, &hardwareAdapter);
+
+ hr = D3D12CreateDevice(hardwareAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(m_D3D12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&m_D3D12Device)) );
+ if( FAILED(hr))
+ {
+ LOG_WARNING_MESSAGE("Failed to create hardware device. Attempting to create WARP device")
+
+ CComPtr<IDXGIAdapter> warpAdapter;
+ hr = factory->EnumWarpAdapter( __uuidof(warpAdapter), reinterpret_cast<void**>(static_cast<IDXGIAdapter**>(&warpAdapter)) );
+ if(FAILED(hr)) LOG_ERROR_AND_THROW("Failed to enum warp adapter")
+
+ hr = D3D12CreateDevice( warpAdapter, D3D_FEATURE_LEVEL_11_0, __uuidof(m_D3D12Device), reinterpret_cast<void**>(static_cast<ID3D12Device**>(&m_D3D12Device)) );
+ if(FAILED(hr)) LOG_ERROR_AND_THROW("Failed to crate warp device")
+ }
+
+#if _DEBUG
+ {
+ CComPtr<ID3D12InfoQueue> pInfoQueue;
+ hr = m_D3D12Device->QueryInterface(__uuidof(pInfoQueue), reinterpret_cast<void**>(static_cast<ID3D12InfoQueue**>(&pInfoQueue)));
+ if( SUCCEEDED(hr) )
+ {
+ // Suppress whole categories of messages
+ //D3D12_MESSAGE_CATEGORY Categories[] = {};
+
+ // Suppress messages based on their severity level
+ D3D12_MESSAGE_SEVERITY Severities[] =
+ {
+ D3D12_MESSAGE_SEVERITY_INFO
+ };
+
+ // Suppress individual messages by their ID
+ //D3D12_MESSAGE_ID DenyIds[] = {};
+
+ D3D12_INFO_QUEUE_FILTER NewFilter = {};
+ //NewFilter.DenyList.NumCategories = _countof(Categories);
+ //NewFilter.DenyList.pCategoryList = Categories;
+ NewFilter.DenyList.NumSeverities = _countof(Severities);
+ NewFilter.DenyList.pSeverityList = Severities;
+ //NewFilter.DenyList.NumIDs = _countof(DenyIds);
+ //NewFilter.DenyList.pIDList = DenyIds;
+
+ hr = pInfoQueue->PushStorageFilter(&NewFilter);
+ VERIFY(SUCCEEDED(hr), "Failed to push storage filter");
+ }
+ }
+#endif
+
+ {
+ auto hr = m_D3D12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(m_D3D12FrameFence), reinterpret_cast<void**>(static_cast<ID3D12Fence**>(&m_D3D12FrameFence)));
+ VERIFY(SUCCEEDED(hr), "Failed to create the fence");
+ m_D3D12FrameFence->SetName(L"Completed Frame Fence fence");
+ m_D3D12FrameFence->Signal(m_CompletedFenceValue); // 0 cmd lists are completed
+ }
+
+#ifndef RELEASE
+ // Prevent the GPU from overclocking or underclocking to get consistent timings
+ //d3d12Device->SetStablePowerState(TRUE);
+#endif
+
+ // Describe and create the command queue.
+ D3D12_COMMAND_QUEUE_DESC queueDesc = {};
+ queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
+ queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+
+ hr = m_D3D12Device->CreateCommandQueue(&queueDesc, __uuidof(m_D3D12CmdQueue), reinterpret_cast<void**>(static_cast<ID3D12CommandQueue**>(&m_D3D12CmdQueue)));
+ if(FAILED(hr)) LOG_ERROR_AND_THROW("Failed to create command queue")
+
+ hr = m_D3D12Device->SetName(L"Main Command Queue");
+ VERIFY_EXPR(SUCCEEDED(hr));
+}
+
+void UnityGraphicsD3D12Impl::CreateSwapChain(void* pNativeWndHandle, unsigned int Width, unsigned int Height)
+{
+#ifdef PLATFORM_WIN32
+ auto hWnd = reinterpret_cast<HWND>(pNativeWndHandle);
+ RECT rc;
+ GetClientRect( hWnd, &rc );
+ VERIFY_EXPR(Width = rc.right - rc.left);
+ VERIFY_EXPR(Height = rc.bottom - rc.top);
+#endif
+
+ DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
+ swapChainDesc.Width = m_BackBufferWidth = Width;
+ swapChainDesc.Height = m_BackBufferHeight = Height;
+ // Flip model swapchains (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD) only support the following Formats:
+ // - DXGI_FORMAT_R16G16B16A16_FLOAT
+ // - DXGI_FORMAT_B8G8R8A8_UNORM
+ // - DXGI_FORMAT_R8G8B8A8_UNORM
+ // - DXGI_FORMAT_R10G10B10A2_UNORM
+ // We will create RGBA8_UNORM swap chain, but RGBA8_UNORM_SRGB render target view
+ swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ swapChainDesc.Stereo = FALSE;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+ swapChainDesc.BufferCount = m_BackBuffersCount;
+ swapChainDesc.Scaling = DXGI_SCALING_NONE;
+ swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
+ swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; // Not used
+ swapChainDesc.Flags = 0;
+
+ CComPtr<IDXGISwapChain1> pSwapChain1;
+ CComPtr<IDXGIFactory4> factory;
+ HRESULT hr = CreateDXGIFactory1(__uuidof(factory), reinterpret_cast<void**>(static_cast<IDXGIFactory4**>(&factory)) );
+ if(FAILED(hr))LOG_ERROR_AND_THROW("Failed to create DXGI factory")
+
+#if defined( PLATFORM_WIN32 )
+ hr = factory->CreateSwapChainForHwnd(m_D3D12CmdQueue, hWnd, &swapChainDesc, nullptr, nullptr, &pSwapChain1);
+ if(FAILED(hr))LOG_ERROR_AND_THROW("Failed to create Swap Chain" );
+
+ // This sample does not support fullscreen transitions.
+ hr = factory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_WINDOW_CHANGES | DXGI_MWA_NO_ALT_ENTER);
+
+#elif defined( PLATFORM_UNIVERSAL_WINDOWS )
+
+ hr = factory->CreateSwapChainForCoreWindow(
+ m_D3D12CmdQueue,
+ reinterpret_cast<IUnknown*>(pNativeWndHandle),
+ &swapChainDesc,
+ nullptr,
+ &pSwapChain1);
+ if(FAILED(hr))LOG_ERROR_AND_THROW("Failed to create DXGI swap chain" );
+
+ // 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.
+ //pDXGIDevice->SetMaximumFrameLatency( 1 );
+#endif
+
+ pSwapChain1->QueryInterface(__uuidof(m_SwapChain), reinterpret_cast<void**>( static_cast<IDXGISwapChain3**>(&m_SwapChain) ));
+
+ m_FrameIndex = m_SwapChain->GetCurrentBackBufferIndex();
+
+ InitBuffersAndViews();
+}
+
+void UnityGraphicsD3D12Impl::InitBuffersAndViews()
+{
+ // Create RTV descriptor heap
+ if (!m_RTVDescriptorHeap)
+ {
+ // Describe and create a render target view (RTV) descriptor heap.
+ D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
+ rtvHeapDesc.NumDescriptors = m_BackBuffersCount;
+ rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
+ rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ auto hr = m_D3D12Device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_RTVDescriptorHeap));
+ if (FAILED(hr))LOG_ERROR_AND_THROW("Failed to create RTV descriptor heap")
+
+ m_rtvDescriptorSize = m_D3D12Device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
+ }
+
+ // Create DSV descriptor heap
+ if (!m_DSVDescriptorHeap)
+ {
+ D3D12_DESCRIPTOR_HEAP_DESC rtvHeapDesc = {};
+ rtvHeapDesc.NumDescriptors = 1;
+ rtvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
+ rtvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
+ auto hr = m_D3D12Device->CreateDescriptorHeap(&rtvHeapDesc, IID_PPV_ARGS(&m_DSVDescriptorHeap));
+ if (FAILED(hr))LOG_ERROR_AND_THROW("Failed to create DSV descriptor heap")
+ }
+
+ {
+ // Create render target views
+ D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = m_RTVDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
+ // Create a RTV for each frame.
+ for (UINT n = 0; n < m_BackBuffersCount; n++)
+ {
+ auto hr = m_SwapChain->GetBuffer(n, IID_PPV_ARGS(&m_RenderTargets[n]));
+
+ D3D12_RENDER_TARGET_VIEW_DESC RTVDesc = {};
+ RTVDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
+ RTVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
+ RTVDesc.Texture2D.MipSlice = 0;
+ RTVDesc.Texture2D.PlaneSlice = 0;
+ m_D3D12Device->CreateRenderTargetView(m_RenderTargets[n], &RTVDesc, rtvHandle);
+ rtvHandle.ptr += m_rtvDescriptorSize;
+ }
+ }
+
+ // Create depth-stencil buffer
+ {
+ D3D12_HEAP_PROPERTIES HeapProps;
+ HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT;
+ HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
+ HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
+ HeapProps.CreationNodeMask = 1;
+ HeapProps.VisibleNodeMask = 1;
+
+ D3D12_RESOURCE_DESC Desc = {};
+ Desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
+ Desc.Alignment = 0;
+ Desc.Width = m_BackBufferWidth;
+ Desc.Height = m_BackBufferHeight;
+ Desc.DepthOrArraySize = 1;
+ Desc.MipLevels = 1;
+ Desc.Format = DXGI_FORMAT_D32_FLOAT;
+ Desc.SampleDesc.Count = 1;
+ Desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
+ Desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
+
+ D3D12_CLEAR_VALUE ClearValue = {};
+ ClearValue.DepthStencil.Depth = 0.f;
+ ClearValue.Format = Desc.Format;
+ auto hr = m_D3D12Device->CreateCommittedResource( &HeapProps, D3D12_HEAP_FLAG_NONE,
+ &Desc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &ClearValue, __uuidof(m_DepthStencilBuffer), reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_DepthStencilBuffer)) );
+ if(FAILED(hr))LOG_ERROR_AND_THROW("Failed to create depth-stencil buffer")
+
+ // Create depth-stencil view
+ D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = m_DSVDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
+ m_D3D12Device->CreateDepthStencilView(m_DepthStencilBuffer, nullptr, dsvHandle);
+ }
+}
+
+void UnityGraphicsD3D12Impl::Present()
+{
+ UINT SyncInterval = 0;
+#ifdef PLATFORM_UNIVERSAL_WINDOWS
+ SyncInterval = 1; // Interval 0 is not supported on Windows Phone
+#endif
+
+ //pImmediateCtxD3D12->Flush();
+
+ auto hr = m_SwapChain->Present( SyncInterval, 0 );
+ VERIFY(SUCCEEDED(hr), "Present failed");
+
+ //auto *pDeviceD3D12 = ValidatedCast<RenderDeviceD3D12Impl>( pImmediateCtxD3D12->GetDevice() );
+ //pDeviceD3D12->FinishFrame();
+ m_FrameIndex = m_SwapChain->GetCurrentBackBufferIndex();
+}
+
+void UnityGraphicsD3D12Impl::ResizeSwapChain( UINT NewWidth, UINT NewHeight )
+{
+ if (NewWidth == 0 || NewHeight == 0)
+ return;
+
+ IdleGPU();
+
+ for (auto &rtv : m_RenderTargets) rtv.Release();
+ m_DepthStencilBuffer.Release();
+
+ m_BackBufferWidth = NewWidth;
+ m_BackBufferHeight = NewHeight;
+
+ DXGI_SWAP_CHAIN_DESC SCDes;
+ memset( &SCDes, 0, sizeof( SCDes ) );
+ m_SwapChain->GetDesc( &SCDes );
+ auto hr = m_SwapChain->ResizeBuffers(SCDes.BufferCount, NewWidth, NewHeight, SCDes.BufferDesc.Format, SCDes.Flags);
+ if(FAILED(hr))
+ LOG_ERROR_MESSAGE("Failed to resize swap chain")
+
+ m_FrameIndex = m_SwapChain->GetCurrentBackBufferIndex();
+
+ InitBuffersAndViews();
+}
+
+bool UnityGraphicsD3D12Emulator::SwapChainInitialized()
+{
+ return m_GraphicsImpl->GetSwapChain() != nullptr;
+}
+
+void* UnityGraphicsD3D12Emulator::GetD3D12Device()
+{
+ return m_GraphicsImpl->GetD3D12Device();
+}
+
+
+CComPtr<ID3D12CommandAllocator> UnityGraphicsD3D12Impl::GetCommandAllocator()
+{
+ if (m_CmdAllocator)
+ return m_CmdAllocator;
+
+ if (!m_DiscardedAllocators.empty())
+ {
+ auto& AllocatorPair = m_DiscardedAllocators.front();
+ if ( IsFenceCompleted(AllocatorPair.first) )
+ {
+ m_CmdAllocator = AllocatorPair.second;
+ auto hr = m_CmdAllocator->Reset();
+ VERIFY_EXPR(SUCCEEDED(hr));
+ m_DiscardedAllocators.pop_front();
+ }
+ }
+
+ // If no allocators were ready to be reused, create a new one
+ if (!m_CmdAllocator)
+ {
+ auto hr = m_D3D12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(m_CmdAllocator), reinterpret_cast<void**>(&m_CmdAllocator));
+ VERIFY(SUCCEEDED(hr), "Failed to create command allocator")
+ m_CmdAllocator->SetName(L"UnityGraphicsD3D12Impl: cmd list allocator");
+ }
+
+ return m_CmdAllocator;
+}
+
+void UnityGraphicsD3D12Impl::DiscardCommandAllocator()
+{
+ VERIFY_EXPR(m_CmdAllocator);
+ m_DiscardedAllocators.emplace_back( m_NextFenceValue, m_CmdAllocator );
+ m_CmdAllocator.Release();
+}
+
+bool UnityGraphicsD3D12Impl::IsFenceCompleted(UINT64 FenceValue)
+{
+ m_CompletedFenceValue = m_D3D12FrameFence->GetCompletedValue();
+ return FenceValue <= m_CompletedFenceValue;
+}
+
+void UnityGraphicsD3D12Impl::IdleGPU()
+{
+ auto SignaledValue = m_NextFenceValue;
+ m_D3D12CmdQueue->Signal(m_D3D12FrameFence, SignaledValue);
+ ++m_NextFenceValue;
+
+ if (m_D3D12FrameFence->GetCompletedValue() < SignaledValue)
+ {
+ // Wait for the fence
+ m_D3D12FrameFence->SetEventOnCompletion(SignaledValue, m_WaitForGPUEventHandle);
+ WaitForSingleObject(m_WaitForGPUEventHandle, INFINITE);
+ }
+}
+
+UINT64 UnityGraphicsD3D12Impl::ExecuteCommandList(ID3D12CommandList *pCmdList)
+{
+ ID3D12CommandList *CmdLists[] = { pCmdList };
+ m_D3D12CmdQueue->ExecuteCommandLists(1, CmdLists);
+ auto FenceValue = m_NextFenceValue;
+ m_D3D12CmdQueue->Signal(m_D3D12FrameFence, m_NextFenceValue++);
+ return FenceValue;
+}
+
+void UnityGraphicsD3D12Impl::TransitonResourceStates(int stateCount, UnityGraphicsD3D12ResourceState* states)
+{
+ if (stateCount >= 0)
+ {
+ VERIFY(m_pStateTransitionHandler != nullptr, "State transition handler is not set")
+ m_pStateTransitionHandler->TransitionResources(stateCount, states);
+ }
+}
+
+
+std::unique_ptr<UnityGraphicsD3D12Impl> UnityGraphicsD3D12Emulator::m_GraphicsImpl;
+
+UnityGraphicsD3D12Emulator::UnityGraphicsD3D12Emulator()
+{
+ VERIFY(!m_GraphicsImpl, "Another emulator has already been initialized");
+ m_GraphicsImpl.reset( new UnityGraphicsD3D12Impl );
+ GeUnityInterfaces().RegisterInterface(IUnityGraphicsD3D12v2_GUID, GetUnityGraphicsAPIInterface());
+}
+
+UnityGraphicsD3D12Emulator& UnityGraphicsD3D12Emulator::GetInstance()
+{
+ static UnityGraphicsD3D12Emulator TheInstance;
+ return TheInstance;
+}
+
+void UnityGraphicsD3D12Emulator::CreateD3D12DeviceAndCommandQueue()
+{
+ m_GraphicsImpl->CreateDeviceAndCommandQueue();
+}
+
+void UnityGraphicsD3D12Emulator::CreateSwapChain(void *pNativeWndHandle, unsigned int Width, unsigned int Height)
+{
+ m_GraphicsImpl->CreateSwapChain(pNativeWndHandle, Width, Height);
+}
+
+void UnityGraphicsD3D12Emulator::SetTransitionHandler(IResourceStateTransitionHandler *pTransitionHandler)
+{
+ m_GraphicsImpl->SetTransitionHandler(pTransitionHandler);
+}
+
+void UnityGraphicsD3D12Emulator::Present()
+{
+ m_GraphicsImpl->Present();
+}
+
+void UnityGraphicsD3D12Emulator::Release()
+{
+ m_GraphicsImpl.reset();
+}
+
+void UnityGraphicsD3D12Emulator::ResizeSwapChain(unsigned int Width, unsigned int Height)
+{
+ m_GraphicsImpl->ResizeSwapChain(Width, Height);
+}
+
+static ID3D12Device* UNITY_INTERFACE_API UnityGraphicsD3D12_GetDevice()
+{
+ auto *GraphicsImpl = UnityGraphicsD3D12Emulator::GetGraphicsImpl();
+ return GraphicsImpl != nullptr ? GraphicsImpl->GetD3D12Device() : nullptr;
+}
+
+static UINT64 UNITY_INTERFACE_API UnityGraphicsD3D12_ExecuteCommandList(ID3D12GraphicsCommandList* commandList, int stateCount, UnityGraphicsD3D12ResourceState* states)
+{
+ auto *GraphicsImpl = UnityGraphicsD3D12Emulator::GetGraphicsImpl();
+ if (GraphicsImpl != nullptr)
+ {
+ if (stateCount > 0)
+ GraphicsImpl->TransitonResourceStates(stateCount, states);
+ return GraphicsImpl->ExecuteCommandList(commandList);
+ }
+ return 0;
+}
+
+UINT64 UNITY_INTERFACE_API UnityGraphicsD3D12_GetNextFrameFenceValue()
+{
+ auto *GraphicsImpl = UnityGraphicsD3D12Emulator::GetGraphicsImpl();
+ return GraphicsImpl != nullptr ? GraphicsImpl->GetNextFenceValue() : 0;
+}
+
+static ID3D12Fence* UNITY_INTERFACE_API UnityGraphicsD3D12_GetFrameFence()
+{
+ auto *GraphicsImpl = UnityGraphicsD3D12Emulator::GetGraphicsImpl();
+ return GraphicsImpl != nullptr ? GraphicsImpl->GetFrameFence() : nullptr;
+}
+
+UnityGraphicsD3D12Impl* UnityGraphicsD3D12Emulator::GetGraphicsImpl()
+{
+ return m_GraphicsImpl.get();
+}
+
+IUnityInterface* UnityGraphicsD3D12Emulator::GetUnityGraphicsAPIInterface()
+{
+ static IUnityGraphicsD3D12v2 UnityGraphicsD3D12;
+ UnityGraphicsD3D12.GetDevice = UnityGraphicsD3D12_GetDevice;
+ UnityGraphicsD3D12.ExecuteCommandList = UnityGraphicsD3D12_ExecuteCommandList;
+ UnityGraphicsD3D12.GetFrameFence = UnityGraphicsD3D12_GetFrameFence;
+ UnityGraphicsD3D12.GetNextFrameFenceValue = UnityGraphicsD3D12_GetNextFrameFenceValue;
+ return &UnityGraphicsD3D12;
+}
+
+UnityGfxRenderer UnityGraphicsD3D12Emulator::GetUnityGfxRenderer()
+{
+ return kUnityGfxRendererD3D12;
+}
+
+void UnityGraphicsD3D12Emulator::BeginFrame()
+{
+ auto Device = m_GraphicsImpl->GetD3D12Device();
+ auto CmdListAllocator = m_GraphicsImpl->GetCommandAllocator();
+ ID3D12GraphicsCommandList* CmdList;
+ auto hr = Device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, CmdListAllocator, nullptr, __uuidof(CmdList), reinterpret_cast<void**>(&CmdList) );
+ VERIFY(SUCCEEDED(hr), "Failed to create command list");
+
+ D3D12_CPU_DESCRIPTOR_HANDLE RTV = m_GraphicsImpl->GetRTV();
+ D3D12_CPU_DESCRIPTOR_HANDLE DSV = m_GraphicsImpl->GetDSV();
+ CmdList->OMSetRenderTargets(1, &RTV, FALSE, &DSV);
+ D3D12_VIEWPORT Viewport;
+ Viewport.TopLeftX = 0;
+ Viewport.TopLeftY = 0;
+ Viewport.Width = static_cast<float>( m_GraphicsImpl->GetBackBufferWidth() );
+ Viewport.Height = static_cast<float>( m_GraphicsImpl->GetBackBufferHeight() );
+ Viewport.MinDepth = 0;
+ Viewport.MaxDepth = 1;
+ CmdList->RSSetViewports(1, &Viewport);
+ float ClearColor[] = { 0, 0, 0.5f, 1 };
+ D3D12_RESOURCE_BARRIER RTVBarrier = {};
+ RTVBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ RTVBarrier.Transition.pResource = m_GraphicsImpl->GetCurrentBackBuffer();
+ RTVBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
+ RTVBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
+ RTVBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ CmdList->ResourceBarrier(1, &RTVBarrier);
+ CmdList->ClearRenderTargetView(RTV, ClearColor, 0, nullptr);
+ CmdList->ClearDepthStencilView(DSV, D3D12_CLEAR_FLAG_DEPTH, UsesReverseZ() ? 0.f : 1.f, 0, 0, nullptr);
+
+ CmdList->Close();
+ m_GraphicsImpl->ExecuteCommandList(CmdList);
+ CmdList->Release();
+}
+
+void UnityGraphicsD3D12Emulator::EndFrame()
+{
+ auto CmdListAllocator = m_GraphicsImpl->GetCommandAllocator();
+ ID3D12GraphicsCommandList* CmdList = nullptr;
+ auto Device = m_GraphicsImpl->GetD3D12Device();
+ auto hr = Device->CreateCommandList(1, D3D12_COMMAND_LIST_TYPE_DIRECT, CmdListAllocator, nullptr, __uuidof(CmdList), reinterpret_cast<void**>(&CmdList) );
+ VERIFY(SUCCEEDED(hr), "Failed to create command list");
+
+ D3D12_RESOURCE_BARRIER RTVBarrier = {};
+ RTVBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
+ RTVBarrier.Transition.pResource = m_GraphicsImpl->GetCurrentBackBuffer();
+ RTVBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
+ RTVBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
+ RTVBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
+ CmdList->ResourceBarrier(1, &RTVBarrier);
+ CmdList->Close();
+ m_GraphicsImpl->ExecuteCommandList(CmdList);
+ CmdList->Release();
+
+ m_GraphicsImpl->DiscardCommandAllocator();
+}
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h
new file mode 100644
index 0000000..df496c7
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsD3D12Impl.h
@@ -0,0 +1,84 @@
+#pragma once
+
+#include <stdexcept>
+#include <deque>
+
+#define NOMINMAX
+#include <D3D12.h>
+#include <dxgi1_4.h>
+#include <atlbase.h>
+
+#include "IUnityGraphicsD3D12.h"
+#include "ResourceStateTransitionHandler.h"
+
+class UnityGraphicsD3D12Impl
+{
+public:
+
+ UnityGraphicsD3D12Impl();
+ ~UnityGraphicsD3D12Impl();
+
+ void CreateDeviceAndCommandQueue();
+
+ void CreateSwapChain(void* pNativeWndHandle, unsigned int Width, unsigned int Height);
+
+ void InitBuffersAndViews();
+
+ void Present();
+ void ResizeSwapChain( UINT NewWidth, UINT NewHeight );
+
+ CComPtr<ID3D12CommandAllocator> GetCommandAllocator();
+
+ void DiscardCommandAllocator();
+
+ bool IsFenceCompleted(UINT64 FenceValue);
+
+ void IdleGPU();
+
+ IDXGISwapChain3* GetDXGISwapChain() { return m_SwapChain; }
+ ID3D12Resource* GetDepthBuffer() { return m_DepthStencilBuffer; }
+ ID3D12Device* GetD3D12Device() { return m_D3D12Device; }
+ ID3D12CommandQueue* GetCommandQueue() { return m_D3D12CmdQueue; }
+ ID3D12Fence* GetFrameFence() { return m_D3D12FrameFence; }
+ ID3D12Resource *GetCurrentBackBuffer() { return m_RenderTargets[m_FrameIndex]; }
+ UINT GetCurrentBackBufferIndex() { return m_FrameIndex; }
+
+ UINT GetBackBufferWidth()const { return m_BackBufferWidth; }
+ UINT GetBackBufferHeight()const { return m_BackBufferHeight; }
+ D3D12_CPU_DESCRIPTOR_HANDLE GetDSV() { return m_DSVDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); }
+ D3D12_CPU_DESCRIPTOR_HANDLE GetRTV()
+ {
+ auto RTVHandle = m_RTVDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
+ RTVHandle.ptr += m_rtvDescriptorSize * m_FrameIndex;
+ return RTVHandle;
+ }
+ UINT64 GetNextFenceValue() { return m_NextFenceValue; }
+ UINT64 GetCompletedFenceValue() { return m_D3D12FrameFence->GetCompletedValue(); }
+ UINT64 ExecuteCommandList(ID3D12CommandList *pCmdList);
+ void SetTransitionHandler(IResourceStateTransitionHandler *pTransitionHandler) { m_pStateTransitionHandler = pTransitionHandler; }
+ void TransitonResourceStates(int stateCount, UnityGraphicsD3D12ResourceState* states);
+ IDXGISwapChain3* GetSwapChain(){ return m_SwapChain; }
+
+private:
+
+ UINT m_BackBufferWidth, m_BackBufferHeight;
+ static const UINT m_BackBuffersCount = 3;
+
+ UINT m_FrameIndex = 0;
+ CComPtr<ID3D12Device> m_D3D12Device;
+ CComPtr<ID3D12CommandQueue> m_D3D12CmdQueue;
+ CComPtr<IDXGISwapChain3> m_SwapChain;
+ CComPtr<ID3D12Fence> m_D3D12FrameFence;
+ UINT64 m_NextFenceValue = 1;
+ UINT64 m_CompletedFenceValue = 0;
+ UINT m_rtvDescriptorSize;
+ CComPtr<ID3D12DescriptorHeap> m_RTVDescriptorHeap;
+ CComPtr<ID3D12DescriptorHeap> m_DSVDescriptorHeap;
+ CComPtr<ID3D12Resource> m_RenderTargets[m_BackBuffersCount];
+ CComPtr<ID3D12Resource> m_DepthStencilBuffer;
+ CComPtr<ID3D12CommandAllocator> m_CmdAllocator;
+ HANDLE m_WaitForGPUEventHandle = {};
+
+ std::deque< std::pair<UINT64, CComPtr<ID3D12CommandAllocator> > > m_DiscardedAllocators;
+ IResourceStateTransitionHandler *m_pStateTransitionHandler = nullptr;
+};
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsEmulator.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsEmulator.cpp
new file mode 100644
index 0000000..cb21cfb
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsEmulator.cpp
@@ -0,0 +1,90 @@
+#include "UnityGraphicsEmulator.h"
+#include "DebugUtilities.h"
+#include "IUnityGraphics.h"
+
+UnityGraphicsEmulator *UnityGraphicsEmulator::m_Instance = nullptr;
+
+UnityGfxRenderer UNITY_INTERFACE_API GetUnityRenderer()
+{
+ return UnityGraphicsEmulator::GetInstance().GetUnityGfxRenderer();
+}
+
+void UNITY_INTERFACE_API RegisterUnityDeviceEventCallback(IUnityGraphicsDeviceEventCallback callback)
+{
+ UnityGraphicsEmulator::GetInstance().RegisterDeviceEventCallback(callback);
+}
+
+void UNITY_INTERFACE_API UnregisterUnityDeviceEventCallback(IUnityGraphicsDeviceEventCallback callback)
+{
+ UnityGraphicsEmulator::GetInstance().UnregisterDeviceEventCallback(callback);
+}
+
+void UnityGraphicsEmulator::RegisterDeviceEventCallback(IUnityGraphicsDeviceEventCallback callback)
+{
+ m_DeviceEventCallbacks.emplace_back(callback);
+}
+
+void UnityGraphicsEmulator::UnregisterDeviceEventCallback(IUnityGraphicsDeviceEventCallback callback)
+{
+ size_t i = 0;
+ while (i < m_DeviceEventCallbacks.size())
+ {
+ if (m_DeviceEventCallbacks[i] == callback)
+ m_DeviceEventCallbacks.erase(m_DeviceEventCallbacks.begin() + i);
+ else
+ ++i;
+ }
+}
+
+void UnityGraphicsEmulator::InvokeDeviceEventCallback(UnityGfxDeviceEventType eventType)
+{
+ for (auto callback : m_DeviceEventCallbacks)
+ (*callback)(eventType);
+}
+
+//static void Get
+UnityGraphicsEmulator::UnityGraphicsEmulator()
+{
+ VERIFY(m_Instance == nullptr, "Only single instance of UnityGraphicsEmulator must be initialized")
+ m_Instance = this;
+ static IUnityGraphics UnityGraphics;
+ UnityGraphics.GetRenderer = GetUnityRenderer;
+ UnityGraphics.RegisterDeviceEventCallback = RegisterUnityDeviceEventCallback;
+ UnityGraphics.UnregisterDeviceEventCallback = UnregisterUnityDeviceEventCallback;
+ RegisterInterface(IUnityGraphics_GUID, &UnityGraphics);
+}
+
+static IUnityInterface* UNITY_INTERFACE_API GetUnityInterface(UnityInterfaceGUID guid)
+{
+ return UnityGraphicsEmulator::GetInstance().GetInterface(guid);
+}
+
+static void UNITY_INTERFACE_API RegisterUnityInterface(UnityInterfaceGUID guid, IUnityInterface* ptr)
+{
+ return UnityGraphicsEmulator::GetInstance().RegisterInterface(guid, ptr);
+}
+
+void UnityGraphicsEmulator::RegisterInterface(const UnityInterfaceGUID &guid, IUnityInterface* ptr)
+{
+ m_Interfaces.emplace_back(guid, ptr);
+}
+
+IUnityInterface* UnityGraphicsEmulator::GetInterface(const UnityInterfaceGUID &guid)
+{
+ for (auto &ifaces : m_Interfaces)
+ {
+ if (ifaces.first == guid)
+ return ifaces.second;
+ }
+ return nullptr;
+}
+
+
+IUnityInterfaces &UnityGraphicsEmulator::GeUnityInterfaces()
+{
+ static IUnityInterfaces UnityInterfaces;
+ UnityInterfaces.GetInterface = GetUnityInterface;
+ UnityInterfaces.RegisterInterface = RegisterUnityInterface;
+
+ return UnityInterfaces;
+}
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp
new file mode 100644
index 0000000..5047b32
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp
@@ -0,0 +1,87 @@
+#include "UnityGraphicsGL_Impl.h"
+
+#include "UnityGraphicsGLCoreES_Emulator.h"
+
+#if OPENGL_SUPPORTED
+
+#include "DebugUtilities.h"
+#include "Errors.h"
+
+std::unique_ptr<UnityGraphicsGL_Impl> UnityGraphicsGLCoreES_Emulator::m_GraphicsImpl;
+
+UnityGraphicsGLCoreES_Emulator::UnityGraphicsGLCoreES_Emulator()
+{
+ VERIFY(!m_GraphicsImpl, "Another emulator has already been initialized");
+ m_GraphicsImpl.reset( new UnityGraphicsGL_Impl );
+ //GeUnityInterfaces().RegisterInterface(IUnityGraphicsGLCoreES__GUID, GetUnityGraphicsAPIInterface());
+}
+
+void UnityGraphicsGLCoreES_Emulator::InitGLContext(void *pNativeWndHandle, int MajorVersion, int MinorVersion)
+{
+ m_GraphicsImpl->InitGLContext(pNativeWndHandle, MajorVersion, MinorVersion);
+}
+
+UnityGraphicsGLCoreES_Emulator& UnityGraphicsGLCoreES_Emulator::GetInstance()
+{
+ static UnityGraphicsGLCoreES_Emulator TheInstance;
+ return TheInstance;
+}
+
+void UnityGraphicsGLCoreES_Emulator::Present()
+{
+ m_GraphicsImpl->SwapBuffers();
+}
+
+void UnityGraphicsGLCoreES_Emulator::Release()
+{
+ m_GraphicsImpl.reset();
+}
+
+void UnityGraphicsGLCoreES_Emulator::ResizeSwapChain(unsigned int Width, unsigned int Height)
+{
+ m_GraphicsImpl->ResizeSwapchain(Width, Height);
+}
+
+bool UnityGraphicsGLCoreES_Emulator::SwapChainInitialized()
+{
+ return m_GraphicsImpl->GetContext() != NULL;
+}
+
+
+UnityGraphicsGL_Impl* UnityGraphicsGLCoreES_Emulator::GetGraphicsImpl()
+{
+ return m_GraphicsImpl.get();
+}
+
+IUnityInterface* UnityGraphicsGLCoreES_Emulator::GetUnityGraphicsAPIInterface()
+{
+ return nullptr;
+}
+
+UnityGfxRenderer UnityGraphicsGLCoreES_Emulator::GetUnityGfxRenderer()
+{
+ return kUnityGfxRendererOpenGLCore;
+}
+
+void UnityGraphicsGLCoreES_Emulator::BeginFrame()
+{
+ glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 );
+ glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 );
+ glClearDepthf( UsesReverseZ() ? 0.f : 1.f );
+ static const float ClearColor[4] = { 0, 0, 0.5f, 1 };
+ glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]);
+ glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDisable( GL_SCISSOR_TEST );
+ glViewport(0, 0, m_GraphicsImpl->GetBackBufferWidth(), m_GraphicsImpl->GetBackBufferHeight() );
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ glDepthRangef( 0, 1 );
+ auto err = glGetError();
+ if( err != GL_NO_ERROR)
+ LOG_ERROR_MESSAGE("GL Error: ", err)
+}
+
+void UnityGraphicsGLCoreES_Emulator::EndFrame()
+{
+}
+
+#endif // OPENGL_SUPPORTED \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.cpp
new file mode 100644
index 0000000..7a3d8c2
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.cpp
@@ -0,0 +1,189 @@
+
+#include "UnityGraphicsGLCore_Impl.h"
+
+#if OPENGL_SUPPORTED
+
+#include "DebugUtilities.h"
+#include "Errors.h"
+
+void APIENTRY openglCallbackFunction( GLenum source,
+ GLenum type,
+ GLuint id,
+ GLenum severity,
+ GLsizei length,
+ const GLchar* message,
+ const void* userParam )
+{
+ std::stringstream MessageSS;
+
+ MessageSS << std::endl << "OPENGL DEBUG MESSAGE: " << message << std::endl;
+ MessageSS << "Type: ";
+ switch( type ) {
+ case GL_DEBUG_TYPE_ERROR:
+ MessageSS << "ERROR";
+ break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ MessageSS << "DEPRECATED_BEHAVIOR";
+ break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ MessageSS << "UNDEFINED_BEHAVIOR";
+ break;
+ case GL_DEBUG_TYPE_PORTABILITY:
+ MessageSS << "PORTABILITY";
+ break;
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ MessageSS << "PERFORMANCE";
+ break;
+ case GL_DEBUG_TYPE_OTHER:
+ MessageSS << "OTHER";
+ break;
+ }
+ MessageSS << std::endl;
+
+ MessageSS << "Severity: ";
+ switch( severity ){
+ case GL_DEBUG_SEVERITY_LOW:
+ MessageSS << "LOW";
+ break;
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ MessageSS << "MEDIUM";
+ break;
+ case GL_DEBUG_SEVERITY_HIGH:
+ MessageSS << "HIGH";
+ break;
+ }
+ MessageSS << std::endl;
+
+ //MessageSS << "Id: "<< id << std::endl;
+
+ OutputDebugStringA( MessageSS.str().c_str() );
+}
+
+
+UnityGraphicsGLCore_Impl::~UnityGraphicsGLCore_Impl()
+{
+ if( m_Context )
+ {
+ wglMakeCurrent( m_WindowHandleToDeviceContext, 0 );
+ wglDeleteContext( m_Context );
+ }
+}
+
+void UnityGraphicsGLCore_Impl::InitGLContext(void *pNativeWndHandle, int MajorVersion, int MinorVersion )
+{
+ HWND hWnd = reinterpret_cast<HWND>(pNativeWndHandle);
+ RECT rc;
+ GetClientRect( hWnd, &rc );
+ m_BackBufferWidth = rc.right - rc.left;
+ m_BackBufferHeight = rc.bottom - rc.top;
+
+ // See http://www.opengl.org/wiki/Tutorial:_OpenGL_3.1_The_First_Triangle_(C%2B%2B/Win)
+ // http://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)
+ PIXELFORMATDESCRIPTOR pfd;
+ memset( &pfd, 0, sizeof( PIXELFORMATDESCRIPTOR ) );
+ pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
+ pfd.nVersion = 1;
+ pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = 32;
+ pfd.cDepthBits = 32;
+ pfd.iLayerType = PFD_MAIN_PLANE;
+
+ m_WindowHandleToDeviceContext = GetDC( hWnd );
+ int nPixelFormat = ChoosePixelFormat( m_WindowHandleToDeviceContext, &pfd );
+
+ if( nPixelFormat == 0 )
+ LOG_ERROR_AND_THROW( "Invalid Pixel Format" );
+
+ BOOL bResult = SetPixelFormat( m_WindowHandleToDeviceContext, nPixelFormat, &pfd );
+ if( !bResult )
+ LOG_ERROR_AND_THROW( "Failed to set Pixel Format" );
+
+ // Create standard OpenGL (2.1) rendering context which will be used only temporarily,
+ HGLRC tempContext = wglCreateContext( m_WindowHandleToDeviceContext );
+ // and make it current
+ wglMakeCurrent( m_WindowHandleToDeviceContext, tempContext );
+
+ // Initialize GLEW
+ GLenum err = glewInit();
+ if( GLEW_OK != err )
+ LOG_ERROR_AND_THROW( "Failed to initialize GLEW" );
+
+ if( wglewIsSupported( "WGL_ARB_create_context" ) == 1 )
+ {
+ // Setup attributes for a new OpenGL rendering context
+ int attribs[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion,
+ WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion,
+ WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ GL_CONTEXT_PROFILE_MASK, GL_CONTEXT_CORE_PROFILE_BIT,
+ 0, 0
+ };
+
+#ifdef _DEBUG
+ attribs[5] |= WGL_CONTEXT_DEBUG_BIT_ARB;
+#endif
+
+ // Create new rendering context
+ // In order to create new OpenGL rendering context we have to call function wglCreateContextAttribsARB(),
+ // which is an OpenGL function and requires OpenGL to be active when it is called.
+ // The only way is to create an old context, activate it, and while it is active create a new one.
+ // Very inconsistent, but we have to live with it!
+ m_Context = wglCreateContextAttribsARB( m_WindowHandleToDeviceContext, 0, attribs );
+
+ // Delete tempContext
+ wglMakeCurrent( NULL, NULL );
+ wglDeleteContext( tempContext );
+ //
+ wglMakeCurrent( m_WindowHandleToDeviceContext, m_Context );
+ wglSwapIntervalEXT( 0 );
+ }
+ else
+ { //It's not possible to make a GL 3.x context. Use the old style context (GL 2.1 and before)
+ m_Context = tempContext;
+ }
+
+ //Checking GL version
+ const GLubyte *GLVersionString = glGetString( GL_VERSION );
+
+ //Or better yet, use the GL3 way to get the version number
+ glGetIntegerv( GL_MAJOR_VERSION, &MajorVersion );
+ glGetIntegerv( GL_MINOR_VERSION, &MinorVersion );
+ LOG_INFO_MESSAGE("Initialized OpenGL ", MajorVersion, '.', MinorVersion, " context")
+
+ if( glDebugMessageCallback )
+ {
+ glEnable( GL_DEBUG_OUTPUT_SYNCHRONOUS );
+ glDebugMessageCallback( openglCallbackFunction, nullptr );
+ GLuint unusedIds = 0;
+ glDebugMessageControl( GL_DONT_CARE,
+ GL_DONT_CARE,
+ GL_DONT_CARE,
+ 0,
+ &unusedIds,
+ true );
+ }
+
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ if( glGetError() != GL_NO_ERROR )
+ LOG_ERROR_MESSAGE("Failed to enable seamless cubemap filtering");
+
+ glEnable(GL_FRAMEBUFFER_SRGB);
+ if( glGetError() != GL_NO_ERROR )
+ LOG_ERROR_MESSAGE("Failed to enable SRGB framebuffers");
+}
+
+void UnityGraphicsGLCore_Impl::ResizeSwapchain(int NewWidth, int NewHeight)
+{
+ m_BackBufferWidth = NewWidth;
+ m_BackBufferHeight = NewHeight;
+ // Nothing more needs to be done in GL
+}
+
+void UnityGraphicsGLCore_Impl::SwapBuffers()
+{
+ ::SwapBuffers( m_WindowHandleToDeviceContext );
+}
+
+#endif // OPENGL_SUPPORTED \ No newline at end of file
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h
new file mode 100644
index 0000000..d1bd531
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "PlatformDefinitions.h"
+
+#if OPENGL_SUPPORTED
+
+#define GLEW_STATIC
+#include "glew.h"
+#define NOMINMAX
+#include "wglew.h"
+#include <GL/GL.h>
+
+class UnityGraphicsGLCore_Impl
+{
+public:
+ ~UnityGraphicsGLCore_Impl();
+
+ void InitGLContext(void *pNativeWndHandle, int MajorVersion, int MinorVersion);
+
+ void ResizeSwapchain(int NewWidth, int NewHeight);
+
+ void SwapBuffers();
+
+ int GetBackBufferWidth()const { return m_BackBufferWidth; }
+ int GetBackBufferHeight()const { return m_BackBufferHeight; }
+ GLenum GetBackBufferFormat()const { return GL_RGBA8; }
+ GLenum GetDepthBufferFormat()const { return GL_DEPTH_COMPONENT32F; }
+ HGLRC GetContext() { return m_Context; }
+
+private:
+ int m_BackBufferWidth = 0;
+ int m_BackBufferHeight = 0;
+ HDC m_WindowHandleToDeviceContext;
+ HGLRC m_Context;
+};
+
+#endif //OPENGL_SUPPORTED
diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h
new file mode 100644
index 0000000..b9f5105
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "PlatformDefinitions.h"
+
+#if defined(PLATFORM_ANDROID)
+# include "Android\UnityGraphicsGLESAndroid_Impl.h"
+#elif defined( PLATFORM_WIN32 ) || defined( PLATFORM_UNIVERSAL_WINDOWS )
+# include "UnityGraphicsGLCore_Impl.h"
+#else
+# error Unknown Platform
+#endif
diff --git a/unityplugin/UnityEmulator/src/Windows/WinMain.cpp b/unityplugin/UnityEmulator/src/Windows/WinMain.cpp
new file mode 100644
index 0000000..9d3ea78
--- /dev/null
+++ b/unityplugin/UnityEmulator/src/Windows/WinMain.cpp
@@ -0,0 +1,344 @@
+/* Copyright 2015-2017 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#include <memory>
+#include <iomanip>
+
+#define NOMINMAX
+#include <Windows.h>
+
+#include "DeviceCaps.h"
+#include "Errors.h"
+#include "Timer.h"
+
+#include "IUnityInterface.h"
+#include "UnityGraphicsD3D11Emulator.h"
+#include "UnityGraphicsD3D12Emulator.h"
+#include "UnityGraphicsGLCoreES_Emulator.h"
+#include "DiligentGraphicsAdapterD3D11.h"
+#include "DiligentGraphicsAdapterD3D12.h"
+#include "DiligentGraphicsAdapterGL.h"
+#include "UnitySceneBase.h"
+#include "StringTools.h"
+
+using namespace Diligent;
+
+LRESULT CALLBACK MessageProc(HWND, UINT, WPARAM, LPARAM);
+
+UnityGraphicsEmulator *g_GraphicsEmulator = nullptr;
+
+typedef void (UNITY_INTERFACE_API *TUnityPluginLoad)(IUnityInterfaces* unityInterfaces);
+typedef void (UNITY_INTERFACE_API *TUnityPluginUnload)();
+typedef UnityRenderingEvent(UNITY_INTERFACE_API *TGetRenderEventFunc)();
+
+TUnityPluginLoad UnityPluginLoad;
+TUnityPluginUnload UnityPluginUnload;
+TGetRenderEventFunc GetRenderEventFunc;
+
+std::unique_ptr<DiligentGraphicsAdapter> g_pDiligentGraphics;
+std::unique_ptr<UnitySceneBase> g_pScene;
+
+HMODULE g_DLLHandle;
+
+static UINT g_WindowWidth = 1024;
+static UINT g_WindowHeight = 768;
+
+static void* LoadPluginFunction(const char* FunctionName)
+{
+ auto Func = GetProcAddress(g_DLLHandle, FunctionName);
+ VERIFY( Func != nullptr, "Failed to import plugin function \"", FunctionName, "\"." );
+ return Func;
+}
+
+bool LoadPlugin()
+{
+ std::string LibName = g_pScene->GetPluginName();
+#if _WIN64
+ LibName += "_64";
+#else
+ LibName += "_32";
+#endif
+
+#ifdef _DEBUG
+ LibName += "d";
+#else
+ LibName += "r";
+#endif
+
+ LibName += ".dll";
+ g_DLLHandle = LoadLibraryA( LibName.c_str() );
+ if( g_DLLHandle == NULL )
+ {
+ LOG_ERROR_MESSAGE( "Failed to load ", LibName, " library." );
+ return false;
+ }
+
+ UnityPluginLoad = reinterpret_cast<TUnityPluginLoad>( GetProcAddress(g_DLLHandle, "UnityPluginLoad") );
+ UnityPluginUnload = reinterpret_cast<TUnityPluginUnload>( GetProcAddress(g_DLLHandle, "UnityPluginUnload") );
+ GetRenderEventFunc = reinterpret_cast<TGetRenderEventFunc>( GetProcAddress(g_DLLHandle, "GetRenderEventFunc") );
+ if( UnityPluginLoad == nullptr || UnityPluginUnload == nullptr || GetRenderEventFunc == nullptr )
+ {
+ LOG_ERROR_MESSAGE( "Failed to import plugin functions from ", LibName, " library." );
+ FreeLibrary( g_DLLHandle );
+ return false;
+ }
+
+ return true;
+}
+
+
+void UnloadPlugin()
+{
+ g_GraphicsEmulator->InvokeDeviceEventCallback(kUnityGfxDeviceEventShutdown);
+ UnityPluginUnload();
+ FreeLibrary(g_DLLHandle);
+}
+
+// Main
+int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int cmdShow)
+{
+#if defined(_DEBUG) || defined(DEBUG)
+ _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#endif
+
+ g_pScene.reset(CreateScene());
+
+ std::wstring Title = WidenString(g_pScene->GetSceneName());
+
+ DeviceType DevType = DeviceType::Undefined;
+ std::wstring CmdLine = GetCommandLine();
+ std::wstring Key = L"mode=";
+ auto pos = CmdLine.find( Key );
+ if( pos != std::string::npos )
+ {
+ pos += Key.length();
+ auto Val = CmdLine.substr( pos );
+ if(Val == L"D3D11")
+ {
+ DevType = DeviceType::D3D11;
+ Title.append( L" (D3D11)" );
+ }
+ else if(Val == L"D3D12")
+ {
+ DevType = DeviceType::D3D12;
+ Title.append( L" (D3D12)" );
+ }
+ else if(Val == L"GL")
+ {
+ DevType = DeviceType::OpenGL;
+ Title.append( L" (OpenGL)" );
+ }
+ else
+ {
+ LOG_ERROR("Unknown device type. Only the following types are supported: D3D11, D3D12, GL")
+ return -1;
+ }
+ }
+ else
+ {
+ LOG_INFO_MESSAGE("Device type is not specified. Using D3D11 device");
+ DevType = DeviceType::D3D11;
+ Title.append( L" (D3D11)" );
+ }
+ // Register our window class
+ WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, MessageProc,
+ 0L, 0L, instance, NULL, NULL, NULL, NULL, L"SampleApp", NULL };
+ RegisterClassEx(&wcex);
+
+ // Create a window
+ UINT ClientAreaWidth = 1280;
+ UINT ClientAreaHeight = 1024;
+ RECT rc = { 0, 0, static_cast<LONG>(ClientAreaWidth), static_cast<LONG>(ClientAreaHeight) };
+ AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
+ HWND wnd = CreateWindow(L"SampleApp", Title.c_str(),
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+ rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, instance, NULL);
+ if (!wnd)
+ {
+ MessageBox(NULL, L"Cannot create window", L"Error", MB_OK|MB_ICONERROR);
+ return -1;
+ }
+ ShowWindow(wnd, cmdShow);
+ UpdateWindow(wnd);
+
+ bool IsDX = false;
+ try
+ {
+ switch (DevType)
+ {
+ case DeviceType::D3D11:
+ {
+ auto &GraphicsD3D11Emulator = UnityGraphicsD3D11Emulator::GetInstance();
+ GraphicsD3D11Emulator.CreateD3D11DeviceAndContext();
+ GraphicsD3D11Emulator.CreateSwapChain(wnd, ClientAreaWidth, ClientAreaHeight);
+ g_GraphicsEmulator = &GraphicsD3D11Emulator;
+ IsDX = true;
+ auto *pDiligentAdapterD3D11 = new DiligentGraphicsAdapterD3D11(GraphicsD3D11Emulator);
+ g_pDiligentGraphics.reset(pDiligentAdapterD3D11);
+ pDiligentAdapterD3D11->InitProxySwapChain();
+ }
+ break;
+
+ case DeviceType::D3D12:
+ {
+ auto &GraphicsD3D12Emulator = UnityGraphicsD3D12Emulator::GetInstance();
+ GraphicsD3D12Emulator.CreateD3D12DeviceAndCommandQueue();
+ GraphicsD3D12Emulator.CreateSwapChain(wnd, ClientAreaWidth, ClientAreaHeight);
+ g_GraphicsEmulator = &GraphicsD3D12Emulator;
+ IsDX = true;
+ auto *pDiligentAdapterD3D12 = new DiligentGraphicsAdapterD3D12(GraphicsD3D12Emulator);
+ g_pDiligentGraphics.reset(pDiligentAdapterD3D12);
+ pDiligentAdapterD3D12->InitProxySwapChain();
+ }
+ break;
+
+ case DeviceType::OpenGL:
+ {
+ auto &GraphicsGLCoreES_Emulator = UnityGraphicsGLCoreES_Emulator::GetInstance();
+ GraphicsGLCoreES_Emulator.InitGLContext(wnd, 4, 4);
+ g_GraphicsEmulator = &GraphicsGLCoreES_Emulator;
+ g_pDiligentGraphics.reset(new DiligentGraphicsAdapterGL(GraphicsGLCoreES_Emulator));
+ }
+ break;
+
+ default:
+ LOG_ERROR("Unsupported device type");
+ return -1;
+ }
+ }
+ catch (std::runtime_error &err)
+ {
+ LOG_ERROR("Failed to initialize unity graphics emulator: ", err.what());
+ return -1;
+ }
+
+ g_pScene->SetDiligentGraphicsAdapter(g_pDiligentGraphics.get());
+ g_pScene->OnGraphicsInitialized();
+ if (DevType == DeviceType::D3D12)
+ {
+ UnityGraphicsD3D12Emulator::GetInstance().SetTransitionHandler(g_pScene->GetStateTransitionHandler());
+ }
+
+ if (!LoadPlugin())
+ {
+ return -1;
+ }
+
+ g_pScene->OnPluginLoad(LoadPluginFunction);
+ UnityPluginLoad(&g_GraphicsEmulator->GeUnityInterfaces());
+
+ auto RenderEventFunc = GetRenderEventFunc();
+
+ Timer timer;
+ auto PrevTime = timer.GetElapsedTime();
+ double filteredFrameTime = 0.0;
+
+ // Main message loop
+ MSG msg = {0};
+ while (WM_QUIT != msg.message)
+ {
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ else
+ {
+ g_GraphicsEmulator->BeginFrame();
+ g_pDiligentGraphics->BeginFrame();
+
+ auto CurrTime = timer.GetElapsedTime();
+ auto ElapsedTime = CurrTime - PrevTime;
+ PrevTime = CurrTime;
+ float fTime = static_cast<float>(CurrTime);
+
+ g_pScene->Render(RenderEventFunc, CurrTime, ElapsedTime);
+
+ g_pDiligentGraphics->EndFrame();
+ g_GraphicsEmulator->EndFrame();
+
+ g_GraphicsEmulator->Present();
+
+ double filterScale = 0.2;
+ filteredFrameTime = filteredFrameTime * (1.0 - filterScale) + filterScale * ElapsedTime;
+ std::wstringstream fpsCounterSS;
+ fpsCounterSS << " - " << std::fixed << std::setprecision(1) << filteredFrameTime * 1000;
+ fpsCounterSS << " ms (" << 1.0 / filteredFrameTime << " fps)";
+ SetWindowText(wnd, (Title + fpsCounterSS.str()).c_str());
+ }
+ }
+
+ g_pScene->OnPluginUnload();
+ g_pScene.reset();
+ UnloadPlugin();
+
+ g_pDiligentGraphics.reset();
+ g_GraphicsEmulator->Release();
+
+ return (int)msg.wParam;
+}
+
+// Called every time the application receives a message
+LRESULT CALLBACK MessageProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // Send event message to AntTweakBar
+ switch (message)
+ {
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ BeginPaint(wnd, &ps);
+ EndPaint(wnd, &ps);
+ return 0;
+ }
+ case WM_SIZE: // Window size has been changed
+ if(g_GraphicsEmulator)
+ {
+ g_WindowWidth = LOWORD(lParam);
+ g_WindowHeight = HIWORD(lParam);
+ g_pDiligentGraphics->PreSwapChainResize();
+ g_GraphicsEmulator->ResizeSwapChain(g_WindowWidth, g_WindowHeight);
+ g_pDiligentGraphics->PostSwapChainResize();
+ g_pScene->OnWindowResize(g_WindowWidth, g_WindowHeight);
+ }
+ return 0;
+ case WM_CHAR:
+ if (wParam == VK_ESCAPE)
+ PostQuitMessage(0);
+ return 0;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ default:
+ {
+ struct WindowMessageData
+ {
+ HWND hWnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ }msg{wnd, message, wParam, lParam};
+ return DefWindowProc(wnd, message, wParam, lParam);
+ }
+ }
+}