Przeglądaj źródła

Merge branch 'master' into preview

BearishSun 10 lat temu
rodzic
commit
4ce5c9b932
100 zmienionych plików z 15202 dodań i 12320 usunięć
  1. 14 10
      .gitignore
  2. 576 522
      BansheeCore/BansheeCore.vcxproj
  3. 916 821
      BansheeCore/BansheeCore.vcxproj.filters
  4. 253 170
      BansheeCore/Include/BsBlendState.h
  5. 94 93
      BansheeCore/Include/BsBlendStateRTTI.h
  6. 0 31
      BansheeCore/Include/BsCameraProxy.h
  7. 382 399
      BansheeCore/Include/BsCommandQueue.h
  8. 414 342
      BansheeCore/Include/BsCommonTypes.h
  9. 111 65
      BansheeCore/Include/BsComponent.h
  10. 60 34
      BansheeCore/Include/BsComponentRTTI.h
  11. 138 113
      BansheeCore/Include/BsCoreApplication.h
  12. 296 266
      BansheeCore/Include/BsCoreObject.h
  13. 92 0
      BansheeCore/Include/BsCoreObjectCore.h
  14. 144 39
      BansheeCore/Include/BsCoreObjectManager.h
  15. 472 372
      BansheeCore/Include/BsCorePrerequisites.h
  16. 142 0
      BansheeCore/Include/BsCoreRenderer.h
  17. 93 63
      BansheeCore/Include/BsCoreSceneManager.h
  18. 220 206
      BansheeCore/Include/BsCoreThread.h
  19. 74 199
      BansheeCore/Include/BsCoreThreadAccessor.h
  20. 42 36
      BansheeCore/Include/BsDeferredCallManager.h
  21. 244 171
      BansheeCore/Include/BsDepthStencilState.h
  22. 53 51
      BansheeCore/Include/BsDepthStencilStateRTTI.h
  23. 0 51
      BansheeCore/Include/BsDrawList.h
  24. 27 25
      BansheeCore/Include/BsDrawOps.h
  25. 60 57
      BansheeCore/Include/BsEventQuery.h
  26. 8 6
      BansheeCore/Include/BsFolderMonitor.h
  27. 100 97
      BansheeCore/Include/BsFont.h
  28. 167 162
      BansheeCore/Include/BsFontDesc.h
  29. 86 76
      BansheeCore/Include/BsFontImportOptions.h
  30. 66 48
      BansheeCore/Include/BsFontImportOptionsRTTI.h
  31. 31 25
      BansheeCore/Include/BsFontManager.h
  32. 141 158
      BansheeCore/Include/BsFontRTTI.h
  33. 138 79
      BansheeCore/Include/BsGameObject.h
  34. 290 298
      BansheeCore/Include/BsGameObjectHandle.h
  35. 67 46
      BansheeCore/Include/BsGameObjectHandleRTTI.h
  36. 155 101
      BansheeCore/Include/BsGameObjectManager.h
  37. 97 54
      BansheeCore/Include/BsGameObjectRTTI.h
  38. 217 184
      BansheeCore/Include/BsGpuBuffer.h
  39. 88 98
      BansheeCore/Include/BsGpuBufferView.h
  40. 301 290
      BansheeCore/Include/BsGpuParam.h
  41. 0 73
      BansheeCore/Include/BsGpuParamBlock.h
  42. 164 120
      BansheeCore/Include/BsGpuParamBlockBuffer.h
  43. 56 57
      BansheeCore/Include/BsGpuParamDesc.h
  44. 344 309
      BansheeCore/Include/BsGpuParams.h
  45. 0 35
      BansheeCore/Include/BsGpuProgInclude.h
  46. 0 28
      BansheeCore/Include/BsGpuProgIncludeImporter.h
  47. 245 207
      BansheeCore/Include/BsGpuProgram.h
  48. 0 87
      BansheeCore/Include/BsGpuProgramImportOptions.h
  49. 0 56
      BansheeCore/Include/BsGpuProgramImportOptionsRTTI.h
  50. 0 27
      BansheeCore/Include/BsGpuProgramImporter.h
  51. 143 112
      BansheeCore/Include/BsGpuProgramManager.h
  52. 72 53
      BansheeCore/Include/BsGpuProgramRTTI.h
  53. 0 50
      BansheeCore/Include/BsGpuResource.h
  54. 99 99
      BansheeCore/Include/BsGpuResourceData.h
  55. 40 32
      BansheeCore/Include/BsGpuResourceDataRTTI.h
  56. 0 33
      BansheeCore/Include/BsGpuResourceRTTI.h
  57. 76 0
      BansheeCore/Include/BsHString.h
  58. 162 173
      BansheeCore/Include/BsHardwareBuffer.h
  59. 135 107
      BansheeCore/Include/BsHardwareBufferManager.h
  60. 41 0
      BansheeCore/Include/BsIResourceListener.h
  61. 41 0
      BansheeCore/Include/BsIconUtility.h
  62. 32 24
      BansheeCore/Include/BsImportOptions.h
  63. 40 31
      BansheeCore/Include/BsImportOptionsRTTI.h
  64. 110 97
      BansheeCore/Include/BsImporter.h
  65. 93 48
      BansheeCore/Include/BsIndexBuffer.h
  66. 246 207
      BansheeCore/Include/BsInput.h
  67. 411 407
      BansheeCore/Include/BsInputFwd.h
  68. 801 575
      BansheeCore/Include/BsMaterial.h
  69. 38 25
      BansheeCore/Include/BsMaterialManager.h
  70. 303 0
      BansheeCore/Include/BsMaterialParam.h
  71. 396 0
      BansheeCore/Include/BsMaterialParams.h
  72. 275 0
      BansheeCore/Include/BsMaterialParamsRTTI.h
  73. 0 74
      BansheeCore/Include/BsMaterialProxy.h
  74. 49 590
      BansheeCore/Include/BsMaterialRTTI.h
  75. 360 242
      BansheeCore/Include/BsMesh.h
  76. 189 204
      BansheeCore/Include/BsMeshBase.h
  77. 61 51
      BansheeCore/Include/BsMeshBaseRTTI.h
  78. 307 296
      BansheeCore/Include/BsMeshData.h
  79. 84 74
      BansheeCore/Include/BsMeshDataRTTI.h
  80. 231 242
      BansheeCore/Include/BsMeshHeap.h
  81. 89 0
      BansheeCore/Include/BsMeshImportOptions.h
  82. 71 0
      BansheeCore/Include/BsMeshImportOptionsRTTI.h
  83. 60 66
      BansheeCore/Include/BsMeshManager.h
  84. 0 19
      BansheeCore/Include/BsMeshProxy.h
  85. 80 72
      BansheeCore/Include/BsMeshRTTI.h
  86. 85 0
      BansheeCore/Include/BsMeshUtility.h
  87. 106 28
      BansheeCore/Include/BsMultiRenderTexture.h
  88. 162 165
      BansheeCore/Include/BsOSInputHandler.h
  89. 75 75
      BansheeCore/Include/BsOcclusionQuery.h
  90. 112 0
      BansheeCore/Include/BsParamBlocks.h
  91. 208 96
      BansheeCore/Include/BsPass.h
  92. 89 68
      BansheeCore/Include/BsPassRTTI.h
  93. 92 102
      BansheeCore/Include/BsPixelBuffer.h
  94. 380 335
      BansheeCore/Include/BsPixelData.h
  95. 101 91
      BansheeCore/Include/BsPixelDataRTTI.h
  96. 229 268
      BansheeCore/Include/BsPixelUtil.h
  97. 48 43
      BansheeCore/Include/BsPixelVolume.h
  98. 450 189
      BansheeCore/Include/BsPlatform.h
  99. 94 0
      BansheeCore/Include/BsPrefab.h
  100. 158 0
      BansheeCore/Include/BsPrefabDiff.h

+ 14 - 10
.gitignore

@@ -1,10 +1,14 @@
-# Ignored files
-*.suo
-*.user
-*.sdf
-*.opensdf
-bin
-obj
-lib
-Intermediate
-Dependencies
+# Ignored files
+*.suo
+*.user
+*.sdf
+*.opensdf
+bin
+obj
+lib
+data
+Intermediate
+Dependencies
+Builds
+*.aps
+*.opendb

+ 576 - 522
BansheeCore/BansheeCore.vcxproj

@@ -1,523 +1,577 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="DebugRelease|Win32">
-      <Configuration>DebugRelease</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="DebugRelease|x64">
-      <Configuration>DebugRelease</Configuration>
-      <Platform>x64</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|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|x64">
-      <Configuration>Release</Configuration>
-      <Platform>x64</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{9B21D41C-516B-43BF-9B10-E99B599C7589}</ProjectGuid>
-    <Keyword>Win32Proj</Keyword>
-    <RootNamespace>CamelotCore</RootNamespace>
-    <ProjectName>BansheeCore</ProjectName>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'" Label="Configuration">
-    <ConfigurationType>DynamicLibrary</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v120</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>NotSet</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup 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" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </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" />
-  </ImportGroup>
-  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'" Label="PropertySheets">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LinkIncremental>true</LinkIncremental>
-    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
-    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <LinkIncremental>true</LinkIncremental>
-    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
-    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
-    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'">
-    <LinkIncremental>false</LinkIncremental>
-    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
-    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
-    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'">
-    <LinkIncremental>false</LinkIncremental>
-    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
-    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
-    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
-    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
-    </ClCompile>
-    <Link>
-      <SubSystem>NotSet</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/Debug</AdditionalLibraryDirectories>
-      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
-    <ClCompile>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
-    </ClCompile>
-    <Link>
-      <SubSystem>NotSet</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Debug</AdditionalLibraryDirectories>
-      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>NotSet</SubSystem>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/Release</AdditionalLibraryDirectories>
-      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <MinimalRebuild>true</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>NotSet</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/DebugRelease</AdditionalLibraryDirectories>
-      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
-      <DebugInformationFormat>None</DebugInformationFormat>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-    </ClCompile>
-    <Link>
-      <SubSystem>NotSet</SubSystem>
-      <GenerateDebugInformation>false</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Release</AdditionalLibraryDirectories>
-      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <PrecompiledHeader>
-      </PrecompiledHeader>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
-      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
-      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
-      <BufferSecurityCheck>false</BufferSecurityCheck>
-      <MinimalRebuild>true</MinimalRebuild>
-    </ClCompile>
-    <Link>
-      <SubSystem>NotSet</SubSystem>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;IPHLPAPI.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/DebugRelease</AdditionalLibraryDirectories>
-      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClInclude Include="Include\BsCameraProxy.h" />
-    <ClInclude Include="Include\BsDrawList.h" />
-    <ClInclude Include="Include\BsMaterialProxy.h" />
-    <ClInclude Include="Include\BsMeshProxy.h" />
-    <ClInclude Include="Include\BsRenderStats.h" />
-    <ClInclude Include="Include\BsCoreThread.h" />
-    <ClInclude Include="Include\BsProfilerCPU.h" />
-    <ClInclude Include="Include\BsDeferredCallManager.h" />
-    <ClInclude Include="Include\BsDrawOps.h" />
-    <ClInclude Include="Include\BsEventQuery.h" />
-    <ClInclude Include="Include\BsFolderMonitor.h" />
-    <ClInclude Include="Include\BsGameObjectHandle.h" />
-    <ClInclude Include="Include\BsGameObject.h" />
-    <ClInclude Include="Include\BsGameObjectHandleRTTI.h" />
-    <ClInclude Include="Include\BsGameObjectManager.h" />
-    <ClInclude Include="Include\BsGameObjectRTTI.h" />
-    <ClInclude Include="Include\BsProfilerGPU.h" />
-    <ClInclude Include="Include\BsGpuResourceData.h" />
-    <ClInclude Include="Include\BsGpuParamBlockBuffer.h" />
-    <ClInclude Include="Include\BsGpuResource.h" />
-    <ClInclude Include="Include\BsGpuResourceDataRTTI.h" />
-    <ClInclude Include="Include\BsGpuResourceRTTI.h" />
-    <ClInclude Include="Include\BsGpuParam.h" />
-    <ClInclude Include="Include\BsInputFwd.h" />
-    <ClInclude Include="Include\BsMeshBase.h" />
-    <ClInclude Include="Include\BsMeshBaseRTTI.h" />
-    <ClInclude Include="Include\BsMeshHeap.h" />
-    <ClInclude Include="Include\BsOSInputHandler.h" />
-    <ClInclude Include="Include\BsPixelData.h" />
-    <ClInclude Include="Include\BsPixelDataRTTI.h" />
-    <ClInclude Include="Include\BsPixelUtil.h" />
-    <ClInclude Include="Include\BsPixelVolume.h" />
-    <ClInclude Include="Include\BsPlatform.h" />
-    <ClInclude Include="Include\BsProfilingManager.h" />
-    <ClInclude Include="Include\BsQueryManager.h" />
-    <ClInclude Include="Include\BsResourceManifest.h" />
-    <ClInclude Include="Include\BsResourceManifestRTTI.h" />
-    <ClInclude Include="Include\BsSceneObjectRTTI.h" />
-    <ClInclude Include="Include\BsCoreApplication.h" />
-    <ClInclude Include="Include\BsBlendStateRTTI.h" />
-    <ClInclude Include="Include\BsCommandQueue.h" />
-    <ClInclude Include="Include\BsCommonTypes.h" />
-    <ClInclude Include="Include\BsComponentRTTI.h" />
-    <ClInclude Include="Include\BsCoreObject.h" />
-    <ClInclude Include="Include\BsCoreObjectManager.h" />
-    <ClInclude Include="Include\BsCoreThreadAccessor.h" />
-    <ClInclude Include="Include\BsDepthStencilStateRTTI.h" />
-    <ClInclude Include="Include\BsDepthStencilState.h" />
-    <ClInclude Include="Include\BsFont.h" />
-    <ClInclude Include="Include\BsFontDesc.h" />
-    <ClInclude Include="Include\BsFontImportOptions.h" />
-    <ClInclude Include="Include\BsFontImportOptionsRTTI.h" />
-    <ClInclude Include="Include\BsFontManager.h" />
-    <ClInclude Include="Include\BsFontRTTI.h" />
-    <ClInclude Include="Include\BsGpuBuffer.h" />
-    <ClInclude Include="Include\BsGpuBufferView.h" />
-    <ClInclude Include="Include\BsGpuParamBlock.h" />
-    <ClInclude Include="Include\BsGpuParamDesc.h" />
-    <ClInclude Include="Include\BsGpuParams.h" />
-    <ClInclude Include="Include\BsGpuProgInclude.h" />
-    <ClInclude Include="Include\BsGpuProgram.h" />
-    <ClInclude Include="Include\BsGpuProgramImporter.h" />
-    <ClInclude Include="Include\BsGpuProgramImportOptions.h" />
-    <ClInclude Include="Include\BsGpuProgramImportOptionsRTTI.h" />
-    <ClInclude Include="Include\BsGpuProgramRTTI.h" />
-    <ClInclude Include="Include\BsHardwareBuffer.h" />
-    <ClInclude Include="Include\BsHardwareBufferManager.h" />
-    <ClInclude Include="Include\BsImportOptions.h" />
-    <ClInclude Include="Include\BsImportOptionsRTTI.h" />
-    <ClInclude Include="Include\BsIndexBuffer.h" />
-    <ClInclude Include="Include\BsMaterialManager.h" />
-    <ClInclude Include="Include\BsMeshManager.h" />
-    <ClInclude Include="Include\BsOcclusionQuery.h" />
-    <ClInclude Include="Include\BsPixelBuffer.h" />
-    <ClInclude Include="Include\BsGpuProgIncludeImporter.h" />
-    <ClInclude Include="Include\BsShaderProxy.h" />
-    <ClInclude Include="Include\BsSubMesh.h" />
-    <ClInclude Include="Include\BsTextureImportOptions.h" />
-    <ClInclude Include="Include\BsTextureImportOptionsRTTI.h" />
-    <ClInclude Include="Include\BsTextureView.h" />
-    <ClInclude Include="Include\BsTextData.h" />
-    <ClInclude Include="Include\BsTimerQuery.h" />
-    <ClInclude Include="Include\BsTransientMesh.h" />
-    <ClInclude Include="Include\BsUUID.h" />
-    <ClInclude Include="Include\BsVertexBuffer.h" />
-    <ClInclude Include="Include\BsGpuProgramManager.h" />
-    <ClInclude Include="Include\BsImporter.h" />
-    <ClInclude Include="Include\BsInput.h" />
-    <ClInclude Include="Include\BsRawInputHandler.h" />
-    <ClInclude Include="Include\BsMaterial.h" />
-    <ClInclude Include="Include\BsMaterialRTTI.h" />
-    <ClInclude Include="Include\BsMesh.h" />
-    <ClInclude Include="Include\BsMeshData.h" />
-    <ClInclude Include="Include\BsMeshDataRTTI.h" />
-    <ClInclude Include="Include\BsMultiRenderTexture.h" />
-    <ClInclude Include="Include\BsPass.h" />
-    <ClInclude Include="Include\BsPassRTTI.h" />
-    <ClInclude Include="Include\BsCorePrerequisites.h" />
-    <ClInclude Include="Include\BsRasterizerState.h" />
-    <ClInclude Include="Include\BsRasterizerStateRTTI.h" />
-    <ClInclude Include="Include\BsRenderer.h" />
-    <ClInclude Include="Include\BsRendererFactory.h" />
-    <ClInclude Include="Include\BsRendererManager.h" />
-    <ClInclude Include="Include\BsRenderStateManager.h" />
-    <ClInclude Include="Include\BsRenderSystem.h" />
-    <ClInclude Include="Include\BsRenderSystemCapabilities.h" />
-    <ClInclude Include="Include\BsRenderSystemFactory.h" />
-    <ClInclude Include="Include\BsRenderSystemManager.h" />
-    <ClInclude Include="Include\BsRenderTarget.h" />
-    <ClInclude Include="Include\BsRenderTexture.h" />
-    <ClInclude Include="Include\BsRenderWindow.h" />
-    <ClInclude Include="Include\BsRenderWindowManager.h" />
-    <ClInclude Include="Include\BsResource.h" />
-    <ClInclude Include="Include\BsResourceHandle.h" />
-    <ClInclude Include="Include\BsResourceHandleRTTI.h" />
-    <ClInclude Include="Include\BsResources.h" />
-    <ClInclude Include="Include\BsSamplerStateRTTI.h" />
-    <ClInclude Include="Include\BsCoreSceneManager.h" />
-    <ClInclude Include="Include\BsShaderRTTI.h" />
-    <ClInclude Include="Include\BsSpecificImporter.h" />
-    <ClInclude Include="Include\BsTechniqueRTTI.h" />
-    <ClInclude Include="Include\BsTexture.h" />
-    <ClInclude Include="Include\BsTextureManager.h" />
-    <ClInclude Include="Include\BsTextureRTTI.h" />
-    <ClInclude Include="Include\BsSamplerState.h" />
-    <ClInclude Include="Include\BsVertexDataDesc.h" />
-    <ClInclude Include="Include\BsVertexDataDescRTTI.h" />
-    <ClInclude Include="Include\BsVertexDeclaration.h" />
-    <ClInclude Include="Include\BsVertexData.h" />
-    <ClInclude Include="Include\BsVideoModeInfo.h" />
-    <ClInclude Include="Include\BsViewport.h" />
-    <ClInclude Include="Include\BsResourceRTTI.h" />
-    <ClInclude Include="Include\BsSceneObject.h" />
-    <ClInclude Include="Include\BsComponent.h" />
-    <ClInclude Include="Include\BsShader.h" />
-    <ClInclude Include="Include\BsBlendState.h" />
-    <ClInclude Include="Include\BsVertexDeclarationRTTI.h" />
-    <ClInclude Include="Include\BsTechnique.h" />
-    <ClInclude Include="Include\Win32\BsPlatformImpl.h" />
-    <ClInclude Include="Include\Win32\BsWin32Defs.h" />
-    <ClInclude Include="Include\Win32\BsPlatformWndProc.h" />
-    <ClInclude Include="Include\Win32\BsWin32DropTarget.h" />
-    <ClInclude Include="Include\Win32\BsWin32FolderMonitor.h" />
-    <ClInclude Include="Source\BsMeshRTTI.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="Source\BsCameraProxy.cpp" />
-    <ClCompile Include="Source\BsCoreThread.cpp" />
-    <ClCompile Include="Source\BsDrawList.cpp" />
-    <ClCompile Include="Source\BsProfilerCPU.cpp" />
-    <ClCompile Include="Source\BsDeferredCallManager.cpp" />
-    <ClCompile Include="Source\BsDrawOps.cpp" />
-    <ClCompile Include="Source\BsEventQuery.cpp" />
-    <ClCompile Include="Source\BsGameObjectHandle.cpp" />
-    <ClCompile Include="Source\BsGameObject.cpp" />
-    <ClCompile Include="Source\BsCoreApplication.cpp" />
-    <ClCompile Include="Source\BsBlendState.cpp" />
-    <ClCompile Include="Source\BsCommandQueue.cpp" />
-    <ClCompile Include="Source\BsCoreObject.cpp" />
-    <ClCompile Include="Source\BsCoreObjectManager.cpp" />
-    <ClCompile Include="Source\BsCoreThreadAccessor.cpp" />
-    <ClCompile Include="Source\BsDepthStencilState.cpp" />
-    <ClCompile Include="Source\BsFont.cpp" />
-    <ClCompile Include="Source\BsFontImportOptions.cpp" />
-    <ClCompile Include="Source\BsFontManager.cpp" />
-    <ClCompile Include="Source\BsGameObjectManager.cpp" />
-    <ClCompile Include="Source\BsGpuBuffer.cpp" />
-    <ClCompile Include="Source\BsGpuBufferView.cpp" />
-    <ClCompile Include="Source\BsGpuParamBlock.cpp" />
-    <ClCompile Include="Source\BsGpuParamBlockBuffer.cpp" />
-    <ClCompile Include="Source\BsGpuParams.cpp" />
-    <ClCompile Include="Source\BsProfilerGPU.cpp" />
-    <ClCompile Include="Source\BsGpuProgInclude.cpp" />
-    <ClCompile Include="Source\BsGpuProgram.cpp" />
-    <ClCompile Include="Source\BsGpuProgramImporter.cpp" />
-    <ClCompile Include="Source\BsGpuProgramImportOptions.cpp" />
-    <ClCompile Include="Source\BsGpuResource.cpp" />
-    <ClCompile Include="Source\BsGpuResourceData.cpp" />
-    <ClCompile Include="Source\BsHardwareBufferManager.cpp" />
-    <ClCompile Include="Source\BsGpuParam.cpp" />
-    <ClCompile Include="Source\BsImportOptions.cpp" />
-    <ClCompile Include="Source\BsIndexBuffer.cpp" />
-    <ClCompile Include="Source\BsMaterialManager.cpp" />
-    <ClCompile Include="Source\BsMeshBase.cpp" />
-    <ClCompile Include="Source\BsMeshHeap.cpp" />
-    <ClCompile Include="Source\BsMeshManager.cpp" />
-    <ClCompile Include="Source\BsOcclusionQuery.cpp" />
-    <ClCompile Include="Source\BsOSInputHandler.cpp" />
-    <ClCompile Include="Source\BsPixelBuffer.cpp" />
-    <ClCompile Include="Source\BsGpuProgIncludeImporter.cpp" />
-    <ClCompile Include="Source\BsPixelData.cpp" />
-    <ClCompile Include="Source\BsPixelUtil.cpp" />
-    <ClCompile Include="Source\BsPixelVolume.cpp" />
-    <ClCompile Include="Source\BsPlatform.cpp" />
-    <ClCompile Include="Source\BsProfilingManager.cpp" />
-    <ClCompile Include="Source\BsQueryManager.cpp" />
-    <ClCompile Include="Source\BsRenderer.cpp" />
-    <ClCompile Include="Source\BsResourceManifest.cpp" />
-    <ClCompile Include="Source\BsTextureImportOptions.cpp" />
-    <ClCompile Include="Source\BsTextureView.cpp" />
-    <ClCompile Include="Source\BsTextData.cpp" />
-    <ClCompile Include="Source\BsTimerQuery.cpp" />
-    <ClCompile Include="Source\BsTransientMesh.cpp" />
-    <ClCompile Include="Source\BsUUID.cpp" />
-    <ClCompile Include="Source\BsVertexBuffer.cpp" />
-    <ClCompile Include="Source\BsGpuProgramManager.cpp" />
-    <ClCompile Include="Source\BsImporter.cpp" />
-    <ClCompile Include="Source\BsInput.cpp" />
-    <ClCompile Include="Source\BsMaterial.cpp" />
-    <ClCompile Include="Source\BsMaterialRTTI.cpp" />
-    <ClCompile Include="Source\BsMesh.cpp" />
-    <ClCompile Include="Source\BsMeshData.cpp" />
-    <ClCompile Include="Source\BsMultiRenderTexture.cpp" />
-    <ClCompile Include="Source\BsPass.cpp" />
-    <ClCompile Include="Source\BsRasterizerState.cpp" />
-    <ClCompile Include="Source\BsRendererManager.cpp" />
-    <ClCompile Include="Source\BsRenderSystem.cpp" />
-    <ClCompile Include="Source\BsRenderSystemCapabilities.cpp" />
-    <ClCompile Include="Source\BsRenderSystemManager.cpp" />
-    <ClCompile Include="Source\BsRenderTarget.cpp" />
-    <ClCompile Include="Source\BsRenderTexture.cpp" />
-    <ClCompile Include="Source\BsRenderWindow.cpp" />
-    <ClCompile Include="Source\BsRenderWindowManager.cpp" />
-    <ClCompile Include="Source\BsResource.cpp" />
-    <ClCompile Include="Source\BsResourceHandle.cpp" />
-    <ClCompile Include="Source\BsResources.cpp" />
-    <ClCompile Include="Source\BsRenderStateManager.cpp" />
-    <ClCompile Include="Source\BsCoreSceneManager.cpp" />
-    <ClCompile Include="Source\BsShader.cpp" />
-    <ClCompile Include="Source\BsSpecificImporter.cpp" />
-    <ClCompile Include="Source\BsTechnique.cpp" />
-    <ClCompile Include="Source\BsTexture.cpp" />
-    <ClCompile Include="Source\BsTextureManager.cpp" />
-    <ClCompile Include="Source\BsSamplerState.cpp" />
-    <ClCompile Include="Source\BsVertexDataDesc.cpp" />
-    <ClCompile Include="Source\BsVertexDeclaration.cpp" />
-    <ClCompile Include="Source\BsVertexData.cpp" />
-    <ClCompile Include="Source\BsVideoModeInfo.cpp" />
-    <ClCompile Include="Source\BsViewport.cpp" />
-    <ClCompile Include="Source\BsSceneObject.cpp" />
-    <ClCompile Include="Source\BsComponent.cpp" />
-    <ClCompile Include="Source\Win32\BsPlatformImpl.cpp" />
-    <ClCompile Include="Source\Win32\BsPlatformWndProc.cpp" />
-    <ClCompile Include="Source\Win32\BsWin32FolderMonitor.cpp" />
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
+<?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="DebugRelease|Win32">
+      <Configuration>DebugRelease</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="DebugRelease|x64">
+      <Configuration>DebugRelease</Configuration>
+      <Platform>x64</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|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{9B21D41C-516B-43BF-9B10-E99B599C7589}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>CamelotCore</RootNamespace>
+    <ProjectName>BansheeCore</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v140</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>NotSet</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup 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" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </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" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
+    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
+    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
+    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
+    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
+    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
+    <OutDir>..\bin\x86\$(Configuration)\</OutDir>
+    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
+    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath)</IncludePath>
+    <LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
+    <OutDir>..\bin\$(Platform)\$(Configuration)\</OutDir>
+    <IntDir>.\Intermediate\$(Platform)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <ExceptionHandling>false</ExceptionHandling>
+      <DisableSpecificWarnings>4530;4577</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>NotSet</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/Debug</AdditionalLibraryDirectories>
+      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <ExceptionHandling>false</ExceptionHandling>
+      <DisableSpecificWarnings>4530;4577</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>NotSet</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Debug</AdditionalLibraryDirectories>
+      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <ExceptionHandling>false</ExceptionHandling>
+      <DisableSpecificWarnings>4530;4577</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>NotSet</SubSystem>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/Release</AdditionalLibraryDirectories>
+      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <MinimalRebuild>true</MinimalRebuild>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <ExceptionHandling>false</ExceptionHandling>
+      <DisableSpecificWarnings>4530;4577</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>NotSet</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/x86/$(Configuration);../Dependencies/lib/x86/DebugRelease</AdditionalLibraryDirectories>
+      <ImportLibrary>..\lib\x86\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+      <DebugInformationFormat>None</DebugInformationFormat>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <ExceptionHandling>false</ExceptionHandling>
+      <DisableSpecificWarnings>4530;4577</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>NotSet</SubSystem>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/Release</AdditionalLibraryDirectories>
+      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugRelease|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;BS_CORE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>./Include;../BansheeUtility/Include;../Dependencies/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <MinimalRebuild>true</MinimalRebuild>
+      <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+      <RuntimeTypeInfo>false</RuntimeTypeInfo>
+      <ExceptionHandling>false</ExceptionHandling>
+      <DisableSpecificWarnings>4530;4577</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>NotSet</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>BansheeUtility.lib;nvtt.lib;Winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalLibraryDirectories>../lib/$(Platform)/$(Configuration);../Dependencies/lib/x64/DebugRelease</AdditionalLibraryDirectories>
+      <ImportLibrary>..\lib\$(Platform)\$(Configuration)\$(TargetName).lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="Include\BsCoreObjectCore.h" />
+    <ClInclude Include="Include\BsHString.h" />
+    <ClInclude Include="Include\BsIconUtility.h" />
+    <ClInclude Include="Include\BsMaterialParams.h" />
+    <ClInclude Include="Include\BsMaterialParamsRTTI.h" />
+    <ClInclude Include="Include\BsMeshImportOptions.h" />
+    <ClInclude Include="Include\BsMeshImportOptionsRTTI.h" />
+    <ClInclude Include="Include\BsMeshRTTI.h" />
+    <ClInclude Include="Include\BsMeshUtility.h" />
+    <ClInclude Include="Include\BsParamBlocks.h" />
+    <ClInclude Include="Include\BsPrefab.h" />
+    <ClInclude Include="Include\BsPrefabDiff.h" />
+    <ClInclude Include="Include\BsPrefabDiffRTTI.h" />
+    <ClInclude Include="Include\BsPrefabRTTI.h" />
+    <ClInclude Include="Include\BsPrefabUtility.h" />
+    <ClInclude Include="Include\BsRendererMeshData.h" />
+    <ClInclude Include="Include\BsShaderIncludeRTTI.h" />
+    <ClInclude Include="Include\BsIResourceListener.h" />
+    <ClInclude Include="Include\BsMaterialParam.h" />
+    <ClInclude Include="Include\BsRenderStats.h" />
+    <ClInclude Include="Include\BsCoreThread.h" />
+    <ClInclude Include="Include\BsProfilerCPU.h" />
+    <ClInclude Include="Include\BsDeferredCallManager.h" />
+    <ClInclude Include="Include\BsDrawOps.h" />
+    <ClInclude Include="Include\BsEventQuery.h" />
+    <ClInclude Include="Include\BsFolderMonitor.h" />
+    <ClInclude Include="Include\BsGameObjectHandle.h" />
+    <ClInclude Include="Include\BsGameObject.h" />
+    <ClInclude Include="Include\BsGameObjectHandleRTTI.h" />
+    <ClInclude Include="Include\BsGameObjectManager.h" />
+    <ClInclude Include="Include\BsGameObjectRTTI.h" />
+    <ClInclude Include="Include\BsProfilerGPU.h" />
+    <ClInclude Include="Include\BsGpuResourceData.h" />
+    <ClInclude Include="Include\BsGpuParamBlockBuffer.h" />
+    <ClInclude Include="Include\BsGpuResourceDataRTTI.h" />
+    <ClInclude Include="Include\BsGpuParam.h" />
+    <ClInclude Include="Include\BsInputFwd.h" />
+    <ClInclude Include="Include\BsMeshBase.h" />
+    <ClInclude Include="Include\BsMeshBaseRTTI.h" />
+    <ClInclude Include="Include\BsMeshHeap.h" />
+    <ClInclude Include="Include\BsOSInputHandler.h" />
+    <ClInclude Include="Include\BsPixelData.h" />
+    <ClInclude Include="Include\BsPixelDataRTTI.h" />
+    <ClInclude Include="Include\BsPixelUtil.h" />
+    <ClInclude Include="Include\BsPixelVolume.h" />
+    <ClInclude Include="Include\BsPlatform.h" />
+    <ClInclude Include="Include\BsProfilingManager.h" />
+    <ClInclude Include="Include\BsQueryManager.h" />
+    <ClInclude Include="Include\BsSavedResourceData.h" />
+    <ClInclude Include="Include\BsSavedResourceDataRTTI.h" />
+    <ClInclude Include="Include\BsResourceListenerManager.h" />
+    <ClInclude Include="Include\BsResourceManifest.h" />
+    <ClInclude Include="Include\BsResourceManifestRTTI.h" />
+    <ClInclude Include="Include\BsResourceMetaData.h" />
+    <ClInclude Include="Include\BsResourceMetaDataRTTI.h" />
+    <ClInclude Include="Include\BsSceneObjectRTTI.h" />
+    <ClInclude Include="Include\BsCoreApplication.h" />
+    <ClInclude Include="Include\BsBlendStateRTTI.h" />
+    <ClInclude Include="Include\BsCommandQueue.h" />
+    <ClInclude Include="Include\BsCommonTypes.h" />
+    <ClInclude Include="Include\BsComponentRTTI.h" />
+    <ClInclude Include="Include\BsCoreObject.h" />
+    <ClInclude Include="Include\BsCoreObjectManager.h" />
+    <ClInclude Include="Include\BsCoreThreadAccessor.h" />
+    <ClInclude Include="Include\BsDepthStencilStateRTTI.h" />
+    <ClInclude Include="Include\BsDepthStencilState.h" />
+    <ClInclude Include="Include\BsFont.h" />
+    <ClInclude Include="Include\BsFontDesc.h" />
+    <ClInclude Include="Include\BsFontImportOptions.h" />
+    <ClInclude Include="Include\BsFontImportOptionsRTTI.h" />
+    <ClInclude Include="Include\BsFontManager.h" />
+    <ClInclude Include="Include\BsFontRTTI.h" />
+    <ClInclude Include="Include\BsGpuBuffer.h" />
+    <ClInclude Include="Include\BsGpuBufferView.h" />
+    <ClInclude Include="Include\BsGpuParamDesc.h" />
+    <ClInclude Include="Include\BsGpuParams.h" />
+    <ClInclude Include="Include\BsShaderInclude.h" />
+    <ClInclude Include="Include\BsGpuProgram.h" />
+    <ClInclude Include="Include\BsGpuProgramRTTI.h" />
+    <ClInclude Include="Include\BsHardwareBuffer.h" />
+    <ClInclude Include="Include\BsHardwareBufferManager.h" />
+    <ClInclude Include="Include\BsImportOptions.h" />
+    <ClInclude Include="Include\BsImportOptionsRTTI.h" />
+    <ClInclude Include="Include\BsIndexBuffer.h" />
+    <ClInclude Include="Include\BsMaterialManager.h" />
+    <ClInclude Include="Include\BsMeshManager.h" />
+    <ClInclude Include="Include\BsOcclusionQuery.h" />
+    <ClInclude Include="Include\BsPixelBuffer.h" />
+    <ClInclude Include="Include\BsShaderIncludeImporter.h" />
+    <ClInclude Include="Include\BsShaderManager.h" />
+    <ClInclude Include="Include\BsStringTable.h" />
+    <ClInclude Include="Include\BsStringTableManager.h" />
+    <ClInclude Include="Include\BsStringTableRTTI.h" />
+    <ClInclude Include="Include\BsSubMesh.h" />
+    <ClInclude Include="Include\BsTextureImportOptions.h" />
+    <ClInclude Include="Include\BsTextureImportOptionsRTTI.h" />
+    <ClInclude Include="Include\BsTextureView.h" />
+    <ClInclude Include="Include\BsTextData.h" />
+    <ClInclude Include="Include\BsTimerQuery.h" />
+    <ClInclude Include="Include\BsTransientMesh.h" />
+    <ClInclude Include="Include\BsUtility.h" />
+    <ClInclude Include="Include\BsUUID.h" />
+    <ClInclude Include="Include\BsVertexBuffer.h" />
+    <ClInclude Include="Include\BsGpuProgramManager.h" />
+    <ClInclude Include="Include\BsImporter.h" />
+    <ClInclude Include="Include\BsInput.h" />
+    <ClInclude Include="Include\BsRawInputHandler.h" />
+    <ClInclude Include="Include\BsMaterial.h" />
+    <ClInclude Include="Include\BsMaterialRTTI.h" />
+    <ClInclude Include="Include\BsMesh.h" />
+    <ClInclude Include="Include\BsMeshData.h" />
+    <ClInclude Include="Include\BsMeshDataRTTI.h" />
+    <ClInclude Include="Include\BsMultiRenderTexture.h" />
+    <ClInclude Include="Include\BsPass.h" />
+    <ClInclude Include="Include\BsPassRTTI.h" />
+    <ClInclude Include="Include\BsCorePrerequisites.h" />
+    <ClInclude Include="Include\BsRasterizerState.h" />
+    <ClInclude Include="Include\BsRasterizerStateRTTI.h" />
+    <ClInclude Include="Include\BsCoreRenderer.h" />
+    <ClInclude Include="Include\BsRendererFactory.h" />
+    <ClInclude Include="Include\BsRendererManager.h" />
+    <ClInclude Include="Include\BsRenderStateManager.h" />
+    <ClInclude Include="Include\BsRenderAPI.h" />
+    <ClInclude Include="Include\BsRenderAPICapabilities.h" />
+    <ClInclude Include="Include\BsRenderAPIFactory.h" />
+    <ClInclude Include="Include\BsRenderAPIManager.h" />
+    <ClInclude Include="Include\BsRenderTarget.h" />
+    <ClInclude Include="Include\BsRenderTexture.h" />
+    <ClInclude Include="Include\BsRenderWindow.h" />
+    <ClInclude Include="Include\BsRenderWindowManager.h" />
+    <ClInclude Include="Include\BsResource.h" />
+    <ClInclude Include="Include\BsResourceHandle.h" />
+    <ClInclude Include="Include\BsResourceHandleRTTI.h" />
+    <ClInclude Include="Include\BsResources.h" />
+    <ClInclude Include="Include\BsSamplerStateRTTI.h" />
+    <ClInclude Include="Include\BsCoreSceneManager.h" />
+    <ClInclude Include="Include\BsShaderRTTI.h" />
+    <ClInclude Include="Include\BsSpecificImporter.h" />
+    <ClInclude Include="Include\BsTechniqueRTTI.h" />
+    <ClInclude Include="Include\BsTexture.h" />
+    <ClInclude Include="Include\BsTextureManager.h" />
+    <ClInclude Include="Include\BsTextureRTTI.h" />
+    <ClInclude Include="Include\BsSamplerState.h" />
+    <ClInclude Include="Include\BsVertexDataDesc.h" />
+    <ClInclude Include="Include\BsVertexDataDescRTTI.h" />
+    <ClInclude Include="Include\BsVertexDeclaration.h" />
+    <ClInclude Include="Include\BsVertexData.h" />
+    <ClInclude Include="Include\BsVideoModeInfo.h" />
+    <ClInclude Include="Include\BsViewport.h" />
+    <ClInclude Include="Include\BsResourceRTTI.h" />
+    <ClInclude Include="Include\BsSceneObject.h" />
+    <ClInclude Include="Include\BsComponent.h" />
+    <ClInclude Include="Include\BsShader.h" />
+    <ClInclude Include="Include\BsBlendState.h" />
+    <ClInclude Include="Include\BsVertexDeclarationRTTI.h" />
+    <ClInclude Include="Include\BsTechnique.h" />
+    <ClInclude Include="Include\BsViewportRTTI.h" />
+    <ClInclude Include="Include\Win32\BsWin32Defs.h" />
+    <ClInclude Include="Include\Win32\BsWin32Platform.h" />
+    <ClInclude Include="Include\Win32\BsWin32DropTarget.h" />
+    <ClInclude Include="Include\Win32\BsWin32FolderMonitor.h" />
+    <ClInclude Include="Include\Win32\BSWin32PlatformData.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\BsCoreObjectCore.cpp" />
+    <ClCompile Include="Source\BsCoreThread.cpp" />
+    <ClCompile Include="Source\BsHString.cpp" />
+    <ClCompile Include="Source\BsIconUtility.cpp" />
+    <ClCompile Include="Source\BsIResourceListener.cpp" />
+    <ClCompile Include="Source\BsMaterialParam.cpp" />
+    <ClCompile Include="Source\BsMeshImportOptions.cpp" />
+    <ClCompile Include="Source\BsMeshUtility.cpp" />
+    <ClCompile Include="Source\BsPrefab.cpp" />
+    <ClCompile Include="Source\BsPrefabDiff.cpp" />
+    <ClCompile Include="Source\BsPrefabUtility.cpp" />
+    <ClCompile Include="Source\BsProfilerCPU.cpp" />
+    <ClCompile Include="Source\BsDeferredCallManager.cpp" />
+    <ClCompile Include="Source\BsDrawOps.cpp" />
+    <ClCompile Include="Source\BsEventQuery.cpp" />
+    <ClCompile Include="Source\BsGameObjectHandle.cpp" />
+    <ClCompile Include="Source\BsGameObject.cpp" />
+    <ClCompile Include="Source\BsCoreApplication.cpp" />
+    <ClCompile Include="Source\BsBlendState.cpp" />
+    <ClCompile Include="Source\BsCommandQueue.cpp" />
+    <ClCompile Include="Source\BsCoreObject.cpp" />
+    <ClCompile Include="Source\BsCoreObjectManager.cpp" />
+    <ClCompile Include="Source\BsCoreThreadAccessor.cpp" />
+    <ClCompile Include="Source\BsDepthStencilState.cpp" />
+    <ClCompile Include="Source\BsFont.cpp" />
+    <ClCompile Include="Source\BsFontImportOptions.cpp" />
+    <ClCompile Include="Source\BsFontManager.cpp" />
+    <ClCompile Include="Source\BsGameObjectManager.cpp" />
+    <ClCompile Include="Source\BsGpuBuffer.cpp" />
+    <ClCompile Include="Source\BsGpuBufferView.cpp" />
+    <ClCompile Include="Source\BsGpuParamBlockBuffer.cpp" />
+    <ClCompile Include="Source\BsGpuParams.cpp" />
+    <ClCompile Include="Source\BsProfilerGPU.cpp" />
+    <ClCompile Include="Source\BsRendererMeshData.cpp" />
+    <ClCompile Include="Source\BsShaderInclude.cpp" />
+    <ClCompile Include="Source\BsGpuProgram.cpp" />
+    <ClCompile Include="Source\BsGpuResourceData.cpp" />
+    <ClCompile Include="Source\BsHardwareBufferManager.cpp" />
+    <ClCompile Include="Source\BsGpuParam.cpp" />
+    <ClCompile Include="Source\BsImportOptions.cpp" />
+    <ClCompile Include="Source\BsIndexBuffer.cpp" />
+    <ClCompile Include="Source\BsMaterialManager.cpp" />
+    <ClCompile Include="Source\BsMeshBase.cpp" />
+    <ClCompile Include="Source\BsMeshHeap.cpp" />
+    <ClCompile Include="Source\BsMeshManager.cpp" />
+    <ClCompile Include="Source\BsOcclusionQuery.cpp" />
+    <ClCompile Include="Source\BsOSInputHandler.cpp" />
+    <ClCompile Include="Source\BsPixelBuffer.cpp" />
+    <ClCompile Include="Source\BsShaderIncludeImporter.cpp" />
+    <ClCompile Include="Source\BsPixelData.cpp" />
+    <ClCompile Include="Source\BsPixelUtil.cpp" />
+    <ClCompile Include="Source\BsPlatform.cpp" />
+    <ClCompile Include="Source\BsProfilingManager.cpp" />
+    <ClCompile Include="Source\BsQueryManager.cpp" />
+    <ClCompile Include="Source\BsCoreRenderer.cpp" />
+    <ClCompile Include="Source\BsSavedResourceData.cpp" />
+    <ClCompile Include="Source\BsResourceListenerManager.cpp" />
+    <ClCompile Include="Source\BsResourceManifest.cpp" />
+    <ClCompile Include="Source\BsResourceMetaData.cpp" />
+    <ClCompile Include="Source\BsShaderManager.cpp" />
+    <ClCompile Include="Source\BsStringTable.cpp" />
+    <ClCompile Include="Source\BsStringTableManager.cpp" />
+    <ClCompile Include="Source\BsTextureImportOptions.cpp" />
+    <ClCompile Include="Source\BsTextureView.cpp" />
+    <ClCompile Include="Source\BsTextData.cpp" />
+    <ClCompile Include="Source\BsTimerQuery.cpp" />
+    <ClCompile Include="Source\BsTransientMesh.cpp" />
+    <ClCompile Include="Source\BsUtility.cpp" />
+    <ClCompile Include="Source\BsUUID.cpp" />
+    <ClCompile Include="Source\BsVertexBuffer.cpp" />
+    <ClCompile Include="Source\BsGpuProgramManager.cpp" />
+    <ClCompile Include="Source\BsImporter.cpp" />
+    <ClCompile Include="Source\BsInput.cpp" />
+    <ClCompile Include="Source\BsMaterial.cpp" />
+    <ClCompile Include="Source\BsMaterialRTTI.cpp" />
+    <ClCompile Include="Source\BsMesh.cpp" />
+    <ClCompile Include="Source\BsMeshData.cpp" />
+    <ClCompile Include="Source\BsMultiRenderTexture.cpp" />
+    <ClCompile Include="Source\BsPass.cpp" />
+    <ClCompile Include="Source\BsRasterizerState.cpp" />
+    <ClCompile Include="Source\BsRendererManager.cpp" />
+    <ClCompile Include="Source\BsRenderAPI.cpp" />
+    <ClCompile Include="Source\BsRenderAPICapabilities.cpp" />
+    <ClCompile Include="Source\BsRenderAPIManager.cpp" />
+    <ClCompile Include="Source\BsRenderTarget.cpp" />
+    <ClCompile Include="Source\BsRenderTexture.cpp" />
+    <ClCompile Include="Source\BsRenderWindow.cpp" />
+    <ClCompile Include="Source\BsRenderWindowManager.cpp" />
+    <ClCompile Include="Source\BsResource.cpp" />
+    <ClCompile Include="Source\BsResourceHandle.cpp" />
+    <ClCompile Include="Source\BsResources.cpp" />
+    <ClCompile Include="Source\BsRenderStateManager.cpp" />
+    <ClCompile Include="Source\BsCoreSceneManager.cpp" />
+    <ClCompile Include="Source\BsShader.cpp" />
+    <ClCompile Include="Source\BsSpecificImporter.cpp" />
+    <ClCompile Include="Source\BsTechnique.cpp" />
+    <ClCompile Include="Source\BsTexture.cpp" />
+    <ClCompile Include="Source\BsTextureManager.cpp" />
+    <ClCompile Include="Source\BsSamplerState.cpp" />
+    <ClCompile Include="Source\BsVertexDataDesc.cpp" />
+    <ClCompile Include="Source\BsVertexDeclaration.cpp" />
+    <ClCompile Include="Source\BsVertexData.cpp" />
+    <ClCompile Include="Source\BsVideoModeInfo.cpp" />
+    <ClCompile Include="Source\BsViewport.cpp" />
+    <ClCompile Include="Source\BsSceneObject.cpp" />
+    <ClCompile Include="Source\BsComponent.cpp" />
+    <ClCompile Include="Source\BsMaterialParams.cpp" />
+    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp" />
+    <ClCompile Include="Source\Win32\BsWin32Platform.cpp" />
+    <ClCompile Include="Source\Win32\BsWin32FolderMonitor.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
 </Project>

+ 916 - 821
BansheeCore/BansheeCore.vcxproj.filters

@@ -1,822 +1,917 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="Source Files">
-      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
-      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
-    </Filter>
-    <Filter Include="Header Files">
-      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
-      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
-    </Filter>
-    <Filter Include="Resource Files">
-      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
-      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
-    </Filter>
-    <Filter Include="Header Files\Utility">
-      <UniqueIdentifier>{2c09857e-4a4a-480f-8ebb-1661a9ce78dd}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\RenderSystem">
-      <UniqueIdentifier>{3480589d-111c-44b8-b0f1-a178cd00f31e}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\RenderSystem">
-      <UniqueIdentifier>{e0bdc5fc-afd1-46f9-9e3e-f85ca3e220b8}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Importer">
-      <UniqueIdentifier>{f1fb2bc5-43c6-476a-89e3-b7de86c5aebe}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Resources">
-      <UniqueIdentifier>{e091a28f-6a0f-44ab-a88f-83e3c970c2f3}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Importer">
-      <UniqueIdentifier>{7ac6e5cb-48f7-4a49-a793-fb2ccfabe895}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Resources">
-      <UniqueIdentifier>{6df1cc13-bf9e-45e7-90ae-337999c702cf}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Scene">
-      <UniqueIdentifier>{327fbccb-fd0d-4fb1-af08-5d00cd7d56a7}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Scene">
-      <UniqueIdentifier>{2211ce11-e426-4aad-a5e6-73727d44bb98}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\RTTI">
-      <UniqueIdentifier>{75249db9-4f2e-43c3-8df4-37250c4b60a2}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Input">
-      <UniqueIdentifier>{7f8e94f3-6990-4723-965a-2b4f9346a7ee}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Input">
-      <UniqueIdentifier>{724588b9-04e2-4e9b-9467-b064ed44f05e}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Material">
-      <UniqueIdentifier>{299ec378-4e67-4818-92f6-ab5ffb9aa9ad}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Material">
-      <UniqueIdentifier>{96caf3fa-c267-4fb4-aaa8-83519666d079}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Renderer">
-      <UniqueIdentifier>{5303462d-20d9-4c00-86b8-162e3a430b07}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Renderer">
-      <UniqueIdentifier>{307618fb-e6a0-41ed-b274-fb1f5f4c6f74}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\RTTI">
-      <UniqueIdentifier>{dc50e07b-6351-4bc2-8bfa-cc3fc1d26c39}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Win32">
-      <UniqueIdentifier>{1d3fe8eb-ec10-4356-90f0-b27f89f01a13}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Win32">
-      <UniqueIdentifier>{5a1e28c5-e784-44e6-974f-f1d0d66474ed}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Text">
-      <UniqueIdentifier>{1daa1a6e-95c0-4e63-b339-4a884773fa64}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Text">
-      <UniqueIdentifier>{96b913ee-4ffb-4c60-9aa9-a51e0faf8060}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Core">
-      <UniqueIdentifier>{62281c40-1fc0-47f6-bc61-ff28314d8e13}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Core">
-      <UniqueIdentifier>{402fe837-7d94-4343-a288-c8308fda8c18}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Header Files\Platform">
-      <UniqueIdentifier>{d53f502a-b966-4162-a828-af2654f0408f}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\Platform">
-      <UniqueIdentifier>{88dfbdf1-6999-424c-ac32-1ffe65b6c9f6}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="Include\BsRenderStats.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCommonTypes.h">
-      <Filter>Header Files\Utility</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCoreApplication.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsViewport.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsUUID.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPixelVolume.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPixelUtil.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDeferredCallManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\Win32\BsWin32Defs.h">
-      <Filter>Header Files\Win32</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\Win32\BsPlatformImpl.h">
-      <Filter>Header Files\Win32</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\Win32\BsPlatformWndProc.h">
-      <Filter>Header Files\Win32</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTextData.h">
-      <Filter>Header Files\Text</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFontManager.h">
-      <Filter>Header Files\Text</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFontImportOptions.h">
-      <Filter>Header Files\Text</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFontDesc.h">
-      <Filter>Header Files\Text</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFont.h">
-      <Filter>Header Files\Text</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsComponent.h">
-      <Filter>Header Files\Scene</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGameObject.h">
-      <Filter>Header Files\Scene</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGameObjectHandle.h">
-      <Filter>Header Files\Scene</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGameObjectManager.h">
-      <Filter>Header Files\Scene</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSceneObject.h">
-      <Filter>Header Files\Scene</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsBlendStateRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsComponentRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDepthStencilStateRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFontImportOptionsRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFontRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGameObjectHandleRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGameObjectRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgramImportOptionsRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgramRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuResourceDataRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuResourceRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsImportOptionsRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMaterialRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshBaseRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshDataRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Source\BsMeshRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPassRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPixelDataRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRasterizerStateRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResourceHandleRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResourceManifestRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResourceRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSamplerStateRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSceneObjectRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsShaderRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTechniqueRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTextureRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVertexDataDescRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVertexDeclarationRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVertexDataDesc.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTransientMesh.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTextureManager.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTexture.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResources.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResourceManifest.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResourceHandle.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsResource.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPixelData.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshHeap.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshData.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshBase.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMesh.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuResourceData.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuResource.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgInclude.h">
-      <Filter>Header Files\Resources</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVideoModeInfo.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVertexDeclaration.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVertexData.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsVertexBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTimerQuery.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTextureView.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSubMesh.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSamplerState.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderWindowManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderWindow.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderTexture.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderTarget.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderSystemManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderSystemFactory.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderSystemCapabilities.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderSystem.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderStateManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRasterizerState.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsQueryManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPixelBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsOcclusionQuery.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMultiRenderTexture.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsIndexBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsHardwareBufferManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsHardwareBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgramManager.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgram.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuParams.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuParamDesc.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuParamBlockBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuParamBlock.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuParam.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuBufferView.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuBuffer.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsEventQuery.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDrawOps.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDepthStencilState.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsBlendState.h">
-      <Filter>Header Files\RenderSystem</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRendererManager.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRendererFactory.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRenderer.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\Win32\BsWin32FolderMonitor.h">
-      <Filter>Header Files\Platform</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\Win32\BsWin32DropTarget.h">
-      <Filter>Header Files\Platform</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPlatform.h">
-      <Filter>Header Files\Platform</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsFolderMonitor.h">
-      <Filter>Header Files\Platform</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTechnique.h">
-      <Filter>Header Files\Material</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsShader.h">
-      <Filter>Header Files\Material</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsPass.h">
-      <Filter>Header Files\Material</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMaterialManager.h">
-      <Filter>Header Files\Material</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMaterial.h">
-      <Filter>Header Files\Material</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsRawInputHandler.h">
-      <Filter>Header Files\Input</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsOSInputHandler.h">
-      <Filter>Header Files\Input</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsInputFwd.h">
-      <Filter>Header Files\Input</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsInput.h">
-      <Filter>Header Files\Input</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsSpecificImporter.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsImportOptions.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsImporter.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgramImportOptions.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgramImporter.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsGpuProgIncludeImporter.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCoreThreadAccessor.h">
-      <Filter>Header Files\Core</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCoreThread.h">
-      <Filter>Header Files\Core</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCoreObjectManager.h">
-      <Filter>Header Files\Core</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCoreObject.h">
-      <Filter>Header Files\Core</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCommandQueue.h">
-      <Filter>Header Files\Core</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCoreSceneManager.h">
-      <Filter>Header Files\Scene</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCorePrerequisites.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsProfilerCPU.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsProfilerGPU.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsProfilingManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsCameraProxy.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsDrawList.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMeshProxy.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsMaterialProxy.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsShaderProxy.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTextureImportOptions.h">
-      <Filter>Header Files\Importer</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\BsTextureImportOptionsRTTI.h">
-      <Filter>Header Files\RTTI</Filter>
-    </ClInclude>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="Source\BsCoreApplication.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsViewport.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsUUID.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsPlatform.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsPixelVolume.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsPixelUtil.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsDrawOps.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsDeferredCallManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\Win32\BsPlatformWndProc.cpp">
-      <Filter>Source Files\Win32</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\Win32\BsPlatformImpl.cpp">
-      <Filter>Source Files\Win32</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsFont.cpp">
-      <Filter>Source Files\Text</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsFontImportOptions.cpp">
-      <Filter>Source Files\Text</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsFontManager.cpp">
-      <Filter>Source Files\Text</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTextData.cpp">
-      <Filter>Source Files\Text</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsComponent.cpp">
-      <Filter>Source Files\Scene</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGameObject.cpp">
-      <Filter>Source Files\Scene</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGameObjectHandle.cpp">
-      <Filter>Source Files\Scene</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGameObjectManager.cpp">
-      <Filter>Source Files\Scene</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsSceneObject.cpp">
-      <Filter>Source Files\Scene</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMaterialRTTI.cpp">
-      <Filter>Source Files\RTTI</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuProgInclude.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuResource.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuResourceData.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMesh.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMeshBase.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMeshData.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMeshHeap.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsPixelData.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsResource.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsResourceHandle.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsResourceManifest.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsResources.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTexture.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTextureManager.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTransientMesh.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsVertexDataDesc.cpp">
-      <Filter>Source Files\Resources</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsBlendState.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsDepthStencilState.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsEventQuery.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuBuffer.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuBufferView.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuParam.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuParamBlock.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuParamBlockBuffer.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuParams.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuProgram.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuProgramManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsHardwareBufferManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsIndexBuffer.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMeshManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMultiRenderTexture.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsOcclusionQuery.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsPixelBuffer.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsQueryManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRasterizerState.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderStateManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderSystem.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderSystemCapabilities.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderSystemManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderTarget.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderTexture.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderWindow.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderWindowManager.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsSamplerState.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTextureView.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTimerQuery.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsVertexBuffer.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsVertexData.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsVertexDeclaration.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsVideoModeInfo.cpp">
-      <Filter>Source Files\RenderSystem</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRenderer.cpp">
-      <Filter>Source Files\Renderer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsRendererManager.cpp">
-      <Filter>Source Files\Renderer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\Win32\BsWin32FolderMonitor.cpp">
-      <Filter>Source Files\Platform</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMaterial.cpp">
-      <Filter>Source Files\Material</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsMaterialManager.cpp">
-      <Filter>Source Files\Material</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsPass.cpp">
-      <Filter>Source Files\Material</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsShader.cpp">
-      <Filter>Source Files\Material</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTechnique.cpp">
-      <Filter>Source Files\Material</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsInput.cpp">
-      <Filter>Source Files\Input</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsOSInputHandler.cpp">
-      <Filter>Source Files\Input</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuProgIncludeImporter.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuProgramImporter.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsGpuProgramImportOptions.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsImporter.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsImportOptions.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsSpecificImporter.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCommandQueue.cpp">
-      <Filter>Source Files\Core</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCoreObject.cpp">
-      <Filter>Source Files\Core</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCoreObjectManager.cpp">
-      <Filter>Source Files\Core</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCoreThread.cpp">
-      <Filter>Source Files\Core</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCoreThreadAccessor.cpp">
-      <Filter>Source Files\Core</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCoreSceneManager.cpp">
-      <Filter>Source Files\Scene</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsProfilerCPU.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsProfilerGPU.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsProfilingManager.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsDrawList.cpp">
-      <Filter>Source Files\Renderer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsCameraProxy.cpp">
-      <Filter>Source Files\Renderer</Filter>
-    </ClCompile>
-    <ClCompile Include="Source\BsTextureImportOptions.cpp">
-      <Filter>Source Files\Importer</Filter>
-    </ClCompile>
-  </ItemGroup>
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+    </Filter>
+    <Filter Include="Header Files\Utility">
+      <UniqueIdentifier>{2c09857e-4a4a-480f-8ebb-1661a9ce78dd}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Importer">
+      <UniqueIdentifier>{f1fb2bc5-43c6-476a-89e3-b7de86c5aebe}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Resources">
+      <UniqueIdentifier>{e091a28f-6a0f-44ab-a88f-83e3c970c2f3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Importer">
+      <UniqueIdentifier>{7ac6e5cb-48f7-4a49-a793-fb2ccfabe895}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Resources">
+      <UniqueIdentifier>{6df1cc13-bf9e-45e7-90ae-337999c702cf}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Scene">
+      <UniqueIdentifier>{327fbccb-fd0d-4fb1-af08-5d00cd7d56a7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Scene">
+      <UniqueIdentifier>{2211ce11-e426-4aad-a5e6-73727d44bb98}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\RTTI">
+      <UniqueIdentifier>{75249db9-4f2e-43c3-8df4-37250c4b60a2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Input">
+      <UniqueIdentifier>{7f8e94f3-6990-4723-965a-2b4f9346a7ee}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Input">
+      <UniqueIdentifier>{724588b9-04e2-4e9b-9467-b064ed44f05e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Material">
+      <UniqueIdentifier>{299ec378-4e67-4818-92f6-ab5ffb9aa9ad}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Material">
+      <UniqueIdentifier>{96caf3fa-c267-4fb4-aaa8-83519666d079}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Renderer">
+      <UniqueIdentifier>{5303462d-20d9-4c00-86b8-162e3a430b07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Renderer">
+      <UniqueIdentifier>{307618fb-e6a0-41ed-b274-fb1f5f4c6f74}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\RTTI">
+      <UniqueIdentifier>{dc50e07b-6351-4bc2-8bfa-cc3fc1d26c39}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Text">
+      <UniqueIdentifier>{1daa1a6e-95c0-4e63-b339-4a884773fa64}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Text">
+      <UniqueIdentifier>{96b913ee-4ffb-4c60-9aa9-a51e0faf8060}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Platform">
+      <UniqueIdentifier>{d53f502a-b966-4162-a828-af2654f0408f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Platform">
+      <UniqueIdentifier>{88dfbdf1-6999-424c-ac32-1ffe65b6c9f6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\RenderAPI">
+      <UniqueIdentifier>{3480589d-111c-44b8-b0f1-a178cd00f31e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\RenderAPI">
+      <UniqueIdentifier>{e0bdc5fc-afd1-46f9-9e3e-f85ca3e220b8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Utility">
+      <UniqueIdentifier>{0d63b345-0a58-4df2-9d01-f4da53fc40c9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Localization">
+      <UniqueIdentifier>{df01dcc2-a0b0-48a8-a6fd-59a556cb67f9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Localization">
+      <UniqueIdentifier>{f8c05475-0bc9-44d9-9702-985ec016f0ba}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\Profiling">
+      <UniqueIdentifier>{4ecc02bc-09b0-4d03-a3c0-0ebb7f154d3c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\Profiling">
+      <UniqueIdentifier>{66694132-958f-435a-808f-3c6eb325a322}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Source Files\CoreThread">
+      <UniqueIdentifier>{402fe837-7d94-4343-a288-c8308fda8c18}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Header Files\CoreThread">
+      <UniqueIdentifier>{62281c40-1fc0-47f6-bc61-ff28314d8e13}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="Include\BsCommonTypes.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreApplication.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTextData.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFontManager.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFontImportOptions.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFontDesc.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFont.h">
+      <Filter>Header Files\Text</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsComponent.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGameObject.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGameObjectHandle.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGameObjectManager.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSceneObject.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsBlendStateRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsComponentRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsDepthStencilStateRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFontImportOptionsRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFontRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGameObjectHandleRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGameObjectRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuProgramRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuResourceDataRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsImportOptionsRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterialRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshBaseRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshDataRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPassRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPixelDataRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRasterizerStateRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceHandleRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceManifestRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSamplerStateRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSceneObjectRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShaderRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTechniqueRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTextureRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVertexDataDescRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVertexDeclarationRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVertexDataDesc.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTransientMesh.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTextureManager.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTexture.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResources.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceManifest.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceHandle.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResource.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPixelData.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshHeap.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshData.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshBase.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMesh.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuResourceData.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVideoModeInfo.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVertexDeclaration.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVertexData.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsVertexBuffer.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTimerQuery.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTextureView.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSubMesh.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSamplerState.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderWindowManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderWindow.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderTexture.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderTarget.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderStateManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRasterizerState.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsQueryManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPixelBuffer.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsOcclusionQuery.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMultiRenderTexture.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsIndexBuffer.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsHardwareBufferManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsHardwareBuffer.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuProgramManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuProgram.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuParams.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuParamDesc.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuParamBlockBuffer.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuParam.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuBufferView.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsGpuBuffer.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsEventQuery.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsDrawOps.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsDepthStencilState.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsBlendState.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRendererManager.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRendererFactory.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\Win32\BsWin32FolderMonitor.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\Win32\BsWin32DropTarget.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPlatform.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsFolderMonitor.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTechnique.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShader.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPass.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterialManager.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterial.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRawInputHandler.h">
+      <Filter>Header Files\Input</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsOSInputHandler.h">
+      <Filter>Header Files\Input</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsInputFwd.h">
+      <Filter>Header Files\Input</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsInput.h">
+      <Filter>Header Files\Input</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSpecificImporter.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsImportOptions.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsImporter.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreThreadAccessor.h">
+      <Filter>Header Files\CoreThread</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreThread.h">
+      <Filter>Header Files\CoreThread</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreObjectManager.h">
+      <Filter>Header Files\CoreThread</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreObject.h">
+      <Filter>Header Files\CoreThread</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCommandQueue.h">
+      <Filter>Header Files\CoreThread</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreSceneManager.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCorePrerequisites.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTextureImportOptions.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsTextureImportOptionsRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceMetaData.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceMetaDataRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsViewportRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterialParam.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreObjectCore.h">
+      <Filter>Header Files\CoreThread</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCoreRenderer.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderAPI.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderAPIManager.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderAPIFactory.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderAPICapabilities.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsUtility.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSavedResourceData.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsSavedResourceDataRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\Win32\BsWin32Defs.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\Win32\BSWin32PlatformData.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\Win32\BsWin32Platform.h">
+      <Filter>Header Files\Platform</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShaderIncludeImporter.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShaderInclude.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShaderIncludeRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsShaderManager.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshImportOptions.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshImportOptionsRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPrefab.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPrefabRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPrefabDiff.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPrefabDiffRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshUtility.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPrefabUtility.h">
+      <Filter>Header Files\Scene</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRendererMeshData.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsHString.h">
+      <Filter>Header Files\Localization</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsStringTable.h">
+      <Filter>Header Files\Localization</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsStringTableManager.h">
+      <Filter>Header Files\Localization</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsStringTableRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsParamBlocks.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsProfilerCPU.h">
+      <Filter>Header Files\Profiling</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsProfilerGPU.h">
+      <Filter>Header Files\Profiling</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsProfilingManager.h">
+      <Filter>Header Files\Profiling</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderStats.h">
+      <Filter>Header Files\Profiling</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsDeferredCallManager.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsResourceListenerManager.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsIconUtility.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsIResourceListener.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsUUID.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsViewport.h">
+      <Filter>Header Files\RenderAPI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPixelUtil.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsPixelVolume.h">
+      <Filter>Header Files\Utility</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterialParams.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterialParamsRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMeshRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Source\BsCoreApplication.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsFont.cpp">
+      <Filter>Source Files\Text</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsFontImportOptions.cpp">
+      <Filter>Source Files\Text</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsFontManager.cpp">
+      <Filter>Source Files\Text</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTextData.cpp">
+      <Filter>Source Files\Text</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsComponent.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGameObject.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGameObjectHandle.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGameObjectManager.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsSceneObject.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMaterialRTTI.cpp">
+      <Filter>Source Files\RTTI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuResourceData.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMesh.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMeshBase.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMeshData.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMeshHeap.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPixelData.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsResource.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsResourceHandle.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsResourceManifest.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsResources.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTexture.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTextureManager.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTransientMesh.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsVertexDataDesc.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsBlendState.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsDepthStencilState.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsEventQuery.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuBuffer.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuBufferView.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuParam.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuParamBlockBuffer.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuParams.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuProgram.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsGpuProgramManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsHardwareBufferManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsIndexBuffer.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMeshManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMultiRenderTexture.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsOcclusionQuery.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPixelBuffer.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsQueryManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRasterizerState.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderStateManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderTarget.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderTexture.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderWindow.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderWindowManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsSamplerState.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTextureView.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTimerQuery.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsVertexBuffer.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsVertexData.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsVertexDeclaration.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsVideoModeInfo.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRendererManager.cpp">
+      <Filter>Source Files\Renderer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Win32\BsWin32FolderMonitor.cpp">
+      <Filter>Source Files\Platform</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMaterial.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMaterialManager.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPass.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsShader.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTechnique.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsInput.cpp">
+      <Filter>Source Files\Input</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsOSInputHandler.cpp">
+      <Filter>Source Files\Input</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsImporter.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsImportOptions.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsSpecificImporter.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCommandQueue.cpp">
+      <Filter>Source Files\CoreThread</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreObject.cpp">
+      <Filter>Source Files\CoreThread</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreObjectManager.cpp">
+      <Filter>Source Files\CoreThread</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreThread.cpp">
+      <Filter>Source Files\CoreThread</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreThreadAccessor.cpp">
+      <Filter>Source Files\CoreThread</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreSceneManager.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsTextureImportOptions.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsResourceMetaData.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMaterialParam.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreObjectCore.cpp">
+      <Filter>Source Files\CoreThread</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsCoreRenderer.cpp">
+      <Filter>Source Files\Renderer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderAPI.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderAPIManager.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRenderAPICapabilities.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsUtility.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsSavedResourceData.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPlatform.cpp">
+      <Filter>Source Files\Platform</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Win32\BsWin32Platform.cpp">
+      <Filter>Source Files\Platform</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsShaderIncludeImporter.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsShaderInclude.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsShaderManager.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMeshImportOptions.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPrefab.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPrefabDiff.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMeshUtility.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPrefabUtility.cpp">
+      <Filter>Source Files\Scene</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsRendererMeshData.cpp">
+      <Filter>Source Files\Renderer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsHString.cpp">
+      <Filter>Source Files\Localization</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsStringTable.cpp">
+      <Filter>Source Files\Localization</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsStringTableManager.cpp">
+      <Filter>Source Files\Localization</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsProfilerCPU.cpp">
+      <Filter>Source Files\Profiling</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsProfilerGPU.cpp">
+      <Filter>Source Files\Profiling</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsProfilingManager.cpp">
+      <Filter>Source Files\Profiling</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsDeferredCallManager.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsResourceListenerManager.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsDrawOps.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsIconUtility.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsUUID.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsIResourceListener.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsViewport.cpp">
+      <Filter>Source Files\RenderAPI</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsPixelUtil.cpp">
+      <Filter>Source Files\Utility</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\BsMaterialParams.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\Win32\BsWin32BrowseDialogs.cpp">
+      <Filter>Source Files\Platform</Filter>
+    </ClCompile>
+  </ItemGroup>
 </Project>

+ 253 - 170
BansheeCore/Include/BsBlendState.h

@@ -1,170 +1,253 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Structure that describes blend states for a single render
-	 * 			target. Used internally by BLEND_STATE_DESC for initializing a BlendState.
-	 * 			
-	 * @see		BLEND_STATE_DESC
-	 * @see		BlendState
-	 */
-	struct BS_CORE_EXPORT RENDER_TARGET_BLEND_STATE_DESC
-	{
-		RENDER_TARGET_BLEND_STATE_DESC()
-			: blendEnable(false)
-			, srcBlend(BF_ONE)
-			, dstBlend(BF_ZERO)
-			, blendOp(BO_ADD)
-			, srcBlendAlpha(BF_ONE)
-			, dstBlendAlpha(BF_ZERO)
-			, blendOpAlpha(BO_ADD)
-			, renderTargetWriteMask(0xFF)
-		{ }
-
-		bool blendEnable;
-		BlendFactor srcBlend;
-		BlendFactor dstBlend;
-		BlendOperation blendOp;
-		BlendFactor srcBlendAlpha;
-		BlendFactor dstBlendAlpha;
-		BlendOperation blendOpAlpha;
-		// Enable write to RGBA channels separately by setting first four bits (0 - R, 1 - G, 2 - B, 3 - A)
-		UINT8 renderTargetWriteMask;
-	};
-
-	/**
-	 * @brief	Structure that describes render pipeline blend states. Used for initializing
-	 * 			BlendState.
-	 * 			
-	 * @see		BlendState.
-	 */
-	struct BS_CORE_EXPORT BLEND_STATE_DESC
-	{
-		BLEND_STATE_DESC()
-			: alphaToCoverageEnable(false)
-			, independantBlendEnable(false)
-		{ }
-
-		bool alphaToCoverageEnable;
-		bool independantBlendEnable;
-		RENDER_TARGET_BLEND_STATE_DESC renderTargetDesc[BS_MAX_MULTIPLE_RENDER_TARGETS];
-	};
-
-	/**
-	 * @brief	Render system pipeline state that allows you to modify how an object is rendered. 
-	 * 			More exactly this state allows to you to control how is a rendered
-	 * 			object blended with any previously renderer objects.
-	 * 			
-	 * @note	Blend states are immutable. Thread safe.
-	 */
-	class BS_CORE_EXPORT BlendState : public Resource
-	{
-	public:
-		virtual ~BlendState() {}
-
-		/**
-		 * @brief	Alpha to coverage allows you to perform blending without needing to worry about order of
-		 * 			rendering like regular blending does. It requires multi-sampling to be active in order to
-		 * 			work, and you need to supply an alpha texture that determines object transparency.
-		 *
-		 *			Blending is then performed by only using sub-samples covered by the alpha texture for the current
-		 *			pixel and combining them with sub-samples previously stored. 
-		 *			
-		 *			Be aware this is a limited technique only useful for certain situations. Unless you are having performance
-		 *			problems use regular blending.
-		 */
-		bool getAlphaToCoverageEnabled() const { return mData.alphaToCoverageEnable; }
-
-		/**
-		 * @brief	When not set, only the first render target blend descriptor will be used for all
-		 * 			render targets. If set each render target will use its own blend descriptor.
-		 */
-		bool getIndependantBlendEnable() const { return mData.independantBlendEnable; }
-
-		/**
-		 * @brief	Queries is blending enabled for the specified render target. Blending
-		 * 			allows you to combine the color from current and previous pixel based on
-		 * 			some value.
-		 */
-		bool getBlendEnabled(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Determines what should the source blend factor be. This value determines
-		 * 			what will the color being generated currently be multiplied by.
-		 */
-		BlendFactor getSrcBlend(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Determines what should the destination blend factor be. This value determines
-		 * 			what will the color already in render target be multiplied by.
-		 */
-		BlendFactor getDstBlend(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Determines how are source and destination colors combined (after they are multiplied
-		 * 			by their respective blend factors).
-		 */
-		BlendOperation getBlendOperation(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Determines what should the alpha source blend factor be. This value determines
-		 * 			what will the alpha value being generated currently be multiplied by.
-		 */
-		BlendFactor getAlphaSrcBlend(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Determines what should the alpha destination blend factor be. This value determines
-		 * 			what will the alpha value already in render target be multiplied by.
-		 */
-		BlendFactor getAlphaDstBlend(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Determines how are source and destination alpha values combined (after they are multiplied
-		 * 			by their respective blend factors).
-		 */
-		BlendOperation getAlphaBlendOperation(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Render target write mask allows to choose which pixel components should the pixel shader
-		 * 			output.
-		 * 			
-		 *			Only the first four bits are used. First bit representing red, second green, third blue and
-		 *			fourth alpha value. Set bits means pixel shader will output those channels.
-		 */
-		UINT8 getRenderTargetWriteMask(UINT32 renderTargetIdx) const;
-
-		/**
-		 * @brief	Creates a new blend state using the specified blend state description structure.
-		 */
-		static HBlendState create(const BLEND_STATE_DESC& desc);
-
-		/**
-		 * @brief	Returns the default blend state that you may use
-		 * 			when no other is available.
-		 */
-		static const BlendStatePtr& getDefault();
-
-	protected:
-		friend class RenderStateManager;
-
-		/**
-		 * @brief	Initializes the blend state. Must be called right after construction.
-		 */
-		virtual void initialize(const BLEND_STATE_DESC& desc);
-
-		BLEND_STATE_DESC mData;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-
-	public:
-		friend class BlendStateRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Structure that describes blend states for a single render target. Used internally by BLEND_STATE_DESC for 
+	 * initializing a BlendState.
+	 * 			
+	 * @see		BLEND_STATE_DESC
+	 * @see		BlendState
+	 */
+	struct BS_CORE_EXPORT RENDER_TARGET_BLEND_STATE_DESC
+	{
+		RENDER_TARGET_BLEND_STATE_DESC()
+			: blendEnable(false)
+			, srcBlend(BF_ONE)
+			, dstBlend(BF_ZERO)
+			, blendOp(BO_ADD)
+			, srcBlendAlpha(BF_ONE)
+			, dstBlendAlpha(BF_ZERO)
+			, blendOpAlpha(BO_ADD)
+			, renderTargetWriteMask(0xFF)
+		{ }
+
+		bool operator==(const RENDER_TARGET_BLEND_STATE_DESC& rhs) const;
+
+		bool blendEnable;
+		BlendFactor srcBlend;
+		BlendFactor dstBlend;
+		BlendOperation blendOp;
+		BlendFactor srcBlendAlpha;
+		BlendFactor dstBlendAlpha;
+		BlendOperation blendOpAlpha;
+		// Enable write to RGBA channels separately by setting first four bits (0 - R, 1 - G, 2 - B, 3 - A)
+		UINT8 renderTargetWriteMask;
+	};
+
+	/** Structure that describes render pipeline blend states. Used for initializing BlendState. */
+	struct BS_CORE_EXPORT BLEND_STATE_DESC
+	{
+		BLEND_STATE_DESC()
+			: alphaToCoverageEnable(false)
+			, independantBlendEnable(false)
+		{ }
+
+		bool operator==(const BLEND_STATE_DESC& rhs) const;
+
+		bool alphaToCoverageEnable;
+		bool independantBlendEnable;
+		RENDER_TARGET_BLEND_STATE_DESC renderTargetDesc[BS_MAX_MULTIPLE_RENDER_TARGETS];
+	};
+
+	/** Properties of a BlendState. Shared between sim and core thread versions of BlendState. */
+	class BS_CORE_EXPORT BlendProperties
+	{
+	public:
+		BlendProperties(const BLEND_STATE_DESC& desc);
+
+		/**
+		 * Alpha to coverage allows you to perform blending without needing to worry about order of rendering like regular 
+		 * blending does. It requires multi-sampling to be active in order to work, and you need to supply an alpha texture
+		 * that determines object transparency.
+		 *
+		 * Blending is then performed by only using sub-samples covered by the alpha texture for the current pixel and 
+		 * combining them with sub-samples previously stored. 
+		 *			
+		 * Be aware this is a limited technique only useful for certain situations. Unless you are having performance 
+		 * problems use regular blending.
+		 */
+		bool getAlphaToCoverageEnabled() const { return mData.alphaToCoverageEnable; }
+
+		/**
+		 * When not set, only the first render target blend descriptor will be used for all render targets. If set each 
+		 * render target will use its own blend descriptor.
+		 */
+		bool getIndependantBlendEnable() const { return mData.independantBlendEnable; }
+
+		/**
+		 * Queries is blending enabled for the specified render target. Blending allows you to combine the color from 
+		 * current and previous pixel based on some value.
+		 */
+		bool getBlendEnabled(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Determines what should the source blend factor be. This value determines what will the color being generated 
+		 * currently be multiplied by.
+		 */
+		BlendFactor getSrcBlend(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Determines what should the destination blend factor be. This value determines what will the color already in 
+		 * render target be multiplied by.
+		 */
+		BlendFactor getDstBlend(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Determines how are source and destination colors combined (after they are multiplied by their respective blend 
+		 * factors).
+		 */
+		BlendOperation getBlendOperation(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Determines what should the alpha source blend factor be. This value determines what will the alpha value being 
+		 * generated currently be multiplied by.
+		 */
+		BlendFactor getAlphaSrcBlend(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Determines what should the alpha destination blend factor be. This value determines what will the alpha value 
+		 * already in render target be multiplied by.
+		 */
+		BlendFactor getAlphaDstBlend(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Determines how are source and destination alpha values combined (after they are multiplied by their respective
+		 * blend factors).
+		 */
+		BlendOperation getAlphaBlendOperation(UINT32 renderTargetIdx) const;
+
+		/**
+		 * Render target write mask allows to choose which pixel components should the pixel shader output.
+		 * 			
+		 * Only the first four bits are used. First bit representing red, second green, third blue and fourth alpha value. 
+		 * Set bits means pixel shader will output those channels.
+		 */
+		UINT8 getRenderTargetWriteMask(UINT32 renderTargetIdx) const;
+
+		/** Returns the hash value generated from the blend state properties. */
+		UINT64 getHash() const { return mHash; }
+
+	protected:
+		friend class BlendState;
+		friend class BlendStateCore;
+		friend class BlendStateRTTI;
+
+		BLEND_STATE_DESC mData;
+		UINT64 mHash;
+	};
+
+	/** @cond INTERNAL */
+
+	/**
+	 * Core thread version of BlendState.
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT BlendStateCore : public CoreObjectCore
+	{
+	public:
+		virtual ~BlendStateCore();
+
+		/** Returns information about the blend state. */
+		const BlendProperties& getProperties() const;
+
+		/** Returns a unique state ID. Only the lowest 10 bits are used. */
+		UINT32 getId() const { return mId; }
+
+		/**	Returns the default blend state that you may use when no other is available. */
+		static const SPtr<BlendStateCore>& getDefault();
+
+	protected:
+		friend class RenderStateCoreManager;
+
+		BlendStateCore(const BLEND_STATE_DESC& desc, UINT32 id);
+
+		/** @copydoc CoreObjectCore::initialize */
+		void initialize() override;
+
+		/**	Creates any API-specific state objects. */
+		virtual void createInternal() { }
+
+		BlendProperties mProperties;
+		UINT32 mId;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Render system pipeline state that allows you to modify how an object is rendered. More exactly this state allows to 
+	 * you to control how is a rendered object blended with any previously renderer objects.
+	 * 			
+	 * @note	Blend states are immutable. Sim thread only.
+	 */
+	class BS_CORE_EXPORT BlendState : public IReflectable, public CoreObject
+	{
+	public:
+		virtual ~BlendState();
+
+		/**	Returns information about a blend state. */
+		const BlendProperties& getProperties() const;
+
+		/** Retrieves a core implementation of the sampler state usable only from the core thread. */
+		SPtr<BlendStateCore> getCore() const;
+
+		/**	Creates a new blend state using the specified blend state description structure. */
+		static BlendStatePtr create(const BLEND_STATE_DESC& desc);
+
+		/**	Returns the default blend state that you may use when no other is available. */
+		static const BlendStatePtr& getDefault();
+
+		/**	Generates a hash value from a blend state descriptor. */
+		static UINT64 generateHash(const BLEND_STATE_DESC& desc);
+
+	protected:
+		friend class RenderStateManager;
+
+		BlendState(const BLEND_STATE_DESC& desc);
+
+		/** @copydoc CoreObjectCore::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		BlendProperties mProperties;
+		mutable UINT32 mId;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class BlendStateRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;	
+	};
+
+	/** @} */
+}
+
+/** @cond STDLIB */
+/** @addtogroup RenderAPI
+ *  @{
+ */
+
+/**	Hash value generator for BLEND_STATE_DESC. */
+template<>
+struct std::hash<BansheeEngine::BLEND_STATE_DESC>
+{
+	size_t operator()(const BansheeEngine::BLEND_STATE_DESC& value) const
+	{
+		return (size_t)BansheeEngine::BlendState::generateHash(value);
+	}
+};
+
+/** @} */
+/** @endcond */

+ 94 - 93
BansheeCore/Include/BsBlendStateRTTI.h

@@ -1,94 +1,95 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsBlendState.h"
-#include "BsRenderStateManager.h"
-
-namespace BansheeEngine
-{
-	template<> struct RTTIPlainType<BLEND_STATE_DESC>
-	{	
-		enum { id = TID_BLEND_STATE_DESC }; enum { hasDynamicSize = 1 };
-
-		static void toMemory(const BLEND_STATE_DESC& data, char* memory)
-		{ 
-			UINT32 size = getDynamicSize(data);
-
-			memcpy(memory, &size, sizeof(UINT32));
-			memory += sizeof(UINT32);
-			size -= sizeof(UINT32);
-			memcpy(memory, &data, size); 
-		}
-
-		static UINT32 fromMemory(BLEND_STATE_DESC& data, char* memory)
-		{ 
-			UINT32 size;
-			memcpy(&size, memory, sizeof(UINT32)); 
-			memory += sizeof(UINT32);
-
-			UINT32 dataSize = size - sizeof(UINT32);
-			memcpy((void*)&data, memory, dataSize); 
-
-			return size;
-		}
-
-		static UINT32 getDynamicSize(const BLEND_STATE_DESC& data)	
-		{ 
-			UINT64 dataSize = sizeof(data) + sizeof(UINT32);
-
-#if BS_DEBUG_MODE
-			if(dataSize > std::numeric_limits<UINT32>::max())
-			{
-				BS_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
-			}
-#endif
-
-			return (UINT32)dataSize;
-		}	
-	}; 
-
-	class BS_CORE_EXPORT BlendStateRTTI : public RTTIType<BlendState, IReflectable, BlendStateRTTI>
-	{
-	private:
-		BLEND_STATE_DESC& getData(BlendState* obj) { return obj->mData; }
-		void setData(BlendState* obj, BLEND_STATE_DESC& val) 
-		{ 
-			obj->mRTTIData = val;
-		} 
-
-	public:
-		BlendStateRTTI()
-		{
-			addPlainField("mData", 0, &BlendStateRTTI::getData, &BlendStateRTTI::setData);
-		}
-
-		virtual void onDeserializationEnded(IReflectable* obj)
-		{
-			BlendState* blendState = static_cast<BlendState*>(obj);
-			if(!blendState->mRTTIData.empty())
-			{
-				BLEND_STATE_DESC desc = any_cast<BLEND_STATE_DESC>(blendState->mRTTIData);
-
-				blendState->initialize(desc);
-			}
-
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "BlendState";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_BlendState;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return RenderStateManager::instance().createEmptyBlendState();
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsBlendState.h"
+#include "BsRenderStateManager.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	template<> struct RTTIPlainType<BLEND_STATE_DESC>
+	{	
+		enum { id = TID_BLEND_STATE_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const BLEND_STATE_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			memcpy(memory, &size, sizeof(UINT32));
+			memory += sizeof(UINT32);
+			size -= sizeof(UINT32);
+			memcpy(memory, &data, size); 
+		}
+
+		static UINT32 fromMemory(BLEND_STATE_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			UINT32 dataSize = size - sizeof(UINT32);
+			memcpy((void*)&data, memory, dataSize); 
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const BLEND_STATE_DESC& data)	
+		{ 
+			UINT64 dataSize = sizeof(data) + sizeof(UINT32);
+
+#if BS_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				BS_EXCEPT(InternalErrorException, "Data overflow! Size doesn't fit into 32 bits.");
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	class BS_CORE_EXPORT BlendStateRTTI : public RTTIType<BlendState, IReflectable, BlendStateRTTI>
+	{
+	private:
+		BLEND_STATE_DESC& getData(BlendState* obj) { return obj->mProperties.mData; }
+		void setData(BlendState* obj, BLEND_STATE_DESC& val) { obj->mProperties.mData = val; } 
+
+	public:
+		BlendStateRTTI()
+		{
+			addPlainField("mData", 0, &BlendStateRTTI::getData, &BlendStateRTTI::setData);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			BlendState* blendState = static_cast<BlendState*>(obj);
+			blendState->initialize();
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "BlendState";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_BlendState;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return RenderStateManager::instance()._createBlendStatePtr(BLEND_STATE_DESC());
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 0 - 31
BansheeCore/Include/BsCameraProxy.h

@@ -1,31 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsViewport.h"
-#include "BsConvexVolume.h"
-#include "BsMatrix4.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains Camera data used by the Renderer.
-	 */
-	class BS_CORE_EXPORT CameraProxy
-	{
-	public:
-		void calcWorldFrustum();
-
-		Viewport viewport;
-		Matrix4 viewMatrix;
-		Matrix4 projMatrix;
-		Matrix4 worldMatrix;
-		INT32 priority;
-		UINT64 layer;
-		bool ignoreSceneRenderables;
-		ConvexVolume frustum;
-		ConvexVolume worldFrustum;
-		Vector3 worldPosition;
-
-		RenderQueuePtr renderQueue;
-	};
-}

+ 382 - 399
BansheeCore/Include/BsCommandQueue.h

@@ -1,399 +1,382 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsAsyncOp.h"
-#include <functional>
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Command queue policy that provides no synchonization. Should be used
-	 * 			with command queues that are used on a single thread only.
-	 */
-	class CommandQueueNoSync
-	{
-	public:
-		CommandQueueNoSync() {}
-		virtual ~CommandQueueNoSync() {}
-
-		bool isValidThread(BS_THREAD_ID_TYPE ownerThread) const
-		{
-			return BS_THREAD_CURRENT_ID == ownerThread;
-		}
-
-		void lock() { };
-		void unlock() { }
-	};
-
-	/**
-	 * @brief	Command queue policy that provides synchonization. Should be used
-	 * 			with command queues that are used on multiple threads.
-	 */
-	class CommandQueueSync
-	{
-	public:
-		CommandQueueSync()
-			:mLock(mCommandQueueMutex, BS_DEFER_LOCK)
-		{ }
-		virtual ~CommandQueueSync() {}
-
-		bool isValidThread(BS_THREAD_ID_TYPE ownerThread) const
-		{
-			return true;
-		}
-
-		void lock() 
-		{
-			mLock.lock();
-		};
-
-		void unlock()
-		{
-			mLock.unlock();
-		}
-
-	private:
-		BS_MUTEX(mCommandQueueMutex);
-		BS_LOCK_TYPE mLock;
-	};
-
-	/**
-	 * @brief	Represents a single queued command in the command list. Contains all the data for executing the command
-	 * 			and checking up on the command status.
-	 */
-	struct QueuedCommand
-	{
-#if BS_DEBUG_MODE
-		QueuedCommand(std::function<void(AsyncOp&)> _callback, UINT32 _debugId, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
-			:callbackWithReturnValue(_callback), debugId(_debugId), returnsValue(true), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(bs_new<AsyncOp>()), ownsData(true)
-		{ }
-
-		QueuedCommand(std::function<void()> _callback, UINT32 _debugId, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
-			:callback(_callback), debugId(_debugId), returnsValue(false), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(nullptr), ownsData(true)
-		{ }
-
-		UINT32 debugId;
-#else
-		QueuedCommand(std::function<void(AsyncOp&)> _callback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
-			:callbackWithReturnValue(_callback), returnsValue(true), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(bs_new<AsyncOp>()), ownsData(true)
-		{ }
-
-		QueuedCommand(std::function<void()> _callback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
-			:callback(_callback), returnsValue(false), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(nullptr), ownsData(true)
-		{ }
-#endif
-
-		~QueuedCommand()
-		{
-			if(ownsData && asyncOp != nullptr)
-				bs_delete(asyncOp);
-		}
-
-		QueuedCommand(const QueuedCommand& source)
-		{
-			ownsData = true;
-			source.ownsData = false;
-
-			callback = source.callback;
-			callbackWithReturnValue = source.callbackWithReturnValue;
-			asyncOp = source.asyncOp;
-			returnsValue = source.returnsValue;
-			callbackId = source.callbackId;
-			notifyWhenComplete = source.notifyWhenComplete;
-		}
-
-		QueuedCommand& operator=(const QueuedCommand& rhs)
-		{
-			ownsData = true;
-			rhs.ownsData = false;
-
-			callback = rhs.callback;
-			callbackWithReturnValue = rhs.callbackWithReturnValue;
-			asyncOp = rhs.asyncOp;
-			returnsValue = rhs.returnsValue;
-			callbackId = rhs.callbackId;
-			notifyWhenComplete = rhs.notifyWhenComplete;
-			
-			return *this;
-		}
-
-		std::function<void()> callback;
-		std::function<void(AsyncOp&)> callbackWithReturnValue;
-		AsyncOp* asyncOp;
-		bool returnsValue;
-		UINT32 callbackId;
-		bool notifyWhenComplete;
-
-		mutable bool ownsData;
-	};
-
-	/**
-	 * @brief	Contains a list of commands you may queue for later execution on the core thread.
-	 */
-	class BS_CORE_EXPORT CommandQueueBase
-	{
-	public:
-		/**
-		 * @brief	Constructor.
-		 *
-		 * @param	threadId	   	Identifier for the thread the command queue will be getting commands from.					
-		 */
-		CommandQueueBase(BS_THREAD_ID_TYPE threadId);
-		virtual ~CommandQueueBase();
-
-		/**
-		 * @brief	Gets the thread identifier the command queue is used on.
-		 * 			
-		 * @note	If the command queue is using a synchonized access policy generally this
-		 * 			is not relevant as it may be used on multiple threads.
-		 */
-		BS_THREAD_ID_TYPE getThreadId() const { return mMyThreadId; }
-
-		/**
-		 * @brief	Executes all provided commands one by one in order. To get the commands you should call flush().
-		 *
-		 * @param	notifyCallback  	Callback that will be called if a command that has "notifyOnComplete" flag set.
-		 * 								The callback will receive "callbackId" of the command.
-		 */
-		void playbackWithNotify(Queue<QueuedCommand>* commands, std::function<void(UINT32)> notifyCallback);
-
-		/**
-		 * @brief	Executes all provided commands one by one in order. To get the commands you should call flush().
-		 */
-		void playback(Queue<QueuedCommand>* commands);
-
-		/**
-		 * @brief	Allows you to set a breakpoint that will trigger when the specified command is executed.
-		 * 			
-		 * @note	This is helpful when you receive an error on the executing thread and you cannot tell from where was
-		 * 			the command that caused the error queued from. However you can make a note of the queue and command index
-		 * 			and set a breakpoint so that it gets triggered next time you run the program. At that point you can know 
-		 * 			exactly which part of code queued the command by examining the stack trace.
-		 *
-		 * @param	queueIdx  	Zero-based index of the queue the command was queued on.
-		 * @param	commandIdx	Zero-based index of the command.
-		 */
-		static void addBreakpoint(UINT32 queueIdx, UINT32 commandIdx);
-
-		/**
-		 * @brief	Queue up a new command to execute. Make sure the provided function has all of its
-		 * 			parameters properly bound. Last parameter must be unbound and of AsyncOp& type.
-		 * 			This is used to signal that the command is completed, and also for storing the return
-		 * 			value.
-		 * 			
-		 * 			@note	Callback method also needs to call AsyncOp::markAsResolved once it is done
-		 * 			processing. (If it doesn't it will still be called automatically, but the return
-		 * 			value will default to nullptr)
-		 *
-		 * @param	_notifyWhenComplete	(optional) Call the notify method (provided in the call to CommandQueue::playback)
-		 * 								when the command is complete.
-		 * @param	_callbackId			(optional) Identifier for the callback so you can then later find it
-		 * 								if needed.
-		 *
-		 * @return	Async operation object that you can continuously check until the command completes. After
-		 * 			it completes AsyncOp::isResolved will return true and return data will be valid (if
-		 * 			the callback provided any).
-		 */
-		AsyncOp queueReturn(std::function<void(AsyncOp&)> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0);
-
-		/**
-		 * @brief	Queue up a new command to execute. Make sure the provided function has all of its
-		 * 			parameters properly bound. Provided command is not expected to return a value. If you
-		 * 			wish to return a value from the callback use the queueReturn which accepts an AsyncOp parameter.
-		 *
-		 * @param	_notifyWhenComplete	(optional) Call the notify method (provided in the call to CommandQueue::playback)
-		 * 								when the command is complete.
-		 * @param	_callbackId		   	(optional) Identifier for the callback so you can then later find
-		 * 								it if needed.
-		 */
-		void queue(std::function<void()> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0);
-
-		/**
-		 * @brief	Returns a copy of all queued commands and makes room for new ones. Must be called from the thread
-		 * 			that created the command queue. Returned commands MUST be passed to "playback" method.
-		 */
-		BansheeEngine::Queue<QueuedCommand>* flush();
-
-		/**
-		 * @brief	Cancels all currently queued commands.
-		 */
-		void cancelAll();
-
-		/**
-		 * @brief	Returns true if no commands are queued.
-		 */
-		bool isEmpty();
-
-	protected:
-		/**
-		 * @brief	Helper method that throws an "Invalid thread" exception. Used primarily
-		 * 			so we can avoid including Exception include in this header.
-		 */
-		void throwInvalidThreadException(const String& message) const;
-
-	private:
-		BansheeEngine::Queue<QueuedCommand>* mCommands;
-		Stack<BansheeEngine::Queue<QueuedCommand>*> mEmptyCommandQueues; // List of empty queues for reuse
-
-		BS_THREAD_ID_TYPE mMyThreadId;
-
-		// Various variables that allow for easier debugging by allowing us to trigger breakpoints
-		// when a certain command was queued.
-#if BS_DEBUG_MODE
-		struct QueueBreakpoint
-		{
-			class HashFunction
-			{
-			public:
-				size_t operator()(const QueueBreakpoint &key) const;
-			};
-
-			class EqualFunction
-			{
-			public:
-				bool operator()(const QueueBreakpoint &a, const QueueBreakpoint &b) const;
-			};
-
-			QueueBreakpoint(UINT32 _queueIdx, UINT32 _commandIdx)
-				:queueIdx(_queueIdx), commandIdx(_commandIdx)
-			{ }
-
-			UINT32 queueIdx;
-			UINT32 commandIdx;
-
-			inline size_t operator()(const QueueBreakpoint& v) const;
-		};
-
-		UINT32 mMaxDebugIdx;
-		UINT32 mCommandQueueIdx;
-
-		static UINT32 MaxCommandQueueIdx;
-		static UnorderedSet<QueueBreakpoint, QueueBreakpoint::HashFunction, QueueBreakpoint::EqualFunction> SetBreakpoints;
-		BS_STATIC_MUTEX(CommandQueueBreakpointMutex);
-
-		/**
-		 * @brief	Checks if the specified command has a breakpoint and throw an assert if it does.
-		 */
-		static void breakIfNeeded(UINT32 queueIdx, UINT32 commandIdx);
-#endif
-	};
-
-	/**
-	 * @copydoc CommandQueueBase
-	 * 			
-	 * @brief	Use SyncPolicy to choose whether you want command queue be synchonized or not. Synchonized
-	 * 			command queues may be used across multiple threads and non-synchonized only on one.
-	 */
-	template<class SyncPolicy = CommandQueueNoSync>
-	class CommandQueue : public CommandQueueBase, public SyncPolicy
-	{
-	public:
-		/**
-		 * @copydoc CommandQueueBase::CommandQueueBase
-		 */
-		CommandQueue(BS_THREAD_ID_TYPE threadId)
-			:CommandQueueBase(threadId)
-		{ }
-
-		~CommandQueue() 
-		{
-#if BS_DEBUG_MODE
-#if BS_THREAD_SUPPORT != 0
-			if(!isValidThread(getThreadId()))
-				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
-#endif
-#endif
-		}
-
-		/**
-		 * @copydoc CommandQueueBase::queueReturn
-		 */
-		AsyncOp queueReturn(std::function<void(AsyncOp&)> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
-		{
-#if BS_DEBUG_MODE
-#if BS_THREAD_SUPPORT != 0
-			if(!isValidThread(getThreadId()))
-				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
-#endif
-#endif
-
-			lock();
-			AsyncOp asyncOp = CommandQueueBase::queueReturn(commandCallback, _notifyWhenComplete, _callbackId);
-			unlock();
-
-			return asyncOp;
-		}
-
-		/**
-		 * @copydoc CommandQueueBase::queue
-		 */
-		void queue(std::function<void()> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
-		{
-#if BS_DEBUG_MODE
-#if BS_THREAD_SUPPORT != 0
-			if(!isValidThread(getThreadId()))
-				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
-#endif
-#endif
-
-			lock();
-			CommandQueueBase::queue(commandCallback, _notifyWhenComplete, _callbackId);
-			unlock();
-		}
-
-		/**
-		 * @copydoc CommandQueueBase::flush
-		 */
-		BansheeEngine::Queue<QueuedCommand>* flush()
-		{
-#if BS_DEBUG_MODE
-#if BS_THREAD_SUPPORT != 0
-			if(!isValidThread(getThreadId()))
-				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
-#endif
-#endif
-
-			lock();
-			BansheeEngine::Queue<QueuedCommand>* commands = CommandQueueBase::flush();
-			unlock();
-
-			return commands;
-		}
-
-		/**
-		 * @copydoc CommandQueueBase::cancelAll
-		 */
-		void cancelAll()
-		{
-#if BS_DEBUG_MODE
-#if BS_THREAD_SUPPORT != 0
-			if(!isValidThread(getThreadId()))
-				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
-#endif
-#endif
-
-			lock();
-			CommandQueueBase::cancelAll();
-			unlock();
-		}
-
-		/**
-		 * @copydoc CommandQueueBase::isEmpty
-		 */
-		bool isEmpty()
-		{
-#if BS_DEBUG_MODE
-#if BS_THREAD_SUPPORT != 0
-			if(!isValidThread(getThreadId()))
-				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
-#endif
-#endif
-
-			lock();
-			bool empty = CommandQueueBase::isEmpty();
-			unlock();
-
-			return empty;
-		}
-	};
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsAsyncOp.h"
+#include <functional>
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup CoreThread
+	 *  @{
+	 */
+
+	/**
+	 * Command queue policy that provides no synchonization. Should be used with command queues that are used on a single 
+	 * thread only.
+	 */
+	class CommandQueueNoSync
+	{
+	public:
+		CommandQueueNoSync() {}
+		virtual ~CommandQueueNoSync() {}
+
+		bool isValidThread(BS_THREAD_ID_TYPE ownerThread) const
+		{
+			return BS_THREAD_CURRENT_ID == ownerThread;
+		}
+
+		void lock() { };
+		void unlock() { }
+	};
+
+	/**
+	 * Command queue policy that provides synchonization. Should be used with command queues that are used on multiple 
+	 * threads.
+	 */
+	class CommandQueueSync
+	{
+	public:
+		CommandQueueSync()
+			:mLock(mCommandQueueMutex, BS_DEFER_LOCK)
+		{ }
+		virtual ~CommandQueueSync() {}
+
+		bool isValidThread(BS_THREAD_ID_TYPE ownerThread) const
+		{
+			return true;
+		}
+
+		void lock() 
+		{
+			mLock.lock();
+		};
+
+		void unlock()
+		{
+			mLock.unlock();
+		}
+
+	private:
+		BS_MUTEX(mCommandQueueMutex);
+		BS_LOCK_TYPE mLock;
+	};
+
+	/**
+	 * Represents a single queued command in the command list. Contains all the data for executing the command and checking 
+	 * up on the command status.
+	 */
+	struct QueuedCommand
+	{
+#if BS_DEBUG_MODE
+		QueuedCommand(std::function<void(AsyncOp&)> _callback, UINT32 _debugId, const AsyncOpSyncDataPtr& asyncOpSyncData,
+			bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
+			:callbackWithReturnValue(_callback), debugId(_debugId), returnsValue(true), 
+			notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(asyncOpSyncData)
+		{ }
+
+		QueuedCommand(std::function<void()> _callback, UINT32 _debugId, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
+			:callback(_callback), debugId(_debugId), returnsValue(false), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(AsyncOpEmpty())
+		{ }
+
+		UINT32 debugId;
+#else
+		QueuedCommand(std::function<void(AsyncOp&)> _callback, const AsyncOpSyncDataPtr& asyncOpSyncData, 
+			bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
+			:callbackWithReturnValue(_callback), returnsValue(true), notifyWhenComplete(_notifyWhenComplete), 
+			callbackId(_callbackId), asyncOp(asyncOpSyncData)
+		{ }
+
+		QueuedCommand(std::function<void()> _callback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
+			:callback(_callback), returnsValue(false), notifyWhenComplete(_notifyWhenComplete), callbackId(_callbackId), asyncOp(AsyncOpEmpty())
+		{ }
+#endif
+
+		~QueuedCommand()
+		{ }
+
+		QueuedCommand(const QueuedCommand& source)
+		{
+			callback = source.callback;
+			callbackWithReturnValue = source.callbackWithReturnValue;
+			asyncOp = source.asyncOp;
+			returnsValue = source.returnsValue;
+			callbackId = source.callbackId;
+			notifyWhenComplete = source.notifyWhenComplete;
+
+#if BS_DEBUG_MODE
+			debugId = source.debugId;
+#endif
+		}
+
+		QueuedCommand& operator=(const QueuedCommand& rhs)
+		{
+			callback = rhs.callback;
+			callbackWithReturnValue = rhs.callbackWithReturnValue;
+			asyncOp = rhs.asyncOp;
+			returnsValue = rhs.returnsValue;
+			callbackId = rhs.callbackId;
+			notifyWhenComplete = rhs.notifyWhenComplete;
+			
+#if BS_DEBUG_MODE
+			debugId = rhs.debugId;
+#endif
+
+			return *this;
+		}
+
+		std::function<void()> callback;
+		std::function<void(AsyncOp&)> callbackWithReturnValue;
+		AsyncOp asyncOp;
+		bool returnsValue;
+		UINT32 callbackId;
+		bool notifyWhenComplete;
+	};
+
+	/** Contains a list of commands you may queue for later execution on the core thread. */
+	class BS_CORE_EXPORT CommandQueueBase
+	{
+	public:
+		/**
+		 * Constructor.
+		 *
+		 * @param[in]	threadId	   	Identifier for the thread the command queue will be getting commands from.					
+		 */
+		CommandQueueBase(BS_THREAD_ID_TYPE threadId);
+		virtual ~CommandQueueBase();
+
+		/**
+		 * Gets the thread identifier the command queue is used on.
+		 * 			
+		 * @note	If the command queue is using a synchonized access policy generally this is not relevant as it may be 
+		 *			used on multiple threads.
+		 */
+		BS_THREAD_ID_TYPE getThreadId() const { return mMyThreadId; }
+
+		/**
+		 * Executes all provided commands one by one in order. To get the commands you should call flush().
+		 *
+		 * @param[in]	notifyCallback  	Callback that will be called if a command that has @p notifyOnComplete flag set.
+		 * 									The callback will receive @p callbackId of the command.
+		 */
+		void playbackWithNotify(Queue<QueuedCommand>* commands, std::function<void(UINT32)> notifyCallback);
+
+		/** Executes all provided commands one by one in order. To get the commands you should call flush(). */
+		void playback(Queue<QueuedCommand>* commands);
+
+		/**
+		 * Allows you to set a breakpoint that will trigger when the specified command is executed.		
+		 *
+		 * @param[in]	queueIdx  	Zero-based index of the queue the command was queued on.
+		 * @param[in]	commandIdx	Zero-based index of the command.
+		 *
+		 * @note	
+		 * This is helpful when you receive an error on the executing thread and you cannot tell from where was the command 
+		 * that caused the error queued from. However you can make a note of the queue and command index and set a 
+		 * breakpoint so that it gets triggered next time you run the program. At that point you can know exactly which part
+		 * of code queued the command by examining the stack trace.
+		 */
+		static void addBreakpoint(UINT32 queueIdx, UINT32 commandIdx);
+
+		/**
+		 * Queue up a new command to execute. Make sure the provided function has all of its parameters properly bound. 
+		 * Last parameter must be unbound and of AsyncOp& type. This is used to signal that the command is completed, and 
+		 * also for storing the return value.		
+		 *
+		 * @param[in]	_notifyWhenComplete	(optional) Call the notify method (provided in the call to playback())
+		 * 									when the command is complete.
+		 * @param[in]	_callbackId			(optional) Identifier for the callback so you can then later find it
+		 * 									if needed.
+		 *
+		 * @return							Async operation object that you can continuously check until the command 
+		 *									completes. After it completes AsyncOp::isResolved() will return true and return 
+		 *									data will be valid (if the callback provided any).
+		 *
+		 * @note	
+		 * Callback method also needs to call AsyncOp::markAsResolved once it is done processing. (If it doesn't it will 
+		 * still be called automatically, but the return value will default to nullptr)
+		 */
+		AsyncOp queueReturn(std::function<void(AsyncOp&)> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0);
+
+		/**
+		 * Queue up a new command to execute. Make sure the provided function has all of its parameters properly bound. 
+		 * Provided command is not expected to return a value. If you wish to return a value from the callback use the 
+		 * queueReturn() which accepts an AsyncOp parameter.
+		 *
+		 * @param[in]	_notifyWhenComplete	(optional) Call the notify method (provided in the call to playback())
+		 * 									when the command is complete.
+		 * @param[in]	_callbackId		   	(optional) Identifier for the callback so you can then later find
+		 * 									it if needed.
+		 */
+		void queue(std::function<void()> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0);
+
+		/**
+		 * Returns a copy of all queued commands and makes room for new ones. Must be called from the thread that created 
+		 * the command queue. Returned commands must be passed to playback() method.
+		 */
+		Queue<QueuedCommand>* flush();
+
+		/** Cancels all currently queued commands. */
+		void cancelAll();
+
+		/**	Returns true if no commands are queued. */
+		bool isEmpty();
+
+	protected:
+		/**
+		 * Helper method that throws an "Invalid thread" exception. Used primarily so we can avoid including Exception 
+		 * include in this header.
+		 */
+		void throwInvalidThreadException(const String& message) const;
+
+	private:
+		Queue<QueuedCommand>* mCommands;
+		Stack<Queue<QueuedCommand>*> mEmptyCommandQueues; /**< List of empty queues for reuse. */
+
+		AsyncOpSyncDataPtr mAsyncOpSyncData;
+		BS_THREAD_ID_TYPE mMyThreadId;
+
+		// Various variables that allow for easier debugging by allowing us to trigger breakpoints
+		// when a certain command was queued.
+#if BS_DEBUG_MODE
+		struct QueueBreakpoint
+		{
+			class HashFunction
+			{
+			public:
+				size_t operator()(const QueueBreakpoint &key) const;
+			};
+
+			class EqualFunction
+			{
+			public:
+				bool operator()(const QueueBreakpoint &a, const QueueBreakpoint &b) const;
+			};
+
+			QueueBreakpoint(UINT32 _queueIdx, UINT32 _commandIdx)
+				:queueIdx(_queueIdx), commandIdx(_commandIdx)
+			{ }
+
+			UINT32 queueIdx;
+			UINT32 commandIdx;
+
+			inline size_t operator()(const QueueBreakpoint& v) const;
+		};
+
+		UINT32 mMaxDebugIdx;
+		UINT32 mCommandQueueIdx;
+		
+		static UINT32 MaxCommandQueueIdx;
+		static UnorderedSet<QueueBreakpoint, QueueBreakpoint::HashFunction, QueueBreakpoint::EqualFunction> SetBreakpoints;
+		BS_STATIC_MUTEX(CommandQueueBreakpointMutex);
+
+		/** Checks if the specified command has a breakpoint and throw an assert if it does. */
+		static void breakIfNeeded(UINT32 queueIdx, UINT32 commandIdx);
+#endif
+	};
+
+	/**
+	 * @copydoc CommandQueueBase
+	 * 			
+	 * Use SyncPolicy to choose whether you want command queue be synchonized or not. Synchonized command queues may be 
+	 * used across multiple threads and non-synchonized only on one.
+	 */
+	template<class SyncPolicy = CommandQueueNoSync>
+	class CommandQueue : public CommandQueueBase, public SyncPolicy
+	{
+	public:
+		/** @copydoc CommandQueueBase::CommandQueueBase */
+		CommandQueue(BS_THREAD_ID_TYPE threadId)
+			:CommandQueueBase(threadId)
+		{ }
+
+		~CommandQueue() 
+		{ }
+
+		/** @copydoc CommandQueueBase::queueReturn */
+		AsyncOp queueReturn(std::function<void(AsyncOp&)> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
+		{
+#if BS_DEBUG_MODE
+#if BS_THREAD_SUPPORT != 0
+			if(!isValidThread(getThreadId()))
+				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
+#endif
+#endif
+
+			lock();
+			AsyncOp asyncOp = CommandQueueBase::queueReturn(commandCallback, _notifyWhenComplete, _callbackId);
+			unlock();
+
+			return asyncOp;
+		}
+
+		/** @copydoc CommandQueueBase::queue */
+		void queue(std::function<void()> commandCallback, bool _notifyWhenComplete = false, UINT32 _callbackId = 0)
+		{
+#if BS_DEBUG_MODE
+#if BS_THREAD_SUPPORT != 0
+			if(!isValidThread(getThreadId()))
+				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
+#endif
+#endif
+
+			lock();
+			CommandQueueBase::queue(commandCallback, _notifyWhenComplete, _callbackId);
+			unlock();
+		}
+
+		/** @copydoc CommandQueueBase::flush */
+		BansheeEngine::Queue<QueuedCommand>* flush()
+		{
+#if BS_DEBUG_MODE
+#if BS_THREAD_SUPPORT != 0
+			if(!isValidThread(getThreadId()))
+				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
+#endif
+#endif
+
+			lock();
+			BansheeEngine::Queue<QueuedCommand>* commands = CommandQueueBase::flush();
+			unlock();
+
+			return commands;
+		}
+
+		/** @copydoc CommandQueueBase::cancelAll */
+		void cancelAll()
+		{
+#if BS_DEBUG_MODE
+#if BS_THREAD_SUPPORT != 0
+			if(!isValidThread(getThreadId()))
+				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
+#endif
+#endif
+
+			lock();
+			CommandQueueBase::cancelAll();
+			unlock();
+		}
+
+		/** @copydoc CommandQueueBase::isEmpty */
+		bool isEmpty()
+		{
+#if BS_DEBUG_MODE
+#if BS_THREAD_SUPPORT != 0
+			if(!isValidThread(getThreadId()))
+				throwInvalidThreadException("Command queue accessed outside of its creation thread.");
+#endif
+#endif
+
+			lock();
+			bool empty = CommandQueueBase::isEmpty();
+			unlock();
+
+			return empty;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 414 - 342
BansheeCore/Include/BsCommonTypes.h

@@ -1,343 +1,415 @@
-#pragma once
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Factors used when blending new pixels with existing pixels.
-	 */
-    enum BlendFactor
-    {
-		BF_ONE, /**< Use a value of one for all pixel components. */
-		BF_ZERO, /**< Use a value of zero for all pixel components. */
-		BF_DEST_COLOR, /**< Use the existing pixel value. */
-		BF_SOURCE_COLOR, /**< Use the newly generated pixel value. */
-		BF_INV_DEST_COLOR, /**< Use the inverse of the existing value. */
-		BF_INV_SOURCE_COLOR, /**< Use the inverse of the newly generated pixel value. */
-		BF_DEST_ALPHA, /**< Use the existing alpha value. */
-		BF_SOURCE_ALPHA, /**< Use the newly generated alpha value. */
-		BF_INV_DEST_ALPHA, /**< Use the inverse of the existing alpha value. */
-		BF_INV_SOURCE_ALPHA /**< Use the inverse of the newly generated alpha value. */
-    };
-
-	/**
-	 * @brief	Operations that determines how are blending factors combined.
-	 */
-	enum BlendOperation
-	{
-		BO_ADD, /**< Blend factors are added together. */
-		BO_SUBTRACT, /**< Blend factors are subtracted in "srcFactor - dstFactor" order. */
-		BO_REVERSE_SUBTRACT, /**< Blend factors are subtracted in "dstFactor - srcFactor" order. */
-		BO_MIN, /**< Minimum of the two factors is chosen. */
-		BO_MAX /**< Maximum of the two factors is chosen. */
-	};
-
-	/**
-	 * @brief	Comparison functions used for the depth/stencil buffer.
-	 */
-    enum CompareFunction
-    {
-		CMPF_ALWAYS_FAIL, /**< Operation will always fail. */
-		CMPF_ALWAYS_PASS, /**< Operation will always pass. */
-		CMPF_LESS, /**< Operation will pass if the new value is less than existing value. */
-        CMPF_LESS_EQUAL, /**< Operation will pass if the new value is less or equal than existing value. */
-        CMPF_EQUAL, /**< Operation will pass if the new value is equal to the existing value. */
-        CMPF_NOT_EQUAL, /**< Operation will pass if the new value is not equal to the existing value. */
-        CMPF_GREATER_EQUAL, /**< Operation will pass if the new value greater or equal than the existing value. */
-        CMPF_GREATER /**< Operation will pass if the new value greater than the existing value. */
-    };
-
-	/**
-	 * @brief	Types of texture addressing modes that determine what happens when texture
-	 *			coordinates are outside of the valid range.
-	 */
-    enum TextureAddressingMode
-    {
-		TAM_WRAP, /**< Coordinates wrap back to the valid range. */
-		TAM_MIRROR, /**< Coordinates flip every time the size of the valid range is passed. */
-		TAM_CLAMP, /**< Coordinates are clamped within the valid range. */
-		TAM_BORDER /**< Coordinates outside of the valid range will return a separately set border color. */
-    };
-
-	/**
-	 * @brief	Types of available filtering situations.
-	 */
-    enum FilterType
-    {
-		FT_MIN, /**< The filter used when shrinking a texture. */
-        FT_MAG, /**< The filter used when magnifying a texture. */
-        FT_MIP /**< The filter used when filtering between mipmaps. */
-    };
-
-	/**
-	 * @brief	Filtering options for textures.
-	 */
-    enum FilterOptions
-    {
-		FO_NONE = 0, /**< Use no filtering. Only relevant for mipmap filtering. */
-		FO_POINT = 1, /**< Filter using the nearest found pixel. Most basic filtering. */
-		FO_LINEAR = 2, /**< Average a 2x2 pixel area, signifies bilinear filtering for texture, trilinear for mipmaps. */
-		FO_ANISOTROPIC = 3, /**< More advanced filtering that improves quality when viewing textures at a steep angle */
-		FO_USE_COMPARISON = 4 /**< Specifies that the sampled values will be compared against existing sampled data. Should be OR-ed with other filtering options. */
-    };
-
-	/**
-	 * @brief	Types of frame buffers.
-	 */
-	enum FrameBufferType
-	{
-		FBT_COLOR = 0x1,
-		FBT_DEPTH = 0x2,
-		FBT_STENCIL = 0x4
-	};
-
-	/**
-	 * @brief	Types of culling that determine how (and if) hardware discards faces with certain
-	 *			winding order. Winding order can be used for determining front or back facing polygons by
-	 *			checking the order of its vertices from the render perspective.
-	 */
-    enum CullingMode
-    {
-		CULL_NONE = 1, /**< Hardware performs no culling and renders both sides. */
-		CULL_CLOCKWISE = 2, /**< Hardware culls faces that have a clockwise vertex ordering. */
-        CULL_COUNTERCLOCKWISE = 3 /**< Hardware culls faces that have a counter-clockwise vertex ordering. */
-    };
-
-	/**
-	 * @brief	Polygon mode to use when rasterizing.
-	 */
-    enum PolygonMode
-    {
-		PM_WIREFRAME = 1, /**< Render as wireframe showing only polygon outlines. */
-        PM_SOLID = 2 /**< Render as solid showing whole polygons. */
-    };
-
-	/**
-	 * @brief	Types of action that can happen on the stencil buffer.
-	 */
-	enum StencilOperation
-	{
-		SOP_KEEP, /**< Leave the stencil buffer unchanged. */
-		SOP_ZERO, /**< Set the stencil value to zero. */
-		SOP_REPLACE, /**< Replace the stencil value with the reference value. */
-		SOP_INCREMENT, /**< Increase the stencil value by 1, clamping at the maximum value. */
-		SOP_DECREMENT, /**< Decrease the stencil value by 1, clamping at 0. */
-		SOP_INCREMENT_WRAP, /**< Increase the stencil value by 1, wrapping back to 0 when incrementing past the maximum value. */
-		SOP_DECREMENT_WRAP, /**< Decrease the stencil value by 1, wrapping when decrementing 0. */
-		SOP_INVERT /**< Invert the bits of the stencil buffer. */
-	};
-
-	/**
-	* @brief	These values represent a hint to the driver when locking a hardware buffer.
-	*
-	*			GBL_WRITE_ONLY - Allows you to write to the buffer. Can cause a CPU-GPU sync point
-	*			so avoid using it often (i.e. every frame) as that might limit your performance significantly.
-	*			GBL_WRITE_ONLY_DISCARD - Allows you to write to the buffer. Tells the driver to completely discard the contents of the 
-	*			buffer you are writing to. The driver will (most likely) internally allocate another buffer with same specifications 
-	*			(which is fairly fast) and you will avoid CPU-GPU stalls.
-	*			GBL_WRITE_ONLY_NO_OVERWRITE - Allows you to write to the buffer. Guarantees the driver that you will not be updating any part of 
-	*			the buffer that is currently used. This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However 
-	*			it is hard to guarantee when GPU has finished using a buffer.
-	*			GBL_READ_ONLY - Allows you to read from a buffer. Be aware that reading is usually a very slow operation.
-	*			GBL_READ_WRITE - Allows you to both read and write to a buffer. 
-	*/
-	enum GpuLockOptions
-	{
-        GBL_READ_WRITE,
-		GBL_WRITE_ONLY_DISCARD,
-		GBL_READ_ONLY,
-        GBL_WRITE_ONLY_NO_OVERWRITE,
-		GBL_WRITE_ONLY	
-	};
-
-	/**
-	 * @brief	Values that represent hardware buffer usage. These usually determine in what
-	 *			type of memory is buffer placed in, however that depends on rendering API.
-	 * 
-	 *			GBU_STATIC - Signifies that you don't plan on modifying the buffer often (or at all)
-	 *			after creation. Modifying such buffer will involve a larger performance hit.
-	 *			GBU_DYNAMIC - Signifies that you will modify this buffer fairly often.
-	 */
-	enum GpuBufferUsage 
-	{
-        GBU_STATIC = 1,
-		GBU_DYNAMIC = 2
-	};
-
-	/**
-	 * @brief	Types of generic GPU buffers that may be attached to GPU programs.
-	 *
-	 *			GBT_STRUCTURED - Buffer containing an array of structures. Structure parameters
-	 *			can usually be easily accessed from within the GPU program.
-	 *			GBT_RAW - Buffer containing raw bytes. It is up to the user to interpret the data.
-	 *			GBT_INDIRECTARGUMENT - Special type of buffer allowing you to specify arguments for
-	 *			draw operations inside the buffer instead of providing them directly. Useful when you want
-	 *			to control drawing directly from GPU.
-	 *			GBT_APPENDCONSUME - A stack-like buffer that allows you to add or remove elements to/from the buffer
-	 *			from within the GPU program.
-	 */
-	enum GpuBufferType
-	{
-		GBT_STRUCTURED,
-		GBT_RAW,
-		GBT_INDIRECTARGUMENT,
-		GBT_APPENDCONSUME
-	};
-
-	/**
-	 * @brief	Different types of GPU views that control how GPU sees a hardware buffer.
-	 *
-	 *			GVU_DEFAULT - Buffer is seen as a default shader resource, used primarily for reading. (e.g. a texture for sampling)
-	 *			GVU_RENDERTARGET - Buffer is seen as a render target that color pixels will be written to after pixel shader stage.
-	 *			GVU_DEPTHSTENCIL - Buffer is seen as a depth stencil target that depth and stencil information is written to.
-	 *			GVU_RANDOMWRITE - Buffer that allows you to write to any part of it from within a GPU program.
-	 */
-	enum GpuViewUsage
-	{
-		GVU_DEFAULT = 0x01,
-		GVU_RENDERTARGET = 0x02,
-		GVU_DEPTHSTENCIL = 0x04,
-		GVU_RANDOMWRITE = 0x08
-	};
-
-	/**
-	 * @brief	Type of parameter block usages. Signifies how often will parameter blocks be changed.
-	 *
-	 *			GPBU_STATIC - Buffer will be rarely, if ever, updated.
-	 *			GPBU_DYNAMIC - Buffer will be updated often (e.g. every frame).
-	 */
-	enum GpuParamBlockUsage
-	{
-		GPBU_STATIC,
-		GPBU_DYNAMIC
-	};
-
-	/**
-	 * @brief	Type of GPU parameter.
-	 *
-	 *			GPT_DATA - Raw data type like float, Vector3, Color, etc.
-	 *			GPT_OBJECT - Reference to some GPU object like Texture, Sampler, etc.
-	 */
-	enum GpuParamType
-	{
-		GPT_DATA,
-		GPT_OBJECT
-	};
-
-	/**
-	 * @brief	Type of GPU data parameters that can be used as inputs to a GPU program.
-	 */
-	enum GpuParamDataType
-	{
-		GPDT_FLOAT1 = 1,
-		GPDT_FLOAT2 = 2,
-		GPDT_FLOAT3 = 3,
-		GPDT_FLOAT4 = 4,
-		GPDT_MATRIX_2X2 = 11,
-		GPDT_MATRIX_2X3 = 12,
-		GPDT_MATRIX_2X4 = 13,
-		GPDT_MATRIX_3X2 = 14,
-		GPDT_MATRIX_3X3 = 15,
-		GPDT_MATRIX_3X4 = 16,
-		GPDT_MATRIX_4X2 = 17,
-		GPDT_MATRIX_4X3 = 18,
-		GPDT_MATRIX_4X4 = 19,
-		GPDT_INT1 = 20,
-		GPDT_INT2 = 21,
-		GPDT_INT3 = 22,
-		GPDT_INT4 = 23,
-		GPDT_BOOL = 24,
-		GPDT_STRUCT = 25,
-		GPDT_UNKNOWN = 0xffff
-	};
-
-	/**
-	 * @brief	Type of GPU object parameters that can be used as inputs to a GPU program.
-	 */
-	enum GpuParamObjectType
-	{
-		GPOT_SAMPLER1D = 1,
-		GPOT_SAMPLER2D = 2,
-		GPOT_SAMPLER3D = 3,
-		GPOT_SAMPLERCUBE = 4,
-		GPOT_TEXTURE1D = 11,
-		GPOT_TEXTURE2D = 12,
-		GPOT_TEXTURE3D = 13,
-		GPOT_TEXTURECUBE = 14,
-		GPOT_RWTEXTURE1D = 21,
-		GPOT_RWTEXTURE2D = 22,
-		GPOT_RWTEXTURE3D = 23,
-		GPOT_BYTE_BUFFER = 32,
-		GPOT_STRUCTURED_BUFFER = 33,
-		GPOT_RWTYPED_BUFFER = 41,
-		GPOT_RWBYTE_BUFFER = 42,
-		GPOT_RWSTRUCTURED_BUFFER = 43,
-		GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER = 44,
-		GPOT_RWAPPEND_BUFFER = 45,
-		GPOT_RWCONSUME_BUFFER = 46,
-		GPOT_UNKNOWN = 0xffff
-	};
-
-	/**
-	 * @brief	These values represent a hint to the driver when writing
-	 * 			to a GPU buffer.
-	 * 			
-	 *			Normal - Default flag with least restrictions. Can cause a CPU-GPU sync point
-	 *			so avoid using it often (i.e. every frame) as that might limit your performance significantly.
-	 *			Discard - Tells the driver to completely discard the contents of the buffer you are writing
-	 *			to. The driver will (most likely) internally allocate another buffer with same specifications (which is fairly fast)
-	 *			and you will avoid CPU-GPU stalls. 
-	 *			NoOverwrite - Guarantees the driver that you will not be updating any part of the buffer that is currently used.
-	 *			This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However it is hard to
-	 *			guarantee when GPU has finished using a buffer.
-	 */
-	enum class BufferWriteType
-	{
-		Normal,
-		Discard,
-		NoOverwrite
-	};
-
-	/**
-	 * @brief	Suggested queue priority numbers used for sorting objects in
-	 *			the render queue. Objects with higher priority will be renderer sooner.
-	 */
-	enum class QueuePriority
-	{
-		Opaque = 100000,
-		Transparent = 90000,
-		Skybox = 80000,
-		Overlay = 70000
-	};
-
-	/**
-	 * @brief	Type of sorting to perform on an object when added to a render queue.
-	 */
-	enum class QueueSortType
-	{
-		FrontToBack, /**< All objects with the same priority will be rendered front to back based on their center. */
-		BackToFront, /**< All objects with the same priority will be rendered back to front based on their center. */
-		None /**< Objects will not be sorted and will be processed in the order they were added to the queue. */
-	};
-
-	/**
-	 * @brief	Texture addressing mode, per component.
-	 */
-	struct UVWAddressingMode
-	{
-		UVWAddressingMode()
-			:u(TAM_WRAP), v(TAM_WRAP), w(TAM_WRAP)
-		{ }
-
-		TextureAddressingMode u, v, w;
-	};
-
-	/**
-	* @brief Represents a MAC (ethernet) address.
-	*/
-	struct MACAddress
-	{
-		UINT8 value[6];
-	};
-    
-	typedef Map<String, String> NameValuePairList;
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Utility-Core
+	 *  @{
+	 */
+
+	/**	Factors used when blending new pixels with existing pixels. */
+    enum BlendFactor
+    {
+		BF_ONE, /**< Use a value of one for all pixel components. */
+		BF_ZERO, /**< Use a value of zero for all pixel components. */
+		BF_DEST_COLOR, /**< Use the existing pixel value. */
+		BF_SOURCE_COLOR, /**< Use the newly generated pixel value. */
+		BF_INV_DEST_COLOR, /**< Use the inverse of the existing value. */
+		BF_INV_SOURCE_COLOR, /**< Use the inverse of the newly generated pixel value. */
+		BF_DEST_ALPHA, /**< Use the existing alpha value. */
+		BF_SOURCE_ALPHA, /**< Use the newly generated alpha value. */
+		BF_INV_DEST_ALPHA, /**< Use the inverse of the existing alpha value. */
+		BF_INV_SOURCE_ALPHA /**< Use the inverse of the newly generated alpha value. */
+    };
+
+	/**	Operations that determines how are blending factors combined. */
+	enum BlendOperation
+	{
+		BO_ADD, /**< Blend factors are added together. */
+		BO_SUBTRACT, /**< Blend factors are subtracted in "srcFactor - dstFactor" order. */
+		BO_REVERSE_SUBTRACT, /**< Blend factors are subtracted in "dstFactor - srcFactor" order. */
+		BO_MIN, /**< Minimum of the two factors is chosen. */
+		BO_MAX /**< Maximum of the two factors is chosen. */
+	};
+
+	/**	Comparison functions used for the depth/stencil buffer. */
+    enum CompareFunction
+    {
+		CMPF_ALWAYS_FAIL, /**< Operation will always fail. */
+		CMPF_ALWAYS_PASS, /**< Operation will always pass. */
+		CMPF_LESS, /**< Operation will pass if the new value is less than existing value. */
+        CMPF_LESS_EQUAL, /**< Operation will pass if the new value is less or equal than existing value. */
+        CMPF_EQUAL, /**< Operation will pass if the new value is equal to the existing value. */
+        CMPF_NOT_EQUAL, /**< Operation will pass if the new value is not equal to the existing value. */
+        CMPF_GREATER_EQUAL, /**< Operation will pass if the new value greater or equal than the existing value. */
+        CMPF_GREATER /**< Operation will pass if the new value greater than the existing value. */
+    };
+
+	/**
+	 * Types of texture addressing modes that determine what happens when texture coordinates are outside of the valid range.
+	 */
+    enum TextureAddressingMode
+    {
+		TAM_WRAP, /**< Coordinates wrap back to the valid range. */
+		TAM_MIRROR, /**< Coordinates flip every time the size of the valid range is passed. */
+		TAM_CLAMP, /**< Coordinates are clamped within the valid range. */
+		TAM_BORDER /**< Coordinates outside of the valid range will return a separately set border color. */
+    };
+
+	/**	Types of available filtering situations. */
+    enum FilterType
+    {
+		FT_MIN, /**< The filter used when shrinking a texture. */
+        FT_MAG, /**< The filter used when magnifying a texture. */
+        FT_MIP /**< The filter used when filtering between mipmaps. */
+    };
+
+	/**	Filtering options for textures. */
+    enum FilterOptions
+    {
+		FO_NONE = 0, /**< Use no filtering. Only relevant for mipmap filtering. */
+		FO_POINT = 1, /**< Filter using the nearest found pixel. Most basic filtering. */
+		FO_LINEAR = 2, /**< Average a 2x2 pixel area, signifies bilinear filtering for texture, trilinear for mipmaps. */
+		FO_ANISOTROPIC = 3, /**< More advanced filtering that improves quality when viewing textures at a steep angle */
+		FO_USE_COMPARISON = 4 /**< Specifies that the sampled values will be compared against existing sampled data. Should be OR-ed with other filtering options. */
+    };
+
+	/**	Types of frame buffers. */
+	enum FrameBufferType
+	{
+		FBT_COLOR = 0x1,
+		FBT_DEPTH = 0x2,
+		FBT_STENCIL = 0x4
+	};
+
+	/**
+	 * Types of culling that determine how (and if) hardware discards faces with certain winding order. Winding order can
+	 * be used for determining front or back facing polygons by checking the order of its vertices from the render 
+	 * perspective.
+	 */
+    enum CullingMode
+    {
+		CULL_NONE = 0, /**< Hardware performs no culling and renders both sides. */
+		CULL_CLOCKWISE = 1, /**< Hardware culls faces that have a clockwise vertex ordering. */
+        CULL_COUNTERCLOCKWISE = 2 /**< Hardware culls faces that have a counter-clockwise vertex ordering. */
+    };
+
+	/**	Polygon mode to use when rasterizing. */
+    enum PolygonMode
+    {
+		PM_WIREFRAME = 1, /**< Render as wireframe showing only polygon outlines. */
+        PM_SOLID = 2 /**< Render as solid showing whole polygons. */
+    };
+
+	/**	Types of action that can happen on the stencil buffer. */
+	enum StencilOperation
+	{
+		SOP_KEEP, /**< Leave the stencil buffer unchanged. */
+		SOP_ZERO, /**< Set the stencil value to zero. */
+		SOP_REPLACE, /**< Replace the stencil value with the reference value. */
+		SOP_INCREMENT, /**< Increase the stencil value by 1, clamping at the maximum value. */
+		SOP_DECREMENT, /**< Decrease the stencil value by 1, clamping at 0. */
+		SOP_INCREMENT_WRAP, /**< Increase the stencil value by 1, wrapping back to 0 when incrementing past the maximum value. */
+		SOP_DECREMENT_WRAP, /**< Decrease the stencil value by 1, wrapping when decrementing 0. */
+		SOP_INVERT /**< Invert the bits of the stencil buffer. */
+	};
+
+	/** These values represent a hint to the driver when locking a hardware buffer. */
+	enum GpuLockOptions
+	{
+		/**
+		 * Allows you to write to the buffer. Can cause a CPU-GPU sync point so avoid using it often (i.e. every frame) as 
+		 * that might limit your performance significantly.
+		 */
+        GBL_READ_WRITE,
+		/**
+		 * Allows you to write to the buffer. Tells the driver to completely discard the contents of the buffer you are 
+		 * writing to. The driver will (most likely) internally allocate another buffer with same specifications (which is
+		 * fairly fast) and you will avoid CPU-GPU stalls.
+		 */
+		GBL_WRITE_ONLY_DISCARD,
+		/**  Allows you to read from a buffer. Be aware that reading is usually a very slow operation. */
+		GBL_READ_ONLY,
+		/**
+		 * Allows you to write to the buffer. Guarantees the driver that you will not be updating any part of the buffer 
+		 * that is currently used. This will also avoid CPU-GPU stalls, without requiring you to discard the entire buffer.
+		 * However it is hard to guarantee when GPU has finished using a buffer.
+		 */
+        GBL_WRITE_ONLY_NO_OVERWRITE,
+		/** Allows you to both read and write to a buffer. */
+		GBL_WRITE_ONLY	
+	};
+
+	/**
+	 * Values that represent hardware buffer usage. These usually determine in what type of memory is buffer placed in,
+	 * however that depends on rendering API.
+	 */
+	enum GpuBufferUsage 
+	{
+		/** 
+		 * Signifies that you don't plan on modifying the buffer often (or at all)	after creation. Modifying such buffer 
+		 * will involve a larger performance hit.
+		 */
+        GBU_STATIC = 1,
+		/** Signifies that you will modify this buffer fairly often. */
+		GBU_DYNAMIC = 2
+	};
+
+	/** Types of generic GPU buffers that may be attached to GPU programs. */
+	enum GpuBufferType
+	{
+		/** 
+		 * Buffer containing an array of structures. Structure parameters can usually be easily accessed from within the
+		 * GPU program.
+		 */
+		GBT_STRUCTURED,
+		/** Buffer containing raw bytes. It is up to the user to interpret the data. */
+		GBT_RAW,
+		/**
+		 * Special type of buffer allowing you to specify arguments for draw operations inside the buffer instead of 
+		 * providing them directly. Useful when you want to control drawing directly from GPU.
+		 */
+		GBT_INDIRECTARGUMENT,
+		/** A stack-like buffer that allows you to add or remove elements to/from the buffer from within the GPU program. */
+		GBT_APPENDCONSUME
+	};
+
+	/** Different types of GPU views that control how GPU sees a hardware buffer. */
+	enum GpuViewUsage
+	{
+		/** Buffer is seen as a default shader resource, used primarily for reading. (e.g. a texture for sampling) */
+		GVU_DEFAULT = 0x01,
+		/** Buffer is seen as a render target that color pixels will be written to after pixel shader stage. */
+		GVU_RENDERTARGET = 0x02,
+		/** Buffer is seen as a depth stencil target that depth and stencil information is written to. */
+		GVU_DEPTHSTENCIL = 0x04,
+		/** Buffer that allows you to write to any part of it from within a GPU program. */
+		GVU_RANDOMWRITE = 0x08
+	};
+
+	/** Type of parameter block usages. Signifies how often will parameter blocks be changed. */
+	enum GpuParamBlockUsage
+	{
+		GPBU_STATIC, /**< Buffer will be rarely, if ever, updated. */
+		GPBU_DYNAMIC /**< Buffer will be updated often (e.g. every frame). */
+	};
+
+	/** Type of a parameter in a GPU program. */
+	enum GpuParamType
+	{
+		GPT_DATA, /**< Raw data type like float, Vector3, Color, etc. */
+		GPT_TEXTURE, /**< Texture type (2D, 3D, cube, etc.) */
+		GPT_BUFFER, /**< Data buffer (raw, structured, etc.) */
+		GPT_SAMPLER /**< Sampler type (2D, 3D, cube, etc.) */
+	};
+
+	/**	Type of GPU data parameters that can be used as inputs to a GPU program. */
+	enum GpuParamDataType
+	{
+		GPDT_FLOAT1 = 1,
+		GPDT_FLOAT2 = 2,
+		GPDT_FLOAT3 = 3,
+		GPDT_FLOAT4 = 4,
+		GPDT_MATRIX_2X2 = 11,
+		GPDT_MATRIX_2X3 = 12,
+		GPDT_MATRIX_2X4 = 13,
+		GPDT_MATRIX_3X2 = 14,
+		GPDT_MATRIX_3X3 = 15,
+		GPDT_MATRIX_3X4 = 16,
+		GPDT_MATRIX_4X2 = 17,
+		GPDT_MATRIX_4X3 = 18,
+		GPDT_MATRIX_4X4 = 19,
+		GPDT_INT1 = 20,
+		GPDT_INT2 = 21,
+		GPDT_INT3 = 22,
+		GPDT_INT4 = 23,
+		GPDT_BOOL = 24,
+		GPDT_STRUCT = 25,
+		GPDT_COLOR = 26, // Same as GPDT_FLOAT4, but can be used to better deduce usage
+		GPDT_COUNT = 27, // Keep at end before GPDT_UNKNOWN
+		GPDT_UNKNOWN = 0xffff
+	};
+
+	/**	Contains data about a type used for GPU data parameters. */
+	struct GpuParamDataTypeInfo
+	{
+		UINT32 baseTypeSize;
+		UINT32 size;
+		UINT32 alignment;
+		UINT32 numRows;
+		UINT32 numColumns;
+	};
+
+	/**	Contains a lookup table for various information of all types used for data GPU parameters. Sizes are in bytes. */
+	struct GpuDataParamInfos
+	{
+		GpuDataParamInfos()
+		{
+			memset(lookup, 0, sizeof(lookup));
+
+			lookup[(UINT32)GPDT_FLOAT1] = { 4, 4, 4, 1, 1 };
+			lookup[(UINT32)GPDT_FLOAT2] = { 4, 8, 8, 1, 2 };
+			lookup[(UINT32)GPDT_FLOAT3] = { 4, 16, 16, 1, 3 };
+			lookup[(UINT32)GPDT_FLOAT4] = { 4, 16, 16, 1, 4 };
+			lookup[(UINT32)GPDT_MATRIX_2X2] = { 4, 16, 8, 2, 2 };
+			lookup[(UINT32)GPDT_MATRIX_2X3] = { 4, 32, 16, 2, 3 };
+			lookup[(UINT32)GPDT_MATRIX_2X4] = { 4, 32, 16, 2, 4 };
+			lookup[(UINT32)GPDT_MATRIX_3X2] = { 4, 24, 8, 3, 2 };
+			lookup[(UINT32)GPDT_MATRIX_3X3] = { 4, 48, 16, 3, 3 };
+			lookup[(UINT32)GPDT_MATRIX_3X4] = { 4, 48, 16, 3, 4 };
+			lookup[(UINT32)GPDT_MATRIX_4X2] = { 4, 32, 8, 4, 2 };
+			lookup[(UINT32)GPDT_MATRIX_4X3] = { 4, 64, 16, 4, 3 };
+			lookup[(UINT32)GPDT_MATRIX_4X4] = { 4, 64, 16, 4, 4 };
+			lookup[(UINT32)GPDT_INT1] = { 4, 4, 4, 1, 1 };
+			lookup[(UINT32)GPDT_INT2] = { 4, 8, 8, 1, 2 };
+			lookup[(UINT32)GPDT_INT3] = { 4, 12, 16, 1, 3 };
+			lookup[(UINT32)GPDT_INT4] = { 4, 16, 16, 1, 4 };
+			lookup[(UINT32)GPDT_BOOL] = { 4, 4, 4, 1, 1 };
+		}
+
+		GpuParamDataTypeInfo lookup[GPDT_COUNT];
+	};
+
+	/**	Type of GPU object parameters that can be used as inputs to a GPU program. */
+	enum GpuParamObjectType
+	{
+		GPOT_SAMPLER1D = 1,
+		GPOT_SAMPLER2D = 2,
+		GPOT_SAMPLER3D = 3,
+		GPOT_SAMPLERCUBE = 4,
+		GPOT_SAMPLER2DMS = 5,
+		GPOT_TEXTURE1D = 11,
+		GPOT_TEXTURE2D = 12,
+		GPOT_TEXTURE3D = 13,
+		GPOT_TEXTURECUBE = 14,
+		GPOT_TEXTURE2DMS = 15,
+		GPOT_BYTE_BUFFER = 32,
+		GPOT_STRUCTURED_BUFFER = 33,
+		GPOT_RWTYPED_BUFFER = 41,
+		GPOT_RWBYTE_BUFFER = 42,
+		GPOT_RWSTRUCTURED_BUFFER = 43,
+		GPOT_RWSTRUCTURED_BUFFER_WITH_COUNTER = 44,
+		GPOT_RWAPPEND_BUFFER = 45,
+		GPOT_RWCONSUME_BUFFER = 46,
+		GPOT_UNKNOWN = 0xffff
+	};
+
+	/** These values represent a hint to the driver when writing to a GPU buffer. */
+	enum class BufferWriteType
+	{
+		/**
+		 * Default flag with least restrictions. Can cause a CPU-GPU sync point so avoid using it often (i.e. every frame)
+		 * as that might limit your performance significantly.
+		 */
+		Normal,
+		/**
+		 * Tells the driver to completely discard the contents of the buffer you are writing to. The driver will (most
+		 * likely) internally allocate another buffer with same specifications (which is fairly fast) and you will avoid 
+		 * CPU-GPU stalls. 
+		 */
+		Discard,
+		/**
+		 * Guarantees the driver that you will not be updating any part of the buffer that is currently used. This will 
+		 * also avoid CPU-GPU stalls, without requiring you to discard the entire buffer. However it is hard to guarantee 
+		 * when GPU has finished using a buffer.
+		 */
+		NoOverwrite
+	};
+
+	/**
+	 * Suggested queue priority numbers used for sorting objects in the render queue. Objects with higher priority will
+	 * be renderer sooner.
+	 */
+	enum class QueuePriority
+	{
+		Opaque = 100000,
+		Transparent = 90000,
+		Skybox = 80000,
+		Overlay = 70000
+	};
+
+	/** Type of sorting to perform on an object when added to a render queue. */
+	enum class QueueSortType
+	{
+		FrontToBack, /**< All objects with the same priority will be rendered front to back based on their center. */
+		BackToFront, /**< All objects with the same priority will be rendered back to front based on their center. */
+		None /**< Objects will not be sorted and will be processed in the order they were added to the queue. */
+	};
+
+	/**	Flags that may be assigned to a shader that let the renderer know how to interpret the shader. */
+	enum class ShaderFlags
+	{
+		Transparent = 0x1 /**< Signifies that the shader is rendering a transparent object. */
+	};
+
+	/**	Texture addressing mode, per component. */
+	struct UVWAddressingMode
+	{
+		UVWAddressingMode()
+			:u(TAM_WRAP), v(TAM_WRAP), w(TAM_WRAP)
+		{ }
+
+		bool operator==(const UVWAddressingMode& rhs) const
+		{
+			return u == rhs.u && v == rhs.v && w == rhs.w;
+		}
+
+		TextureAddressingMode u, v, w;
+	};
+    
+	/**	References a subset of surfaces within a texture. */
+	struct TextureSurface
+	{
+		TextureSurface(UINT32 mipLevel = 0, UINT32 numMipLevels = 1, 
+			UINT32 arraySlice = 0, UINT32 numArraySlices = 1)
+			:mipLevel(mipLevel), numMipLevels(numMipLevels), 
+			arraySlice(arraySlice), numArraySlices(numArraySlices)
+		{ }
+
+		UINT32 mipLevel;
+		UINT32 numMipLevels;
+		UINT32 arraySlice;
+		UINT32 numArraySlices;
+	};
+
+	/** Helper class for syncing dirty data from sim CoreObject to core CoreObject and other way around. */
+	class CoreSyncData
+	{
+	public:
+		CoreSyncData()
+			:data(nullptr), size(0)
+		{ }
+
+		CoreSyncData(UINT8* data, UINT32 size)
+			:data(data), size(size)
+		{ }
+
+		/** Gets the internal data and checks the data is of valid size. */
+		template<class T>
+		const T& getData() const
+		{
+			assert(sizeof(T) == size);
+
+			return *(T*)data;
+		}
+
+		/**	Returns a pointer to internal data buffer. */
+		UINT8* getBuffer() const { return data; }
+
+		/**	Returns the size of the internal data buffer. */
+		UINT32 getBufferSize() const { return size; }
+
+	private:
+		UINT8* data;
+		UINT32 size;
+	};
+
+	typedef Map<String, String> NameValuePairList;
+
+	/** @cond SPECIALIZATIONS */
+	BS_ALLOW_MEMCPY_SERIALIZATION(TextureSurface);
+	/** @endcond */
+
+	/** @} */
 }

+ 111 - 65
BansheeCore/Include/BsComponent.h

@@ -1,66 +1,112 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsGameObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Components represent primarily logic elements in the scene. 
-	 *			They are attached to scene objects.
-	 */
-	class BS_CORE_EXPORT Component : public GameObject
-	{
-	public:
-		/**
-		 * @brief	Returns the SceneObject this Component is assigned to.
-		 */
-		HSceneObject sceneObject() const { return mParent; }
-
-		/**
-		 * @copydoc	sceneObject
-		 */
-		HSceneObject SO() const { return sceneObject(); }
-
-		/**
-		 * @brief	Called once per frame on all components.
-		 * 			
-		 * @note	Internal method.
-		 */
-		virtual void update() { }
-
-		/**
-		 * @brief	Removes the component from parent SceneObject and deletes it. All
-		 * 			the references to this component will be marked as destroyed and you
-		 * 			will get an exception if you try to use them.
-		 */
-		void destroy();
-
-	protected:
-		friend class SceneObject;
-
-		Component(const HSceneObject& parent);
-		virtual ~Component();
-
-		/**
-		 * @brief	Called just before the component is destroyed.
-		 */
-		virtual void onDestroyed() {}
-	private:
-		Component(const Component& other) { }
-
-	protected:
-		HSceneObject mParent;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-	public:
-		friend class ComponentRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-
-	protected:
-		Component() {} // Serialization only
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGameObject.h"
+#include "BsBounds.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/** Components represent primary logic elements in the scene. They are attached to scene objects. */
+	class BS_CORE_EXPORT Component : public GameObject
+	{
+	public:
+		/**	Returns the SceneObject this Component is assigned to. */
+		HSceneObject sceneObject() const { return mParent; }
+
+		/** @copydoc sceneObject */
+		HSceneObject SO() const { return sceneObject(); }
+
+		/**
+		 * Called once per frame on all components.
+		 * 			
+		 * @note	Internal method.
+		 */
+		virtual void update() { }
+
+		/**
+		 * Calculates bounds of the visible contents represented by this component (e.g. a mesh for Renderable).
+		 * 
+		 * @param[in]	bounds	Bounds of the contents in world space coordinates.	
+		 * @return				True if the component has bounds with non-zero volume, otherwise false.
+		 */
+		virtual bool calculateBounds(Bounds& bounds);
+
+		/**
+		 * Checks if this and the provided component represent the same type.
+		 * 			
+		 * @note	
+		 * RTTI type cannot be checked directly since components can be further specialized internally for scripting 
+		 * purposes.
+		 */
+		virtual bool typeEquals(const Component& other);
+
+		/**
+		 * Removes the component from parent SceneObject and deletes it. All the references to this component will be 
+		 * marked as destroyed and you will get an exception if you try to use them.
+		 *
+		 * @param[in]	immediate	If true the destruction will be performed immediately, otherwise it will be delayed 
+		 *							until the end of the current frame (preferred option).
+		 */
+		void destroy(bool immediate = false);
+
+	protected:
+		friend class SceneObject;
+		friend class SceneObjectRTTI;
+
+		Component(const HSceneObject& parent);
+		virtual ~Component();
+
+		/**
+		 * Construct any resources the component needs before use. Called when the parent scene object is instantiated. 
+		 * A non-instantiated component shouldn't be used for any other purpose than serialization.
+		 */
+		virtual void instantiate() {}
+
+		/**	Called when the component is ready to be initialized. */
+		virtual void onInitialized() {}
+
+		/**	Called just before the component is destroyed. */
+		virtual void onDestroyed() {}
+
+		/**	Called just before the component is deactivated or destroyed. */
+		virtual void onDisabled() {}
+
+		/**	Called when the component is activated or created. */
+		virtual void onEnabled() {}
+
+		/**
+		 * Destroys this component.
+		 *
+		 * @param[in]	handle		Game object handle this this object.
+		 * @param[in]	immediate	If true, the object will be deallocated and become unusable right away. Otherwise the 
+		 *							deallocation will be delayed to the end of frame (preferred method).
+		 *
+		 * @note	Unlike destroy(), does not remove the component from its parent.
+		 */
+		void destroyInternal(GameObjectHandleBase& handle, bool immediate = false) override;
+	private:
+		Component(const Component& other) { }
+
+	protected:
+		HSceneObject mParent;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class ComponentRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		Component() {} // Serialization only
+	};
+
+	/** @} */
 }

+ 60 - 34
BansheeCore/Include/BsComponentRTTI.h

@@ -1,35 +1,61 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsComponent.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT ComponentRTTI : public RTTIType<Component, GameObject, ComponentRTTI>
-	{
-	private:
-
-	public:
-		ComponentRTTI()
-		{
-
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "Component";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_Component;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsComponent.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT ComponentRTTI : public RTTIType<Component, GameObject, ComponentRTTI>
+	{
+	public:
+		ComponentRTTI()
+		{ }
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			Component* comp = static_cast<Component*>(obj);
+			GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(comp->mRTTIData);
+
+			// This shouldn't be null during normal deserialization but could be during some other operations, like applying
+			// a binary diff.
+			if (deserializationData.ptr != nullptr)
+			{
+				// Register the newly created SO with the GameObjectManager and provide it with the original ID so that
+				// deserialized handles pointing to this object can be resolved.
+				ComponentPtr compPtr = std::static_pointer_cast<Component>(deserializationData.ptr);
+
+				GameObjectManager::instance().registerObject(compPtr, deserializationData.originalId);
+			}
+			
+			comp->mRTTIData = nullptr;
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "Component";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_Component;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 138 - 113
BansheeCore/Include/BsCoreApplication.h

@@ -1,114 +1,139 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsCoreThreadAccessor.h"
-#include "BsRenderWindow.h"
-#include "BsEvent.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Structure containing parameters for starting the application.
-	 */
-	struct START_UP_DESC
-	{
-		String renderSystem; /**< Name of the render system plugin to use. */
-		String renderer; /**< Name of the renderer plugin to use. */
-
-		String input; /**< Name of the input plugin to use. */
-		String sceneManager; /**< Name of the scene manager plugin to use. */
-
-		RENDER_WINDOW_DESC primaryWindowDesc; /**< Describes the window to create during start-up. */
-
-		Vector<String> importers; /**< A list of importer plugins to load. */
-	};
-
-	/**
-	 * @brief	Represents the primary entry point for the core systems. Handles
-	 *			start-up, shutdown, primary loop and allows you to load and unload
-	 *			plugins.
-	 *
-	 * @note	Sim thread only.
-	 */
-	class BS_CORE_EXPORT CoreApplication : public Module<CoreApplication>
-	{
-		public:
-			CoreApplication(START_UP_DESC& desc);
-			virtual ~CoreApplication();
-
-			/**
-			 * @brief	Executes the main loop. This will update your components and modules, queue objects 
-			 *			for rendering and run the simulation. Usually called immediately after startUp().
-			 * 			
-			 *			This will run infinitely until stopMainLoop is called (usually from another thread or internally).
-			 */
-			void runMainLoop();
-
-			/**
-			 * @brief	Stops a (infinite) main loop from running. The loop will complete its current cycle before stopping.
-			 */
-			void stopMainLoop();
-
-			/**
-			 * @brief	
-			 */
-			RenderWindowPtr getPrimaryWindow() const { return mPrimaryWindow; }
-
-			/**
-			 * @brief	Loads a plugin.
-			 *
-			 * @param	pluginName		Name of the plugin to load, without extension.
-			 * @param	[out] library	Specify as not null to receive a reference to 
-			 *							the loaded library.
-			 * @param	passThrough		Optional parameter that will be passed to the loadPlugin function.
-			 * 
-			 * @returns	Value returned from the plugin start-up method.
-			 */
-			void* loadPlugin(const String& pluginName, DynLib** library = nullptr, void* passThrough = nullptr);
-
-			/**
-			 * @brief	Unloads a previously loaded plugin. 
-			 */
-			void unloadPlugin(DynLib* library);
-
-	protected:
-		/**
-		 * @brief	Called for each iteration of the main loop.
-		 */
-		virtual void update();
-
-	private:
-		/**
-		 * @brief	Called when the frame finishes rendering.
-		 */
-		void frameRenderingFinishedCallback();
-
-		/**
-		 * @brief	Called by the core thread to begin profiling.
-		 */
-		void beginCoreProfiling();
-
-		/**
-		 * @brief	Called by the core thread to end profiling.
-		 */
-		void endCoreProfiling();
-
-	private:
-		RenderWindowPtr mPrimaryWindow;
-
-		DynLib* mSceneManagerPlugin;
-		DynLib* mRendererPlugin;
-
-		bool mIsFrameRenderingFinished;
-		BS_MUTEX(mFrameRenderingFinishedMutex);
-		BS_THREAD_SYNCHRONISER(mFrameRenderingFinishedCondition);
-
-		volatile bool mRunMainLoop;
-	};
-
-	/**
-	 * @brief	Provides easy access to primary entry point for the engine.
-	 */
-	BS_CORE_EXPORT CoreApplication& gCoreApplication();
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsCoreThreadAccessor.h"
+#include "BsRenderWindow.h"
+#include "BsEvent.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Application-Core
+	 *  @{
+	 */
+
+	/**	Structure containing parameters for starting the application. */
+	struct START_UP_DESC
+	{
+		String renderAPI; /**< Name of the render system plugin to use. */
+		String renderer; /**< Name of the renderer plugin to use. */
+
+		String input; /**< Name of the input plugin to use. */
+
+		RENDER_WINDOW_DESC primaryWindowDesc; /**< Describes the window to create during start-up. */
+
+		Vector<String> importers; /**< A list of importer plugins to load. */
+	};
+
+	/**
+	 * Represents the primary entry point for the core systems. Handles start-up, shutdown, primary loop and allows you to
+	 * load and unload plugins.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT CoreApplication : public Module<CoreApplication>
+	{
+		public:
+			CoreApplication(START_UP_DESC desc);
+			virtual ~CoreApplication();
+
+			/**
+			 * Executes the main loop. This will update your components and modules, queue objects for rendering and run 
+			 * the simulation. Usually called immediately after startUp().
+			 * 			
+			 * This will run infinitely until stopMainLoop is called (usually from another thread or internally).
+			 */
+			void runMainLoop();
+
+			/**	Stops a (infinite) main loop from running. The loop will complete its current cycle before stopping. */
+			void stopMainLoop();
+
+			/** Changes the maximum FPS the application is allowed to run in. Zero means unlimited. */
+			void setFPSLimit(UINT32 limit);
+
+			/**
+			 * Issues a request for the application to close. Application may choose to ignore the request depending on the
+			 * circumstances and the implementation.
+			 */
+			virtual void quitRequested();
+
+			/**	Returns the main window that was created on application start-up. */
+			RenderWindowPtr getPrimaryWindow() const { return mPrimaryWindow; }
+
+			/**
+			 * Returns the id of the simulation thread.
+			 *
+			 * @note	Thread safe.
+			 */
+			BS_THREAD_ID_TYPE getSimThreadId() { return mSimThreadId; }
+
+			/**	Returns true if the application is running in an editor, false if standalone. */
+			virtual bool isEditor() const { return false; }
+
+			/**
+			 * Loads a plugin.
+			 *
+			 * @param[in]	pluginName	Name of the plugin to load, without extension.
+			 * @param[out]	library		Specify as not null to receive a reference to the loaded library.
+			 * @param[in]	passThrough	Optional parameter that will be passed to the loadPlugin function.
+			 * @return					Value returned from the plugin start-up method.
+			 */
+			void* loadPlugin(const String& pluginName, DynLib** library = nullptr, void* passThrough = nullptr);
+
+			/**	Unloads a previously loaded plugin. */
+			void unloadPlugin(DynLib* library);
+
+	protected:
+		/** @copydoc Module::onStartUp */
+		virtual void onStartUp() override;
+
+		/**	Called for each iteration of the main loop. Called before any game objects or plugins are updated. */
+		virtual void preUpdate();
+
+		/**	Called for each iteration of the main loop. Called after all game objects and plugins are updated. */
+		virtual void postUpdate();
+
+		/**	Initializes the renderer specified during construction. Called during initialization. */
+		virtual void startUpRenderer();
+
+		/**	Returns a handler that is used for resolving shader include file paths. */
+		virtual ShaderIncludeHandlerPtr getShaderIncludeHandler() const;
+
+	private:
+		/**	Called when the frame finishes rendering. */
+		void frameRenderingFinishedCallback();
+
+		/**	Called by the core thread to begin profiling. */
+		void beginCoreProfiling();
+
+		/**	Called by the core thread to end profiling. */
+		void endCoreProfiling();
+
+	private:
+		typedef void(*UpdatePluginFunc)();
+
+		RenderWindowPtr mPrimaryWindow;
+		START_UP_DESC mStartUpDesc;
+
+		UINT64 mFrameStep; // Microseconds
+		UINT64 mLastFrameTime; // Microseconds
+
+		DynLib* mRendererPlugin;
+
+		Map<DynLib*, UpdatePluginFunc> mPluginUpdateFunctions;
+
+		bool mIsFrameRenderingFinished;
+		BS_MUTEX(mFrameRenderingFinishedMutex);
+		BS_THREAD_SYNCHRONISER(mFrameRenderingFinishedCondition);
+		BS_THREAD_ID_TYPE mSimThreadId;
+
+		volatile bool mRunMainLoop;
+	};
+
+	/**	Provides easy access to CoreApplication. */
+	BS_CORE_EXPORT CoreApplication& gCoreApplication();
+
+	/** @} */
 }

+ 296 - 266
BansheeCore/Include/BsCoreObject.h

@@ -1,266 +1,296 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsAsyncOp.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	This class provides some common functionality that all low-level objects
-	 * 			used on the core thread need to implement.
-	 * 			
-	 * @note	This involves initializing, keeping track of, and releasing GPU resources.
-	 * 			All core GPU objects are initialized on the core thread, and destroyed on the core thread,
-	 * 			so majority of these methods will just schedule object initialization/destruction.
-	 * 			Non-GPU core objects can normally be initialized on the caller thread.
-	 */
-	class BS_CORE_EXPORT CoreObject
-	{
-	protected:
-		/**
-		 * @brief	Values that represent current state of the object
-		 */
-		enum Flags
-		{
-			CGO_INITIALIZED = 0x01, /**< Object has been fully initialized and may be used. */
-			CGO_INIT_ON_CORE_THREAD = 0x02, /**< Object requires initialization on core thread. */
-			CGO_SCHEDULED_FOR_INIT = 0x04, /**< Object has been scheduled for initialization but core thread has not completed it yet. */
-			CGO_SCHEDULED_FOR_DELETE = 0x08 /**< Object has been scheduled for deletion but core thread has not completed it yet. */
-		};
-
-	public:
-		/**
-		 * @brief	Constructs a new core object.
-		 *
-		 * @param	requiresGpuInit	(optional) If true the objects initialize_internal and destroy_internal methods
-		 * 							will be called from the core thread asynchronously. Otherwise they will be called 
-		 * 							by the caller thread synchronously.
-		 */
-		CoreObject(bool requiresGpuInit = true);
-		virtual ~CoreObject();
-
-		/**
-		 * @brief	Destroys all GPU resources of this object.
-		 * 			
-		 * @note	If is created with "CGO_INIT_ON_CORE_THREAD" flag destruction is not done immediately, 
-		 * 			and is instead just scheduled on the core thread. 
-		 * 			Unless called from core thread in which case it is executed immediately.
-		 * 			Objects without "CGO_INIT_ON_CORE_THREAD" flag are destructed immediately.
-		 */
-		virtual void destroy();
-
-		/**
-		 * @brief	Initializes all the internal resources of this object. Should be called by the
-		 * 			factory creation methods automatically after construction and not by user directly.
-		 * 					
-		 * @note	If is created with "CGO_INIT_ON_CORE_THREAD" flag initialization is not done immediately, 
-		 * 			and is instead just scheduled on the core thread. 
-		 * 			Unless called from core thread in which case it is executed immediately.
-		 * 			Objects without "CGO_INIT_ON_CORE_THREAD" flag are initialized immediately.
-		 */
-		virtual void initialize();
-
-		/**
-		 * @brief	Returns true if the object has been properly initialized. You are not
-		 * 			allowed to call any methods on the resource until you are sure resource is initialized.
-		 * 			
-		 * @note	Normally CPU objects are initialized on creation and this will never be false, and GPU
-		 * 			objects are initialized when the core thread processes them.
-		 */
-		bool isInitialized() const { return (mFlags & CGO_INITIALIZED) != 0; }
-
-		/**
-		 * @brief	Blocks the current thread until the resource is fully initialized.
-		 * 			
-		 * @note	If you call this without calling initialize first a deadlock will occur.
-		 * 			You should not call this from core thread.
-		 */
-		void synchronize();
-
-		/**
-		 * @brief	Internal method. Sets a shared this pointer to this object. This MUST be called immediately after construction.
-		 *
-		 * @note	Called automatically by the factory creation methods so user should not call this manually.
-		 */
-		void _setThisPtr(std::shared_ptr<CoreObject> ptrThis);
-
-		/**
-		 * @brief	Returns an unique identifier for this object.
-		 */
-		UINT64 getInternalID() const { return mInternalID; }
-
-		/**
-		 * @brief	Internal method. Schedules the object to be destroyed, and then deleted.
-		 */
-		template<class T, class MemAlloc>
-		static void _deleteDelayed(CoreObject* obj)
-		{
-			_deleteDelayedInternal(obj);
-
-			if(obj->isInitialized())
-			{
-				std::shared_ptr<CoreObject> thisPtr(obj);
-				obj->_setThisPtr(thisPtr);
-				obj->destroy();
-			}
-			else
-			{
-				bs_delete<MemAlloc, T>((T*)obj);
-			}
-		}
-
-		/**
-		 * @brief	Returns a shared_ptr version of "this" pointer.
-		 */
-		std::shared_ptr<CoreObject> getThisPtr() const { return mThis.lock(); }
-
-	protected:
-		/**
-		 * @brief	Frees all of the objects dynamically allocated memory. All derived classes that have something to free
-		 * 			should do it here instead of their destructor. All derived classes need to call this base method when they're done.
-		 * 			
-		 * @note	For objects with "CGO_INIT_ON_CORE_THREAD" flag this is scheduled to be executed on the core thread, 
-		 * 			so normally you want to destroy all GPU specific resources here.
-		 */
-		virtual void destroy_internal();
-
-		/**
-		 * @brief	Initializes all the internal resources of this object. Needs to be called before doing
-		 * 			any operations with the object. All derived classes also need to call this base method.
-		 * 			
-		 * @note	For objects with "CGO_INIT_ON_CORE_THREAD" flag this is scheduled to be executed on the core thread, 
-		 * 			so normally you want to initialize all GPU specific resources here.
-		 */
-		virtual void initialize_internal();
-
-		/**
-		 * @brief	Performs some internal checks when an object is being deleted.
-		 */
-		static void _deleteDelayedInternal(CoreObject* obj);
-
-		/**
-		 * @brief	Queues a command to be executed on the core thread, without a return value.
-		 * 			
-		 * @note	Requires a shared pointer to the object this function will be executed on, in order to 
-		 * 			make sure the object is not deleted before the command executes. Can be null if the 
-		 * 			function is static or global.
-		 */
-		static void queueGpuCommand(std::shared_ptr<CoreObject>& obj, std::function<void()> func);
-
-		/**
-		 * @brief	Queues a command to be executed on the core thread, with a return value in the form of AsyncOp.
-		 * 			
-		 * @see		AsyncOp
-		 * 			
-		 * @note	Requires a shared pointer to the object this function will be executed on, in order to
-		 * 			make sure the object is not deleted before the command executes. Can be null if the
-		 * 			function is static or global.
-		 */
-		static AsyncOp queueReturnGpuCommand(std::shared_ptr<CoreObject>& obj, std::function<void(AsyncOp&)> func);
-
-		bool isScheduledToBeInitialized() const { return (mFlags & CGO_SCHEDULED_FOR_INIT) != 0; }
-		bool isScheduledToBeDeleted() const { return (mFlags & CGO_SCHEDULED_FOR_DELETE) != 0; }
-		bool requiresInitOnCoreThread() const { return (mFlags & CGO_INIT_ON_CORE_THREAD) != 0; }
-
-		void setIsInitialized(bool initialized) { mFlags = initialized ? mFlags | CGO_INITIALIZED : mFlags & ~CGO_INITIALIZED; }
-		void setScheduledToBeInitialized(bool scheduled) { mFlags = scheduled ? mFlags | CGO_SCHEDULED_FOR_INIT : mFlags & ~CGO_SCHEDULED_FOR_INIT; }
-		void setScheduledToBeDeleted(bool scheduled) { mFlags = scheduled ? mFlags | CGO_SCHEDULED_FOR_DELETE : mFlags & ~CGO_SCHEDULED_FOR_DELETE; }
-	private:
-		friend class CoreObjectManager;
-
-		volatile UINT8 mFlags;
-		UINT64 mInternalID; // ID == 0 is not a valid ID
-		std::weak_ptr<CoreObject> mThis;
-
-		BS_STATIC_THREAD_SYNCHRONISER(mCoreGpuObjectLoadedCondition)
-		BS_STATIC_MUTEX(mCoreGpuObjectLoadedMutex)
-
-		/**
-		 * @brief	Queues object initialization command on the core thread. The command is added to the
-		 * 			primary core thread queue and will be executed as soon as the core thread is ready.
-		 */
-		static void queueInitializeGpuCommand(std::shared_ptr<CoreObject>& obj);
-
-		/**
-		 * @brief	Queues object destruction command on the core thread. The command is added to the
-		 * 			core thread accessor of this thread and will be executed after accessor commands
-		 * 			are submitted and any previously queued commands are executed.
-		 *
-		 * @note	It is up to the caller to ensure no other accessors attempt to use this object.
-		 */
-		static void queueDestroyGpuCommand(std::shared_ptr<CoreObject>& obj);
-
-		/**
-		 * @brief	Helper wrapper method used for queuing commands with no return value on the core thread.
-		 */
-		static void executeGpuCommand(std::shared_ptr<CoreObject> obj, std::function<void()> func);
-
-		/**
-		 * @brief	Helper wrapper method used for queuing commands with a return value on the core thread.
-		 */
-		static void executeReturnGpuCommand(std::shared_ptr<CoreObject> obj, std::function<void(AsyncOp&)> func, AsyncOp& op); 
-	};
-
-	/**
-	 * @brief	Creates a new core object using the specified allocators and returns a shared pointer to it.
-	 *
-	 * @note	All core thread object shared pointers must be created using this method or its overloads
-	 * 			and you should not create them manually.
-	 */
-	template<class Type, class MainAlloc, class PtrDataAlloc, class... Args>
-	std::shared_ptr<Type> bs_core_ptr(Args &&...args)
-	{
-		return std::shared_ptr<Type>(bs_new<Type, MainAlloc>(std::forward<Args>(args)...),
-			&CoreObject::_deleteDelayed<Type, MainAlloc>, StdAlloc<PtrDataAlloc>());
-	}
-
-	/**
-	 * @brief	Creates a new core object using the specified allocator and returns a shared pointer to it.
-	 *
-	 * @note	All core thread object shared pointers must be created using this method or its overloads
-	 * 			and you should not create them manually.
-	 */
-	template<class Type, class MainAlloc, class... Args>
-	std::shared_ptr<Type> bs_core_ptr(Args &&...args)
-	{
-		return std::shared_ptr<Type>(bs_new<Type, MainAlloc>(std::forward<Args>(args)...),
-			&CoreObject::_deleteDelayed<Type, MainAlloc>, StdAlloc<GenAlloc>());
-	}
-
-	/**
-	 * @brief	Creates a new core object and returns a shared pointer to it.
-	 *
-	 * @note	All core thread object shared pointers must be created using this method or its overloads
-	 * 			and you should not create them manually.
-	 */
-	template<class Type, class... Args>
-	std::shared_ptr<Type> bs_core_ptr(Args &&...args)
-	{
-		return std::shared_ptr<Type>(bs_new<Type, GenAlloc>(std::forward<Args>(args)...),
-			&CoreObject::_deleteDelayed<Type, GenAlloc>, StdAlloc<GenAlloc>());
-	}
-
-	/**
-	 * @brief	Creates a core object shared pointer using a previously constructed object.
-	 *
-	 * @note	All core thread object shared pointers must be created using this method or its overloads
-	 * 			and you should not create them manually.
-	 */
-	template<class Type, class MainAlloc>
-	std::shared_ptr<Type> bs_core_ptr(Type* data)
-	{
-		return std::shared_ptr<Type>(data, &CoreObject::_deleteDelayed<Type, MainAlloc>, StdAlloc<GenAlloc>());  
-	}
-
-	/**
-	 * @brief	Creates a core object shared pointer using a previously constructed object.
-	 *
-	 * @note	All core thread object shared pointers must be created using this method or its overloads
-	 * 			and you should not create them manually.
-	 */
-	template<class Type, class MainAlloc, class PtrDataAlloc>
-	std::shared_ptr<Type> bs_core_ptr(Type* data)
-	{
-		return std::shared_ptr<Type>(data, &CoreObject::_deleteDelayed<Type, MainAlloc>, StdAlloc<PtrDataAlloc>());  
-	}
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCoreObjectCore.h"
+#include "BsAsyncOp.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup CoreThread
+	 *  @{
+	 */
+
+	/**
+	 * Core objects provides functionality for dealing with objects that need to exist on both simulation and core thread.
+	 * It handles cross-thread initialization, destruction as well as syncing data between the two threads.
+	 * 			
+	 * It also provides a standardized way to initialize/destroy objects, and a way to specify dependant CoreObject%s. For
+	 * those purposes it might also be used for objects that only exist on the core thread.
+	 *
+	 * @note	CoreObjectCore is a counterpart to CoreObject that is used exclusively on the core thread. CoreObject on the
+	 *			other hand should be used exclusively on the simulation thread. Types that exist on both threads need to
+	 *			implement both of these.
+	 */
+	class BS_CORE_EXPORT CoreObject
+	{
+	protected:
+		/** Values that represent current state of the core object */
+		enum Flags
+		{
+			CGO_DESTROYED = 0x01, /**< Object has been destroyed and shouldn't be used. */
+			CGO_INIT_ON_CORE_THREAD = 0x02 /**< Object requires initialization on core thread. */
+		};
+
+	public:
+		/**
+		 * Frees all the data held by this object.
+		 * 			
+		 * @note	
+		 * If this object require initialization on core thread destruction is not done immediately, and is 
+		 * instead just scheduled on the core thread. Otherwise the object is destroyed immediately.
+		 */
+		virtual void destroy();
+
+		/**
+		 * Initializes all the internal resources of this object. Must be called right after construction. Generally you
+		 * should call this from a factory method to avoid the issue where user forgets to call it.
+		 * 					
+		 * @note	
+		 * If this object require initialization on core thread initialization is not done immediately, and is instead just 
+		 * scheduled on the core thread. Otherwise the object is initialized immediately.
+		 */
+		virtual void initialize();
+
+		/** Returns true if the object has been destroyed. Destroyed object should not be used. */
+		bool isDestroyed() const { return (mFlags & CGO_DESTROYED) != 0; }
+
+		/**
+		 * Blocks the current thread until the resource is fully initialized.
+		 * 			
+		 * @note	
+		 * If you call this without calling initialize first a deadlock will occur. You should not call this from core thread.
+		 */
+		void blockUntilCoreInitialized() const;
+
+		/** Returns an unique identifier for this object. */
+		UINT64 getInternalID() const { return mInternalID; }
+
+		/** Returns a shared_ptr version of "this" pointer. */
+		SPtr<CoreObject> getThisPtr() const { return mThis.lock(); }
+
+		/**
+		 * Returns an object that contains a core thread specific implementation of this CoreObject. Null is a valid return
+		 * value in case object requires no core thread implementation.
+		 *
+		 * @note	Thread safe to retrieve, but its data is only valid on the core thread.
+		 */
+		SPtr<CoreObjectCore> getCore() const { return mCoreSpecific; }
+
+		/**
+		 * Ensures all dirty syncable data is send to the core thread counterpart of this object (if any).
+		 *
+		 * @note	Call this if you have modified the object and need to make sure core thread has an up to date version. 
+		 *			Normally this is done automatically at the end of a frame.
+		 */
+		void syncToCore(CoreAccessor& accessor);
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Sets a shared this pointer to this object. This must be called immediately after construction, but before
+		 * initialize().
+		 *
+		 * @note	Internal method.
+		 * @note	This should be called by the factory creation methods so user doesn't have to call it manually.
+		 */
+		void _setThisPtr(std::shared_ptr<CoreObject> ptrThis);
+
+		/**
+		 * Schedules the object to be destroyed, and then deleted.
+		 *
+		 * @note	Internal method.
+		 */
+		template<class T, class MemAlloc>
+		static void _delete(CoreObject* obj)
+		{
+			if (!obj->isDestroyed())
+				obj->destroy();
+
+			bs_delete<T, MemAlloc>((T*)obj);
+		}
+
+		/** @endcond */
+	protected:
+		/**
+		 * Constructs a new core object.
+		 *
+		 * @param[in]	requiresCoreInit	(optional) Determines if the CoreObjectCore counterpart of this object 
+		 *									(if it has any, see createCore()) requires initialization and destruction on the
+		 *									core thread.
+		 */
+		CoreObject(bool requiresCoreInit = true);
+		virtual ~CoreObject();
+
+		/**
+		 * Queues a command to be executed on the core thread, without a return value.
+		 * 			
+		 * @note	
+		 * Requires a shared pointer to the object this function will be executed on, in order to make sure the object is 
+		 * not deleted before the command executes. Can be null if the function is static or global.
+		 */
+		static void queueGpuCommand(const SPtr<CoreObjectCore>& obj, std::function<void()> func);
+
+		/**
+		 * Queues a command to be executed on the core thread, with a return value in the form of AsyncOp.
+		 * 			
+		 * @see		AsyncOp
+		 * 			
+		 * @note	
+		 * Requires a shared pointer to the object this function will be executed on, in order to make sure the object is 
+		 * not deleted before the command executes. Can be null if the function is static or global.
+		 */
+		static AsyncOp queueReturnGpuCommand(const SPtr<CoreObjectCore>& obj, std::function<void(AsyncOp&)> func);
+
+		bool requiresInitOnCoreThread() const { return (mFlags & CGO_INIT_ON_CORE_THREAD) != 0; }
+		void setIsDestroyed(bool destroyed) { mFlags = destroyed ? mFlags | CGO_DESTROYED : mFlags & ~CGO_DESTROYED; }
+	private:
+		friend class CoreObjectManager;
+
+		volatile UINT8 mFlags;
+		UINT32 mCoreDirtyFlags;
+		UINT64 mInternalID; // ID == 0 is not a valid ID
+		std::weak_ptr<CoreObject> mThis;
+
+		/**
+		 * Queues object initialization command on the core thread. The command is added to the primary core thread queue 
+		 * and will be executed as soon as the core thread is ready.
+		 */
+		static void queueInitializeGpuCommand(const SPtr<CoreObjectCore>& obj);
+
+		/**
+		 * Queues object destruction command on the core thread. The command is added to the core thread accessor of this 
+		 * thread and will be executed after accessor commands are submitted and any previously queued commands are executed.
+		 *
+		 * @note	It is up to the caller to ensure no other accessors attempt to use this object.
+		 */
+		static void queueDestroyGpuCommand(const SPtr<CoreObjectCore>& obj);
+
+		/** Helper wrapper method used for queuing commands with no return value on the core thread. */
+		static void executeGpuCommand(const SPtr<CoreObjectCore>& obj, std::function<void()> func);
+
+		/**	Helper wrapper method used for queuing commands with a return value on the core thread. */
+		static void executeReturnGpuCommand(const SPtr<CoreObjectCore>& obj, std::function<void(AsyncOp&)> func, AsyncOp& op);
+
+	protected:
+		/************************************************************************/
+		/* 							CORE OBJECT SYNC                      		*/
+		/************************************************************************/
+
+		/**
+		 * Creates an object that contains core thread specific data and methods for this CoreObject. Can be null if such 
+		 * object is not required.
+		 */
+		virtual SPtr<CoreObjectCore> createCore() const { return nullptr; }
+
+		/**
+		 * Marks the core data as dirty. This causes the syncToCore() method to trigger the next time objects are synced 
+		 * between core and sim threads.
+		 *
+		 * @param[in]	flags	(optional)	Flags in case you want to signal that only part of the internal data is dirty. 
+		 *									syncToCore() will be called regardless and it's up to the implementation to read
+		 *									the flags value if needed.
+		 */
+		void markCoreDirty(UINT32 flags = 0xFFFFFFFF);
+
+		/** Marks the core data as clean. Normally called right after syncToCore() has been called. */
+		void markCoreClean() { mCoreDirtyFlags = 0; }
+
+		/**
+		 * Notifies the core object manager that this object is dependant on some other CoreObject(s), and the dependencies
+		 * changed since the last call to this method. This will trigger a call to  getCoreDependencies() to collect the 
+		 * new dependencies.
+		 */
+		void markDependenciesDirty();
+
+		/**
+		 * Checks is the core dirty flag set. This is used by external systems to know when internal data has changed and 
+		 * core thread potentially needs to be notified.
+		 */
+		bool isCoreDirty() const { return mCoreDirtyFlags != 0; }
+
+		/**
+		 * Returns the exact value of the internal flag that signals whether an object needs to be synced with the core thread.
+		 */
+		UINT32 getCoreDirtyFlags() const { return mCoreDirtyFlags; }
+
+		/**
+		 * Copy internal dirty data to a memory buffer that will be used for updating core thread version of that data.
+		 *
+		 * @note	
+		 * This generally happens at the end of every sim thread frame. Synced data becomes available to the core thread 
+		 * the start of the next core thread frame.
+		 */
+		virtual CoreSyncData syncToCore(FrameAlloc* allocator) { return CoreSyncData(); }
+
+		/**
+		 * Populates the provided array with all core objects that this core object depends upon. Dependencies are required
+		 * for syncing to the core thread, so the system can be aware to update the dependant objects if a dependency is
+		 * marked as dirty. (e.g. updating a camera's viewport should also trigger an update on camera so it has
+		 * a chance to potentially update its data).
+		 */
+		virtual void getCoreDependencies(Vector<CoreObject*>& dependencies) { }
+
+	protected:
+		SPtr<CoreObjectCore> mCoreSpecific;
+	};
+
+	/**
+	 * Creates a new core object using the specified allocators and returns a shared pointer to it.
+	 *
+	 * @note	
+	 * All core thread object shared pointers must be created using this method or its overloads and you should not create 
+	 * them manually.
+	 */
+	template<class Type, class MainAlloc, class PtrDataAlloc, class... Args>
+	std::shared_ptr<Type> bs_core_ptr_new(Args &&...args)
+	{
+		return std::shared_ptr<Type>(bs_new<Type, MainAlloc>(std::forward<Args>(args)...),
+			&CoreObject::_delete<Type, MainAlloc>, StdAlloc<Type, PtrDataAlloc>());
+	}
+
+	/**
+	 * Creates a new core object using the specified allocator and returns a shared pointer to it.
+	 *
+	 * @note	
+	 * All core thread object shared pointers must be created using this method or its overloads and you should not create 
+	 * them manually.
+	 */
+	template<class Type, class MainAlloc, class... Args>
+	std::shared_ptr<Type> bs_core_ptr_new(Args &&...args)
+	{
+		return std::shared_ptr<Type>(bs_new<Type, MainAlloc>(std::forward<Args>(args)...),
+			&CoreObject::_delete<Type, MainAlloc>, StdAlloc<Type, GenAlloc>());
+	}
+
+	/**
+	 * Creates a new core object and returns a shared pointer to it.
+	 *
+	 * @note	
+	 * All core thread object shared pointers must be created using this method or its overloads and you should not create 
+	 * them manually.
+	 */
+	template<class Type, class... Args>
+	std::shared_ptr<Type> bs_core_ptr_new(Args &&...args)
+	{
+		return std::shared_ptr<Type>(bs_new<Type, GenAlloc>(std::forward<Args>(args)...),
+			&CoreObject::_delete<Type, GenAlloc>, StdAlloc<Type, GenAlloc>());
+	}
+
+	/**
+	 * Creates a core object shared pointer using a previously constructed object.
+	 *
+	 * @note	
+	 * All core thread object shared pointers must be created using this method or its overloads and you should not create 
+	 * them manually.
+	 */
+	template<class Type, class MainAlloc = GenAlloc, class PtrDataAlloc = GenAlloc>
+	std::shared_ptr<Type> bs_core_ptr(Type* data)
+	{
+		return std::shared_ptr<Type>(data, &CoreObject::_delete<Type, MainAlloc>, StdAlloc<Type, PtrDataAlloc>());  
+	}
+
+	/** @} */
+}
+

+ 92 - 0
BansheeCore/Include/BsCoreObjectCore.h

@@ -0,0 +1,92 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsAsyncOp.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup CoreThread
+	 *  @{
+	 */
+
+	/**
+	 * Represents counterpart of a CoreObject that is meant to be used specifically on the core thread. 
+	 *
+	 * @note	Core thread only.
+	 * @note	Different CoreObject implementations should implement this class for their own needs.
+	 */
+	class BS_CORE_EXPORT CoreObjectCore
+	{
+	protected:
+		/** Values that represent current state of the object */
+		enum Flags
+		{
+			CGCO_INITIALIZED = 0x01, /**< Object has been initialized and can be used. */
+			CGCO_SCHEDULED_FOR_INIT = 0x02 /**< Object has been scheduled for initialization but core thread has not completed it yet. */
+		};
+
+	public:
+		CoreObjectCore();
+		virtual ~CoreObjectCore();
+
+		/**	Called on the core thread when the object is first created. */
+		virtual void initialize();
+
+		/** Returns a shared_ptr version of "this" pointer. */
+		SPtr<CoreObjectCore> getThisPtr() const { return mThis.lock(); }
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Sets a shared this pointer to this object. This MUST be called immediately after construction.
+		 *
+		 * @note	Internal method.
+		 * @note	Called automatically by the factory creation methods so user should not call this manually.
+		 */
+		void _setThisPtr(std::shared_ptr<CoreObjectCore> ptrThis);
+
+		/** @endcond */
+
+	protected:
+		friend class CoreObjectManager;
+		friend class CoreObject;
+
+		/**
+		 * Update internal data from provided memory buffer that was populated with data from the sim thread.
+		 *
+		 * @note	
+		 * This generally happens at the start of a core thread frame. Data used was recorded on the previous sim thread 
+		 * frame.
+		 */
+		virtual void syncToCore(const CoreSyncData& data) { }
+
+		/**
+		 * Blocks the current thread until the resource is fully initialized.
+		 * 			
+		 * @note	
+		 * If you call this without calling initialize first a deadlock will occur. You should not call this from core thread.
+		 */
+		void synchronize();
+
+		/**
+		 * Returns true if the object has been properly initialized. Methods are not allowed to be called on the object
+		 * until it is initialized.
+		 */
+		bool isInitialized() const { return (mFlags & CGCO_INITIALIZED) != 0; }
+		bool isScheduledToBeInitialized() const { return (mFlags & CGCO_SCHEDULED_FOR_INIT) != 0; }
+
+		void setIsInitialized(bool initialized) { mFlags = initialized ? mFlags | CGCO_INITIALIZED : mFlags & ~CGCO_INITIALIZED; }
+		void setScheduledToBeInitialized(bool scheduled) { mFlags = scheduled ? mFlags | CGCO_SCHEDULED_FOR_INIT : mFlags & ~CGCO_SCHEDULED_FOR_INIT; }
+
+		volatile UINT8 mFlags;
+		std::weak_ptr<CoreObjectCore> mThis;
+
+		BS_STATIC_THREAD_SYNCHRONISER(mCoreGpuObjectLoadedCondition)
+		BS_STATIC_MUTEX(mCoreGpuObjectLoadedMutex)
+	};
+
+	/** @} */
+}
+

+ 144 - 39
BansheeCore/Include/BsCoreObjectManager.h

@@ -1,39 +1,144 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	// TODO Low priority - Add debug option that would remember a call stack for each resource initialization,
-	// so when we fail to release one we know which one it is.
-	
-	/**
-	 * @brief	Manager that keeps track of all active CoreObjects.
-	 * 			
-	 * @note	Thread safe.
-	 */
-	class BS_CORE_EXPORT CoreObjectManager : public Module<CoreObjectManager>
-	{
-	public:
-		CoreObjectManager();
-		~CoreObjectManager();
-
-		/**
-		 * @brief	Registers a new CoreObject notifying the manager the object
-		 * 			is created.
-		 */
-		UINT64 registerObject(CoreObject* object);
-
-		/**
-		 * @brief	Unregisters a CoreObject notifying the manager the object
-		 * 			is destroyed.
-		 */
-		void unregisterObject(CoreObject* object);
-
-	private:
-		UINT64 mNextAvailableID;
-		Map<UINT64, CoreObject*> mObjects;
-		BS_MUTEX(mObjectsMutex);
-	};
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCoreObjectCore.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup CoreThread
+	 *  @{
+	 */
+
+	// TODO Low priority - Add debug option that would remember a call stack for each resource initialization,
+	// so when we fail to release one we know which one it is.
+	
+	/**
+	 * Manager that keeps track of all active CoreObject%s.
+	 * 			
+	 * @note	Internal class. 
+	 * @note	Thread safe unless specified otherwise.
+	 */
+	class BS_CORE_EXPORT CoreObjectManager : public Module<CoreObjectManager>
+	{
+		/**
+		 * Stores dirty data that is to be transferred from sim  thread to core thread part of a CoreObject, for a single 
+		 * object.
+		 */
+		struct CoreStoredSyncObjData
+		{
+			CoreStoredSyncObjData()
+				:internalId(0)
+			{ }
+
+			CoreStoredSyncObjData(const SPtr<CoreObjectCore> destObj, UINT64 internalId, const CoreSyncData& syncData)
+				:destinationObj(destObj), syncData(syncData), internalId(internalId)
+			{ }
+
+			std::weak_ptr<CoreObjectCore> destinationObj;
+			CoreSyncData syncData;
+			UINT64 internalId;
+		};
+
+		/**
+		 * Stores dirty data that is to be transferred from sim thread to core thread part of a CoreObject, for all dirty
+		 * objects in one frame.
+		 */
+		struct CoreStoredSyncData
+		{
+			FrameAlloc* alloc = nullptr;
+			Vector<CoreStoredSyncObjData> entries;
+		};
+
+		/** Contains information about a dirty CoreObject that requires syncing to the core thread. */	
+		struct DirtyObjectData
+		{
+			CoreObject* object;
+			INT32 syncDataId;
+		};
+
+	public:
+		CoreObjectManager();
+		~CoreObjectManager();
+
+		/** Registers a new CoreObject notifying the manager the object	is created. */
+		UINT64 registerObject(CoreObject* object);
+
+		/** Unregisters a CoreObject notifying the manager the object is destroyed. */
+		void unregisterObject(CoreObject* object);
+
+		/**	Notifies the system that a CoreObject is dirty and needs to be synced with the core thread. */
+		void notifyCoreDirty(CoreObject* object);
+
+		/**	Notifies the system that CoreObject dependencies are dirty and should be updated. */
+		void notifyDependenciesDirty(CoreObject* object);
+
+		/**
+		 * Synchronizes all dirty CoreObjects with the core thread. Their dirty data will be allocated using the global 
+		 * frame allocator and then queued for update using the provided core thread accessor.
+		 *
+		 * @note	Sim thread only.
+		 */
+		void syncToCore(CoreAccessor& accessor);
+
+		/**
+		 * Synchronizes an individual dirty CoreObject with the core thread. Its dirty data will be allocated using the 
+		 * global frame allocator and then queued for update using the provided core thread accessor.
+		 *
+		 * @note	Sim thread only.
+		 */
+		void syncToCore(CoreObject* object, CoreAccessor& accessor);
+
+		/**
+		 * Clears any objects that are dirty and queued for sync on the core thread. Normally you only want to call this 
+		 * during shutdown when you no longer care about any of that data.
+		 */
+		void clearDirty();
+
+	private:
+		/**
+		 * Stores all syncable data from dirty core objects into memory allocated by the provided allocator. Additional 
+		 * meta-data is stored internally to be used by call to syncUpload().
+		 *
+		 * @param[in]	allocator Allocator to use for allocating memory for stored data.
+		 *
+		 * @note	Sim thread only.
+		 * @note	Must be followed by a call to syncUpload() with the same type.
+		 */
+		void syncDownload(FrameAlloc* allocator);
+
+		/**
+		 * Copies all the data stored by previous call to syncDownload() into core thread versions of CoreObjects.
+		 *
+		 * @note	Core thread only.
+		 * @note	Must be preceded by a call to syncDownload().
+		 */
+		void syncUpload();
+
+		/**
+		 * Updates the cached list of dependencies and dependants for the specified object.
+		 * 			
+		 * @param[in]	object			Update to update dependencies for.
+		 * @param[in]	dependencies	New set of dependencies, or null to clear all dependencies.
+		 */
+		void updateDependencies(CoreObject* object, Vector<CoreObject*>* dependencies);
+
+		UINT64 mNextAvailableID;
+		Map<UINT64, CoreObject*> mObjects;
+		Map<UINT64, DirtyObjectData> mDirtyObjects;
+		Map<UINT64, Vector<CoreObject*>> mDependencies;
+		Map<UINT64, Vector<CoreObject*>> mDependants;
+
+		Vector<CoreStoredSyncObjData> mDestroyedSyncData;
+		List<CoreStoredSyncData> mCoreSyncData;
+
+		BS_MUTEX(mObjectsMutex);
+	};
+
+	/** @} */
+	/** @endcond */
+}
+

+ 472 - 372
BansheeCore/Include/BsCorePrerequisites.h

@@ -1,373 +1,473 @@
-#pragma once
-
-#include "BsPrerequisitesUtil.h"
-
-#define BS_MAX_MULTIPLE_RENDER_TARGETS 8
-#define BS_FORCE_SINGLETHREADED_RENDERING 0
-
-// Windows Settings
-#if BS_PLATFORM == BS_PLATFORM_WIN32
-
-// If we're not including this from a client build, specify that the stuff
-// should get exported. Otherwise, import it.
-#	if defined(BS_STATIC_LIB)
-// Linux compilers don't have symbol import/export directives.
-#   	define BS_CORE_EXPORT
-#   else
-#   	if defined(BS_CORE_EXPORTS)
-#       	define BS_CORE_EXPORT __declspec( dllexport )
-#   	else
-#           if defined( __MINGW32__ )
-#               define BS_CORE_EXPORT
-#           else
-#       	    define BS_CORE_EXPORT __declspec( dllimport )
-#           endif
-#   	endif
-#	endif
-// Win32 compilers use _DEBUG for specifying debug builds.
-// for MinGW, we set DEBUG
-#   if defined(_DEBUG) || defined(DEBUG)
-#       define BS_DEBUG_MODE 1
-#   else
-#       define BS_DEBUG_MODE 0
-#   endif
-
-#endif
-
-// Linux/Apple Settings
-#if BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_APPLE
-
-// Enable GCC symbol visibility
-#   if defined( BS_GCC_VISIBILITY )
-#       define BS_CORE_EXPORT  __attribute__ ((visibility("default")))
-#       define BS_HIDDEN __attribute__ ((visibility("hidden")))
-#   else
-#       define BS_CORE_EXPORT
-#       define BS_HIDDEN
-#   endif
-
-// A quick define to overcome different names for the same function
-#   define stricmp strcasecmp
-
-#   ifdef DEBUG
-#       define BS_DEBUG_MODE 1
-#   else
-#       define BS_DEBUG_MODE 0
-#   endif
-
-#endif
-
-namespace BansheeEngine 
-{
-    class Color;
-    class GpuProgram;
-    class GpuProgramManager;
-    class IndexBuffer;
-    class OcclusionQuery;
-    class VertexBuffer;
-	class PixelBuffer;
-	class GpuBuffer;
-	class HighLevelGpuProgram;
-	class GpuProgramManager;
-	class GpuProgramFactory;
-    class IndexData;
-    class Pass;
-	class Technique;
-	class Shader;
-	class Material;
-    class RenderSystem;
-    class RenderSystemCapabilities;
-    class RenderTarget;
-    class RenderTexture;
-	class MultiRenderTexture;
-    class RenderWindow;
-    struct RenderOpMesh;
-    class StringInterface;
-    class SamplerState;
-    class TextureManager;
-    class Viewport;
-    class VertexData;
-    class VertexDeclaration;
-	class Input;
-	struct PointerEvent;
-	class RawInputHandler;
-	class Renderer;
-	class RendererFactory;
-	class PassParameters;
-	class AsyncOp;
-	class HardwareBufferManager;
-	class FontManager;
-	class DepthStencilState;
-	class RenderStateManager;
-	class RasterizerState;
-	class BlendState;
-	class GpuParamBlock;
-	class GpuParamBlockBuffer;
-	class GpuParams;
-	struct GpuParamDesc;
-	struct GpuParamDataDesc;
-	struct GpuParamObjectDesc;
-	struct GpuParamBlockDesc;
-	class GpuProgInclude;
-	class TextureView;
-	class CoreObject;
-	class ImportOptions;
-	struct FontData;
-	class GameObject;
-	class GpuResource;
-	class GpuResourceData;
-	struct RenderOperation;
-	class RenderQueue;
-	struct ProfilerReport;
-	class VertexDataDesc;
-	class EventQuery;
-	class TimerQuery;
-	class OcclusionQuery;
-	class FrameAlloc;
-	class FolderMonitor;
-	class VideoMode;
-	class VideoOutputInfo;
-	class VideoModeInfo;
-	class RenderableElement;
-	class CameraProxy;
-	struct MaterialProxy;
-	struct MaterialProxyPass;
-	struct MeshProxy;
-	struct ShaderProxy;
-	class DrawList;
-	// Asset import
-	class SpecificImporter;
-	class Importer;
-	// Resources
-	class Resource;
-	class Resources;
-	class ResourceManifest;
-	class Texture;
-	class Mesh;
-	class MeshBase;
-	class TransientMesh;
-	class MeshHeap;
-	class Font;
-	class OSDropTarget;
-	// Scene
-	class SceneObject;
-	class Component;
-	class SceneManager;
-	// RTTI
-	class MeshRTTI;
-	// Desc structs
-	struct SAMPLER_STATE_DESC;
-	struct DEPTH_STENCIL_STATE_DESC;
-	struct RASTERIZER_STATE_DESC;
-	struct BLEND_STATE_DESC;
-	struct RENDER_TARGET_BLEND_STATE_DESC;
-	struct RENDER_TEXTURE_DESC;
-	struct RENDER_WINDOW_DESC;
-	struct FONT_DESC;
-
-	template<class T>
-	class CoreThreadAccessor;
-	class CommandQueueNoSync;
-	class CommandQueueSync;
-}
-
-/************************************************************************/
-/* 						Shared pointer typedefs	                    	*/
-/************************************************************************/
-
-namespace BansheeEngine
-{
-	typedef std::shared_ptr<RenderSystem> RenderSystemPtr;
-	typedef std::shared_ptr<GpuProgram> GpuProgramPtr;
-	typedef std::shared_ptr<PixelBuffer> PixelBufferPtr;
-	typedef std::shared_ptr<VertexBuffer> VertexBufferPtr;
-	typedef std::shared_ptr<IndexBuffer> IndexBufferPtr;
-	typedef std::shared_ptr<GpuBuffer> GpuBufferPtr;
-	typedef std::shared_ptr<VertexDeclaration> VertexDeclarationPtr;
-	typedef std::shared_ptr<Mesh> MeshPtr;
-	typedef std::shared_ptr<MeshBase> MeshBasePtr;
-	typedef std::shared_ptr<MeshHeap> MeshHeapPtr;
-	typedef std::shared_ptr<TransientMesh> TransientMeshPtr;
-	typedef std::shared_ptr<Texture> TexturePtr;
-	typedef std::shared_ptr<Resource> ResourcePtr;
-	typedef std::shared_ptr<Technique> TechniquePtr;
-	typedef std::shared_ptr<Pass> PassPtr;
-	typedef std::shared_ptr<Shader> ShaderPtr;
-	typedef std::shared_ptr<Material> MaterialPtr;
-	typedef std::shared_ptr<Renderer> RendererPtr;
-	typedef std::shared_ptr<RendererFactory> RendererFactoryPtr;
-	typedef std::shared_ptr<PassParameters> PassParametersPtr;
-	typedef std::shared_ptr<Component> ComponentPtr;
-	typedef std::shared_ptr<SceneObject> GameObjectPtr;
-	typedef std::shared_ptr<SamplerState> SamplerStatePtr;
-	typedef std::shared_ptr<DepthStencilState> DepthStencilStatePtr;
-	typedef std::shared_ptr<RasterizerState> RasterizerStatePtr;
-	typedef std::shared_ptr<BlendState> BlendStatePtr;
-	typedef std::shared_ptr<RenderWindow> RenderWindowPtr;
-	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
-	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
-	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
-	typedef std::shared_ptr<GpuParamBlock> GpuParamBlockPtr;
-	typedef std::shared_ptr<GpuParamBlockBuffer> GpuParamBlockBufferPtr;
-	typedef std::shared_ptr<GpuParams> GpuParamsPtr;
-	typedef std::shared_ptr<TextureView> TextureViewPtr;
-	typedef std::shared_ptr<Viewport> ViewportPtr;
-	typedef std::shared_ptr<GpuProgInclude> GpuProgIncludePtr;
-	typedef std::shared_ptr<ImportOptions> ImportOptionsPtr;
-	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
-	typedef std::shared_ptr<Font> FontPtr;
-	typedef std::shared_ptr<GpuResource> GpuResourcePtr;
-	typedef std::shared_ptr<VertexDataDesc> VertexDataDescPtr;
-	typedef CoreThreadAccessor<CommandQueueNoSync> CoreAccessor;
-	typedef CoreThreadAccessor<CommandQueueSync> SyncedCoreAccessor;
-	typedef std::shared_ptr<CoreThreadAccessor<CommandQueueNoSync>> CoreAccessorPtr;
-	typedef std::shared_ptr<CoreThreadAccessor<CommandQueueSync>> SyncedCoreAccessorPtr;
-	typedef std::shared_ptr<EventQuery> EventQueryPtr;
-	typedef std::shared_ptr<TimerQuery> TimerQueryPtr;
-	typedef std::shared_ptr<OcclusionQuery> OcclusionQueryPtr;
-	typedef std::shared_ptr<ResourceManifest> ResourceManifestPtr;
-	typedef std::shared_ptr<VideoModeInfo> VideoModeInfoPtr;
-	typedef std::shared_ptr<DrawList> DrawListPtr;
-	typedef std::shared_ptr<RenderQueue> RenderQueuePtr;
-	typedef std::shared_ptr<CameraProxy> CameraProxyPtr;
-	typedef std::shared_ptr<MaterialProxy> MaterialProxyPtr;
-	typedef std::shared_ptr<MeshProxy> MeshProxyPtr;
-	typedef std::shared_ptr<ShaderProxy> ShaderProxyPtr;
-	typedef std::shared_ptr<GpuParamDesc> GpuParamDescPtr;
-}
-
-/************************************************************************/
-/* 									RTTI                      			*/
-/************************************************************************/
-namespace BansheeEngine
-{
-	enum TypeID_Core
-	{
-		TID_Texture = 1001,
-		TID_Mesh = 1002,
-		TID_MeshData = 1003,
-		TID_VertexDeclaration = 1004,
-		TID_VertexElementData = 1005,
-		TID_Component = 1006,
-		TID_ResourceHandle = 1009,
-		TID_GpuProgram = 1010,
-		TID_ResourceHandleData = 1011,
-		TID_CgProgram = 1012,
-		TID_Pass = 1014,
-		TID_Technique = 1015,
-		TID_Shader = 1016,
-		TID_Material = 1017,
-		TID_MaterialParams = 1018,
-		TID_FloatParamKVP = 1019,
-		TID_MaterialTexParamKVP = 1020,
-		TID_SamplerState = 1021,
-		TID_SamplerStateParamKVP = 1022,
-		TID_BlendState = 1023,
-		TID_RasterizerState = 1024,
-		TID_DepthStencilState = 1025,
-		TID_MaterialParamFloat = 1026,
-		TID_MaterialParamVec2 = 1027,
-		TID_MaterialParamVec3 = 1028,
-		TID_MaterialParamVec4 = 1029,
-		TID_MaterialParamMat3 = 1030,
-		TID_MaterialParamMat4 = 1031,
-		TID_MaterialParamTexture = 1032,
-		TID_MaterialParamSamplerState = 1033,
-		TID_BLEND_STATE_DESC = 1034,
-		TID_SHADER_DATA_PARAM_DESC = 1035,
-		TID_SHADER_OBJECT_PARAM_DESC = 1036,
-		TID_SHADER_PARAM_BLOCK_DESC = 1047,
-		TID_ImportOptions = 1048,
-		TID_GpuProgramImportOptions = 1049,
-		TID_MaterialParamStruct = 1050,
-		TID_Font = 1051,
-		TID_FONT_DESC = 1052,
-		TID_CHAR_DESC = 1053,
-		TID_FontImportOptions = 1056,
-		TID_FontData = 1057,
-		TID_SceneObject = 1059,
-		TID_GameObject = 1060,
-		TID_GpuResource = 1061,
-		TID_PixelData = 1062,
-		TID_GpuResourceData = 1063,
-		TID_VertexDataDesc = 1064,
-		TID_MeshBase = 1065,
-		TID_GameObjectHandleBase = 1066,
-		TID_ResourceManifest = 1067,
-		TID_ResourceManifestEntry = 1068,
-		TID_EmulatedParamBlock = 1069,
-		TID_TextureImportOptions = 1070
-	};
-}
-
-/************************************************************************/
-/* 							Resource references                   		*/
-/************************************************************************/
-
-#include "BsResourceHandle.h"
-
-namespace BansheeEngine
-{
-	// Resource handles
-	typedef ResourceHandle<Resource> HResource;
-	typedef ResourceHandle<Texture> HTexture;
-	typedef ResourceHandle<Mesh> HMesh;
-	typedef ResourceHandle<GpuProgram> HGpuProgram;
-	typedef ResourceHandle<Material> HMaterial;
-	typedef ResourceHandle<SamplerState> HSamplerState;
-	typedef ResourceHandle<RasterizerState> HRasterizerState;
-	typedef ResourceHandle<DepthStencilState> HDepthStencilState;
-	typedef ResourceHandle<BlendState> HBlendState;
-	typedef ResourceHandle<GpuProgInclude> HGpuProgInclude;
-	typedef ResourceHandle<Font> HFont;
-}
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Defers function execution until the next frame. If this function is called
-	 * 			within another deferred call, then it will be executed the same frame,
-	 * 			but only after all existing deferred calls are done.
-	 * 			
-	 * @note	This method can be used for breaking dependencies among other things. If a class
-	 * 			A depends on class B having something done, but class B also depends in some way on class A,
-	 * 			you can break up the initialization into two separate steps, queuing the second step
-	 * 			using this method.
-	 * 			
-	 *			Similar situation can happen if you have multiple classes being initialized in an undefined order
-	 *			but some of them depend on others. Using this method you can defer the dependent step until next frame,
-	 *			which will ensure everything was initialized.
-	 *
-	 * @param	callback	The callback.
-	 */
-	void BS_CORE_EXPORT deferredCall(std::function<void()> callback);
-
-	// Special types for use by profilers
-	typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, ProfilerAlloc>> ProfilerString;
-
-	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
-	using ProfilerVector = std::vector<T, A>;
-
-	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
-	using ProfilerStack = std::stack<T, std::deque<T, A>>;
-
-	/**
-	* @brief	Banshee thread policy that performs special startup/shutdown on threads
-	*			managed by thread pool.
-	*/
-	class BS_CORE_EXPORT ThreadBansheePolicy
-	{
-	public:
-		static void onThreadStarted(const String& name)
-		{
-			MemStack::beginThread();
-		}
-
-		static void onThreadEnded(const String& name)
-		{
-			MemStack::endThread();
-		}
-	};
-}
-
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsPrerequisitesUtil.h"
+
+/** @defgroup Core Core
+ *	Second lowest layer that provides some very game-specific modules tied into a coherent whole, but it tries to be very 
+ *  generic and offer something that every engine might need instead of focusing on very specialized techniques.
+ *  @{
+ */
+
+/** @defgroup CoreThread Core thread
+ *	Functionality for dealing with core objects and interaction with the core thread.
+ */
+
+/** @defgroup Importer Importer
+ *	Functionality for dealing with import of resources into engine friendly format.
+ */
+
+/** @defgroup Input Input
+ *	Functionality for dealing with input (mouse, keyboard, gamepad, etc.).
+ */
+
+/** @defgroup Localization Localization
+ *	Functionality for dealing with GUI localization.
+ */
+
+/** @defgroup Material Material
+ *	Functionality for dealing with materials, shaders, and in general how objects are rendered.
+ */
+
+/** @defgroup Platform Platform
+ *	Functionality specific for some platform (e.g. Windows, Mac).
+ */
+
+ /** @defgroup Profiling Profiling
+  *	Functionality for measuring CPU and GPU execution times and memory usage.
+  */
+
+/** @defgroup RenderAPI RenderAPI
+  *	Functionality for interacting with underlying render API (e.g. DirectX, OpenGL).
+  */
+
+/** @defgroup Renderer Renderer
+  *	Abstract interface and helper functionality for rendering scene objects.
+  */
+
+/** @defgroup Resources Resources
+  *	Contains core resource types and resource management functionality (loading, saving, etc.).
+  */
+
+/** @defgroup RTTI-Impl-Core RTTI types
+ *  Types containing RTTI for specific classes.
+ */
+
+/** @defgroup Scene Scene
+ *  Functionality for managing scene objects and their hierarchy.
+ */
+
+/** @defgroup Text Text
+ *  Functionality for rendering text.
+ */
+
+/** @defgroup Utility-Core Utility
+ *  Various utility methods and types used by the core layer.
+ */
+
+/** @defgroup Application-Core Application
+ *  Entry point into the application.
+ */
+
+/** @} */
+
+#define BS_MAX_MULTIPLE_RENDER_TARGETS 8
+#define BS_FORCE_SINGLETHREADED_RENDERING 0
+
+// Windows Settings
+#if BS_PLATFORM == BS_PLATFORM_WIN32
+
+// If we're not including this from a client build, specify that the stuff
+// should get exported. Otherwise, import it.
+#	if defined(BS_STATIC_LIB)
+// Linux compilers don't have symbol import/export directives.
+#   	define BS_CORE_EXPORT
+#   else
+#   	if defined(BS_CORE_EXPORTS)
+#       	define BS_CORE_EXPORT __declspec( dllexport )
+#   	else
+#           if defined( __MINGW32__ )
+#               define BS_CORE_EXPORT
+#           else
+#       	    define BS_CORE_EXPORT __declspec( dllimport )
+#           endif
+#   	endif
+#	endif
+
+#endif
+
+// Linux/Apple Settings
+#if BS_PLATFORM == BS_PLATFORM_LINUX || BS_PLATFORM == BS_PLATFORM_APPLE
+
+// Enable GCC symbol visibility
+#   if defined( BS_GCC_VISIBILITY )
+#       define BS_CORE_EXPORT  __attribute__ ((visibility("default")))
+#       define BS_HIDDEN __attribute__ ((visibility("hidden")))
+#   else
+#       define BS_CORE_EXPORT
+#       define BS_HIDDEN
+#   endif
+
+#endif
+
+#include "BsHString.h"
+
+namespace BansheeEngine 
+{
+	static const StringID RenderAPIAny = "AnyRenderAPI";
+	static const StringID RendererAny = "AnyRenderer";
+
+    class Color;
+    class GpuProgram;
+    class GpuProgramManager;
+    class IndexBuffer;
+	class IndexBufferCore;
+    class OcclusionQuery;
+    class VertexBuffer;
+	class VertexBufferCore;
+	class PixelBuffer;
+	class GpuBuffer;
+	class HighLevelGpuProgram;
+	class GpuProgramManager;
+	class GpuProgramFactory;
+    class IndexData;
+    class Pass;
+	class Technique;
+	class Shader;
+	class Material;
+    class RenderAPICore;
+    class RenderAPICapabilities;
+    class RenderTarget;
+	class RenderTargetCore;
+    class RenderTexture;
+	class RenderTextureCore;
+	class MultiRenderTexture;
+	class MultiRenderTextureCore;
+    class RenderWindow;
+	class RenderWindowCore;
+	class RenderTargetProperties;
+    struct RenderOpMesh;
+    class StringInterface;
+    class SamplerState;
+	class SamplerStateCore;
+    class TextureManager;
+    class Viewport;
+    class VertexData;
+    class VertexDeclaration;
+	class Input;
+	struct PointerEvent;
+	class RawInputHandler;
+	class CoreRenderer;
+	class RendererFactory;
+	class AsyncOp;
+	class HardwareBufferManager;
+	class FontManager;
+	class DepthStencilState;
+	class DepthStencilStateCore;
+	class RenderStateManager;
+	class RasterizerState;
+	class RasterizerStateCore;
+	class BlendState;
+	class BlendStateCore;
+	class GpuParamBlock;
+	class GpuParamBlockBuffer;
+	class GpuParams;
+	struct GpuParamDesc;
+	struct GpuParamDataDesc;
+	struct GpuParamObjectDesc;
+	struct GpuParamBlockDesc;
+	class ShaderInclude;
+	class TextureView;
+	class CoreObject;
+	class CoreObjectCore;
+	class ImportOptions;
+	class TextureImportOptions;
+	class FontImportOptions;
+	class GpuProgramImportOptions;
+	class MeshImportOptions;
+	struct FontBitmap;
+	class GameObject;
+	class GpuResourceData;
+	struct RenderOperation;
+	class RenderQueue;
+	struct ProfilerReport;
+	class VertexDataDesc;
+	class EventQuery;
+	class TimerQuery;
+	class OcclusionQuery;
+	class FrameAlloc;
+	class FolderMonitor;
+	class VideoMode;
+	class VideoOutputInfo;
+	class VideoModeInfo;
+	class RenderableElement;
+	class CameraCore;
+	class MeshCoreBase;
+	class MeshCore;
+	struct SubMesh;
+	class TransientMeshCore;
+	class TextureCore;
+	class MeshHeapCore;
+	class VertexDeclarationCore;
+	class GpuBufferCore;
+	class GpuParamBlockBufferCore;
+	class GpuParamsCore;
+	class ShaderCore;
+	class ViewportCore;
+	class PassCore;
+	class PassParametersCore;
+	class TechniqueCore;
+	class MaterialCore;
+	class GpuProgramCore;
+	class IResourceListener;
+	class TextureProperties;
+	class IShaderIncludeHandler;
+	class Prefab;
+	class PrefabDiff;
+	class RendererMeshData;
+	class LightCore;
+	class Light;
+	class Win32Window;
+	class RenderAPIFactory;
+	// Asset import
+	class SpecificImporter;
+	class Importer;
+	// Resources
+	class Resource;
+	class Resources;
+	class ResourceManifest;
+	class Texture;
+	class Mesh;
+	class MeshBase;
+	class TransientMesh;
+	class MeshHeap;
+	class Font;
+	class ResourceMetaData;
+	class OSDropTarget;
+	class StringTable;
+	// Scene
+	class SceneObject;
+	class Component;
+	class SceneManager;
+	// RTTI
+	class MeshRTTI;
+	// Desc structs
+	struct SAMPLER_STATE_DESC;
+	struct DEPTH_STENCIL_STATE_DESC;
+	struct RASTERIZER_STATE_DESC;
+	struct BLEND_STATE_DESC;
+	struct RENDER_TARGET_BLEND_STATE_DESC;
+	struct RENDER_TEXTURE_DESC;
+	struct RENDER_WINDOW_DESC;
+	struct FONT_DESC;
+
+	template<class T>
+	class CoreThreadAccessor;
+	class CommandQueueNoSync;
+	class CommandQueueSync;
+}
+
+/************************************************************************/
+/* 						Shared pointer typedefs	                    	*/
+/************************************************************************/
+
+namespace BansheeEngine
+{
+	typedef std::shared_ptr<RenderAPICore> RenderAPIPtr;
+	typedef std::shared_ptr<GpuProgram> GpuProgramPtr;
+	typedef std::shared_ptr<PixelBuffer> PixelBufferPtr;
+	typedef std::shared_ptr<VertexBuffer> VertexBufferPtr;
+	typedef std::shared_ptr<IndexBuffer> IndexBufferPtr;
+	typedef std::shared_ptr<GpuBuffer> GpuBufferPtr;
+	typedef std::shared_ptr<VertexDeclaration> VertexDeclarationPtr;
+	typedef std::shared_ptr<Mesh> MeshPtr;
+	typedef std::shared_ptr<MeshBase> MeshBasePtr;
+	typedef std::shared_ptr<MeshHeap> MeshHeapPtr;
+	typedef std::shared_ptr<TransientMesh> TransientMeshPtr;
+	typedef std::shared_ptr<Texture> TexturePtr;
+	typedef std::shared_ptr<Resource> ResourcePtr;
+	typedef std::shared_ptr<Technique> TechniquePtr;
+	typedef std::shared_ptr<Pass> PassPtr;
+	typedef std::shared_ptr<Shader> ShaderPtr;
+	typedef std::shared_ptr<Material> MaterialPtr;
+	typedef std::shared_ptr<CoreRenderer> CoreRendererPtr;
+	typedef std::shared_ptr<RendererFactory> RendererFactoryPtr;
+	typedef std::shared_ptr<Component> ComponentPtr;
+	typedef std::shared_ptr<GameObject> GameObjectPtr;
+	typedef std::shared_ptr<SceneObject> SceneObjectPtr;
+	typedef std::shared_ptr<SamplerState> SamplerStatePtr;
+	typedef std::shared_ptr<DepthStencilState> DepthStencilStatePtr;
+	typedef std::shared_ptr<RasterizerState> RasterizerStatePtr;
+	typedef std::shared_ptr<BlendState> BlendStatePtr;
+	typedef std::shared_ptr<RenderWindow> RenderWindowPtr;
+	typedef std::shared_ptr<RenderTarget> RenderTargetPtr;
+	typedef std::shared_ptr<RenderTexture> RenderTexturePtr;
+	typedef std::shared_ptr<MultiRenderTexture> MultiRenderTexturePtr;
+	typedef std::shared_ptr<GpuParamBlockBuffer> GpuParamBlockBufferPtr;
+	typedef std::shared_ptr<GpuParams> GpuParamsPtr;
+	typedef std::shared_ptr<TextureView> TextureViewPtr;
+	typedef std::shared_ptr<Viewport> ViewportPtr;
+	typedef std::shared_ptr<ShaderInclude> ShaderIncludePtr;
+	typedef std::shared_ptr<ImportOptions> ImportOptionsPtr;
+	typedef std::shared_ptr<const ImportOptions> ConstImportOptionsPtr;
+	typedef std::shared_ptr<Font> FontPtr;
+	typedef std::shared_ptr<VertexDataDesc> VertexDataDescPtr;
+	typedef CoreThreadAccessor<CommandQueueNoSync> CoreAccessor;
+	typedef CoreThreadAccessor<CommandQueueSync> SyncedCoreAccessor;
+	typedef std::shared_ptr<CoreThreadAccessor<CommandQueueNoSync>> CoreAccessorPtr;
+	typedef std::shared_ptr<CoreThreadAccessor<CommandQueueSync>> SyncedCoreAccessorPtr;
+	typedef std::shared_ptr<EventQuery> EventQueryPtr;
+	typedef std::shared_ptr<TimerQuery> TimerQueryPtr;
+	typedef std::shared_ptr<OcclusionQuery> OcclusionQueryPtr;
+	typedef std::shared_ptr<ResourceManifest> ResourceManifestPtr;
+	typedef std::shared_ptr<VideoModeInfo> VideoModeInfoPtr;
+	typedef std::shared_ptr<RenderQueue> RenderQueuePtr;
+	typedef std::shared_ptr<GpuParamDesc> GpuParamDescPtr;
+	typedef std::shared_ptr<ResourceMetaData> ResourceMetaDataPtr;
+	typedef std::shared_ptr<IShaderIncludeHandler> ShaderIncludeHandlerPtr;
+	typedef std::shared_ptr<Prefab> PrefabPtr;
+	typedef std::shared_ptr<PrefabDiff> PrefabDiffPtr;
+	typedef std::shared_ptr<RendererMeshData> RendererMeshDataPtr;
+	typedef std::shared_ptr<RenderAPIFactory> RenderAPIFactoryPtr;
+}
+
+/************************************************************************/
+/* 									RTTI                      			*/
+/************************************************************************/
+namespace BansheeEngine
+{
+	enum TypeID_Core
+	{
+		TID_Texture = 1001,
+		TID_Mesh = 1002,
+		TID_MeshData = 1003,
+		TID_VertexDeclaration = 1004,
+		TID_VertexElementData = 1005,
+		TID_Component = 1006,
+		TID_ResourceHandle = 1009,
+		TID_GpuProgram = 1010,
+		TID_ResourceHandleData = 1011,
+		TID_CgProgram = 1012,
+		TID_Pass = 1014,
+		TID_Technique = 1015,
+		TID_Shader = 1016,
+		TID_Material = 1017,
+		TID_SamplerState = 1021,
+		TID_BlendState = 1023,
+		TID_RasterizerState = 1024,
+		TID_DepthStencilState = 1025,
+		TID_BLEND_STATE_DESC = 1034,
+		TID_SHADER_DATA_PARAM_DESC = 1035,
+		TID_SHADER_OBJECT_PARAM_DESC = 1036,
+		TID_SHADER_PARAM_BLOCK_DESC = 1047,
+		TID_ImportOptions = 1048,
+		TID_Font = 1051,
+		TID_FONT_DESC = 1052,
+		TID_CHAR_DESC = 1053,
+		TID_FontImportOptions = 1056,
+		TID_FontBitmap = 1057,
+		TID_SceneObject = 1059,
+		TID_GameObject = 1060,
+		TID_PixelData = 1062,
+		TID_GpuResourceData = 1063,
+		TID_VertexDataDesc = 1064,
+		TID_MeshBase = 1065,
+		TID_GameObjectHandleBase = 1066,
+		TID_ResourceManifest = 1067,
+		TID_ResourceManifestEntry = 1068,
+		TID_EmulatedParamBlock = 1069,
+		TID_TextureImportOptions = 1070,
+		TID_ResourceMetaData = 1071,
+		TID_ShaderInclude = 1072,
+		TID_Viewport = 1073,
+		TID_ResourceDependencies = 1074,
+		TID_ShaderMetaData = 1075,
+		TID_MeshImportOptions = 1076,
+		TID_Prefab = 1077,
+		TID_PrefabDiff = 1078,
+		TID_PrefabObjectDiff = 1079,
+		TID_PrefabComponentDiff = 1080,
+		TID_CGUIWidget = 1081,
+		TID_ProfilerOverlay = 1082,
+		TID_StringTable = 1083,
+		TID_LanguageData = 1084,
+		TID_LocalizedStringData = 1085,
+		TID_MaterialParamColor = 1086,
+		TID_WeakResourceHandle = 1087,
+		TID_TextureParamData = 1088,
+		TID_StructParamData = 1089,
+		TID_MaterialParams = 1090,
+		TID_MaterialRTTIParam = 1091
+	};
+}
+
+/************************************************************************/
+/* 							Resource references                   		*/
+/************************************************************************/
+
+#include "BsResourceHandle.h"
+
+namespace BansheeEngine
+{
+	// Resource handles
+	typedef ResourceHandle<Resource> HResource;
+	typedef ResourceHandle<Texture> HTexture;
+	typedef ResourceHandle<Mesh> HMesh;
+	typedef ResourceHandle<Material> HMaterial;
+	typedef ResourceHandle<ShaderInclude> HShaderInclude;
+	typedef ResourceHandle<Font> HFont;
+	typedef ResourceHandle<Shader> HShader;
+	typedef ResourceHandle<Prefab> HPrefab;
+	typedef ResourceHandle<StringTable> HStringTable;
+}
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Defers function execution until the next frame. If this function is called
+	 * 			within another deferred call, then it will be executed the same frame,
+	 * 			but only after all existing deferred calls are done.
+	 * 			
+	 * @note	This method can be used for breaking dependencies among other things. If a class
+	 * 			A depends on class B having something done, but class B also depends in some way on class A,
+	 * 			you can break up the initialization into two separate steps, queuing the second step
+	 * 			using this method.
+	 * 			
+	 *			Similar situation can happen if you have multiple classes being initialized in an undefined order
+	 *			but some of them depend on others. Using this method you can defer the dependent step until next frame,
+	 *			which will ensure everything was initialized.
+	 *
+	 * @param	callback	The callback.
+	 */
+	void BS_CORE_EXPORT deferredCall(std::function<void()> callback);
+
+	// Special types for use by profilers
+	typedef std::basic_string<char, std::char_traits<char>, StdAlloc<char, ProfilerAlloc>> ProfilerString;
+
+	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
+	using ProfilerVector = std::vector<T, A>;
+
+	template <typename T, typename A = StdAlloc<T, ProfilerAlloc>>
+	using ProfilerStack = std::stack<T, std::deque<T, A>>;
+
+	/**
+	* @brief	Banshee thread policy that performs special startup/shutdown on threads
+	*			managed by thread pool.
+	*/
+	class BS_CORE_EXPORT ThreadBansheePolicy
+	{
+	public:
+		static void onThreadStarted(const String& name)
+		{
+			MemStack::beginThread();
+		}
+
+		static void onThreadEnded(const String& name)
+		{
+			MemStack::endThread();
+		}
+	};
+}
+
 #include "BsCommonTypes.h"

+ 142 - 0
BansheeCore/Include/BsCoreRenderer.h

@@ -0,0 +1,142 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsStringID.h"
+#include "BsRendererMeshData.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Renderer
+	 *  @{
+	 */
+
+	/**
+	 * Available parameter block semantics that allow the renderer to identify the use of a GPU program parameter block 
+	 * specified in a shader.
+	 */
+	static StringID RBS_Static = "Static";
+	static StringID RBS_PerCamera = "PerCamera";
+	static StringID RBS_PerFrame = "PerFrame";
+	static StringID RBS_PerObject = "PerObject";
+
+	/**
+	 * Available parameter semantics that allow the renderer to identify the use of a GPU parameter specified in a shader.
+	 */
+	static StringID RPS_WorldViewProjTfrm = "WVP";
+	static StringID RPS_ViewProjTfrm = "VP";
+	static StringID RPS_ProjTfrm = "P";
+	static StringID RPS_ViewTfrm = "V";
+	static StringID RPS_WorldTfrm = "W";
+	static StringID RPS_InvWorldTfrm = "IW";
+	static StringID RPS_WorldNoScaleTfrm = "WNoScale";
+	static StringID RPS_InvWorldNoScaleTfrm = "IWNoScale";
+	static StringID RPS_WorldDeterminantSign = "WorldDeterminantSign";
+	static StringID RPS_Diffuse = "Diffuse";
+	static StringID RPS_ViewDir = "ViewDir";
+
+	/**	Set of options that can be used for controlling the renderer. */	
+	struct BS_CORE_EXPORT CoreRendererOptions
+	{
+		virtual ~CoreRendererOptions() { }
+	};
+
+	/**
+	 * Primarily rendering class that allows you to specify how to render objects that exist in the scene graph. You need
+	 * to provide your own implementation of your class.
+	 *
+	 * @note	
+	 * Normally you would iterate over all cameras, find visible objects for each camera and render those objects in some way.
+	 */
+	class BS_CORE_EXPORT CoreRenderer
+	{
+	public:
+		CoreRenderer();
+		virtual ~CoreRenderer() { }
+
+		/** Initializes the renderer. Must be called before using the renderer. */
+		virtual void initialize() { }
+
+		/**	Cleans up the renderer. Must be called before the renderer is deleted. */
+		virtual void destroy() { }
+
+		/** Name of the renderer. Used by materials to find an appropriate technique for this renderer. */
+		virtual const StringID& getName() const = 0;
+
+		/** Called in order to render all currently active cameras. */
+		virtual void renderAll() = 0;
+
+		/**
+		 * Called whenever a new camera is created.
+		 *
+		 * @note	Core thread.
+		 */
+		virtual void _notifyCameraAdded(const CameraCore* camera) { }
+
+		/**
+		 * Called whenever a camera is destroyed.
+		 *
+		 * @note	Core thread.
+		 */
+		virtual void _notifyCameraRemoved(const CameraCore* camera) { }
+
+		/**
+		 * Creates a new empty renderer mesh data.
+		 *
+		 * @note	Sim thread.
+		 *			
+		 * @see		RendererMeshData
+		 */
+		virtual RendererMeshDataPtr _createMeshData(UINT32 numVertices, UINT32 numIndices, VertexLayout layout, IndexType indexType = IT_32BIT);
+
+		/**
+		 * Creates a new renderer mesh data using an existing generic mesh data buffer.
+		 *
+		 * @note	Sim thread.
+		 *			
+		 * @see		RendererMeshData
+		 */
+		virtual RendererMeshDataPtr _createMeshData(const MeshDataPtr& meshData);
+
+		/**
+		 * Registers a new callback that will be executed when the the specify camera is being rendered.
+		 *
+		 * @param[in]	camera		Camera for which to trigger the callback.
+		 * @param[in]	index		Index that determines the order of rendering when there are multiple registered 
+		 *							callbacks. This must be unique. Lower indices get rendered sooner. Indices below 0 get 
+		 *							rendered before the main viewport elements, while indices equal or greater to zero after. 
+		 * @param[in]	callback	Callback to trigger when the specified camera is being rendered.
+		 * @param[in]	isOverlay	If true the render callback guarantees that it will only render overlay data. Overlay 
+		 *							data doesn't require a depth buffer, a multisampled render target and is usually cheaper
+		 *							to render (although this depends on the exact renderer). 
+		 *							Overlay callbacks are always rendered after all other callbacks, even if their index is negative.
+		 *
+		 * @note	Core thread.
+		 */
+		void _registerRenderCallback(const CameraCore* camera, INT32 index, const std::function<void()>& callback, bool isOverlay = false);
+
+		/** Removes a previously registered callback registered with _registerRenderCallback(). */
+		void _unregisterRenderCallback(const CameraCore* camera, INT32 index);
+
+		/**	Sets options used for controlling the rendering. */
+		virtual void setOptions(const SPtr<CoreRendererOptions>& options) { }
+
+		/**	Returns current set of options used for controlling the rendering. */
+		virtual SPtr<CoreRendererOptions> getOptions() const { return SPtr<CoreRendererOptions>(); }
+
+	protected:
+		/**	Contains information about a render callback. */
+		struct RenderCallbackData
+		{
+			bool overlay;
+			std::function<void()> callback;
+		};
+
+		UnorderedMap<const CameraCore*, Map<INT32, RenderCallbackData>> mRenderCallbacks;
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 93 - 63
BansheeCore/Include/BsCoreSceneManager.h

@@ -1,64 +1,94 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsGameObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Manages all objects in the scene and provides various query methods
-	 * 			for finding objects. This is just the base class with basic query 
-	 *			functionality. You should override it with your own version that
-	 * 			implements a spatial data structure of your choice for faster queries.
-	 */
-	class BS_CORE_EXPORT CoreSceneManager : public Module<CoreSceneManager>
-	{
-	public:
-		CoreSceneManager();
-		virtual ~CoreSceneManager();
-
-		/**
-		 * @brief	Returns the root scene object.
-		 */
-		HSceneObject getRootNode() const { return mRootNode; }
-
-		/**
-		 * @brief	Called every frame.
-		 *
-		 * @note	Internal method.
-		 */
-		virtual void _update();
-
-	protected:
-		friend class SceneObject;
-
-		/**
-		 * @brief	Register a new node in the scene manager, on the top-most level of the hierarchy.
-		 * 			
-		 * @note	After you add a node in the scene manager, it takes ownership of its memory and is responsible for releasing it.
-		 * 			Do NOT add nodes that have already been added (i.e. if you just want to change their parent). Normally this method will only be called by SceneObject.
-		 *
-		 * @param [in]	node	Node you wish to add. It's your responsibility not to add duplicate or null nodes. This method won't check.
-		 */
-		void registerNewSO(const HSceneObject& node);
-
-		/**
-		 * @brief	SceneObjects call this when they have a component added to them.
-		 */
-		virtual void notifyComponentAdded(const HComponent& component);
-
-		/**
-		 * @brief	SceneObjects call this when they have a component removed from them.
-		 */
-		virtual void notifyComponentRemoved(const HComponent& component);
-
-	protected:
-		HSceneObject mRootNode;
-	};
-
-	/**
-	 * @brief	Provides easy access to the scene manager.
-	 */
-	BS_CORE_EXPORT CoreSceneManager& gSceneManager();
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsGameObject.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/**
+	 * Manages all objects in the scene and provides various query methods for finding objects. This is just the base class
+	 * with basic query functionality. You should override it with your own version.
+	 */
+	class BS_CORE_EXPORT CoreSceneManager : public Module<CoreSceneManager>
+	{
+	public:
+		CoreSceneManager();
+		virtual ~CoreSceneManager();
+
+		/**	Returns the root scene object. */
+		HSceneObject getRootNode() const { return mRootNode; }
+
+		/**
+		 * Destroys all scene objects in the scene.
+		 *
+		 * @param[in]	forceAll	If true, then even the persistent objects will be unloaded.
+		 */
+		void clearScene(bool forceAll = false);
+
+		/** Changes the root scene object. Any persistent objects will remain in the scene, now parented to the new root. */
+		void _setRootNode(const HSceneObject& root);
+
+		/** Called every frame. Calls update methods on all scene objects and their components. */
+		virtual void _update();
+
+		/** Updates dirty transforms on any core objects that may be tied with scene objects. */
+		virtual void _updateCoreObjectTransforms() { }
+
+	protected:
+		friend class SceneObject;
+
+		/**
+		 * Register a new node in the scene manager, on the top-most level of the hierarchy.
+		 * 			
+		 * @param [in]	node	Node you wish to add. It's your responsibility not to add duplicate or null nodes. This 
+		 *						method won't check.
+		 *
+		 * @note	
+		 * After you add a node in the scene manager, it takes ownership of its memory and is responsible for releasing it.
+		 * Do NOT add nodes that have already been added (i.e. if you just want to change their parent). Normally this 
+		 * method will only be called by SceneObject.
+		 */
+		void registerNewSO(const HSceneObject& node);
+
+	protected:
+		HSceneObject mRootNode;
+	};
+
+	/**
+	 * Handles creation of a scene manager.
+	 *
+	 * @note	
+	 * Since scene manager implementations may vary it is expected that a concrete implementation of a scene manager will 
+	 * register its creation method using setFactoryMethod() which will then later be used for creating the scene manager
+	 * during application start up.
+	 */
+	class BS_CORE_EXPORT SceneManagerFactory
+	{
+	public:
+		/**	Creates a concrete scene manager, depending on the currently set factory method. */
+		static void create();
+
+		/**	Sets method that will be used for creating the scene manager when create() gets called. */
+		static void setFactoryMethod(const std::function<void()>& method)
+		{
+			mFactoryMethod = method;
+		}
+
+	private:
+		static std::function<void()> mFactoryMethod;
+	};
+
+	/**	Provides easy access to the CoreSceneManager. */
+	BS_CORE_EXPORT CoreSceneManager& gCoreSceneManager();
+
+	/** @} */
+	/** @endcond */
 }

+ 220 - 206
BansheeCore/Include/BsCoreThread.h

@@ -1,206 +1,220 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsCommandQueue.h"
-#include "BsCoreThreadAccessor.h"
-#include "BsThreadPool.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Manager for the core thread. Takes care of starting, running, queuing commands
-	 * 			and shutting down the core thread.
-	 * 			
-	 * @note	How threading works:
-	 * 			 - This class contains a queue which is filled by commands from other threads via queueCommand and queueReturnCommand  
-	 * 			 - Commands are executed on the core thread as soon as they are queued (if core thread is not busy with previous commands)  
-	 * 			 - Core thread accessors are helpers for queuing commands. They serve two purposes:  
-	 * 				- They contain helper methods for various common Core thread commands.
-	 * 				- They perform better than queuing each command directly using queueCommand or queueReturnCommand    
-	 * 			 - Accessors contain a command queue of their own, and queuing commands in them will not automatically start executing the commands  
-	 * 			   like with queueCommand or queueReturnCommand. Instead you must manually call "submitAccessors" when you are ready to send their
-	 * 			   commands to the core thread.
-	 * 			 - Synced accessor is a special type of accessor which may be accessed from any thread. Its commands are always executed after all other  
-	 * 			   non-synced accessors. It is primarily useful when multiple threads are managing the same resource and you must ensure proper order of operations.
-	 * 			   You should use normal accessors whenever possible as synced accessors involve potentially slow synchronization operations.
-	 */
-	class CoreThread : public Module<CoreThread>
-	{
-		struct AccessorContainer
-		{
-			CoreAccessorPtr accessor;
-		};
-
-public:
-	BS_CORE_EXPORT CoreThread();
-	BS_CORE_EXPORT ~CoreThread();
-
-	/**
-		* @brief	Returns the id of the core thread. 
-		*/
-	BS_CORE_EXPORT BS_THREAD_ID_TYPE getCoreThreadId() { return mCoreThreadId; }
-
-	/**
-		* @brief	Creates or retrieves an accessor that you can use for executing commands on the core thread from 
-		* 			a non-core thread. The accessor will be bound to the thread you call this method on.
-		* 			
-		* @note		Accessors contain their own command queue and their commands will only start to get executed once that queue is submitted
-		* 			to the core thread via "submitAccessors" method.
-		*/
-	BS_CORE_EXPORT CoreAccessorPtr getAccessor();
-
-	/**
-	* @brief	Retrieves an accessor that you can use for executing commands on the core thread from
-	* 			a non-core thread. There is only one synchronized accessor and you may access it from any thread you wish.
-	* 			Note however that it is much more efficient to retrieve a separate non-synchronized accessor using
-	* 			"getAccessor" for each thread you will be using it on.
-	* 			
-	* @note		Accessors contain their own command queue and their commands will only start to get executed once that queue is submitted
-	* 			to the core thread via "submitAccessors" method.
-	* 			
-	*			Synced accessor commands are sent after all non-synced accessor commands are sent.
-	*/
-	BS_CORE_EXPORT SyncedCoreAccessor& getSyncedAccessor();
-
-	/**
-	 * @brief	Queues all the accessor commands and starts executing them on the core thread.
-	 */
-	BS_CORE_EXPORT void submitAccessors(bool blockUntilComplete = false);
-
-	/**
-		* @brief	Queues a new command that will be added to the global command queue. You are allowed to call this from any thread,
-		* 			however be aware that it involves possibly slow synchronization primitives, so limit your usage.
-		* 			
-		* @param	blockUntilComplete If true the thread will be blocked until the command executes. Be aware that there may be many commands queued before it
-		* 							   and they all need to be executed in order before the current command is reached, which might take a long time.
-		* 	
-		* @see		CommandQueue::queueReturn
-		*/
-	BS_CORE_EXPORT AsyncOp queueReturnCommand(std::function<void(AsyncOp&)> commandCallback, bool blockUntilComplete = false);
-
-	/**
-	* @brief	Queues a new command that will be added to the global command queue.You are allowed to call this from any thread,
-		* 			however be aware that it involves possibly slow synchronization primitives, so limit your usage.
-		* 	
-		* @param	blockUntilComplete If true the thread will be blocked until the command executes. Be aware that there may be many commands queued before it
-		* 							   and they all need to be executed in order before the current command is reached, which might take a long time.
-		* @see		CommandQueue::queue
-		*/
-	BS_CORE_EXPORT void queueCommand(std::function<void()> commandCallback, bool blockUntilComplete = false);
-
-	/**
-	 * @brief	Called once every frame.
-	 * 			
-	 * @note	Must be called before sim thread schedules any core thread operations for the frame. 
-	 */
-	BS_CORE_EXPORT void update();
-
-	/**
-	 * @brief	Returns a frame allocator that should be used for allocating temporary data being passed to the
-	 * 			core thread. As the name implies the data only lasts one frame, so you need to be careful not
-	 * 			to use it for longer than that.
-	 * 			
-	 * @note	Sim thread only.
-	 */
-	BS_CORE_EXPORT FrameAlloc* getFrameAlloc() const;
-private:
-	/**
-	 * @brief	Double buffered frame allocators. Means sim thread cannot be more than 1 frame ahead of core thread
-	 *			(If that changes you should be able to easily add more).
-	 */
-	FrameAlloc* mFrameAllocs[2]; 
-	UINT32 mActiveFrameAlloc;
-
-	static BS_THREADLOCAL AccessorContainer* mAccessor;
-	Vector<AccessorContainer*> mAccessors;
-
-	volatile bool mCoreThreadShutdown;
-
-	HThread mCoreThread;
-	BS_THREAD_ID_TYPE mCoreThreadId;
-	BS_MUTEX(mCommandQueueMutex)
-	BS_MUTEX(mAccessorMutex)
-	BS_THREAD_SYNCHRONISER(mCommandReadyCondition)
-	BS_MUTEX(mCommandNotifyMutex)
-	BS_THREAD_SYNCHRONISER(mCommandCompleteCondition)
-
-	CommandQueue<CommandQueueSync>* mCommandQueue;
-
-	UINT32 mMaxCommandNotifyId; /**< ID that will be assigned to the next command with a notifier callback. */
-	Vector<UINT32> mCommandsCompleted; /**< Completed commands that have notifier callbacks set up */
-
-	SyncedCoreAccessor* mSyncedCoreAccessor;
-
-	/**
-		* @brief	Starts the core thread worker method. Should only be called once.
-		*/
-	void initCoreThread();
-
-	/**
-		* @brief	Main worker method of the core thread. Called once thread is started.
-		*/
-	void runCoreThread();
-
-	/**
-		* @brief	Shutdowns the core thread. It will complete all ready commands
-		* 			before shutdown.
-		*/
-	void shutdownCoreThread();
-
-	/**
-		* @brief	Blocks the calling thread until the command with the specified ID completes.
-		* 			Make sure that the specified ID actually exists, otherwise this will block forever.
-		*/
-	void blockUntilCommandCompleted(UINT32 commandId);
-
-	/**
-		* @brief	Callback called by the command list when a specific command finishes executing.
-		* 			This is only called on commands that have a special notify on complete flag set.
-		*
-		* @param	commandId	Identifier for the command.
-		*/
-	void commandCompletedNotify(UINT32 commandId);
-	};
-
-	/**
-	 * @brief	Returns the core thread manager used for dealing with the core thread from external threads.
-	 * 			
-	 * @see		CoreThread
-	 */
-	BS_CORE_EXPORT CoreThread& gCoreThread();
-
-	/**
-	 * @brief	Returns a core thread accessor for the current thread. Accessor is retrieved or created depending
-	 * 			if it previously existed. Each thread has its own accessor.
-	 * 	
-	 * @see		CoreThread
-	 */
-	BS_CORE_EXPORT CoreThreadAccessor<CommandQueueNoSync>& gCoreAccessor();
-
-	/**
-	 * @brief	Returns a synchronized core accessor you may call from any thread for working with the core thread.
-	 * 			Only one of these exists.
-	 * 			
-	 * @see		CoreThread
-	 */
-	BS_CORE_EXPORT CoreThreadAccessor<CommandQueueSync>& gSyncedCoreAccessor();
-
-	/**
-	  * @brief	Throws an exception if current thread isn't the core thread;
-	  */
-	BS_CORE_EXPORT void throwIfNotCoreThread();
-
-	/**
-	  * @brief	Throws an exception if current thread is the core thread;
-	  */
-	BS_CORE_EXPORT void throwIfCoreThread();
-
-#if BS_DEBUG_MODE
-#define THROW_IF_NOT_CORE_THREAD throwIfNotCoreThread();
-#define THROW_IF_CORE_THREAD throwIfCoreThread();
-#else
-#define THROW_IF_NOT_CORE_THREAD 
-#define THROW_IF_CORE_THREAD
-#endif
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsCommandQueue.h"
+#include "BsCoreThreadAccessor.h"
+#include "BsThreadPool.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup CoreThread
+	 *  @{
+	 */
+	/** @cond INTERNAL */
+
+	/**
+	 * Manager for the core thread. Takes care of starting, running, queuing commands and shutting down the core thread.
+	 * 			
+	 * @note	
+	 * How threading works:
+	 * 	- This class contains a queue which is filled by commands from other threads via queueCommand() and queueReturnCommand()  
+	 * 	- Commands are executed on the core thread as soon as they are queued (if core thread is not busy with previous commands)  
+	 * 	- Core thread accessors are helpers for queuing commands. They perform better than queuing each command directly 
+	 *    using queueCommand() or queueReturnCommand().
+	 * 	- Accessors contain a command queue of their own, and queuing commands in them will not automatically start 
+	 *    executing the commands like with queueCommand or queueReturnCommand. Instead you must manually call 
+	 *    submitAccessors() when you are ready to send their commands to the core thread. Sending commands "in bulk" like 
+	 *    this is what makes them faster than directly queuing commands.
+	 * 	- Synced accessor is a special type of accessor which may be accessed from any thread. Its commands are always 
+	 *    executed after all other non-synced accessors. It is primarily useful when multiple threads are managing the same
+	 *    resource and you must ensure proper order of operations. You should use normal accessors whenever possible as 
+	 *    synced accessors involve potentially slow synchronization operations.
+	 */
+	class BS_CORE_EXPORT CoreThread : public Module<CoreThread>
+	{
+		/** Contains data about an accessor for a specific thread. */
+		struct AccessorContainer
+		{
+			CoreAccessorPtr accessor;
+			bool isMain;
+		};
+
+		/** Wrapper for the thread-local variable because MSVC can't deal with a thread-local variable marked with dllimport or dllexport,  
+		 *  and we cannot use per-member dllimport/dllexport specifiers because Module's members will then not be exported and its static
+		 *  members will not have external linkage. */
+		struct AccessorData
+		{
+			static BS_THREADLOCAL AccessorContainer* current;
+		};
+
+public:
+	CoreThread();
+	~CoreThread();
+
+	/** Returns the id of the core thread.  */
+	BS_THREAD_ID_TYPE getCoreThreadId() { return mCoreThreadId; }
+
+	/**
+	 * Creates or retrieves an accessor that you can use for executing commands on the core thread from a non-core thread. 
+	 * The accessor will be bound to the thread you call this method on.
+	 * 			
+	 * @note		
+	 * Accessors contain their own command queue and their commands will only start to get executed once that queue is 
+	 * submitted to the core thread via submitAccessors() method.
+	 */
+	CoreAccessorPtr getAccessor();
+
+	/**
+	 * Retrieves an accessor that you can use for executing commands on the core thread from a non-core thread. There is 
+	 * only one synchronized accessor and you may access it from any thread you wish. Note however that it is much more 
+	 * efficient to retrieve a separate non-synchronized accessor for each thread you will be using it on.
+	 * 			
+	 * @note	
+	 * Accessors contain their own command queue and their commands will only start to get executed once that queue
+	 * is submitted to the core thread via submitAccessors() method.
+	 * @note			
+	 * Synced accessor commands are sent after all non-synced accessor commands are sent.
+	 */
+	SyncedCoreAccessor& getSyncedAccessor();
+
+	/** Queues all the accessor commands and starts executing them on the core thread. */
+	void submitAccessors(bool blockUntilComplete = false);
+
+	/**
+	 * Queues a new command that will be added to the global command queue. You are allowed to call this from any thread,
+	 * however be aware that it involves possibly slow synchronization primitives, so limit your usage.
+	 * 			
+	 * @param[in]	blockUntilComplete	If true the thread will be blocked until the command executes. Be aware that there 
+	 *									may be many commands queued before it and they all need to be executed in order 
+	 *									before the current command is reached, which might take a long time.
+	 * 	
+	 * @see		CommandQueue::queueReturn()
+	 */
+	AsyncOp queueReturnCommand(std::function<void(AsyncOp&)> commandCallback, bool blockUntilComplete = false);
+
+	/**
+	 * Queues a new command that will be added to the global command queue.You are allowed to call this from any thread,
+	 * however be aware that it involves possibly slow synchronization primitives, so limit your usage.
+	 * 	
+	 * @param[in]	blockUntilComplete	If true the thread will be blocked until the command executes. Be aware that there 
+	 *									may be many commands queued before it and they all need to be executed in order 
+	 *									before the current command is reached, which might take a long time.
+	 *
+	 * @see		CommandQueue::queue()
+	 */
+	void queueCommand(std::function<void()> commandCallback, bool blockUntilComplete = false);
+
+	/**
+	 * Called once every frame.
+	 * 			
+	 * @note	Must be called before sim thread schedules any core thread operations for the frame. 
+	 */
+	void update();
+
+	/**
+	 * Returns a frame allocator that should be used for allocating temporary data being passed to the core thread. As the 
+	 * name implies the data only lasts one frame, so you need to be careful not to use it for longer than that.
+	 * 			
+	 * @note	Sim thread only.
+	 */
+	FrameAlloc* getFrameAlloc() const;
+private:
+	static const int NUM_FRAME_ALLOCS = 2;
+
+	/**
+	 * Double buffered frame allocators. Means sim thread cannot be more than 1 frame ahead of core thread (If that changes
+	 * you should be able to easily add more).
+	 */
+	FrameAlloc* mFrameAllocs[NUM_FRAME_ALLOCS];
+	UINT32 mActiveFrameAlloc;
+
+	static AccessorData mAccessor;
+	Vector<AccessorContainer*> mAccessors;
+
+	volatile bool mCoreThreadShutdown;
+
+	HThread mCoreThread;
+	bool mCoreThreadStarted;
+	BS_THREAD_ID_TYPE mSimThreadId;
+	BS_THREAD_ID_TYPE mCoreThreadId;
+	BS_MUTEX(mCommandQueueMutex)
+	BS_MUTEX(mAccessorMutex)
+	BS_THREAD_SYNCHRONISER(mCommandReadyCondition)
+	BS_MUTEX(mCommandNotifyMutex)
+	BS_THREAD_SYNCHRONISER(mCommandCompleteCondition)
+	BS_MUTEX(mThreadStartedMutex)
+	BS_THREAD_SYNCHRONISER(mCoreThreadStartedCondition)
+
+	CommandQueue<CommandQueueSync>* mCommandQueue;
+
+	UINT32 mMaxCommandNotifyId; /**< ID that will be assigned to the next command with a notifier callback. */
+	Vector<UINT32> mCommandsCompleted; /**< Completed commands that have notifier callbacks set up */
+
+	SyncedCoreAccessor* mSyncedCoreAccessor;
+
+	/** Starts the core thread worker method. Should only be called once. */
+	void initCoreThread();
+
+	/**	Main worker method of the core thread. Called once thread is started. */
+	void runCoreThread();
+
+	/** Shutdowns the core thread. It will complete all ready commands before shutdown. */
+	void shutdownCoreThread();
+
+	/**
+	 * Blocks the calling thread until the command with the specified ID completes. Make sure that the specified ID 
+	 * actually exists, otherwise this will block forever.
+	 */
+	void blockUntilCommandCompleted(UINT32 commandId);
+
+	/**
+	 * Callback called by the command list when a specific command finishes executing. This is only called on commands that
+	 * have a special notify on complete flag set.
+	 *
+	 * @param[in]	commandId	Identifier for the command.
+	 */
+	void commandCompletedNotify(UINT32 commandId);
+	};
+
+	/**
+	 * Returns the core thread manager used for dealing with the core thread from external threads.
+	 * 			
+	 * @see		CoreThread
+	 */
+	BS_CORE_EXPORT CoreThread& gCoreThread();
+
+	/**	Throws an exception if current thread isn't the core thread. */
+	BS_CORE_EXPORT void throwIfNotCoreThread();
+
+	/** Throws an exception if current thread is the core thread. */
+	BS_CORE_EXPORT void throwIfCoreThread();
+
+#if BS_DEBUG_MODE
+#define THROW_IF_NOT_CORE_THREAD throwIfNotCoreThread();
+#define THROW_IF_CORE_THREAD throwIfCoreThread();
+#else
+#define THROW_IF_NOT_CORE_THREAD 
+#define THROW_IF_CORE_THREAD
+#endif
+
+	/** @endcond */
+
+	/** 
+	 * Creates or retrieves an accessor that you can use for executing commands on the core thread from a non-core thread. 
+	 * The accessor will be bound to the thread you call this method on. 
+	 */
+	BS_CORE_EXPORT CoreThreadAccessor<CommandQueueNoSync>& gCoreAccessor();
+
+	/**
+	 * Retrieves an accessor that you can use for executing commands on the core thread from a non-core thread. There is 
+	 * only one synchronized accessor and you may access it from any thread you wish. Note however that it is much more 
+	 * efficient to retrieve a separate non-synchronized accessor for each thread you will be using it on.
+	 */
+	BS_CORE_EXPORT CoreThreadAccessor<CommandQueueSync>& gSyncedCoreAccessor();
+
+	/** @} */
+}
+

+ 74 - 199
BansheeCore/Include/BsCoreThreadAccessor.h

@@ -1,200 +1,75 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRenderSystem.h"
-#include "BsCommandQueue.h"
-#include "BsAsyncOp.h"
-#include "BsViewport.h"
-#include "BsColor.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains some base functionality used for CoreThreadAccessor.
-	 * 			
-	 * @see		CoreThreadAccesor
-	 */
-	class BS_CORE_EXPORT CoreThreadAccessorBase
-	{
-	public:
-		CoreThreadAccessorBase(CommandQueueBase* commandQueue);
-		virtual ~CoreThreadAccessorBase();
-
-		/** @copydoc RenderSystem::disableTextureUnit() */
-		void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit);
-
-		/** @copydoc RenderSystem::setTexture() */
-		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
-
-		/** @copydoc RenderSystem::setSamplerState() */
-		void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerStatePtr& samplerState);
-
-		/** @copydoc RenderSystem::setBlendState() */
-		void setBlendState(const BlendStatePtr& blendState);
-
-		/** @copydoc RenderSystem::setRasterizerState() */
-		void setRasterizerState(const RasterizerStatePtr& rasterizerState);
-
-		/** @copydoc RenderSystem::setRasterizerState() */
-		void setDepthStencilState(const DepthStencilStatePtr& depthStencilState, UINT32 stencilRefValue);
-
-		/** @copydoc RenderSystem::setViewport() */
-		void setViewport(Viewport vp);
-
-		/** @copydoc RenderSystem::setDrawOperation() */
-		void setDrawOperation(DrawOperationType op);
-
-		/** @copydoc RenderSystem::setClipPlanes() */
-		void setClipPlanes(const PlaneList& clipPlanes);
-
-		/** @copydoc RenderSystem::addClipPlane(const Plane&) */
-		void addClipPlane(const Plane& p);
-
-		/** @copydoc RenderSystem::resetClipPlanes() */
-		void resetClipPlanes();
-
-		/** @copydoc RenderSystem::setScissorTest() */
-		void setScissorTest(UINT32 left = 0, UINT32 top = 0, UINT32 right = 800, UINT32 bottom = 600);
-
-		/** @copydoc RenderSystem::setRenderTarget() */
-		void setRenderTarget(RenderTargetPtr target);
-
-		/** @copydoc RenderSystem::bindGpuProgram() */
-		void bindGpuProgram(HGpuProgram prg);
-
-		/** @copydoc RenderSystem::unbindGpuProgram() */
-		void unbindGpuProgram(GpuProgramType gptype);
-
-		/** @copydoc RenderSystem::bindGpuParams() */
-		void bindGpuParams(GpuProgramType gptype, const GpuParamsPtr& params);
-
-		/** @copydoc RenderSystem::beginFrame() */
-		void beginRender();
-
-		/** @copydoc RenderSystem::endFrame() */
-		void endRender();
-
-		/** @copydoc RenderSystem::clearRenderTarget() */
-		void clearRenderTarget(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0);
-
-		/** @copydoc RenderSystem::clearViewport() */
-		void clearViewport(UINT32 buffers, const Color& color = Color::Black, float depth = 1.0f, UINT16 stencil = 0);
-
-		/** @copydoc RenderSystem::swapBuffers() */
-		void swapBuffers(RenderTargetPtr target);
-
-		/** @copydoc RenderSystem::render() */
-		void render(const MeshBasePtr& mesh, UINT32 indexOffset = 0, UINT32 indexCount = 0, bool useIndices = true, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/** @copydoc RenderSystem::draw() */
-		void draw(UINT32 vertexOffset, UINT32 vertexCount);
-
-		/** @copydoc RenderSystem::drawIndexed() */
-		void drawIndexed(UINT32 startIndex, UINT32 indexCount, UINT32 vertexOffset, UINT32 vertexCount);
-
-		/**
-		 * @copydoc RenderSystem::writeSubresource()
-		 *
-		 * @param discardEntireBuffer When true the existing contents of the resource you are updating will be discarded. This can make the
-		 * 							  operation faster. Resources with certain buffer types might require this flag to be in a specific state
-		 * 							  otherwise the operation will fail. 
-		 *
-		 * @note Resource is updated with data from "data" parameter when the async operation completes. 
-		 * 		 Until the async operation completes "data" is owned by the core thread and you won't
-		 * 		 be able to access it. 
-		 * 		 
-		 *		Normally dynamic buffers will require you to enable "discardEntireBuffer" flag, while static buffers require it disabled.
-		 */
-		AsyncOp writeSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data, bool discardEntireBuffer = false);
-
-		/**
-		 * @copydoc RenderSystem::readSubresource()
-		 *
-		 * @note "data" parameter is populated with subresource data when the async operation completes. 
-		 * 		 Until the async operation completes "data" is owned by the core thread and you won't
-		 * 		 be able to access it.
-		 */
-		AsyncOp readSubresource(GpuResourcePtr resource, UINT32 subresourceIdx, const GpuResourceDataPtr& data);
-
-		/**
-		 * @brief	Resize the provided window to specified width and height in pixels.
-		 */
-		void resizeWindow(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height);
-
-		/**
-		 * @brief	Move the provided window to specified screen coordinates.
-		 */
-		void moveWindow(RenderWindowPtr& renderWindow, INT32 left, INT32 top);
-
-		/**
-		 * @brief	Hide the provided window. (Does not destroy it, just hides it).
-		 */
-		void hideWindow(RenderWindowPtr& renderWindow);
-
-		/**
-		 * @brief	Shows a previously hidden window.
-		 */
-		void showWindow(RenderWindowPtr& renderWindow);
-
-		/**
-		 * @copydoc RenderWindow::setFullscreen(UINT32, UINT32, float, UINT32)
-		 */
-		void setFullscreen(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height, float refreshRate = 60.0f, UINT32 monitorIdx = 0);
-
-		/**
-		 * @copydoc RenderWindow::setFullscreen(const VideoMode&)
-		 */
-		void setFullscreen(RenderWindowPtr& renderWindow, const VideoMode& mode);
-
-		/**
-		 * @copydoc RenderWindow::setWindowed
-		 */
-		void setWindowed(RenderWindowPtr& renderWindow, UINT32 width, UINT32 height);
-
-		/**
-		* @brief	Queues a new generic command that will be added to the command queue.
-		*/
-		AsyncOp queueReturnCommand(std::function<void(AsyncOp&)> commandCallback);
-
-		/**
-		* @brief	Queues a new generic command that will be added to the command queue.
-		*/
-		void queueCommand(std::function<void()> commandCallback);
-
-		/**
-		 * @brief	Makes all the currently queued commands available to the core thread. They will be executed
-		 * 			as soon as the core thread is ready. All queued commands are removed from the accessor.
-		 */
-		void submitToCoreThread(bool blockUntilComplete = false);
-
-		/**
-		 * @brief	Cancels all commands in the queue.
-		 */
-		void cancelAll();
-
-	private:
-		CommandQueueBase* mCommandQueue;
-	};
-
-	/**
-	 * @brief	Core thread accessor allows you to schedule core commands outside of the core thread. Provides a set of common
-	 * 			methods you may want to execute on the core thread, as well as a general command queuing methods.
-	 * 			
-	 * @note	Queued commands are only executed after the call to submitToCoreThread, in the order they were submitted.
-	 */
-	template <class CommandQueueSyncPolicy = CommandQueueNoSync>
-	class BS_CORE_EXPORT CoreThreadAccessor : public CoreThreadAccessorBase
-	{
-	public:
-		/**
-		 * @brief	Constructor.
-		 *
-		 * @param	threadId		Identifier for the thread that created the accessor.
-		 */
-		CoreThreadAccessor(BS_THREAD_ID_TYPE threadId)
-			:CoreThreadAccessorBase(bs_new<CommandQueue<CommandQueueSyncPolicy>>(threadId))
-		{
-
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCommandQueue.h"
+#include "BsAsyncOp.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup CoreThread
+	 *  @{
+	 */
+
+	/**
+	 * Contains base functionality used for CoreThreadAccessor.
+	 * 			
+	 * @see		CoreThreadAccesor
+	 */
+	class BS_CORE_EXPORT CoreThreadAccessorBase
+	{
+	public:
+		CoreThreadAccessorBase(CommandQueueBase* commandQueue);
+		virtual ~CoreThreadAccessorBase();
+
+		/**
+		 * Queues a new generic command that will be added to the command queue. Returns an async operation object that you 
+		 * may use to check if the operation has finished, and to retrieve the return value once finished.
+		 */
+		AsyncOp queueReturnCommand(std::function<void(AsyncOp&)> commandCallback);
+
+		/** Queues a new generic command that will be added to the command queue. */
+		void queueCommand(std::function<void()> commandCallback);
+
+		/**
+		 * Makes all the currently queued commands available to the core thread. They will be executed as soon as the core 
+		 * thread is ready. All queued commands are removed from the accessor.
+		 *
+		 * @param[in]	blockUntilComplete	If true, the calling thread will block until the core thread finished executing
+		 *									all currently queued commands. This is usually very expensive and should only be
+		 *									used in performance non-critical code.
+		 */
+		void submitToCoreThread(bool blockUntilComplete = false);
+
+		/** Cancels all commands in the queue. */
+		void cancelAll();
+
+	private:
+		CommandQueueBase* mCommandQueue;
+	};
+
+	/**
+	 * Core thread accessor allows you to schedule core commands outside of the core thread. Provides a set of common 
+	 * methods you may want to execute on the core thread, as well as a general command queuing methods.
+	 * 			
+	 * @note	Queued commands are only executed after the call to submitToCoreThread(), in the order they were submitted.
+	 */
+	template <class CommandQueueSyncPolicy = CommandQueueNoSync>
+	class BS_CORE_EXPORT CoreThreadAccessor : public CoreThreadAccessorBase
+	{
+	public:
+		/**
+		 * Constructor.
+		 *
+		 * @param[in]	threadId		Identifier for the thread that created the accessor.
+		 */
+		CoreThreadAccessor(BS_THREAD_ID_TYPE threadId)
+			:CoreThreadAccessorBase(bs_new<CommandQueue<CommandQueueSyncPolicy>>(threadId))
+		{
+
+		}
+	};
+
+	/** @} */
 }

+ 42 - 36
BansheeCore/Include/BsDeferredCallManager.h

@@ -1,37 +1,43 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Allows you to queue calls that can get executed later.
-	 * 			
-	 * @note	Sim thread only.
-	 */
-	class BS_CORE_EXPORT DeferredCallManager : public Module<DeferredCallManager>
-	{
-	public:
-		DeferredCallManager();
-
-		/**
-		 * @brief	Register a deferred call that will be executed once at the start of next frame.
-		 *
-		 * @param	func		The function to execute.
-		 */
-		void queueDeferredCall(std::function<void()> func);
-
-		/**
-		 * @brief	Executes all the scheduled calls. To be called once per frame.
-		 *
-		 * @note	Internal method.
-		 */
-		void _update();
-
-	private:
-		friend class DeferredCall;
-
-		Vector<std::function<void()>> mCallbacks;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Utility-Core
+	 *  @{
+	 */
+
+	/**
+	 * Allows you to queue calls that can get executed later.
+	 * 			
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT DeferredCallManager : public Module<DeferredCallManager>
+	{
+	public:
+		DeferredCallManager();
+
+		/**
+		 * Register a deferred call that will be executed once at the start of next frame.
+		 *
+		 * @param[in]	func	The function to execute.
+		 */
+		void queueDeferredCall(std::function<void()> func);
+
+		/** Executes all the scheduled calls. To be called once per frame. */
+		void _update();
+
+	private:
+		friend class DeferredCall;
+
+		Vector<std::function<void()>> mCallbacks;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 244 - 171
BansheeCore/Include/BsDepthStencilState.h

@@ -1,171 +1,244 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Descriptor structured used for initializing DepthStencilState.
-	 *
-	 * @see		DepthStencilState
-	 */
-	struct BS_CORE_EXPORT DEPTH_STENCIL_STATE_DESC
-	{
-		DEPTH_STENCIL_STATE_DESC()
-			: depthReadEnable(true)
-			, depthWriteEnable(true)
-			, depthComparisonFunc(CMPF_LESS)
-			, stencilEnable(false)
-			, stencilReadMask(0xFF)
-			, stencilWriteMask(0xFF)
-			, frontStencilFailOp(SOP_KEEP)
-			, frontStencilZFailOp(SOP_KEEP)
-			, frontStencilPassOp(SOP_KEEP)
-			, frontStencilComparisonFunc(CMPF_ALWAYS_PASS)
-			, backStencilFailOp(SOP_KEEP)
-			, backStencilZFailOp(SOP_KEEP)
-			, backStencilPassOp(SOP_KEEP)
-			, backStencilComparisonFunc(CMPF_ALWAYS_PASS)
-		{ }
-
-		bool depthReadEnable;
-		bool depthWriteEnable;
-		CompareFunction depthComparisonFunc;
-
-		bool stencilEnable;
-		UINT8 stencilReadMask;
-		UINT8 stencilWriteMask;
-
-		StencilOperation frontStencilFailOp;
-		StencilOperation frontStencilZFailOp;
-		StencilOperation frontStencilPassOp;
-		CompareFunction frontStencilComparisonFunc;
-
-		StencilOperation backStencilFailOp;
-		StencilOperation backStencilZFailOp;
-		StencilOperation backStencilPassOp;
-		CompareFunction backStencilComparisonFunc;
-	};
-
-	BS_ALLOW_MEMCPY_SERIALIZATION(DEPTH_STENCIL_STATE_DESC);
-
-	/**
-	* @brief	Render system pipeline state that allows you to modify how an object is rendered.
-	* 			More exactly this state allows to you to control how are depth and stencil buffers
-	*			modified upon rendering.
-	*
-	* @note		Depth stencil states are immutable. Thread safe.
-	*/
-	class BS_CORE_EXPORT DepthStencilState : public Resource
-	{
-	public:
-		virtual ~DepthStencilState() {}
-
-		/**
-		 * @brief	If enabled, any pixel about to be written will be tested against the depth value
-		 *			currently in the buffer. If the depth test passes (depending on the set value
-		 *			and chosen depth comparison function), that pixel is written and depth is
-		 *			updated (if depth write is enabled).
-		 */
-		bool getDepthReadEnable() const { return mData.depthReadEnable; }
-
-		/**
-		 * @brief	If enabled rendering pixels will update the depth buffer value. 
-		 */
-		bool getDepthWriteEnable() const { return mData.depthWriteEnable; }
-
-		/**
-		 * @brief	Determines what operation should the renderer use when comparing previous and 
-		 *			current depth value. If the operation passes, pixel with the current depth
-		 *			value will be considered visible.
-		 */
-		CompareFunction getDepthComparisonFunc() const { return mData.depthComparisonFunc; }
-
-		/**
-		 * @brief	If true then stencil buffer will also be updated when a pixel is written, and
-		 *			pixels will be tested against the stencil buffer before rendering.
-		 */
-		bool getStencilEnable() const { return mData.stencilEnable; }
-
-		/**
-		 * @brief	Mask to apply to any value read from the stencil buffer, before applying the
-		 *			stencil comparison function.
-		 */
-		UINT8 getStencilReadMask() const { return mData.stencilReadMask; }
-
-		/**
-		 * @brief	Mask to apply to any value about to be written in the stencil buffer.
-		 */
-		UINT8 getStencilWriteMask() const { return mData.stencilWriteMask; }
-
-		/**
-		 * @brief	Operation that happens when stencil comparison function fails on a front facing polygon.
-		 */
-		StencilOperation getStencilFrontFailOp() const { return mData.frontStencilFailOp; }
-
-		/**
-		* @brief	Operation that happens when stencil comparison function passes but depth test fails
-		*			on a front facing polygon.
-		*/
-		StencilOperation getStencilFrontZFailOp() const { return mData.frontStencilZFailOp; }
-
-		/**
-		* @brief	Operation that happens when stencil comparison function passes on a front facing polygon.
-		*/
-		StencilOperation getStencilFrontPassOp() const { return mData.frontStencilPassOp; }
-
-		/**
-		 * @brief	Stencil comparison function used for front facing polygons. Stencil buffer will be modified according
-		 *			to previously set stencil operations depending whether this comparison passes or fails.
-		 */
-		CompareFunction getStencilFrontCompFunc() const { return mData.frontStencilComparisonFunc; }
-
-		/**
-		* @brief	Operation that happens when stencil comparison function fails on a back facing polygon.
-		*/
-		StencilOperation getStencilBackFailOp() const { return mData.backStencilFailOp; }
-
-		/**
-		* @brief	Operation that happens when stencil comparison function passes but depth test fails
-		*			on a back facing polygon.
-		*/
-		StencilOperation getStencilBackZFailOp() const { return mData.backStencilZFailOp; }
-
-		/**
-		* @brief	Operation that happens when stencil comparison function passes on a back facing polygon.
-		*/
-		StencilOperation getStencilBackPassOp() const { return mData.backStencilPassOp; }
-
-		/**
-		* @brief	Stencil comparison function used for back facing polygons. Stencil buffer will be modified according
-		*			to previously set stencil operations depending whether this comparison passes or fails.
-		*/
-		CompareFunction getStencilBackCompFunc() const { return mData.backStencilComparisonFunc; }
-
-		/**
-		 * @brief	Creates a new depth stencil state using the specified depth stencil state description structure.
-		 */
-		static HDepthStencilState create(const DEPTH_STENCIL_STATE_DESC& desc);
-
-		/**
-		 * @brief	Returns the default depth stencil state that you may use when no other is available.
-		 */
-		static const DepthStencilStatePtr& getDefault();
-	protected:
-		friend class RenderStateManager;
-
-		virtual void initialize(const DEPTH_STENCIL_STATE_DESC& desc);
-
-		DEPTH_STENCIL_STATE_DESC mData;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-
-	public:
-		friend class DepthStencilStateRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Descriptor structured used for initializing DepthStencilState.
+	 *
+	 * @see		DepthStencilState
+	 */
+	struct BS_CORE_EXPORT DEPTH_STENCIL_STATE_DESC
+	{
+		DEPTH_STENCIL_STATE_DESC()
+			: depthReadEnable(true)
+			, depthWriteEnable(true)
+			, depthComparisonFunc(CMPF_LESS)
+			, stencilEnable(false)
+			, stencilReadMask(0xFF)
+			, stencilWriteMask(0xFF)
+			, frontStencilFailOp(SOP_KEEP)
+			, frontStencilZFailOp(SOP_KEEP)
+			, frontStencilPassOp(SOP_KEEP)
+			, frontStencilComparisonFunc(CMPF_ALWAYS_PASS)
+			, backStencilFailOp(SOP_KEEP)
+			, backStencilZFailOp(SOP_KEEP)
+			, backStencilPassOp(SOP_KEEP)
+			, backStencilComparisonFunc(CMPF_ALWAYS_PASS)
+		{ }
+
+		bool operator==(const DEPTH_STENCIL_STATE_DESC& rhs) const;
+
+		bool depthReadEnable;
+		bool depthWriteEnable;
+		CompareFunction depthComparisonFunc;
+
+		bool stencilEnable;
+		UINT8 stencilReadMask;
+		UINT8 stencilWriteMask;
+
+		StencilOperation frontStencilFailOp;
+		StencilOperation frontStencilZFailOp;
+		StencilOperation frontStencilPassOp;
+		CompareFunction frontStencilComparisonFunc;
+
+		StencilOperation backStencilFailOp;
+		StencilOperation backStencilZFailOp;
+		StencilOperation backStencilPassOp;
+		CompareFunction backStencilComparisonFunc;
+	};
+
+	/** @cond SPECIALIZATIONS */
+	BS_ALLOW_MEMCPY_SERIALIZATION(DEPTH_STENCIL_STATE_DESC);
+	/** @endcond */
+
+	/** Properties of DepthStencilState. Shared between sim and core thread versions of DepthStencilState. */
+	class BS_CORE_EXPORT DepthStencilProperties
+	{
+	public:
+		DepthStencilProperties(const DEPTH_STENCIL_STATE_DESC& desc);
+
+		/**
+		 * If enabled, any pixel about to be written will be tested against the depth value currently in the buffer. If the 
+		 * depth test passes (depending on the set valueand chosen depth comparison function), that pixel is written and 
+		 * depth is updated (if depth write is enabled).
+		 */
+		bool getDepthReadEnable() const { return mData.depthReadEnable; }
+
+		/** If enabled rendering pixels will update the depth buffer value. */
+		bool getDepthWriteEnable() const { return mData.depthWriteEnable; }
+
+		/**
+		 * Determines what operation should the renderer use when comparing previous and current depth value. If the 
+		 * operation passes, pixel with the current depth value will be considered visible.
+		 */
+		CompareFunction getDepthComparisonFunc() const { return mData.depthComparisonFunc; }
+
+		/**
+		 * If true then stencil buffer will also be updated when a pixel is written, and pixels will be tested against 
+		 * the stencil buffer before rendering.
+		 */
+		bool getStencilEnable() const { return mData.stencilEnable; }
+
+		/** Mask to apply to any value read from the stencil buffer, before applying the stencil comparison function. */
+		UINT8 getStencilReadMask() const { return mData.stencilReadMask; }
+
+		/**	Mask to apply to any value about to be written in the stencil buffer. */
+		UINT8 getStencilWriteMask() const { return mData.stencilWriteMask; }
+
+		/**	Operation that happens when stencil comparison function fails on a front facing polygon. */
+		StencilOperation getStencilFrontFailOp() const { return mData.frontStencilFailOp; }
+
+		/** Operation that happens when stencil comparison function passes but depth test fails on a front facing polygon. */
+		StencilOperation getStencilFrontZFailOp() const { return mData.frontStencilZFailOp; }
+
+		/**	Operation that happens when stencil comparison function passes on a front facing polygon. */
+		StencilOperation getStencilFrontPassOp() const { return mData.frontStencilPassOp; }
+
+		/**
+		 * Stencil comparison function used for front facing polygons. Stencil buffer will be modified according to 
+		 * previously set stencil operations depending whether this comparison passes or fails.
+		 */
+		CompareFunction getStencilFrontCompFunc() const { return mData.frontStencilComparisonFunc; }
+
+		/** Operation that happens when stencil comparison function fails on a back facing polygon. */
+		StencilOperation getStencilBackFailOp() const { return mData.backStencilFailOp; }
+
+		/** Operation that happens when stencil comparison function passes but depth test fails on a back facing polygon. */
+		StencilOperation getStencilBackZFailOp() const { return mData.backStencilZFailOp; }
+
+		/**	Operation that happens when stencil comparison function passes on a back facing polygon. */
+		StencilOperation getStencilBackPassOp() const { return mData.backStencilPassOp; }
+
+		/**
+		 * Stencil comparison function used for back facing polygons. Stencil buffer will be modified according	to 
+		 * previously set stencil operations depending whether this comparison passes or fails.
+		 */
+		CompareFunction getStencilBackCompFunc() const { return mData.backStencilComparisonFunc; }
+
+		/** Returns the hash value generated from the depth-stencil state properties. */
+		UINT64 getHash() const { return mHash; }
+
+	protected:
+		friend class DepthStencilState;
+		friend class DepthStencilStateCore;
+		friend class DepthStencilStateRTTI;
+
+		DEPTH_STENCIL_STATE_DESC mData;
+		UINT64 mHash;
+	};
+
+	/** @cond INTERNAL */
+
+	/**
+	 * Core thread version of DepthStencilState.
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT DepthStencilStateCore : public CoreObjectCore
+	{
+	public:
+		virtual ~DepthStencilStateCore();
+
+		/**	Returns information about the depth stencil state. */
+		const DepthStencilProperties& getProperties() const;
+
+		/**	Returns a unique state ID. Only the lowest 10 bits are used. */
+		UINT32 getId() const { return mId; }
+
+		/**	Returns the default depth stencil state that you may use when no other is available. */
+		static const SPtr<DepthStencilStateCore>& getDefault();
+
+	protected:
+		friend class RenderStateCoreManager;
+
+		DepthStencilStateCore(const DEPTH_STENCIL_STATE_DESC& desc, UINT32 id);
+
+		/** @copydoc CoreObjectCore::initialize */
+		void initialize() override;
+
+		/**	Creates any API-specific state objects. */
+		virtual void createInternal() { }
+
+		DepthStencilProperties mProperties;
+		UINT32 mId;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Render system pipeline state that allows you to modify how an object is rendered. More exactly this state allows to 
+	 * you to control how are depth and stencil buffers modified upon rendering.
+	 *
+	 * @note	Depth stencil states are immutable. Sim thread only.
+	 */
+	class BS_CORE_EXPORT DepthStencilState : public IReflectable, public CoreObject
+	{
+	public:
+		virtual ~DepthStencilState();
+
+		/**	Returns information about the depth stencil state. */
+		const DepthStencilProperties& getProperties() const;
+
+		/**	Retrieves a core implementation of a sampler state usable only from the core thread. */
+		SPtr<DepthStencilStateCore> getCore() const;
+
+		/**	Creates a new depth stencil state using the specified depth stencil state description structure. */
+		static DepthStencilStatePtr create(const DEPTH_STENCIL_STATE_DESC& desc);
+
+		/**	Returns the default depth stencil state that you may use when no other is available. */
+		static const DepthStencilStatePtr& getDefault();
+
+		/**	Generates a hash value from a depth-stencil state descriptor. */
+		static UINT64 generateHash(const DEPTH_STENCIL_STATE_DESC& desc);
+
+	protected:
+		friend class RenderStateManager;
+
+		DepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc);
+
+		/** @copydoc CoreObjectCore::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		DepthStencilProperties mProperties;
+		mutable UINT32 mId;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class DepthStencilStateRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;	
+	};
+
+	/** @} */
+}
+
+/** @cond STDLIB */
+/** @addtogroup RenderAPI
+ *  @{
+ */
+
+/**	Hash value generator for DEPTH_STENCIL_STATE_DESC. */
+template<>
+struct std::hash<BansheeEngine::DEPTH_STENCIL_STATE_DESC>
+{
+	size_t operator()(const BansheeEngine::DEPTH_STENCIL_STATE_DESC& value) const
+	{
+		return (size_t)BansheeEngine::DepthStencilState::generateHash(value);
+	}
+};
+
+/** @} */
+/** @endcond */

+ 53 - 51
BansheeCore/Include/BsDepthStencilStateRTTI.h

@@ -1,52 +1,54 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsDepthStencilState.h"
-#include "BsRenderStateManager.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT DepthStencilStateRTTI : public RTTIType<DepthStencilState, IReflectable, DepthStencilStateRTTI>
-	{
-	private:
-		DEPTH_STENCIL_STATE_DESC& getData(DepthStencilState* obj) { return obj->mData; }
-		void setData(DepthStencilState* obj, DEPTH_STENCIL_STATE_DESC& val) 
-		{ 
-			obj->mRTTIData = val;
-		} 
-
-	public:
-		DepthStencilStateRTTI()
-		{
-			addPlainField("mData", 0, &DepthStencilStateRTTI::getData, &DepthStencilStateRTTI::setData);
-		}
-
-		virtual void onDeserializationEnded(IReflectable* obj)
-		{
-			DepthStencilState* depthStencilState = static_cast<DepthStencilState*>(obj);
-			if(!depthStencilState->mRTTIData.empty())
-			{
-				DEPTH_STENCIL_STATE_DESC desc = any_cast<DEPTH_STENCIL_STATE_DESC>(depthStencilState->mRTTIData);
-
-				depthStencilState->initialize(desc);
-			}
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "DepthStencilState";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_DepthStencilState;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return RenderStateManager::instance().createEmptyDepthStencilState();
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsDepthStencilState.h"
+#include "BsRenderStateManager.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT DepthStencilStateRTTI : public RTTIType<DepthStencilState, IReflectable, DepthStencilStateRTTI>
+	{
+	private:
+		DEPTH_STENCIL_STATE_DESC& getData(DepthStencilState* obj) { return obj->mProperties.mData; }
+		void setData(DepthStencilState* obj, DEPTH_STENCIL_STATE_DESC& val) { obj->mProperties.mData = val; } 
+
+	public:
+		DepthStencilStateRTTI()
+		{
+			addPlainField("mData", 0, &DepthStencilStateRTTI::getData, &DepthStencilStateRTTI::setData);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			DepthStencilState* depthStencilState = static_cast<DepthStencilState*>(obj);
+			depthStencilState->initialize();
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "DepthStencilState";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_DepthStencilState;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return RenderStateManager::instance()._createDepthStencilStatePtr(DEPTH_STENCIL_STATE_DESC());
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 0 - 51
BansheeCore/Include/BsDrawList.h

@@ -1,51 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsVector3.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Represents a single drawable object
-	 *			stored in a DrawList.
-	 */
-	struct BS_CORE_EXPORT DrawOperation
-	{
-		MaterialPtr material;
-		MeshBasePtr mesh;
-		UINT32 submeshIdx;
-		Vector3 worldPosition;
-	};
-
-	/**
-	 * @brief	A container you may use to queue
-	 *			custom drawable objects in.
-	 */
-	class BS_CORE_EXPORT DrawList
-	{
-	public:
-		/**
-		 * @brief	Adds a new drawable object.
-		 *
-		 * @param	material		Material to draw the object with.
-		 * @param	mesh			Parent mesh of the object.
-		 * @param	submeshIdx		Index of the sub-mesh to render, in the parent mesh.
-		 * @param	worldPosForSort	World position of the object that will be used for distance
-		 *							sorting before rendering.
-		 */
-		void add(const MaterialPtr& material, const MeshBasePtr& mesh, UINT32 submeshIdx, const Vector3& worldPosForSort);
-
-		/**
-		 * @brief	Removes all queued drawable objects.
-		 */
-		void clear();
-
-		/**
-		 * @brief	Returns all queued drawable objects.
-		 */
-		const Vector<DrawOperation>& getDrawOperations() const;
-
-	protected:
-		Vector<DrawOperation> mDrawOperations;
-	};
-}

+ 27 - 25
BansheeCore/Include/BsDrawOps.h

@@ -1,26 +1,28 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Describes operation that will be used for rendering a certain
-	 *			set of vertices.
-	 */
-	enum DrawOperationType 
-	{
-		DOT_POINT_LIST = 1,
-		DOT_LINE_LIST = 2,
-		DOT_LINE_STRIP = 3,
-		DOT_TRIANGLE_LIST = 4,
-		DOT_TRIANGLE_STRIP = 5,
-		DOT_TRIANGLE_FAN = 6
-	};
-
-	/**
-	* @brief	Converts the number of vertices to number of primitives
-	* 			based on the specified draw operation.
-	*/
-	UINT32 BS_CORE_EXPORT vertexCountToPrimCount(DrawOperationType type, UINT32 elementCount);
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** Describes operation that will be used for rendering a certain set of vertices. */
+	enum DrawOperationType 
+	{
+		DOT_POINT_LIST = 1,
+		DOT_LINE_LIST = 2,
+		DOT_LINE_STRIP = 3,
+		DOT_TRIANGLE_LIST = 4,
+		DOT_TRIANGLE_STRIP = 5,
+		DOT_TRIANGLE_FAN = 6
+	};
+
+	/** Converts the number of vertices to number of primitives based on the specified draw operation. */
+	UINT32 BS_CORE_EXPORT vertexCountToPrimCount(DrawOperationType type, UINT32 elementCount);
+
+	/** @} */
 }

+ 60 - 57
BansheeCore/Include/BsEventQuery.h

@@ -1,58 +1,61 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Represents a GPU query that gets triggered when GPU starts processing the query.
-	 * 			
-	 * @note	Normally GPU will have many commands in its command buffer. When EventQuery::begin is called it is placed
-	 * 			in that command buffer. Once the buffer empties and GPU reaches the EventQuery command, the query
-	 * 			callback is triggered.
-	 * 			
-	 *			Core thread only.
-	 */
-	class BS_CORE_EXPORT EventQuery
-	{
-	public:
-		EventQuery()
-			:mActive(false) {}
-		virtual ~EventQuery() {}
-
-		/**
-		 * @brief	Starts the query. 
-		 * 			
-		 * @note	Once the query is started you may poll "isReady" method to check when query has finished,
-		 * 			or you may hook up an "onTriggered" callback and be notified that way.
-		 */
-		virtual void begin() = 0;
-
-		/**
-		 * @brief	Check if GPU has processed the query.
-		 */
-		virtual bool isReady() const = 0;
-
-		/**
-		 * @brief	Triggered when GPU starts processing the query.
-		 */
-		Event<void()> onTriggered;
-
-		/**
-		 * @brief	Creates a new query, but does not schedule it on GPU.
-		 */
-		static EventQueryPtr create();
-
-	protected:
-		friend class QueryManager;
-
-		/**
-		 * @brief	Returns true if the has still not been completed by the GPU.
-		 */
-		bool isActive() const { return mActive; }
-		void setActive(bool active) { mActive = active; }
-
-	protected:
-		bool mActive;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Represents a GPU query that gets triggered when GPU starts processing the query.
+	 * 			
+	 * @note	
+	 * Normally GPU will have many commands in its command buffer. When begin() is called it is placed in that command 
+	 * buffer. Once the buffer empties and GPU reaches the EventQuery command, the query callback is triggered.
+	 * @note			
+	 * Core thread only.
+	 */
+	class BS_CORE_EXPORT EventQuery
+	{
+	public:
+		EventQuery()
+			:mActive(false) {}
+		virtual ~EventQuery() {}
+
+		/**
+		 * Starts the query. 
+		 * 			
+		 * @note	
+		 * Once the query is started you may poll isReady() method to check when query has finished, or you may hook up 
+		 * an ::onTriggered callback and be notified that way.
+		 */
+		virtual void begin() = 0;
+
+		/** Check if GPU has processed the query. */
+		virtual bool isReady() const = 0;
+
+		/**	Triggered when GPU starts processing the query. */
+		Event<void()> onTriggered;
+
+		/**	Creates a new query, but does not schedule it on GPU. */
+		static EventQueryPtr create();
+
+	protected:
+		friend class QueryManager;
+
+		/**	Returns true if the has still not been completed by the GPU. */
+		bool isActive() const { return mActive; }
+		void setActive(bool active) { mActive = active; }
+
+	protected:
+		bool mActive;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 8 - 6
BansheeCore/Include/BsFolderMonitor.h

@@ -1,7 +1,9 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-#if BS_PLATFORM == BS_PLATFORM_WIN32
-#include "Win32/BsWin32FolderMonitor.h"
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+#if BS_PLATFORM == BS_PLATFORM_WIN32
+#include "Win32/BsWin32FolderMonitor.h"
 #endif

+ 100 - 97
BansheeCore/Include/BsFont.h

@@ -1,98 +1,101 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-#include "BsFontDesc.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains data about font characters of a specific size. Contains
-	 *			textures in which the characters are located and information
-	 *			about each individual character.
-	 */
-	struct BS_CORE_EXPORT FontData : public IReflectable
-	{
-		/**
-		 * @brief	Returns a character description for the character with the specified ID.
-		 */
-		const CHAR_DESC& getCharDesc(UINT32 charId) const;
-
-		UINT32 size; /**< Font size for which the data is contained. */
-		FONT_DESC fontDesc; /**< Font description containing per-character and general font data. */
-		Vector<HTexture> texturePages; /**< Textures in which the characters are stored. */
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class FontDataRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
-
-	// TODO - When saved on disk font currently stores a copy of the texture pages. This should be acceptable
-	// if you import a new TrueType or OpenType font since the texture will be generated on the spot
-	// but if you use a bitmap texture to initialize the font manually, then you will potentially have duplicate textures.
-	// Also, changing the source texture will not automatically update the font because there is no direct link between them.
-	// -- This is probably not a large problem, but it is something to keep an eye out.
-
-	/**
-	 * @brief	Font resource containing data about textual characters
-	 *			and how to render text.
-	 */
-	class BS_CORE_EXPORT Font : public Resource
-	{
-	public:
-		virtual ~Font();
-
-		/**
-		 * @brief	Initializes the font with specified per-size font data.
-		 *
-		 * @note	Internal method. Factory methods will call this automatically for you.
-		 */
-		void initialize(const Vector<FontData>& fontData);
-
-		/**
-		 * @brief	Returns font data for a specific size if it exists, null otherwise.
-		 */
-		const FontData* getFontDataForSize(UINT32 size) const;
-
-		/**
-		 * @brief	Attempts to find nearest available size next to the provided size.
-		 */
-		INT32 getClosestAvailableSize(UINT32 size) const;
-
-		/************************************************************************/
-		/* 								STATICS		                     		*/
-		/************************************************************************/
-
-		/**
-		 * @brief	Creates a new font from the provided per-size font data.
-		 */
-		static HFont create(const Vector<FontData>& fontInitData);
-
-		/**
-		 * @brief	Creates a new font pointer.
-		 *
-		 * @note	Internal method.
-		 */
-		static FontPtr _createPtr(const Vector<FontData>& fontInitData);
-
-	protected:
-		friend class FontManager;
-
-		Font();
-
-	private:
-		Map<UINT32, FontData> mFontDataPerSize;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class FontRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+#include "BsFontDesc.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Text
+	 *  @{
+	 */
+
+	/**	Contains textures and data about every character for a bitmap font of a specific size. */
+	struct BS_CORE_EXPORT FontBitmap : public IReflectable
+	{
+		/**	Returns a character description for the character with the specified Unicode key. */
+		const CHAR_DESC& getCharDesc(UINT32 charId) const;
+
+		UINT32 size; /**< Font size for which the data is contained. */
+		FONT_DESC fontDesc; /**< Font description containing per-character and general font data. */
+		Vector<HTexture> texturePages; /**< Textures in which the character's pixels are stored. */
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class FontBitmapRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	// TODO - When saved on disk font currently stores a copy of the texture pages. This should be acceptable
+	// if you import a new TrueType or OpenType font since the texture will be generated on the spot
+	// but if you use a bitmap texture to initialize the font manually, then you will potentially have duplicate textures.
+	// Also, changing the source texture will not automatically update the font because there is no direct link between them.
+	// -- This is probably not a large problem, but it is something to keep an eye out.
+
+	/**	Font resource containing data about textual characters and how to render text. */
+	class BS_CORE_EXPORT Font : public Resource
+	{
+	public:
+		virtual ~Font();
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Initializes the font with specified per-size font data.
+		 *
+		 * @note	Internal method. Factory methods will call this automatically for you.
+		 */
+		void initialize(const Vector<SPtr<FontBitmap>>& fontData);
+
+		/** @endcond */
+
+		/**
+		 * Returns font bitmap for a specific size if it exists, null otherwise.
+		 *
+		 * @param[in]	size	Size of the bitmap in points.
+		 */
+		SPtr<const FontBitmap> getBitmap(UINT32 size) const;
+
+		/**	Finds the available font bitmap size closest to the provided size. */
+		INT32 getClosestSize(UINT32 size) const;
+
+		/**	Creates a new font from the provided per-size font data. */
+		static HFont create(const Vector<SPtr<FontBitmap>>& fontInitData);
+
+		/** @cond INTERNAL */
+
+		/** Creates a new font as a pointer instead of a resource handle. */
+		static FontPtr _createPtr(const Vector<SPtr<FontBitmap>>& fontInitData);
+
+		/** @endcond */
+
+	protected:
+		friend class FontManager;
+
+		Font();
+
+		/** @copydoc Resource::getResourceDependencies */
+		void getResourceDependencies(FrameVector<HResource>& dependencies) const override;
+
+		/** @copydoc CoreObject::getCoreDependencies */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+	private:
+		Map<UINT32, SPtr<FontBitmap>> mFontDataPerSize;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class FontRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 167 - 162
BansheeCore/Include/BsFontDesc.h

@@ -1,163 +1,168 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Kerning pair representing extra or less offset between
-	 *			a specific pair of characters.
-	 */
-	struct KerningPair
-	{
-		UINT32 otherCharId;
-		INT32 amount;
-	};
-
-	/**
-	 * @brief	Describes a single character in a font.
-	 */
-	struct CHAR_DESC
-	{
-		UINT32 charId; /**< Character ID, corresponding to a Unicode key. */
-		UINT32 page; /**< Index of the texture the character is located on. */
-		float uvX, uvY; /**< Texture coordinates of the character in the page texture. */
-		float uvWidth, uvHeight; /**< Width/height of the character in texture coordinates. */
-		UINT32 width, height; /**< Width/height of the character in pixels. */
-		INT32 xOffset, yOffset; /**< Determines offset for the visible portion of the character in pixels. */
-		INT32 xAdvance, yAdvance; /**< Determines how much to advance the pen after writing this character. In pixels. */
-
-		Vector<KerningPair> kerningPairs; /**< Pairs that determine if certain character pairs should be closer or father together. e.g. "AV" combination */
-	};
-
-	/**
-	 * @brief	Describes a font.
-	 */
-	struct FONT_DESC
-	{
-		Map<UINT32, CHAR_DESC> characters; /**< All characters in the font referenced by character ID. */
-		INT32 baselineOffset; /**< Y offset to the baseline on which the characters are placed. In pixels. */
-		UINT32 lineHeight; /**< Height of a single line of the font. In pixels. */
-		CHAR_DESC missingGlyph; /**< Character index to use when data for a character is missing. */
-		UINT32 spaceWidth; /**< Determines width of the space in pixels. */
-	};
-
-	// Make CHAR_DESC serializable
-	template<> struct RTTIPlainType<CHAR_DESC>
-	{	
-		enum { id = TID_CHAR_DESC }; enum { hasDynamicSize = 1 };
-
-		static void toMemory(const CHAR_DESC& data, char* memory)
-		{ 
-			UINT32 size = getDynamicSize(data);
-
-			memcpy(memory, &size, sizeof(UINT32));
-			memory += sizeof(UINT32);
-
-			memory = rttiWriteElem(data.charId, memory);
-			memory = rttiWriteElem(data.page, memory);
-			memory = rttiWriteElem(data.uvX, memory);
-			memory = rttiWriteElem(data.uvY, memory);
-			memory = rttiWriteElem(data.uvWidth, memory);
-			memory = rttiWriteElem(data.uvHeight, memory);
-			memory = rttiWriteElem(data.width, memory);
-			memory = rttiWriteElem(data.height, memory);
-			memory = rttiWriteElem(data.xOffset, memory);
-			memory = rttiWriteElem(data.yOffset, memory);
-			memory = rttiWriteElem(data.xAdvance, memory);
-			memory = rttiWriteElem(data.yAdvance, memory);
-			memory = rttiWriteElem(data.kerningPairs, memory);
-		}
-
-		static UINT32 fromMemory(CHAR_DESC& data, char* memory)
-		{ 
-			UINT32 size;
-			memcpy(&size, memory, sizeof(UINT32)); 
-			memory += sizeof(UINT32);
-
-			memory = rttiReadElem(data.charId, memory);
-			memory = rttiReadElem(data.page, memory);
-			memory = rttiReadElem(data.uvX, memory);
-			memory = rttiReadElem(data.uvY, memory);
-			memory = rttiReadElem(data.uvWidth, memory);
-			memory = rttiReadElem(data.uvHeight, memory);
-			memory = rttiReadElem(data.width, memory);
-			memory = rttiReadElem(data.height, memory);
-			memory = rttiReadElem(data.xOffset, memory);
-			memory = rttiReadElem(data.yOffset, memory);
-			memory = rttiReadElem(data.xAdvance, memory);
-			memory = rttiReadElem(data.yAdvance, memory);
-			memory = rttiReadElem(data.kerningPairs, memory);
-
-			return size;
-		}
-
-		static UINT32 getDynamicSize(const CHAR_DESC& data)	
-		{ 
-			UINT64 dataSize = sizeof(data.charId)
-				+ sizeof(data.page)
-				+ sizeof(data.uvX)
-				+ sizeof(data.uvY)
-				+ sizeof(data.uvWidth)
-				+ sizeof(data.uvHeight)
-				+ sizeof(data.width)
-				+ sizeof(data.height)
-				+ sizeof(data.xOffset)
-				+ sizeof(data.yOffset)
-				+ sizeof(data.xAdvance)
-				+ sizeof(data.yAdvance)
-				+ RTTIPlainType<Vector<KerningPair>>::getDynamicSize(data.kerningPairs);
-
-			dataSize += sizeof(UINT32);
-
-			return (UINT32)dataSize;
-		}	
-	}; 
-
-	// Make FONT_DESC serializable
-	template<> struct RTTIPlainType<FONT_DESC>
-	{	
-		enum { id = TID_FONT_DESC }; enum { hasDynamicSize = 1 };
-
-		static void toMemory(const FONT_DESC& data, char* memory)
-		{ 
-			UINT32 size = getDynamicSize(data);
-
-			memcpy(memory, &size, sizeof(UINT32));
-			memory += sizeof(UINT32);
-			
-			RTTIPlainType<Map<UINT32, CHAR_DESC>>::toMemory(data.characters, memory);
-			rttiWriteElem(data.baselineOffset, memory);
-			rttiWriteElem(data.lineHeight, memory);
-			rttiWriteElem(data.missingGlyph, memory);
-			rttiWriteElem(data.spaceWidth, memory);
-		}
-
-		static UINT32 fromMemory(FONT_DESC& data, char* memory)
-		{ 
-			UINT32 size;
-			memcpy(&size, memory, sizeof(UINT32)); 
-			memory += sizeof(UINT32);
-
-			RTTIPlainType<Map<UINT32, CHAR_DESC>>::fromMemory(data.characters, memory);
-			rttiReadElem(data.baselineOffset, memory);
-			rttiReadElem(data.lineHeight, memory);
-			rttiReadElem(data.missingGlyph, memory);
-			rttiReadElem(data.spaceWidth, memory);
-
-			return size;
-		}
-
-		static UINT32 getDynamicSize(const FONT_DESC& data)	
-		{ 
-			UINT64 dataSize = sizeof(UINT32);
-			dataSize += RTTIPlainType<Map<UINT32, CHAR_DESC>>::getDynamicSize(data.characters);
-			dataSize += rttiGetElemSize(data.baselineOffset);
-			dataSize += rttiGetElemSize(data.lineHeight);
-			dataSize += rttiGetElemSize(data.missingGlyph);
-			dataSize += rttiGetElemSize(data.spaceWidth);
-
-			return (UINT32)dataSize;
-		}	
-	}; 
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Text
+	 *  @{
+	 */
+
+	/**	Kerning pair representing larger or smaller offset between a specific pair of characters. */
+	struct KerningPair
+	{
+		UINT32 otherCharId;
+		INT32 amount;
+	};
+
+	/**	Describes a single character in a font of a specific size. */
+	struct CHAR_DESC
+	{
+		UINT32 charId; /**< Character ID, corresponding to a Unicode key. */
+		UINT32 page; /**< Index of the texture the character is located on. */
+		float uvX, uvY; /**< Texture coordinates of the character in the page texture. */
+		float uvWidth, uvHeight; /**< Width/height of the character in texture coordinates. */
+		UINT32 width, height; /**< Width/height of the character in pixels. */
+		INT32 xOffset, yOffset; /**< Offset for the visible portion of the character in pixels. */
+		INT32 xAdvance, yAdvance; /**< Determines how much to advance the pen after writing this character, in pixels. */
+
+		Vector<KerningPair> kerningPairs; /**< Pairs that determine if certain character pairs should be closer or father together. e.g. "AV" combination. */
+	};
+
+	/**	Describes a font. */
+	struct FONT_DESC
+	{
+		Map<UINT32, CHAR_DESC> characters; /**< All characters in the font referenced by character ID. */
+		INT32 baselineOffset; /**< Y offset to the baseline on which the characters are placed, in pixels. */
+		UINT32 lineHeight; /**< Height of a single line of the font, in pixels. */
+		CHAR_DESC missingGlyph; /**< Character to use when data for a character is missing. */
+		UINT32 spaceWidth; /**< Width of a space in pixels. */
+	};
+
+	/** @cond SPECIALIZATIONS */
+
+	// Make CHAR_DESC serializable
+	template<> struct RTTIPlainType<CHAR_DESC>
+	{	
+		enum { id = TID_CHAR_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const CHAR_DESC& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			memcpy(memory, &size, sizeof(UINT32));
+			memory += sizeof(UINT32);
+
+			memory = rttiWriteElem(data.charId, memory);
+			memory = rttiWriteElem(data.page, memory);
+			memory = rttiWriteElem(data.uvX, memory);
+			memory = rttiWriteElem(data.uvY, memory);
+			memory = rttiWriteElem(data.uvWidth, memory);
+			memory = rttiWriteElem(data.uvHeight, memory);
+			memory = rttiWriteElem(data.width, memory);
+			memory = rttiWriteElem(data.height, memory);
+			memory = rttiWriteElem(data.xOffset, memory);
+			memory = rttiWriteElem(data.yOffset, memory);
+			memory = rttiWriteElem(data.xAdvance, memory);
+			memory = rttiWriteElem(data.yAdvance, memory);
+			memory = rttiWriteElem(data.kerningPairs, memory);
+		}
+
+		static UINT32 fromMemory(CHAR_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			memory = rttiReadElem(data.charId, memory);
+			memory = rttiReadElem(data.page, memory);
+			memory = rttiReadElem(data.uvX, memory);
+			memory = rttiReadElem(data.uvY, memory);
+			memory = rttiReadElem(data.uvWidth, memory);
+			memory = rttiReadElem(data.uvHeight, memory);
+			memory = rttiReadElem(data.width, memory);
+			memory = rttiReadElem(data.height, memory);
+			memory = rttiReadElem(data.xOffset, memory);
+			memory = rttiReadElem(data.yOffset, memory);
+			memory = rttiReadElem(data.xAdvance, memory);
+			memory = rttiReadElem(data.yAdvance, memory);
+			memory = rttiReadElem(data.kerningPairs, memory);
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const CHAR_DESC& data)	
+		{ 
+			UINT64 dataSize = sizeof(data.charId)
+				+ sizeof(data.page)
+				+ sizeof(data.uvX)
+				+ sizeof(data.uvY)
+				+ sizeof(data.uvWidth)
+				+ sizeof(data.uvHeight)
+				+ sizeof(data.width)
+				+ sizeof(data.height)
+				+ sizeof(data.xOffset)
+				+ sizeof(data.yOffset)
+				+ sizeof(data.xAdvance)
+				+ sizeof(data.yAdvance)
+				+ RTTIPlainType<Vector<KerningPair>>::getDynamicSize(data.kerningPairs);
+
+			dataSize += sizeof(UINT32);
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	// Make FONT_DESC serializable
+	template<> struct RTTIPlainType<FONT_DESC>
+	{	
+		enum { id = TID_FONT_DESC }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const FONT_DESC& data, char* memory)
+		{ 
+			UINT32 size = sizeof(UINT32);
+			char* memoryStart = memory;
+			memory += sizeof(UINT32);
+			
+			memory = rttiWriteElem(data.characters, memory, size);
+			memory = rttiWriteElem(data.baselineOffset, memory, size);
+			memory = rttiWriteElem(data.lineHeight, memory, size);
+			memory = rttiWriteElem(data.missingGlyph, memory, size);
+			memory = rttiWriteElem(data.spaceWidth, memory, size);
+
+			memcpy(memoryStart, &size, sizeof(UINT32));
+		}
+
+		static UINT32 fromMemory(FONT_DESC& data, char* memory)
+		{ 
+			UINT32 size;
+			memcpy(&size, memory, sizeof(UINT32)); 
+			memory += sizeof(UINT32);
+
+			memory = rttiReadElem(data.characters, memory);
+			memory = rttiReadElem(data.baselineOffset, memory);
+			memory = rttiReadElem(data.lineHeight, memory);
+			memory = rttiReadElem(data.missingGlyph, memory);
+			memory = rttiReadElem(data.spaceWidth, memory);
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const FONT_DESC& data)	
+		{ 
+			UINT64 dataSize = sizeof(UINT32);
+			dataSize += rttiGetElemSize(data.characters);
+			dataSize += rttiGetElemSize(data.baselineOffset);
+			dataSize += rttiGetElemSize(data.lineHeight);
+			dataSize += rttiGetElemSize(data.missingGlyph);
+			dataSize += rttiGetElemSize(data.spaceWidth);
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	/** @endcond */
+	/** @} */
 }

+ 86 - 76
BansheeCore/Include/BsFontImportOptions.h

@@ -1,77 +1,87 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsImportOptions.h"
-#include "BsFont.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Import options that allow you to control how is a font
-	 *			imported.
-	 */
-	class BS_CORE_EXPORT FontImportOptions : public ImportOptions
-	{
-	public:
-		FontImportOptions();
-
-		/**
-		 * @brief	Sets font sizes you wish to import. Sizes are in points.
-		 */
-		void setFontSizes(const Vector<UINT32>& fontSizes) { mFontSizes = fontSizes; }
-
-		/**
-		 * @brief	Adds an index range of characters to import. 
-		 */
-		void addCharIndexRange(UINT32 from, UINT32 to);
-
-		/**
-		 * @brief	Clears all character indexes, so no character are imported.
-		 */
-		void clearCharIndexRanges();
-
-		/**
-		 * @brief	Sets dots per inch scale to use when rendering the characters into the texture.
-		 */
-		void setDPI(UINT32 dpi) { mDPI = dpi; }
-
-		/**
-		 * @brief	Set to true if you want your characters to be antialiased.
-		 */
-		void setAntialiasing(bool enabled) { mAntialiasing = enabled; }
-
-		/**
-		 * @brief	Gets the sizes that are to be imported.
-		 */
-		Vector<UINT32> getFontSizes() const { return mFontSizes; }
-
-		/**
-		 * @brief	Gets character index ranges to import.
-		 */
-		Vector<std::pair<UINT32, UINT32>> getCharIndexRanges() const { return mCharIndexRanges; }
-
-		/**
-		 * @brief	Returns dots per inch scale that will be used when rendering the characters.
-		 */
-		UINT32 getDPI() const { return mDPI; }
-
-		/**
-		 * @brief	Query if antialiasing will be used when rendering the characters.
-		 */
-		bool getAntialiasing() const { return mAntialiasing; }
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class FontImportOptionsRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-
-	private:
-		Vector<UINT32> mFontSizes;
-		Vector<std::pair<UINT32, UINT32>> mCharIndexRanges;
-		UINT32 mDPI;
-		bool mAntialiasing;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsImportOptions.h"
+#include "BsFont.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Text
+	 *  @{
+	 */
+
+	/**	Determines how is a font rendered into the bitmap texture. */
+	enum class FontRenderMode
+	{
+		Smooth, /*< Render antialiased fonts without hinting (slightly more blurry). */
+		Raster, /*< Render non-antialiased fonts without hinting (slightly more blurry). */
+		HintedSmooth, /*< Render antialiased fonts with hinting. */
+		HintedRaster /*< Render non-antialiased fonts with hinting. */
+	};
+
+	/**	Import options that allow you to control how is a font imported. */
+	class BS_CORE_EXPORT FontImportOptions : public ImportOptions
+	{
+	public:
+		FontImportOptions();
+
+		/**	Sets font sizes that are to be imported. Sizes are in points. */
+		void setFontSizes(const Vector<UINT32>& fontSizes) { mFontSizes = fontSizes; }
+
+		/**	Adds an index range of characters to import.  */
+		void addCharIndexRange(UINT32 from, UINT32 to);
+
+		/**	Clears all character indexes, so no character are imported. */
+		void clearCharIndexRanges();
+
+		/**	Sets dots per inch resolution to use when rendering the characters into the texture. */
+		void setDPI(UINT32 dpi) { mDPI = dpi; }
+
+		/**	Set the render mode used for rendering the characters into a bitmap. */
+		void setRenderMode(FontRenderMode renderMode) { mRenderMode = renderMode; }
+
+		/**	Sets whether the bold font style should be used when rendering. */
+		void setBold(bool bold) { mBold = bold; }
+
+		/**	Sets whether the italic font style should be used when rendering. */
+		void setItalic(bool italic) { mItalic = italic; }
+
+		/**	Gets the sizes that are to be imported. Ranges are defined as unicode numbers. */
+		Vector<UINT32> getFontSizes() const { return mFontSizes; }
+
+		/**	Gets character index ranges to import. Ranges are defined as unicode numbers. */
+		Vector<std::pair<UINT32, UINT32>> getCharIndexRanges() const { return mCharIndexRanges; }
+
+		/**	Returns dots per inch scale that will be used when rendering the characters. */
+		UINT32 getDPI() const { return mDPI; }
+
+		/**	Get the render mode used for rendering the characters into a bitmap. */
+		FontRenderMode getRenderMode() const { return mRenderMode; }
+
+		/**	Sets whether the bold font style should be used when rendering. */
+		bool getBold() const { return mBold; }
+
+		/**	Sets whether the italic font style should be used when rendering. */
+		bool getItalic() const { return mItalic; }
+
+	private:
+		Vector<UINT32> mFontSizes;
+		Vector<std::pair<UINT32, UINT32>> mCharIndexRanges;
+		UINT32 mDPI;
+		FontRenderMode mRenderMode;
+		bool mBold;
+		bool mItalic;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class FontImportOptionsRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 66 - 48
BansheeCore/Include/BsFontImportOptionsRTTI.h

@@ -1,49 +1,67 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsFontImportOptions.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT FontImportOptionsRTTI : public RTTIType<FontImportOptions, IReflectable, FontImportOptionsRTTI>
-	{
-	private:
-		Vector<UINT32>& getFontSizes(FontImportOptions* obj) { return obj->mFontSizes; }
-		void setFontSizes(FontImportOptions* obj, Vector<UINT32>& value) { obj->mFontSizes = value; }
-
-		Vector<std::pair<UINT32, UINT32>>& getCharIndexRanges(FontImportOptions* obj) { return obj->mCharIndexRanges; }
-		void setCharIndexRanges(FontImportOptions* obj, Vector<std::pair<UINT32, UINT32>>& value) { obj->mCharIndexRanges = value; }
-
-		UINT32& getDPI(FontImportOptions* obj) { return obj->mDPI; }
-		void setDPI(FontImportOptions* obj, UINT32& value) { obj->mDPI = value; }
-
-		bool& getAntialiasing(FontImportOptions* obj) { return obj->mAntialiasing; }
-		void setAntialiasing(FontImportOptions* obj, bool& value) { obj->mAntialiasing = value; }
-
-	public:
-		FontImportOptionsRTTI()
-		{
-			addPlainField("mFontSizes", 0, &FontImportOptionsRTTI::getFontSizes, &FontImportOptionsRTTI::setFontSizes);
-			addPlainField("mCharIndexRanges", 1, &FontImportOptionsRTTI::getCharIndexRanges, &FontImportOptionsRTTI::setCharIndexRanges);
-			addPlainField("mDPI", 2, &FontImportOptionsRTTI::getDPI, &FontImportOptionsRTTI::setDPI);
-			addPlainField("mAntialiasing", 3, &FontImportOptionsRTTI::getAntialiasing, &FontImportOptionsRTTI::setAntialiasing);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "FontImportOptions";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_FontImportOptions;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return bs_shared_ptr<FontImportOptions, PoolAlloc>();
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsFontImportOptions.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT FontImportOptionsRTTI : public RTTIType<FontImportOptions, ImportOptions, FontImportOptionsRTTI>
+	{
+	private:
+		Vector<UINT32>& getFontSizes(FontImportOptions* obj) { return obj->mFontSizes; }
+		void setFontSizes(FontImportOptions* obj, Vector<UINT32>& value) { obj->mFontSizes = value; }
+
+		Vector<std::pair<UINT32, UINT32>>& getCharIndexRanges(FontImportOptions* obj) { return obj->mCharIndexRanges; }
+		void setCharIndexRanges(FontImportOptions* obj, Vector<std::pair<UINT32, UINT32>>& value) { obj->mCharIndexRanges = value; }
+
+		UINT32& getDPI(FontImportOptions* obj) { return obj->mDPI; }
+		void setDPI(FontImportOptions* obj, UINT32& value) { obj->mDPI = value; }
+
+		FontRenderMode& getRenderMode(FontImportOptions* obj) { return obj->mRenderMode; }
+		void setRenderMode(FontImportOptions* obj, FontRenderMode& value) { obj->mRenderMode = value; }
+
+		bool& getBold(FontImportOptions* obj) { return obj->mBold; }
+		void setBold(FontImportOptions* obj, bool& value) { obj->mBold = value; }
+
+		bool& getItalic(FontImportOptions* obj) { return obj->mItalic; }
+		void setItalic(FontImportOptions* obj, bool& value) { obj->mItalic = value; }
+
+	public:
+		FontImportOptionsRTTI()
+		{
+			addPlainField("mFontSizes", 0, &FontImportOptionsRTTI::getFontSizes, &FontImportOptionsRTTI::setFontSizes);
+			addPlainField("mCharIndexRanges", 1, &FontImportOptionsRTTI::getCharIndexRanges, &FontImportOptionsRTTI::setCharIndexRanges);
+			addPlainField("mDPI", 2, &FontImportOptionsRTTI::getDPI, &FontImportOptionsRTTI::setDPI);
+			addPlainField("mRenderMode", 3, &FontImportOptionsRTTI::getRenderMode, &FontImportOptionsRTTI::setRenderMode);
+			addPlainField("mBold", 4, &FontImportOptionsRTTI::getBold, &FontImportOptionsRTTI::setBold);
+			addPlainField("mItalic", 5, &FontImportOptionsRTTI::getItalic, &FontImportOptionsRTTI::setItalic);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "FontImportOptions";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_FontImportOptions;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<FontImportOptions>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 31 - 25
BansheeCore/Include/BsFontManager.h

@@ -1,26 +1,32 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Handles creation of fonts.
-	 */
-	class BS_CORE_EXPORT FontManager : public Module<FontManager>
-	{
-	public:
-		/**
-		 * @brief	Creates a new font from the provided populated font data structure.
-		 */
-		FontPtr create(const Vector<FontData>& fontData) const;
-
-		/**
-		 * @brief	Creates an empty font.
-		 *
-		 * @note	Internal method. Used by factory methods.
-		 */
-		FontPtr _createEmpty() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Text
+	 *  @{
+	 */
+
+	/**	Handles creation of fonts. */
+	class BS_CORE_EXPORT FontManager : public Module<FontManager>
+	{
+	public:
+		/**	Creates a new font from the provided populated font data structure. */
+		FontPtr create(const Vector<SPtr<FontBitmap>>& fontData) const;
+
+		/**
+		 * Creates an empty font.
+		 *
+		 * @note	Internal method. Used by factory methods.
+		 */
+		FontPtr _createEmpty() const;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 141 - 158
BansheeCore/Include/BsFontRTTI.h

@@ -1,159 +1,142 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsFont.h"
-#include "BsFontManager.h"
-#include "BsTexture.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT FontDataRTTI : public RTTIType<FontData, Resource, FontDataRTTI>
-	{
-	private:
-		UINT32& getSize(FontData* obj)
-		{
-			return obj->size;
-		}
-
-		void setSize(FontData* obj, UINT32& size)
-		{
-			obj->size = size;
-		}
-
-		FONT_DESC& getFontDesc(FontData* obj)
-		{
-			return obj->fontDesc;
-		}
-
-		void setFontDesc(FontData* obj, FONT_DESC& val)
-		{
-			obj->fontDesc = val;
-		}
-
-		HTexture& getTexture(FontData* obj, UINT32 idx)
-		{
-			return obj->texturePages.at(idx);
-		}
-
-		void setTexture(FontData* obj, UINT32 idx, HTexture& value)
-		{
-			obj->texturePages[idx] = value;
-		}
-
-		UINT32 getTextureArraySize(FontData* obj)
-		{
-			return (UINT32)obj->texturePages.size();
-		}
-
-		void setTextureArraySize(FontData* obj, UINT32 size)
-		{
-			obj->texturePages.resize(size);
-		}
-
-	public:
-		FontDataRTTI()
-		{
-			addPlainField("size", 0, &FontDataRTTI::getSize, &FontDataRTTI::setSize);
-			addPlainField("fontDesc", 1, &FontDataRTTI::getFontDesc, &FontDataRTTI::setFontDesc);
-			addReflectableArrayField("texturePages", 2, &FontDataRTTI::getTexture, &FontDataRTTI::getTextureArraySize, &FontDataRTTI::setTexture, &FontDataRTTI::setTextureArraySize);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "FontData";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_FontData;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return bs_shared_ptr<FontData, PoolAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT FontRTTI : public RTTIType<Font, Resource, FontRTTI>
-	{
-		struct FontInitData
-		{
-			Vector<FontData> fontDataPerSize;
-		};
-
-	private:
-		FontData& getFontData(Font* obj, UINT32 idx)
-		{
-			if(idx >= obj->mFontDataPerSize.size())
-				BS_EXCEPT(InternalErrorException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((int)obj->mFontDataPerSize.size()));
-
-			auto iter = obj->mFontDataPerSize.begin();
-			for(UINT32 i = 0; i < idx; i++, ++iter)
-			{ }
-
-			return iter->second;
-		}
-
-		void setFontData(Font* obj, UINT32 idx, FontData& value)
-		{
-			FontInitData* initData = any_cast<FontInitData*>(obj->mRTTIData);
-
-			initData->fontDataPerSize[idx] = value;
-		}
-
-		UINT32 getNumFontData(Font* obj)
-		{
-			return (UINT32)obj->mFontDataPerSize.size();
-		}
-
-		void setNumFontData(Font* obj, UINT32 size)
-		{
-			FontInitData* initData = any_cast<FontInitData*>(obj->mRTTIData);
-
-			initData->fontDataPerSize.resize(size);
-		}
-
-	public:
-		FontRTTI()
-		{
-			addReflectableArrayField("mFontDataPerSize", 0, &FontRTTI::getFontData, &FontRTTI::getNumFontData, &FontRTTI::setFontData, &FontRTTI::setNumFontData);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "Font";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_Font;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return FontManager::instance()._createEmpty();
-		}
-
-	protected:
-		virtual void onDeserializationStarted(IReflectable* obj)
-		{
-			FontInitData* initData = bs_new<FontInitData, PoolAlloc>();
-
-			Font* font = static_cast<Font*>(obj);
-			font->mRTTIData = initData;
-		}
-
-		virtual void onDeserializationEnded(IReflectable* obj)
-		{
-			Font* font = static_cast<Font*>(obj);
-			FontInitData* initData = any_cast<FontInitData*>(font->mRTTIData);
-
-			font->initialize(initData->fontDataPerSize);
-
-			bs_delete<PoolAlloc>(initData);
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsFont.h"
+#include "BsFontManager.h"
+#include "BsTexture.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT FontBitmapRTTI : public RTTIType<FontBitmap, IReflectable, FontBitmapRTTI>
+	{
+	private:
+		UINT32& getSize(FontBitmap* obj) { return obj->size; }
+		void setSize(FontBitmap* obj, UINT32& size) { obj->size = size; }
+
+		FONT_DESC& getFontDesc(FontBitmap* obj) { return obj->fontDesc; }
+		void setFontDesc(FontBitmap* obj, FONT_DESC& val) { obj->fontDesc = val; }
+
+		HTexture& getTexture(FontBitmap* obj, UINT32 idx) { return obj->texturePages.at(idx); }
+		void setTexture(FontBitmap* obj, UINT32 idx, HTexture& value) { obj->texturePages[idx] = value; }
+
+		UINT32 getTextureArraySize(FontBitmap* obj) { return (UINT32)obj->texturePages.size(); }
+		void setTextureArraySize(FontBitmap* obj, UINT32 size) { obj->texturePages.resize(size); }
+
+	public:
+		FontBitmapRTTI()
+		{
+			addPlainField("size", 0, &FontBitmapRTTI::getSize, &FontBitmapRTTI::setSize);
+			addPlainField("fontDesc", 1, &FontBitmapRTTI::getFontDesc, &FontBitmapRTTI::setFontDesc);
+			addReflectableArrayField("texturePages", 2, &FontBitmapRTTI::getTexture, &FontBitmapRTTI::getTextureArraySize, &FontBitmapRTTI::setTexture, &FontBitmapRTTI::setTextureArraySize);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "FontData";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_FontBitmap;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<FontBitmap>();
+		}
+	};
+
+	class BS_CORE_EXPORT FontRTTI : public RTTIType<Font, Resource, FontRTTI>
+	{
+		struct FontInitData
+		{
+			Vector<SPtr<FontBitmap>> fontDataPerSize;
+		};
+
+	private:
+		FontBitmap& getBitmap(Font* obj, UINT32 idx)
+		{
+			if(idx >= obj->mFontDataPerSize.size())
+				BS_EXCEPT(InternalErrorException, "Index out of range: " + toString(idx) + ". Valid range: 0 .. " + toString((int)obj->mFontDataPerSize.size()));
+
+			auto iter = obj->mFontDataPerSize.begin();
+			for(UINT32 i = 0; i < idx; i++, ++iter)
+			{ }
+
+			return *iter->second;
+		}
+
+		void setBitmap(Font* obj, UINT32 idx, FontBitmap& value)
+		{
+			FontInitData* initData = any_cast<FontInitData*>(obj->mRTTIData);
+
+			initData->fontDataPerSize[idx] = bs_shared_ptr_new<FontBitmap>();
+			*initData->fontDataPerSize[idx] = value;
+		}
+
+		UINT32 getNumBitmaps(Font* obj)
+		{
+			return (UINT32)obj->mFontDataPerSize.size();
+		}
+
+		void setNumBitmaps(Font* obj, UINT32 size)
+		{
+			FontInitData* initData = any_cast<FontInitData*>(obj->mRTTIData);
+
+			initData->fontDataPerSize.resize(size);
+		}
+
+	public:
+		FontRTTI()
+		{
+			addReflectableArrayField("mBitmaps", 0, &FontRTTI::getBitmap, &FontRTTI::getNumBitmaps, &FontRTTI::setBitmap, &FontRTTI::setNumBitmaps);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "Font";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_Font;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return FontManager::instance()._createEmpty();
+		}
+
+	protected:
+		void onDeserializationStarted(IReflectable* obj) override
+		{
+			FontInitData* initData = bs_new<FontInitData>();
+
+			Font* font = static_cast<Font*>(obj);
+			font->mRTTIData = initData;
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			Font* font = static_cast<Font*>(obj);
+			FontInitData* initData = any_cast<FontInitData*>(font->mRTTIData);
+
+			font->initialize(initData->fontDataPerSize);
+
+			bs_delete(initData);
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 138 - 79
BansheeCore/Include/BsGameObject.h

@@ -1,80 +1,139 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsIReflectable.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains instance data that is held by all GameObject handles.
-	 */
-	struct GameObjectInstanceData
-	{
-		GameObjectInstanceData()
-			:mInstanceId(0), object(nullptr)
-		{ }
-
-		std::shared_ptr<GameObject> object;
-		UINT64 mInstanceId;
-	};
-
-	/**
-	 * @brief	Type of object that can be referenced by a GameObject handle.
-	 *			Each object has an unique ID and is registered with the GameObjectManager.
-	 */
-	class BS_CORE_EXPORT GameObject : public IReflectable
-	{
-	public:
-		GameObject();
-		virtual ~GameObject();
-
-		/**
-		 * @brief	Returns the unique instance ID of the GameObject.
-		 */
-		UINT64 getInstanceId() const { return mInstanceData->mInstanceId; }
-
-		/**
-		 * @brief	Gets the name of the object.
-		 */
-		const String& getName() const { return mName; }
-
-		/**
-		 * @brief	Sets the name of the object.
-		 */
-		void setName(const String& name) { mName = name; }
-
-	protected:
-		friend class GameObjectHandleBase;
-		friend class GameObjectManager;
-
-		/**
-		 * @brief	Initializes the GameObject after construction.
-		 */
-		void initialize(const std::shared_ptr<GameObject>& object, UINT64 instanceId);
-
-	protected:
-		String mName;
-
-	private:
-		std::shared_ptr<GameObjectInstanceData> mInstanceData;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-
-	public:
-		friend class GameObjectRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
-}
-
-#include "BsGameObjectHandle.h"
-
-namespace BansheeEngine
-{
-	// Game object handles
-	typedef GameObjectHandle<GameObject> HGameObject;
-	typedef GameObjectHandle<SceneObject> HSceneObject;
-	typedef GameObjectHandle<Component> HComponent;
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/** @cond INTERNAL */
+
+	/**	Contains instance data that is held by all GameObject handles. */
+	struct GameObjectInstanceData
+	{
+		GameObjectInstanceData()
+		:mInstanceId(0), object(nullptr)
+		{ }
+
+		std::shared_ptr<GameObject> object;
+		UINT64 mInstanceId;
+	};
+
+	typedef std::shared_ptr<GameObjectInstanceData> GameObjectInstanceDataPtr;
+
+	/** @endcond */
+
+	/**
+	 * Type of object that can be referenced by a GameObject handle. Each object has an unique ID and is registered with 
+	 * the GameObjectManager.
+	 */
+	class BS_CORE_EXPORT GameObject : public IReflectable
+	{
+	public:
+		GameObject();
+		virtual ~GameObject();
+
+		/**	Returns the unique instance ID of the GameObject. */
+		UINT64 getInstanceId() const { return mInstanceData->mInstanceId; }
+
+		/**
+		 * Returns an ID that identifies a link between this object and its equivalent in the linked prefab. This will be
+		 * -1 if the object has no prefab link, or if the object is specific to the instance and has no prefab equivalent.
+		 */
+		UINT32 getLinkId() const { return mLinkId; }
+
+		/**	Gets the name of the object. */
+		const String& getName() const { return mName; }
+
+		/**	Sets the name of the object. */
+		void setName(const String& name) { mName = name; }
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Marks the object as destroyed. Generally this means the object has been queued for destruction but it hasn't 
+		 * occurred yet.
+		 */
+		void _setIsDestroyed() { mIsDestroyed = true; }
+
+		/**	Checks if the object has been destroyed. */
+		bool _getIsDestroyed() const { return mIsDestroyed; }
+
+		/** Changes the prefab link ID for this object. See getLinkId(). */
+		void _setLinkId(UINT32 id) { mLinkId = id; }
+
+		/**
+		 * Replaces the instance data with another objects instance data. This object will basically become the original 
+		 * owner of the provided instance data as far as all game object handles referencing it are concerned.
+		 *
+		 * @note
+		 * No alive objects should ever be sharing the same instance data. This can be used for restoring dead handles.
+		 */
+		virtual void _setInstanceData(GameObjectInstanceDataPtr& other);
+
+		/** Returns instance data that identifies this GameObject and is used for referencing by game object handles. */
+		virtual GameObjectInstanceDataPtr _getInstanceData() const { return mInstanceData; }
+
+		/** @endcond */
+
+	protected:
+		friend class GameObjectHandleBase;
+		friend class GameObjectManager;
+		friend class PrefabDiff;
+		friend class PrefabUtility;
+
+		/**	Initializes the GameObject after construction. */
+		void initialize(const std::shared_ptr<GameObject>& object, UINT64 instanceId);
+
+		/**
+		 * Destroys this object.
+		 *
+		 * @param[in]	handle		Game object handle to this object.
+		 * @param[in]	immediate	If true, the object will be deallocated and become unusable right away. Otherwise the 
+		 *							deallocation will be delayed to the end of frame (preferred method).
+		 */
+		virtual void destroyInternal(GameObjectHandleBase& handle, bool immediate = false) = 0;
+
+	protected:
+		String mName;
+		UINT32 mLinkId;
+
+	private:
+		friend class Prefab;
+
+		GameObjectInstanceDataPtr mInstanceData;
+		bool mIsDestroyed;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class GameObjectRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
+}
+
+#include "BsGameObjectHandle.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	// Game object handles
+	typedef GameObjectHandle<GameObject> HGameObject;
+	typedef GameObjectHandle<SceneObject> HSceneObject;
+	typedef GameObjectHandle<Component> HComponent;
+
+	/** @} */
 }

+ 290 - 298
BansheeCore/Include/BsGameObjectHandle.h

@@ -1,299 +1,291 @@
-#pragma once
-
-namespace BansheeEngine
-{
-	class GameObjectManager;
-
-	/**
-	 * @brief	Internal data shared between GameObject handles.
-	 */
-	struct BS_CORE_EXPORT GameObjectHandleData
-	{
-		GameObjectHandleData()
-			:mPtr(nullptr), mInstanceId(0)
-		{ }
-
-		GameObjectHandleData(const std::shared_ptr<GameObjectInstanceData>& ptr)
-		{
-			mPtr = ptr;
-			if(ptr != nullptr)
-				mInstanceId = ptr->object->getInstanceId();
-			else
-				mInstanceId = 0;
-		}
-
-		std::shared_ptr<GameObjectInstanceData> mPtr;
-		UINT64 mInstanceId;
-	};
-
-	/**
-	 * @brief	A handle that can point to various types of game objects.
-	 * 			It primarily keeps track if the object is still alive, so anything
-	 * 			still referencing it doesn't accidentally use it.
-	 * 			
-	 * @note	This class exists because references between game objects should be quite loose.
-	 * 			For example one game object should be able to reference another one without the other
-	 * 			one knowing. But if that is the case I also need to handle the case when the other
-	 * 			object we're referencing has been deleted, and that is the main purpose of this class.
-	 * 			
-	 */
-	class BS_CORE_EXPORT GameObjectHandleBase : public IReflectable
-	{
-	public:
-		GameObjectHandleBase();
-
-		/**
-		 * @brief	Returns true if the object the handle is pointing to has been destroyed.
-		 */
-		bool isDestroyed() const { return mData->mPtr == nullptr || mData->mPtr->object == nullptr; }
-
-		/**
-		 * @brief	Returns the instance ID of the object the handle is referencing.
-		 */
-		UINT64 getInstanceId() const { return mData->mInstanceId; }
-
-		/**
-		 * @brief	Returns pointer to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		GameObject* get() const 
-		{ 
-			throwIfDestroyed();
-
-			return mData->mPtr->object.get(); 
-		}
-
-		/**
-		 * @brief	Returns a smart pointer to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		std::shared_ptr<GameObject> getInternalPtr() const
-		{
-			throwIfDestroyed();
-
-			return mData->mPtr->object;
-		}
-
-		/**
-		 * @brief	Returns pointer to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		GameObject* operator->() const { return get(); }
-
-		/**
-		 * @brief	Returns reference to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		GameObject& operator*() const { return *get(); }
-
-		/**
-		 * @brief	Returns internal handle data.
-		 *
-		 * @note	Internal method.
-		 */
-		std::shared_ptr<GameObjectHandleData> _getHandleData() const { return mData; }
-
-		/**
-		 * @brief	Resolves a handle to a proper GameObject in case it was created uninitialized.
-		 *
-		 * @note	Internal method.
-		 */
-		void _resolve(const GameObjectHandleBase& object);
-
-	protected:
-		friend class SceneObject;
-		friend class SceneObjectRTTI;
-		friend class GameObjectManager;
-
-		GameObjectHandleBase(const std::shared_ptr<GameObject> ptr);
-		GameObjectHandleBase(const std::shared_ptr<GameObjectHandleData>& data);
-		GameObjectHandleBase(std::nullptr_t ptr);
-
-		/**
-		 * @brief	Throws an exception if the referenced GameObject has been destroyed.
-		 */
-		inline void throwIfDestroyed() const;
-		
-		/**
-		 * @brief	Invalidates the handle signifiying the referenced object was destroyed.
-		 */
-		void destroy()
-		{
-			// We need to clear mData->mPtr before we clear mData->mPtr->object,
-			// as this handle could be stored within the "object" and destroyed when
-			// we set it to null 
-			std::shared_ptr<GameObjectInstanceData> instanceData = mData->mPtr;
-			mData->mPtr = nullptr;
-
-			if(instanceData != nullptr)
-				instanceData->object = nullptr;
-		}
-
-		std::shared_ptr<GameObjectHandleData> mData;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-	public:
-		friend class GameObjectHandleRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
-
-	/**
-	 * @copydoc	GameObjectHandleBase
-	 *
-	 * @note	It is important this class contains no data since we often 
-	 *			value cast it to its base.
-	 */
-	template <typename T>
-	class GameObjectHandle : public GameObjectHandleBase
-	{
-	public:
-		/**
-		 * @brief	Constructs a new empty handle.
-		 */
-		GameObjectHandle()
-			:GameObjectHandleBase()
-		{	
-			mData = bs_shared_ptr<GameObjectHandleData, PoolAlloc>();
-		}
-
-		/**
-		 * @brief	Copy constructor from another handle of the same type.
-		 */
-		template <typename T1>
-		GameObjectHandle(const GameObjectHandle<T1>& ptr)
-			:GameObjectHandleBase()
-		{ 	
-			mData = ptr._getHandleData();
-		}
-
-		/**
-		 * @brief	Copy constructor from another handle of the base type.
-		 */
-		GameObjectHandle(const GameObjectHandleBase& ptr)
-			:GameObjectHandleBase()
-		{ 	
-			mData = ptr._getHandleData();
-		}
-
-		/**
-		 * @brief	Invalidates the handle.
-		 */
-		inline GameObjectHandle<T>& operator=(std::nullptr_t ptr)
-		{ 	
-			mData = bs_shared_ptr<GameObjectHandleData, PoolAlloc>();
-
-			return *this;
-		}
-
-		/**
-		 * @brief	Casts a specific handle to the base handle.
-		 */
-		inline operator GameObjectHandleBase()
-		{
-			GameObjectHandleBase base(mData);
-
-			return base;
-		}
-
-		/**
-		 * @brief	Returns a pointer to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		T* get() const 
-		{ 
-			throwIfDestroyed();
-
-			return reinterpret_cast<T*>(mData->mPtr->object.get()); 
-		}
-
-		/**
-		 * @brief	Returns a smart pointer to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		std::shared_ptr<T> getInternalPtr() const
-		{
-			throwIfDestroyed();
-
-			return std::static_pointer_cast<T>(mData->mPtr->object);
-		}
-
-		/**
-		 * @brief	Returns pointer to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		T* operator->() const { return get(); }
-
-		/**
-		 * @brief	Returns reference to the referenced GameObject.
-		 *
-		 * @note	Throws exception if the GameObject was destroyed.
-		 */
-		T& operator*() const { return *get(); }
-
-		template<class _Ty>
-		struct Bool_struct
-		{
-			int _Member;
-		};
-
-		/**
-		 * @brief	Allows direct conversion of handle to bool.
-		 *
-		 * @note	This is needed because we can't directly convert to bool
-		 *			since then we can assign pointer to bool and that's weird.
-		 */
-		operator int Bool_struct<T>::*() const
-		{
-			return (((mData->mPtr != nullptr) && (mData->mPtr->object != nullptr)) ? &Bool_struct<T>::_Member : 0);
-		}
-
-	private:
-		friend class SceneObject;
-		friend class SceneObjectRTTI;
-		friend class GameObjectManager;
-
-		/**
-		 * @brief	Creates a handle from a smart pointer.
-		 */
-		explicit GameObjectHandle(const std::shared_ptr<T> ptr)
-			:GameObjectHandleBase(ptr)
-		{ }
-	};
-
-	/**
-	 * @brief	Casts one handle type to another.
-	 */
-	template<class _Ty1, class _Ty2>
-		GameObjectHandle<_Ty1> static_object_cast(const GameObjectHandle<_Ty2>& other)
-	{	
-		return GameObjectHandle<_Ty1>(other);
-	}
-
-	/**
-	 * @brief	Compares if two handles point to the same GameObject.
-	 */
-	template<class _Ty1, class _Ty2>
-	bool operator==(const GameObjectHandle<_Ty1>& _Left, const GameObjectHandle<_Ty2>& _Right)
-	{	
-		return (_Left == nullptr && _Right == nullptr) || (_Left != nullptr && _Right != nullptr && _Left.get() == _Right.get());
-	}
-
-	/**
-	 * @brief	Compares if two handles point to different GameObjects.
-	 */
-	template<class _Ty1, class _Ty2>
-	bool operator!=(const GameObjectHandle<_Ty1>& _Left, const GameObjectHandle<_Ty2>& _Right)
-	{	
-		return (!(_Left == _Right));
-	}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	class GameObjectManager;
+
+	template <typename T>
+	class GameObjectHandle;
+
+	/** @cond INTERNAL */
+
+	/**	Internal data shared between GameObject handles. */
+	struct BS_CORE_EXPORT GameObjectHandleData
+	{
+		GameObjectHandleData()
+			:mPtr(nullptr)
+		{ }
+
+		GameObjectHandleData(const std::shared_ptr<GameObjectInstanceData>& ptr)
+		{
+			mPtr = ptr;
+		}
+
+		std::shared_ptr<GameObjectInstanceData> mPtr;
+	};
+
+	/** @endcond */
+
+	/**
+	 * A handle that can point to various types of game objects. It primarily keeps track if the object is still alive, 
+	 * so anything still referencing it doesn't accidentally use it.
+	 * 			
+	 * @note	
+	 * This class exists because references between game objects should be quite loose. For example one game object should
+	 * be able to reference another one without the other one knowing. But if that is the case I also need to handle the
+	 * case when the other object we're referencing has been deleted, and that is the main purpose of this class.	
+	 */
+	class BS_CORE_EXPORT GameObjectHandleBase : public IReflectable
+	{
+	public:
+		GameObjectHandleBase();
+
+		/**
+		 * Returns true if the object the handle is pointing to has been destroyed.
+		 *
+		 * @param[in] checkQueued	Game objects can be queued for destruction but not actually destroyed yet, and still
+		 *							accessible. If this is false this method will return true only if the object is 
+		 *							completely inaccessible (fully destroyed). If this is true this method will return true
+		 *							if object is completely inaccessible or if it is just queued for destruction.
+		 */
+		bool isDestroyed(bool checkQueued = false) const
+		{
+			return mData->mPtr == nullptr || mData->mPtr->object == nullptr 
+				|| (checkQueued && mData->mPtr->object->_getIsDestroyed());
+		}
+
+		/**	Returns the instance ID of the object the handle is referencing. */
+		UINT64 getInstanceId() const { return mData->mPtr != nullptr ? mData->mPtr->mInstanceId : 0; }
+
+		/**
+		 * Returns pointer to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		GameObject* get() const 
+		{ 
+			throwIfDestroyed();
+
+			return mData->mPtr->object.get(); 
+		}
+
+		/**
+		 * Returns a smart pointer to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		std::shared_ptr<GameObject> getInternalPtr() const
+		{
+			throwIfDestroyed();
+
+			return mData->mPtr->object;
+		}
+
+		/**
+		 * Returns pointer to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		GameObject* operator->() const { return get(); }
+
+		/**
+		 * Returns reference to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		GameObject& operator*() const { return *get(); }
+
+		/** @cond INTERNAL */
+
+		/** Returns internal handle data. */
+		std::shared_ptr<GameObjectHandleData> _getHandleData() const { return mData; }
+
+		/** Resolves a handle to a proper GameObject in case it was created uninitialized. */
+		void _resolve(const GameObjectHandleBase& object);
+
+		/**	Changes the GameObject instance the handle is pointing to. */
+		void _setHandleData(const GameObjectPtr& object);
+
+		/** @endcond */
+
+	protected:
+		friend class GameObjectManager;
+
+		template<class _Ty1, class _Ty2>
+		friend bool operator==(const GameObjectHandle<_Ty1>& _Left, const GameObjectHandle<_Ty2>& _Right);
+
+		GameObjectHandleBase(const std::shared_ptr<GameObject> ptr);
+		GameObjectHandleBase(const std::shared_ptr<GameObjectHandleData>& data);
+		GameObjectHandleBase(std::nullptr_t ptr);
+
+		/**	Throws an exception if the referenced GameObject has been destroyed. */
+		inline void throwIfDestroyed() const;
+		
+		/**	Invalidates the handle signifying the referenced object was destroyed. */
+		void destroy()
+		{
+			// It's important not to clear mData->mPtr as some code might rely
+			// on it. (e.g. for restoring lost handles)
+
+			if (mData->mPtr != nullptr)
+				mData->mPtr->object = nullptr;
+		}
+
+		std::shared_ptr<GameObjectHandleData> mData;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class GameObjectHandleRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
+
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	GameObjectHandleBase
+	 *
+	 * @note	It is important this class contains no data since we often value cast it to its base.
+	 */
+	template <typename T>
+	class GameObjectHandle : public GameObjectHandleBase
+	{
+	public:
+		/**	Constructs a new empty handle. */
+		GameObjectHandle()
+			:GameObjectHandleBase()
+		{	
+			mData = bs_shared_ptr_new<GameObjectHandleData>();
+		}
+
+		/**	Copy constructor from another handle of the same type. */
+		template <typename T1>
+		GameObjectHandle(const GameObjectHandle<T1>& ptr)
+			:GameObjectHandleBase()
+		{ 	
+			mData = ptr._getHandleData();
+		}
+
+		/**	Copy constructor from another handle of the base type. */
+		GameObjectHandle(const GameObjectHandleBase& ptr)
+			:GameObjectHandleBase()
+		{ 	
+			mData = ptr._getHandleData();
+		}
+
+		/**	Invalidates the handle. */
+		GameObjectHandle<T>& operator=(std::nullptr_t ptr)
+		{ 	
+			mData = bs_shared_ptr_new<GameObjectHandleData>();
+
+			return *this;
+		}
+
+		/**	Casts a specific handle to the base handle. */
+		operator GameObjectHandleBase()
+		{
+			GameObjectHandleBase base(mData);
+
+			return base;
+		}
+
+		/**
+		 * Returns a pointer to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		T* get() const 
+		{ 
+			throwIfDestroyed();
+
+			return reinterpret_cast<T*>(mData->mPtr->object.get()); 
+		}
+
+		/**
+		 * Returns a smart pointer to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		std::shared_ptr<T> getInternalPtr() const
+		{
+			throwIfDestroyed();
+
+			return std::static_pointer_cast<T>(mData->mPtr->object);
+		}
+
+		/**
+		 * Returns pointer to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		T* operator->() const { return get(); }
+
+		/**
+		 * Returns reference to the referenced GameObject.
+		 *
+		 * @note	Throws exception if the GameObject was destroyed.
+		 */
+		T& operator*() const { return *get(); }
+
+		/** @cond INTERNAL */
+
+		template<class _Ty>
+		struct Bool_struct
+		{
+			int _Member;
+		};
+
+		/**
+		 * Allows direct conversion of handle to bool.
+		 *
+		 * @note	
+		 * This is needed because we can't directly convert to bool since then we can assign pointer to bool and that's 
+		 * weird.
+		 */
+		operator int Bool_struct<T>::*() const
+		{
+			return (((mData->mPtr != nullptr) && (mData->mPtr->object != nullptr)) ? &Bool_struct<T>::_Member : 0);
+		}
+
+		/** @endcond */
+	};
+
+	/**	Casts one GameObject handle type to another. */
+	template<class _Ty1, class _Ty2>
+		GameObjectHandle<_Ty1> static_object_cast(const GameObjectHandle<_Ty2>& other)
+	{	
+		return GameObjectHandle<_Ty1>(other);
+	}
+
+	/** @cond INTERNAL */
+
+	/**	Compares if two handles point to the same GameObject. */
+	template<class _Ty1, class _Ty2>
+	bool operator==(const GameObjectHandle<_Ty1>& _Left, const GameObjectHandle<_Ty2>& _Right)
+	{	
+		return (_Left.mData == nullptr && _Right.mData == nullptr) || 
+			(_Left.mData != nullptr && _Right.mData != nullptr && _Left.getInstanceId() == _Right.getInstanceId());
+	}
+
+	/**	Compares if two handles point to different GameObject%s. */
+	template<class _Ty1, class _Ty2>
+	bool operator!=(const GameObjectHandle<_Ty1>& _Left, const GameObjectHandle<_Ty2>& _Right)
+	{	
+		return (!(_Left == _Right));
+	}
+
+	/** @endcond */
+	/** @} */
 }

+ 67 - 46
BansheeCore/Include/BsGameObjectHandleRTTI.h

@@ -1,47 +1,68 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGameObjectHandle.h"
-#include "BsGameObjectManager.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GameObjectHandleRTTI : public RTTIType<GameObjectHandleBase, IReflectable, GameObjectHandleRTTI>
-	{
-	private:
-		UINT64& getInstanceId(GameObjectHandleBase* obj) { return obj->mData->mInstanceId; }
-		void setInstanceId(GameObjectHandleBase* obj, UINT64& value) { obj->mData->mInstanceId = value; } 
-
-	public:
-		GameObjectHandleRTTI()
-		{
-			addPlainField("mInstanceID", 0, &GameObjectHandleRTTI::getInstanceId, &GameObjectHandleRTTI::setInstanceId);
-		}
-
-		void onDeserializationEnded(IReflectable* obj)
-		{
-			GameObjectHandleBase* gameObjectHandle = static_cast<GameObjectHandleBase*>(obj);
-
-			GameObjectManager::instance().registerUnresolvedHandle(*gameObjectHandle);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GameObjectHandleBase";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GameObjectHandleBase;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			std::shared_ptr<GameObjectHandleBase> obj = bs_shared_ptr<GameObjectHandleBase, PoolAlloc>(new (bs_alloc<GameObjectHandleBase, PoolAlloc>()) GameObjectHandleBase());
-
-			return obj;
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsGameObjectHandle.h"
+#include "BsGameObjectManager.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT GameObjectHandleRTTI : public RTTIType<GameObjectHandleBase, IReflectable, GameObjectHandleRTTI>
+	{
+	private:
+		UINT64& getInstanceId(GameObjectHandleBase* obj)
+		{
+			static UINT64 invalidId = 0;
+
+			if (obj->mData->mPtr != nullptr)
+				return obj->mData->mPtr->mInstanceId;
+
+			return invalidId;
+		}
+
+		void setInstanceId(GameObjectHandleBase* obj, UINT64& value) { obj->mRTTIData = value; } 
+
+	public:
+		GameObjectHandleRTTI()
+		{
+			addPlainField("mInstanceID", 0, &GameObjectHandleRTTI::getInstanceId, &GameObjectHandleRTTI::setInstanceId);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			GameObjectHandleBase* gameObjectHandle = static_cast<GameObjectHandleBase*>(obj);
+
+			UINT64 originalInstanceId = any_cast<UINT64>(gameObjectHandle->mRTTIData);
+			GameObjectManager::instance().registerUnresolvedHandle(originalInstanceId, *gameObjectHandle);
+			gameObjectHandle->mRTTIData = nullptr;
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "GameObjectHandleBase";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_GameObjectHandleBase;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			std::shared_ptr<GameObjectHandleBase> obj = bs_shared_ptr<GameObjectHandleBase>(new (bs_alloc<GameObjectHandleBase>()) GameObjectHandleBase());
+
+			return obj;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 155 - 101
BansheeCore/Include/BsGameObjectManager.h

@@ -1,102 +1,156 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsGameObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Tracks GameObject creation and destructions. Also resolves
-	 *			GameObject references from GameObject handles.
-	 *
-	 * @note	Sim thread only.
-	 */
-	class BS_CORE_EXPORT GameObjectManager : public Module<GameObjectManager>
-	{
-	public:
-		GameObjectManager();
-		~GameObjectManager();
-
-		/**
-		 * @brief	Registers a new GameObject and returns the handle to the object.
-		 */
-		GameObjectHandleBase registerObject(const std::shared_ptr<GameObject>& object);
-
-		/**
-		 * @brief	Unregisters a GameObject.
-		 */
-		void unregisterObject(const GameObjectHandleBase& object);
-
-		/**
-		 * @brief	Attempts to find a GameObject handle based on the GameObject instance ID.
-		 *			Returns empty handle if ID cannot be found.
-		 */
-		GameObjectHandleBase getObject(UINT64 id) const;
-
-		/**
-		 * @brief	Attempts to find a GameObject handle based on the GameObject instance ID.
-		 *			Returns true if object with the specified ID is found, false otherwise.
-		 */
-		bool tryGetObject(UINT64 id, GameObjectHandleBase& object) const;
-
-		/**
-		 * @brief	Checks if the GameObject with the specified instance ID exists.
-		 */
-		bool objectExists(UINT64 id) const;
-
-		/************************************************************************/
-		/* 							DESERIALIZATION                      		*/
-		/************************************************************************/
-		// Note: GameObjects need a bit of special handling when it comes to deserialization,
-		// which is what this part of the code is used for. It performs two main actions:
-		//  - 1. Resolves all GameObjectHandles on deserialization
-		//    - We can't just resolve them as we go because during deserialization not all objects
-		//      have necessarily been created.
-		//  - 2. Maps serialized IDs to actual in-engine ids. 
-
-		/**
-		 * @brief	Needs to be called whenever GameObject deserialization starts. Must be followed
-		 * 			by endDeserialization call.
-		 */
-		void startDeserialization();
-
-		/**
-		 * @brief	Needs to be called whenever GameObject deserialization ends. Must be preceded
-		 * 			by startDeserialization call.
-		 */
-		void endDeserialization();
-
-		/**
-		 * @brief	Returns true if GameObject deserialization is currently in progress.
-		 */
-		bool isGameObjectDeserializationActive() const { return mIsDeserializationActive; }
-
-		/**
-		 * @brief	Registers an id that was deserialized, and has been remapped to
-		 * 			an actual in-engine ID. This will be used when resolving GameObjectHandles
-		 * 			(since they might point to the invalid deserialized id).
-		 */
-		void registerDeserializedId(UINT64 deserializedId, UINT64 actualId);
-
-		/**
-		 * @brief	Queues the specified handle and resolves it when deserialization ends.
-		 */
-		void registerUnresolvedHandle(const GameObjectHandleBase& object);
-
-		/**
-		 * @brief	Registers a callback that will be triggered when GameObject serialization ends.
-		 */
-		void registerOnDeserializationEndCallback(std::function<void()> callback);
-
-	private:
-		UINT64 mNextAvailableID; // 0 is not a valid ID
-		Map<UINT64, GameObjectHandleBase> mObjects;
-
-		GameObject* mActiveDeserializedObject;
-		bool mIsDeserializationActive;
-		Map<UINT64, UINT64> mIdMapping;
-		Vector<GameObjectHandleBase> mUnresolvedHandles;
-		Vector<std::function<void()>> mEndCallbacks;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsGameObject.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/**	Possible modes to use when deserializing games objects. */
+	enum GameObjectHandleDeserializationMode
+	{
+		/** All handles will point to old ID that were restored from the deserialized file. */
+		GODM_UseOriginalIds = 0x01, 
+		/** All handles will point to new IDs that were given to the deserialized GameObjects. */
+		GODM_UseNewIds = 0x02,
+		/** Handles pointing to GameObjects outside of the currently deserialized set
+		will attempt to be restored in case those objects are still active. */
+		GODM_RestoreExternal = 0x04,
+		/** Handles pointing to GameObjects outside of the currently deserialized set
+		will be broken. */
+		GODM_BreakExternal = 0x08,
+		/** Handles pointing to GameObjects that cannot be found will not be set to null. */
+		GODM_KeepMissing = 0x10
+	};
+
+	/**
+	 * Tracks GameObject creation and destructions. Also resolves GameObject references from GameObject handles.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT GameObjectManager : public Module<GameObjectManager>
+	{
+		/**	Contains data for an yet unresolved game object handle. */
+		struct UnresolvedHandle
+		{
+			UINT64 originalInstanceId;
+			GameObjectHandleBase handle;
+		};
+
+	public:
+		GameObjectManager();
+		~GameObjectManager();
+
+		/**
+		 * Registers a new GameObject and returns the handle to the object.
+		 * 			
+		 * @param[in]	object			Constructed GameObject to wrap in the handle and initialize.
+		 * @param[in]	originalId		If the object is being created due to deserialization you must provide the original
+		 *								object's ID so that deserialized handles can map to it properly.
+		 * @return						Handle to the GameObject.
+		 */
+		GameObjectHandleBase registerObject(const std::shared_ptr<GameObject>& object, UINT64 originalId = 0);
+
+		/**
+		 * Unregisters a GameObject. Handles to this object will no longer be valid after this call. This should be called
+		 * whenever a GameObject is destroyed.
+		 */
+		void unregisterObject(GameObjectHandleBase& object);
+
+		/**
+		 * Attempts to find a GameObject handle based on the GameObject instance ID. Returns empty handle if ID cannot be 
+		 * found.
+		 */
+		GameObjectHandleBase getObject(UINT64 id) const;
+
+		/**
+		 * Attempts to find a GameObject handle based on the GameObject instance ID. Returns true if object with the 
+		 * specified ID is found, false otherwise.
+		 */
+		bool tryGetObject(UINT64 id, GameObjectHandleBase& object) const;
+
+		/**	Checks if the GameObject with the specified instance ID exists. */
+		bool objectExists(UINT64 id) const;
+
+		/**
+		 * Changes the instance ID by which an object can be retrieved by. 
+		 *
+		 * @note	Caller is required to update the object itself with the new ID.
+		 */
+		void remapId(UINT64 oldId, UINT64 newId);
+
+		/**	Queues the object to be destroyed at the end of a GameObject update cycle. */
+		void queueForDestroy(const GameObjectHandleBase& object);
+
+		/**	Destroys any GameObjects that were queued for destruction. */
+		void destroyQueuedObjects();
+
+		/**	Triggered when a game object is being destroyed. */
+		Event<void(const HGameObject&)> onDestroyed;
+
+		/************************************************************************/
+		/* 							DESERIALIZATION                      		*/
+		/************************************************************************/
+		// Note: GameObjects need a bit of special handling when it comes to deserialization,
+		// which is what this part of the code is used for. It performs two main actions:
+		//  - 1. Resolves all GameObjectHandles on deserialization
+		//    - We can't just resolve them as we go because during deserialization not all objects
+		//      have necessarily been created.
+		//  - 2. Maps serialized IDs to actual in-engine IDs. 
+
+		/** Needs to be called whenever GameObject deserialization starts. Must be followed by endDeserialization() call. */
+		void startDeserialization();
+
+		/** Needs to be called whenever GameObject deserialization ends. Must be preceded by startDeserialization() call. */
+		void endDeserialization();
+
+		/**	Returns true if GameObject deserialization is currently in progress. */
+		bool isGameObjectDeserializationActive() const { return mIsDeserializationActive; }
+
+		/**	Queues the specified handle and resolves it when deserialization ends. */
+		void registerUnresolvedHandle(UINT64 originalId, GameObjectHandleBase& object);
+
+		/**	Registers a callback that will be triggered when GameObject serialization ends. */
+		void registerOnDeserializationEndCallback(std::function<void()> callback);
+
+		/**
+		 * Changes the deserialization mode for any following GameObject handle.
+		 *
+		 * @param[in]	gameObjectDeserializationMode	Mode that controls how are GameObjects handles resolved when being
+		 *												deserialized.
+		 */
+		void setDeserializationMode(UINT32 gameObjectDeserializationMode);
+
+		/**
+		 * Attempts to update the ID of the provided handle by mapping its old ID to the newly deserialized object and its
+		 * new ID. Game object deserialization must be active.
+		 */
+		void resolveDeserializedHandle(UnresolvedHandle& data, UINT32 flags);
+
+		/**	Gets the currently active flags that control how are game object handles deserialized. */
+		UINT32 getDeserializationFlags() const { return mGODeserializationMode; }
+
+	private:
+		UINT64 mNextAvailableID; // 0 is not a valid ID
+		Map<UINT64, GameObjectHandleBase> mObjects;
+		Map<UINT64, GameObjectHandleBase> mQueuedForDestroy;
+
+		GameObject* mActiveDeserializedObject;
+		bool mIsDeserializationActive;
+		Map<UINT64, UINT64> mIdMapping;
+		Map<UINT64, SPtr<GameObjectHandleData>> mUnresolvedHandleData;
+		Vector<UnresolvedHandle> mUnresolvedHandles;
+		Vector<std::function<void()>> mEndCallbacks;
+		UINT32 mGODeserializationMode;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 97 - 54
BansheeCore/Include/BsGameObjectRTTI.h

@@ -1,55 +1,98 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGameObject.h"
-#include "BsSceneObject.h"
-#include "BsGameObjectManager.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GameObjectRTTI : public RTTIType<GameObject, IReflectable, GameObjectRTTI>
-	{
-	private:
-		String& getName(GameObject* obj) { return obj->mName; }
-		void setName(GameObject* obj, String& name) { obj->mName = name; }
-
-		UINT64& getInstanceID(GameObject* obj) { return obj->mInstanceData->mInstanceId; }
-		void setInstanceID(GameObject* obj, UINT64& instanceId) 
-		{  
-			// The system will have already assigned the instance ID, but since other objects might be referencing
-			// the old (serialized) ID we store it in the GameObjectSerializationManager so we can map from old to new id.
-			GameObjectManager::instance().registerDeserializedId(instanceId, obj->getInstanceId());
-		}
-
-	public:
-		template <typename T>
-		static std::shared_ptr<T> createGameObject()
-		{
-			return SceneObject::createEmptyComponent<T>();
-		}
-
-	public:
-		GameObjectRTTI()
-		{
-			addPlainField("mInstanceID", 0, &GameObjectRTTI::getInstanceID, &GameObjectRTTI::setInstanceID);
-			addPlainField("mName", 1, &GameObjectRTTI::getName, &GameObjectRTTI::setName);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GameObject";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GameObject;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsGameObject.h"
+#include "BsSceneObject.h"
+#include "BsGameObjectManager.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	/**	Provides temporary storage for data used during GameObject deserialization. */
+	struct GODeserializationData
+	{
+		GODeserializationData()
+			:isDeserializationParent(false), originalId(0)
+		{ }
+
+		GameObjectPtr ptr;
+		bool isDeserializationParent;
+		UINT64 originalId;
+		Any moreData;
+	};
+
+	class BS_CORE_EXPORT GameObjectRTTI : public RTTIType<GameObject, IReflectable, GameObjectRTTI>
+	{
+	private:
+		String& getName(GameObject* obj) { return obj->mName; }
+		void setName(GameObject* obj, String& name) { obj->mName = name; }
+
+		UINT64& getInstanceID(GameObject* obj) { return obj->mInstanceData->mInstanceId; }
+		void setInstanceID(GameObject* obj, UINT64& instanceId) 
+		{  
+			// We record the ID for later use. Any child RTTI of GameObject must call GameObjectManager::registerObject
+			// with this ID, so we know how to map deserialized GO handles to live objects, otherwise the handle
+			// references will get broken.
+			GameObject* go = static_cast<GameObject*>(obj);
+			GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(go->mRTTIData);
+
+			deserializationData.originalId = instanceId;
+		}
+
+		UINT32& getLinkId(GameObject* obj) { return obj->mLinkId; }
+		void setLinkId(GameObject* obj, UINT32& linkId) { obj->mLinkId = linkId; }
+
+	public:
+		/**
+		 * @brief	Helper method used for creating Component objects used during deserialization.
+		 */
+		template <typename T>
+		static std::shared_ptr<T> createGameObject()
+		{
+			SPtr<T> component = SceneObject::createEmptyComponent<T>();
+
+			// Every GameObject must store GODeserializationData in its RTTI data field during deserialization
+			component->mRTTIData = GODeserializationData();
+			GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(component->mRTTIData);
+
+			// Store shared pointer since the system only provides us with raw ones
+			deserializationData.ptr = component;
+
+			return component;
+		}
+
+	public:
+		GameObjectRTTI()
+		{
+			addPlainField("mInstanceID", 0, &GameObjectRTTI::getInstanceID, &GameObjectRTTI::setInstanceID);
+			addPlainField("mName", 1, &GameObjectRTTI::getName, &GameObjectRTTI::setName);
+			addPlainField("mLinkId", 2, &GameObjectRTTI::getLinkId, &GameObjectRTTI::setLinkId);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "GameObject";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_GameObject;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 217 - 184
BansheeCore/Include/BsGpuBuffer.h

@@ -1,184 +1,217 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsGpuBufferView.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Handles a generic GPU buffer that you may use for storing any kind of data you wish to be accessible
-	 *			to the GPU. These buffers may be bounds to GPU program binding slots and accessed from a GPU program,
-	 *			or may be used by fixed pipeline in some way.
-	 *
-	 *			Buffer types:
-	 *			  - Raw buffers containing a block of bytes that are up to the GPU program to interpret.
-	 *			  - Structured buffer containing an array of structures compliant to a certain layout. Similar to raw
-	 *				buffer but easier to interpret the data.
-	 *			  - Random read/write buffers that allow you to write to random parts of the buffer from within
-	 *				the GPU program, and then read it later. These can only be bound to pixel and compute stages.
-	 *			  - Append/Consume buffers also allow you to write to them, but in a stack-like fashion, usually where one set
-	 *				of programs produces data while other set consumes it from the same buffer. Append/Consume buffers are structured
-	 *				by default.
-	 *
-	 * @note	Core thread only.
-	 */
-	class BS_CORE_EXPORT GpuBuffer : public CoreObject
-    {
-    public:
-        virtual ~GpuBuffer();
-
-		/**
-		 * @brief	Locks the buffer returning a pointer to the internal buffer data that you may then
-		 *			read or write to. Caller must ensure it will only perform actions promised in the
-		 *			provided GPU lock options parameter.
-		 *
-		 * @param	offset	Number of bytes at which to lock the buffer. Returned pointer points to this location.
-		 * @param	length	Number of bytes to lock.
-		 * @param	options How to lock the buffer. Certain options offer better performance than others.
-		 */
-		virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
-
-		/**
-		 * @brief	Unlocks a previously locked buffer. Any pointers to internal buffers returned when
-		 *			it was locked will become invalid.
-		 */
-		virtual void unlock() = 0;
-
-		/**
-		 * @brief	Reads buffer data into the previously allocated buffer.
-		 *
-		 * @param	offset	Number of bytes at which to start reading the buffer.
-		 * @param	length	Number of bytes to read.
-		 * @param	pDest	Previously allocated buffer of "length" bytes size.
-		 */
-        virtual void readData(UINT32 offset, UINT32 length, void* pDest) = 0;
-
-		/**
-		* @brief	Writes data into the buffer.
-		*
-		* @param	offset		Number of bytes at which to start writing to the buffer.
-		* @param	length		Number of bytes to write.
-		* @param	pDest		Previously allocated buffer used to retrieve the data from.
-		* @param	writeFlags  Flags that may be used to improve performance for specific use cases.
-		*/
-        virtual void writeData(UINT32 offset, UINT32 length, const void* pSource, BufferWriteType writeFlags = BufferWriteType::Normal) = 0;
-
-		/**
-		 * @brief	Copies data from another buffer into this buffer.
-		 *
-		 * @param	srcBuffer			Buffer to copy the data from.
-		 * @param	srcOffset			Offset in bytes into the source buffer - this is where reading starts from.
-		 * @param	dstOffset			Offset in bytes into the destination buffer - this is where writing starts from.
-		 * @param	length				Number of bytes to copy from source to destination.
-		 * @param	discardWholeBuffer	If true, the contents of the current buffer will be entirely discarded. This can improve
-		 *								performance if you know you wont be needing that data any more.
-		 */
-		virtual void copyData(GpuBuffer& srcBuffer, UINT32 srcOffset, 
-			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false) = 0;
-
-		/**
-		 * @brief	Creates a buffer view that may be used for binding a buffer to a slot in the pipeline. Views allow you to specify
-		 *			how is data in the buffer organized to make it easier for the pipeline to interpret.
-		 *
-		 * @param	buffer			Buffer to create the view for.
-		 * @param	firstElement	Position of the first element visible by the view.
-		 * @param	elementWidth	Width of one element in bytes.
-		 * @param	numElements		Number of elements in the buffer.
-		 * @param	useCounter		Should the buffer allow use of a counter. This is only relevant for random read write buffers.
-		 * @param	usage			Determines type of the view we are creating, and which slots in the pipeline will the view be bindable to.
-		 *
-		 * @note	If a view with this exact parameters already exists, it will be returned and new one will not be created.
-		 *
-		 *			Only Default and RandomWrite views are supported for this type of buffer. 
-		 *			TODO Low Priority: Perhaps reflect this limitation by having an enum with only
-		 *			those two options?
-		 */
-		static GpuBufferView* requestView(GpuBufferPtr buffer, UINT32 firstElement, UINT32 elementWidth, UINT32 numElements, bool useCounter, GpuViewUsage usage);
-
-		/**
-		 * @brief	Releases a view created with requestView. 
-		 *
-		 * @note	View will only truly get released once all references to it are released.
-		 */
-		static void releaseView(GpuBufferView* view);
-
-		/**
-		 * @brief	Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created
-		 *			for the buffer, and how is data read or modified in it.
-		 */
-		GpuBufferType getType() const { return mType; }
-
-		/**
-		 * @brief	Returns buffer usage which determines how are planning on updating the buffer contents.
-		 */
-		GpuBufferUsage getUsage() const { return mUsage; }
-
-		/**
-		 * @brief	Return whether the buffer supports random reads and writes within the GPU programs.
-		 */
-		bool getRandomGpuWrite() const { return mRandomGpuWrite; }
-
-		/**
-		 * @brief	Returns whether the buffer supports counter use within GPU programs.
-		 */
-		bool getUseCounter() const { return mUseCounter; }
-
-		/**
-		 * @brief	Returns number of elements in the buffer.
-		 */
-		UINT32 getElementCount() const { return mElementCount; }
-
-		/**
-		 * @brief	Returns size of a single element in the buffer in bytes.
-		 */
-		UINT32 getElementSize() const { return mElementSize; }
-
-	protected:
-		GpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
-
-		/**
-		 * @brief	Creates an empty view for the current buffer.
-		 */
-		virtual GpuBufferView* createView() = 0;
-
-		/**
-		 * @brief	Destroys a view previously created for this buffer.
-		 */
-		virtual void destroyView(GpuBufferView* view) = 0;
-
-		/**
-		 * @brief	Destroys all buffer views regardless if their reference count is
-		 *			zero or not.
-		 */
-		void clearBufferViews();
-
-		/**
-		 * @copydoc CoreObject::destroy_internal()
-		 */
-		virtual void destroy_internal();
-
-		/**
-		 * @brief	Helper class to help with reference counting for GPU buffer views.
-		 */
-		struct GpuBufferReference
-		{
-			GpuBufferReference(GpuBufferView* _view)
-				:view(_view), refCount(0)
-			{ }
-
-			GpuBufferView* view;
-			UINT32 refCount;
-		};
-
-		UnorderedMap<GPU_BUFFER_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
-
-	protected:
-		GpuBufferType mType;
-		GpuBufferUsage mUsage;
-		bool mRandomGpuWrite;
-		bool mUseCounter;
-		UINT32 mElementCount;
-		UINT32 mElementSize;
-    };
-}
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuBufferView.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** 
+	 * Information about a GpuBuffer. Allows core and non-core versions of GpuBuffer to share the same structure for 
+	 * properties. 
+	 */
+	class BS_CORE_EXPORT GpuBufferProperties
+	{
+	public:
+		GpuBufferProperties(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
+			GpuBufferUsage usage, bool randomGpuWrite, bool useCounter);
+
+		/**
+		 * Returns the type of the GPU buffer. Type determines which kind of views (if any) can be created for the buffer, 
+		 * and how is data read or modified in it.
+		 */
+		GpuBufferType getType() const { return mType; }
+
+		/** Returns buffer usage which determines how are planning on updating the buffer contents. */
+		GpuBufferUsage getUsage() const { return mUsage; }
+
+		/** Return whether the buffer supports random reads and writes within the GPU programs. */
+		bool getRandomGpuWrite() const { return mRandomGpuWrite; }
+
+		/**	Returns whether the buffer supports counter use within GPU programs. */
+		bool getUseCounter() const { return mUseCounter; }
+
+		/**	Returns number of elements in the buffer. */
+		UINT32 getElementCount() const { return mElementCount; }
+
+		/**	Returns size of a single element in the buffer in bytes. */
+		UINT32 getElementSize() const { return mElementSize; }
+
+	protected:
+		GpuBufferType mType;
+		GpuBufferUsage mUsage;
+		bool mRandomGpuWrite;
+		bool mUseCounter;
+		UINT32 mElementCount;
+		UINT32 mElementSize;
+	};
+
+	/** @cond INTERNAL */
+
+	/**
+	 * Core thread version of a GpuBuffer.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT GpuBufferCore : public CoreObjectCore
+	{
+	public:
+		virtual ~GpuBufferCore();
+
+		/**
+		 * Locks the buffer returning a pointer to the internal buffer data that you may then read or write to. 
+		 * Caller must ensure it will only perform actions promised in the provided GPU lock options parameter.
+		 *
+		 * @param[in]	offset	Number of bytes at which to lock the buffer. Returned pointer points to this location.
+		 * @param[in]	length	Number of bytes to lock.
+		 * @param[in]	options How to lock the buffer. Certain options offer better performance than others.
+		 */
+		virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
+
+		/**
+		 * Unlocks a previously locked buffer. Any pointers to internal buffers returned when it was locked will become 
+		 * invalid.
+		 */
+		virtual void unlock() = 0;
+
+		/**
+		 * Reads buffer data into the previously allocated buffer.
+		 *
+		 * @param[in]	offset	Number of bytes at which to start reading the buffer.
+		 * @param[in]	length	Number of bytes to read.
+		 * @param[in]	pDest	Previously allocated buffer of @p length bytes size.
+		 */
+        virtual void readData(UINT32 offset, UINT32 length, void* pDest) = 0;
+
+		/**
+		 * Writes data into the buffer.
+		 *
+		 * @param[in]	offset		Number of bytes at which to start writing to the buffer.
+		 * @param[in]	length		Number of bytes to write.
+		 * @param[in]	pDest		Previously allocated buffer used to retrieve the data from.
+		 * @param[in]	writeFlags  Flags that may be used to improve performance for specific use cases.
+		 */
+        virtual void writeData(UINT32 offset, UINT32 length, const void* pSource, BufferWriteType writeFlags = BufferWriteType::Normal) = 0;
+
+		/**
+		 * Copies data from another buffer into this buffer.
+		 *
+		 * @param[in]	srcBuffer			Buffer to copy the data from.
+		 * @param[in]	srcOffset			Offset in bytes into the source buffer - this is where reading starts from.
+		 * @param[in]	dstOffset			Offset in bytes into the destination buffer - this is where writing starts from.
+		 * @param[in]	length				Number of bytes to copy from source to destination.
+		 * @param[in]	discardWholeBuffer	If true, the contents of the current buffer will be entirely discarded. This can
+		 *									improve performance if you know you wont be needing that data any more.
+		 */
+		virtual void copyData(GpuBufferCore& srcBuffer, UINT32 srcOffset,
+			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false) = 0;
+
+		/** Returns properties describing the buffer. */
+		const GpuBufferProperties& getProperties() const { return mProperties; }
+
+		/**
+		 * Creates a buffer view that may be used for binding a buffer to a slot in the pipeline. Views allow you to specify
+		 * how is data in the buffer organized to make it easier for the pipeline to interpret.
+		 *
+		 * @param[in]	buffer			Buffer to create the view for.
+		 * @param[in]	firstElement	Position of the first element visible by the view.
+		 * @param[in]	elementWidth	Width of one element in bytes.
+		 * @param[in]	numElements		Number of elements in the buffer.
+		 * @param[in]	useCounter		Should the buffer allow use of a counter. This is only relevant for random read write buffers.
+		 * @param[in]	usage			Determines type of the view we are creating, and which slots in the pipeline will the view be bindable to.
+		 *
+		 * @note If a view with this exact parameters already exists, it will be returned and new one will not be created.
+		 * @note Only Default and RandomWrite views are supported for this type of buffer. 
+		 */
+		// TODO Low Priority: Perhaps reflect usage flag limitation by having an enum with only the supported two options?
+		static GpuBufferView* requestView(const SPtr<GpuBufferCore>& buffer, UINT32 firstElement, UINT32 elementWidth, 
+			UINT32 numElements, bool useCounter, GpuViewUsage usage);
+
+		/**
+		 * Releases a view created with requestView. 
+		 *
+		 * @note	View will only truly get released once all references to it are released.
+		 */
+		static void releaseView(GpuBufferView* view);
+
+	protected:
+		GpuBufferCore(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, 
+			GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+
+		/** Creates an empty view for the current buffer. */
+		virtual GpuBufferView* createView() = 0;
+
+		/**	Destroys a view previously created for this buffer. */
+		virtual void destroyView(GpuBufferView* view) = 0;
+
+		/**	Destroys all buffer views regardless if their reference count is zero or not. */
+		void clearBufferViews();
+
+		/**	Helper class to help with reference counting for GPU buffer views. */
+		struct GpuBufferReference
+		{
+			GpuBufferReference(GpuBufferView* _view)
+				:view(_view), refCount(0)
+			{ }
+
+			GpuBufferView* view;
+			UINT32 refCount;
+		};
+
+		UnorderedMap<GPU_BUFFER_DESC, GpuBufferReference*, GpuBufferView::HashFunction, GpuBufferView::EqualFunction> mBufferViews;
+		GpuBufferProperties mProperties;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Handles a generic GPU buffer that you may use for storing any kind of data you wish to be accessible to the GPU.
+	 * These buffers may be bounds to GPU program binding slots and accessed from a GPU program, or may be used by fixed 
+	 * pipeline in some way.
+	 *
+	 * Buffer types:
+	 *  - Raw buffers containing a block of bytes that are up to the GPU program to interpret.
+	 *	- Structured buffer containing an array of structures compliant to a certain layout. Similar to raw buffer but 
+	 *    easier to interpret the data.
+	 *	- Random read/write buffers that allow you to write to random parts of the buffer from within the GPU program, and 
+	 *    then read it later. These can only be bound to pixel and compute stages.
+	 *	- Append/Consume buffers also allow you to write to them, but in a stack-like fashion, usually where one set of 
+	 *    programs produces data while other set consumes it from the same buffer. Append/Consume buffers are structured
+	 *	  by default.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT GpuBuffer : public CoreObject
+    {
+    public:
+		virtual ~GpuBuffer() { }
+
+		/** Returns properties describing the buffer. */
+		const GpuBufferProperties& getProperties() const { return mProperties; }
+
+		/** Retrieves a core implementation of a GPU buffer usable only from the core thread. */
+		SPtr<GpuBufferCore> getCore() const;
+
+	protected:
+		friend class HardwareBufferManager;
+
+		GpuBuffer(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferUsage usage, 
+			bool randomGpuWrite = false, bool useCounter = false);
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
+		static GpuParamBlockBufferPtr create(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+
+		GpuBufferProperties mProperties;
+    };
+
+	/** @} */
+}

+ 88 - 98
BansheeCore/Include/BsGpuBufferView.h

@@ -1,99 +1,89 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Descriptor structure used for initializing a GPU buffer view.
-	 *
-	 * @see		GpuBufferView
-	 * @see		GpuBuffer
-	 */
-	struct BS_CORE_EXPORT GPU_BUFFER_DESC
-	{
-		UINT32 firstElement;
-		UINT32 elementWidth;
-		UINT32 numElements;
-		bool useCounter;
-		GpuViewUsage usage;
-	};
-
-	/**
-	 * @brief	Holds information about a GPU buffer view. Views allow you to specify
-	 *			how is data in a buffer organized to make it easier for the pipeline to interpret.
-	 *			
-	 * @note	Buffers don't get bound to the pipeline directly, views do.
-	 *			Core thread only.
-	 *
-	 * @see		GpuBuffer
-	 */
-	class BS_CORE_EXPORT GpuBufferView
-	{
-	public:
-		class HashFunction
-		{
-		public:
-			size_t operator()(const GPU_BUFFER_DESC& key) const;
-		};
-
-		class EqualFunction
-		{
-		public:
-			bool operator()(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const;
-		};
-
-		GpuBufferView();
-		virtual ~GpuBufferView();
-
-		/**
-		 * @brief	Initializes the view with the specified buffer and 
-		 *			a set of parameters describing the view to create.
-		 *			Must be called right after construction.
-		 */
-		virtual void initialize(GpuBufferPtr buffer, GPU_BUFFER_DESC& desc);
-
-		/**
-		 * @brief	Returns a descriptor structure used for creating the view.
-		 */
-		const GPU_BUFFER_DESC& getDesc() const { return mDesc; }
-
-		/**
-		 * @brief	Returns the buffer this view was created for.
-		 */
-		GpuBufferPtr getBuffer() const { return mBuffer; }
-
-		/**
-		 * @brief	Returns index of first element in the buffer that this view
-		 *			provides access to.
-		 */
-		UINT32 getFirstElement() const { return mDesc.firstElement; }
-
-		/**
-		 * @brief	Returns width of an element in the buffer, in bytes.
-		 */
-		UINT32 getElementWidth() const { return mDesc.elementWidth; }
-
-		/**
-		 * @brief	Returns the total number of elements this buffer provides
-		 *			access to.
-		 */
-		UINT32 getNumElements() const { return mDesc.numElements; }
-
-		/**
-		 * @brief	Returns true if this view allows a GPU program to use counters on
-		 *			the bound buffer.
-		 */
-		bool getUseCounter() const { return mDesc.useCounter; }
-
-		/**
-		 * @brief	Returns view usage which determines where in the pipeline 
-		 *			can the view be bound.
-		 */
-		GpuViewUsage getUsage() const { return mDesc.usage; }
-
-	protected:
-		GPU_BUFFER_DESC mDesc;
-		GpuBufferPtr mBuffer;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Descriptor structure used for initializing a GPUBufferView.
+	 *
+	 * @see		GpuBuffer
+	 */
+	struct BS_CORE_EXPORT GPU_BUFFER_DESC
+	{
+		UINT32 firstElement;
+		UINT32 elementWidth;
+		UINT32 numElements;
+		bool useCounter;
+		GpuViewUsage usage;
+	};
+
+	/**
+	 * Holds information about a GPU buffer view. Views allow you to specify how is data in a buffer organized to make it 
+	 * easier for the pipeline to interpret.
+	 *			
+	 * @note	Buffers don't get bound to the pipeline directly, views do. 
+	 * @note	Core thread only.
+	 *
+	 * @see		GpuBuffer
+	 */
+	class BS_CORE_EXPORT GpuBufferView
+	{
+	public:
+		class HashFunction
+		{
+		public:
+			size_t operator()(const GPU_BUFFER_DESC& key) const;
+		};
+
+		class EqualFunction
+		{
+		public:
+			bool operator()(const GPU_BUFFER_DESC& a, const GPU_BUFFER_DESC& b) const;
+		};
+
+		GpuBufferView();
+		virtual ~GpuBufferView();
+
+		/**
+		 * Initializes the view with the specified buffer and a set of parameters describing the view to create. Must be 
+		 * called right after construction.
+		 */
+		virtual void initialize(const SPtr<GpuBufferCore>& buffer, GPU_BUFFER_DESC& desc);
+
+		/** Returns a descriptor structure used for creating the view. */
+		const GPU_BUFFER_DESC& getDesc() const { return mDesc; }
+
+		/**	Returns the buffer this view was created for. */
+		SPtr<GpuBufferCore> getBuffer() const { return mBuffer; }
+
+		/** Returns index of first element in the buffer that this view provides access to. */
+		UINT32 getFirstElement() const { return mDesc.firstElement; }
+
+		/** Returns width of an element in the buffer, in bytes. */
+		UINT32 getElementWidth() const { return mDesc.elementWidth; }
+
+		/**	Returns the total number of elements this buffer provides access to. */
+		UINT32 getNumElements() const { return mDesc.numElements; }
+
+		/**	Returns true if this view allows a GPU program to use counters on the bound buffer. */
+		bool getUseCounter() const { return mDesc.useCounter; }
+
+		/** Returns view usage which determines where in the pipeline can the view be bound. */
+		GpuViewUsage getUsage() const { return mDesc.usage; }
+
+	protected:
+		GPU_BUFFER_DESC mDesc;
+		SPtr<GpuBufferCore> mBuffer;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 301 - 290
BansheeCore/Include/BsGpuParam.h

@@ -1,291 +1,302 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsGpuParamDesc.h"
-#include "BsGpuParamBlock.h"
-#include "BsDebug.h"
-#include "BsException.h"
-#include "BsMatrix3.h"
-#include "BsMatrix4.h"
-
-namespace BansheeEngine
-{
-	struct GpuParamsInternalData;
-
-	/**
-	 * @brief	Base class containing some non-templated methods for
-	 *			GpuDataParam.
-	 *
-	 * @see		TGpuDataParam
-	 */
-	class BS_CORE_EXPORT GpuDataParamBase
-	{
-	protected:
-		GpuDataParamBase();
-		GpuDataParamBase(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
-
-		/**
-		 * @brief	Checks if the gpu param is still valid or were the parent GpuParams destroyed.
-		 */
-		bool isDestroyed() const;
-
-		/**
-		 * @brief	Gets a parameter block at the specified slot index.
-		 */
-		GpuParamBlockPtr getParamBlock(UINT32 slotIdx) const;
-
-		/**
-		 * @brief	Returns true if matrices need to be transposed when reading/writing them.
-		 */
-		bool getTransposeMatrices() const;
-
-		/**
-		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
-		 */
-		void markCoreDirty();
-
-	protected:
-		GpuParamDataDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
-	};
-
-	/**
-	 * @brief	A handle that allows you to set a GpuProgram parameter. Internally keeps a reference to the 
-	 *			GPU parameter buffer and the necessary offsets. You should specialize this type for specific 
-	 *			parameter types. 
-	 *
-	 *			Object of this type must be returned by a Material. Setting/Getting parameter values will internally
-	 *			access a GPU parameter buffer attached to the Material this parameter was created from. Anything
-	 *			rendered with that material will then use those set values.
-	 * 			
-	 * @note	Normally you can set a GpuProgram parameter by calling various set/get methods on a Material.
-	 *			This class primarily used an as optimization in performance critical bits of code
-	 * 			where it is important to locate and set parameters quickly without any lookups
-	 *			(Mentioned set/get methods expect a parameter name). You just retrieve the handle 
-	 *			once and then set the parameter value many times with minimal performance impact.
-	 * 
-	 * @see		Material
-	 *
-	 * @note	Sim thread only.
-	 */
-	template<class T>
-	class BS_CORE_EXPORT TGpuDataParam : public GpuDataParamBase
-	{
-	private:
-		friend class GpuParams;
-
-		/**
-		 * @brief	Policy class that allows us to re-use this template class for matrices which might
-		 *			need transposing, and other types which do not. Matrix needs to be transposed for
-		 *			certain render systems depending on how they store them in memory.
-		 */
-		template<class Type>
-		struct TransposePolicy
-		{
-			static Type transpose(const Type& value) { return value; }
-			static bool transposeEnabled(bool enabled) { return false; }
-		};
-
-		/**
-		 * @brief	Transpose policy for 3x3 matrix.
-		 */
-		template<>
-		struct TransposePolicy<Matrix3>
-		{
-			static Matrix3 transpose(const Matrix3& value) { return value.transpose(); }
-			static bool transposeEnabled(bool enabled) { return enabled; }
-		};
-
-		/**
-		* @brief	Transpose policy for 4x4 matrix.
-		*/
-		template<>
-		struct TransposePolicy<Matrix4>
-		{
-			static Matrix4 transpose(const Matrix4& value) { return value.transpose(); }
-			static bool transposeEnabled(bool enabled) { return enabled; }
-		};
-
-	public:
-		TGpuDataParam()
-		{ }
-
-		/**
-		 * @brief	Sets a parameter value at the specified array index. If parameter does not
-		 *			contain an array leave the index at 0.
-		 *
-		 * @note	Like with all GPU parameters, the actual GPU buffer will not be updated until rendering
-		 *			with material this parameter was created from starts on the core thread.
-		 */
-		void set(const T& value, UINT32 arrayIdx = 0)
-		{
-			if (isDestroyed())
-				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
-#if BS_DEBUG_MODE
-			if (arrayIdx >= mParamDesc->arraySize)
-			{
-				BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-					toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
-			}
-#endif
-
-			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
-			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T)); // Truncate if it doesn't fit within parameter size
-			GpuParamBlockPtr paramBlock = getParamBlock(mParamDesc->paramBlockSlot);
-
-			if (TransposePolicy<T>::transposeEnabled(getTransposeMatrices()))
-			{
-				T transposed = TransposePolicy<T>::transpose(value);
-				paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &transposed, sizeBytes);
-			}
-			else
-				paramBlock->write((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
-
-			// Set unused bytes to 0
-			if(sizeBytes < elementSizeBytes)
-			{
-				UINT32 diffSize = elementSizeBytes - sizeBytes;
-				paramBlock->zeroOut((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride)  * sizeof(UINT32)+sizeBytes, diffSize);
-			}
-
-			markCoreDirty();
-		}
-
-		/**
-		 * @brief	Returns a value of a parameter at the specified array index. If parameter does not
-		 *			contain an array leave the index at 0.
-		 *
-		 * @note	No GPU reads are done. Data returned was cached when it was written. 
-		 */
-		T get(UINT32 arrayIdx = 0)
-		{
-			if (isDestroyed())
-				BS_EXCEPT(InternalErrorException, "Trying to access a destroyed gpu parameter.");
-
-#if BS_DEBUG_MODE
-			if (arrayIdx >= mParamDesc->arraySize)
-			{
-				BS_EXCEPT(InvalidParametersException, "Array index out of range. Array size: " + 
-					toString(mParamDesc->arraySize) + ". Requested size: " + toString(arrayIdx));
-			}
-#endif
-
-			UINT32 elementSizeBytes = mParamDesc->elementSize * sizeof(UINT32);
-			UINT32 sizeBytes = std::min(elementSizeBytes, (UINT32)sizeof(T));
-			GpuParamBlockPtr paramBlock = getParamBlock(mParamDesc->paramBlockSlot);
-
-			T value;
-			paramBlock->read((mParamDesc->cpuMemOffset + arrayIdx * mParamDesc->arrayElementStride) * sizeof(UINT32), &value, sizeBytes);
-
-			if (TransposePolicy<T>::transposeEnabled(getTransposeMatrices()))
-				return TransposePolicy<T>::transpose(value);
-			else
-				return value;
-		}
-
-	private:
-		TGpuDataParam(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-			:GpuDataParamBase(paramDesc, internalData)
-		{ }
-	};
-
-	typedef TGpuDataParam<float> GpuParamFloat;
-	typedef TGpuDataParam<Vector2> GpuParamVec2;
-	typedef TGpuDataParam<Vector3> GpuParamVec3;
-	typedef TGpuDataParam<Vector4> GpuParamVec4;
-	typedef TGpuDataParam<Matrix3> GpuParamMat3;
-	typedef TGpuDataParam<Matrix4> GpuParamMat4;
-
-	/**
-	 * @copydoc GpuDataParamBase
-	 */
-	class BS_CORE_EXPORT GpuParamStruct
-	{
-	private:
-		friend class GpuParams;
-
-	public:
-		GpuParamStruct();
-
-		/**
-		 * @copydoc	GpuDataParamBase::set
-		 */
-		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
-
-		/**
-		 * @copydoc	GpuDataParamBase::get
-		 */
-		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
-
-		/**
-		 * @brief	Returns the size of the struct in bytes.
-		 */
-		UINT32 getElementSize() const;
-
-	private:
-		GpuParamStruct(GpuParamDataDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
-
-	private:
-		GpuParamDataDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
-	};
-
-	/**
-	 * @copydoc GpuDataParamBase
-	 */
-	class BS_CORE_EXPORT GpuParamTexture
-	{
-	private:
-		friend class GpuParams;
-
-	public:
-		GpuParamTexture();
-
-		/**
-		 * @copydoc	GpuDataParamBase::set
-		 */
-		void set(const HTexture& texture);
-
-		/**
-		 * @copydoc	GpuDataParamBase::get
-		 */
-		HTexture get();
-		
-	private:
-		GpuParamTexture(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
-
-	private:
-		GpuParamObjectDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
-	};
-
-	/**
-	 * @copydoc GpuDataParamBase
-	 */
-	class BS_CORE_EXPORT GpuParamSampState
-	{
-	private:
-		friend class GpuParams;
-
-	public:
-		GpuParamSampState();
-
-		/**
-		 * @copydoc	GpuDataParamBase::set
-		 */
-		void set(const HSamplerState& texture);
-
-		/**
-		 * @copydoc	GpuDataParamBase::get
-		 */
-		HSamplerState get();
-
-	private:
-		GpuParamSampState(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData);
-
-	private:
-		GpuParamObjectDesc* mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsVector2.h"
+#include "BsVector3.h"
+#include "BsVector4.h"
+#include "BsMatrix3.h"
+#include "BsMatrix4.h"
+#include "BsMatrixNxM.h"
+#include "BsVectorNI.h"
+#include "BsColor.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	template<bool Core> struct TGpuParamsPtrType { };
+	template<> struct TGpuParamsPtrType<false> { typedef SPtr<GpuParams> Type; };
+	template<> struct TGpuParamsPtrType<true> { typedef SPtr<GpuParamsCore> Type; };
+
+	template<bool Core> struct TGpuParamTextureType { };
+	template<> struct TGpuParamTextureType < false > { typedef HTexture Type; };
+	template<> struct TGpuParamTextureType < true > { typedef SPtr<TextureCore> Type; };
+
+	template<bool Core> struct TGpuParamSamplerStateType { };
+	template<> struct TGpuParamSamplerStateType < false > { typedef SamplerStatePtr Type; };
+	template<> struct TGpuParamSamplerStateType < true > { typedef SPtr<SamplerStateCore> Type; };
+
+	/**
+	 * A handle that allows you to set a GpuProgram parameter. Internally keeps a reference to the GPU parameter buffer and
+	 * the necessary offsets. You should specialize this type for specific parameter types. 
+	 *
+	 * Object of this type must be returned by a Material. Setting/Getting parameter values will internally access a GPU 
+	 * parameter buffer attached to the Material this parameter was created from. Anything rendered with that material will
+	 * then use those set values.
+	 * 			
+	 * @note	
+	 * Normally you can set a GpuProgram parameter by calling various set/get methods on a Material. This class primarily 
+	 * used an as optimization in performance critical bits of code where it is important to locate and set parameters 
+	 * quickly without any lookups (Mentioned set/get methods expect a parameter name). You just retrieve the handle once 
+	 * and then set the parameter value many times with minimal performance impact.
+	 * 
+	 * @see		Material
+	 */
+	template<class T, bool Core>
+	class BS_CORE_EXPORT TGpuDataParam
+	{
+	private:
+		template<bool Core> struct TGpuParamBufferType { };
+		template<> struct TGpuParamBufferType < false > { typedef SPtr<GpuParamBlockBuffer> Type; };
+		template<> struct TGpuParamBufferType < true > { typedef SPtr<GpuParamBlockBufferCore> Type; };
+
+		typedef typename TGpuParamBufferType<Core>::Type GpuParamBufferType;
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+
+		/**
+		 * Policy class that allows us to re-use this template class for matrices which might need transposing, and other 
+		 * types which do not. Matrix needs to be transposed for certain render systems depending on how they store them 
+		 * in memory.
+		 */
+		template<class Type>
+		struct TransposePolicy
+		{
+			static Type transpose(const Type& value) { return value; }
+			static bool transposeEnabled(bool enabled) { return false; }
+		};
+
+		/** Transpose policy for 3x3 matrix. */
+		template<>
+		struct TransposePolicy<Matrix3>
+		{
+			static Matrix3 transpose(const Matrix3& value) { return value.transpose(); }
+			static bool transposeEnabled(bool enabled) { return enabled; }
+		};
+
+		/**	Transpose policy for 4x4 matrix. */
+		template<>
+		struct TransposePolicy<Matrix4>
+		{
+			static Matrix4 transpose(const Matrix4& value) { return value.transpose(); }
+			static bool transposeEnabled(bool enabled) { return enabled; }
+		};
+
+		/**	Transpose policy for NxM matrix. */
+		template<int N, int M>
+		struct TransposePolicy<MatrixNxM<N, M>>
+		{
+			static MatrixNxM<N, M> transpose(const MatrixNxM<N, M>& value) { return value.transpose(); }
+			static bool transposeEnabled(bool enabled) { return enabled; }
+		};
+
+	public:
+		TGpuDataParam();
+		TGpuDataParam(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);
+
+		/**
+		 * Sets a parameter value at the specified array index. If parameter does not contain an array leave the index at 0.
+		 *
+		 * @note	
+		 * Like with all GPU parameters, the actual GPU buffer will not be updated until rendering with material this 
+		 * parameter was created from starts on the core thread.
+		 */
+		void set(const T& value, UINT32 arrayIdx = 0);
+
+		/**
+		 * Returns a value of a parameter at the specified array index. If parameter does not contain an array leave the 
+		 * index at 0.
+		 *
+		 * @note	No GPU reads are done. Data returned was cached when it was written. 
+		 */
+		T get(UINT32 arrayIdx = 0);
+
+		/** Checks if param is initialized. */
+		bool operator==(const nullptr_t &nullval) const
+		{
+			return mParamDesc == nullptr;
+		}
+
+	protected:
+		GpuParamsType mParent;
+		GpuParamDataDesc* mParamDesc;
+	};
+
+	/** @copydoc TGpuDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamStruct
+	{
+	public:
+		template<bool Core> struct TGpuParamBufferType { };
+		template<> struct TGpuParamBufferType < false > { typedef SPtr<GpuParamBlockBuffer> Type; };
+		template<> struct TGpuParamBufferType < true > { typedef SPtr<GpuParamBlockBufferCore> Type; };
+
+		typedef typename TGpuParamBufferType<Core>::Type GpuParamBufferType;
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+
+		TGpuParamStruct();
+		TGpuParamStruct(GpuParamDataDesc* paramDesc, const GpuParamsType& parent);
+
+		/** @copydoc TGpuDataParam::set */
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuDataParam::get */
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/**	Returns the size of the struct in bytes. */
+		UINT32 getElementSize() const;
+
+		/**	Checks if param is initialized. */
+		bool operator==(const nullptr_t &nullval) const
+		{
+			return mParamDesc == nullptr;
+		}
+
+	protected:
+		GpuParamsType mParent;
+		GpuParamDataDesc* mParamDesc;
+	};
+
+	/** @copydoc TGpuObjectParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamTexture
+	{
+	private:
+		friend class GpuParams;
+		friend class GpuParamsCore;
+
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+		typedef typename TGpuParamTextureType<Core>::Type TextureType;
+
+	public:
+		TGpuParamTexture();
+		TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
+
+		/** @copydoc TGpuDataParam::set */
+		void set(const TextureType& texture);
+
+		/** @copydoc TGpuDataParam::get */
+		TextureType get();
+
+		/** Checks if param is initialized. */
+		bool operator==(const nullptr_t &nullval) const
+		{
+			return mParamDesc == nullptr;
+		}
+
+	protected:
+		GpuParamsType mParent;
+		GpuParamObjectDesc* mParamDesc;
+	};
+
+	/** @copydoc TGpuObjectParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamLoadStoreTexture
+	{
+	private:
+		friend class GpuParams;
+		friend class GpuParamsCore;
+
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+		typedef typename TGpuParamTextureType<Core>::Type TextureType;
+
+	public:
+		TGpuParamLoadStoreTexture();
+		TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
+
+		/** @copydoc TGpuDataParam::set */
+		void set(const TextureType& texture, const TextureSurface& surface);
+
+		/** @copydoc TGpuDataParam::get */
+		TextureType get();
+
+		/**	Checks if param is initialized. */
+		bool operator==(const nullptr_t &nullval) const
+		{
+			return mParamDesc == nullptr;
+		}
+
+	protected:
+		GpuParamsType mParent;
+		GpuParamObjectDesc* mParamDesc;
+	};
+
+	/** @copydoc TGpuObjectParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TGpuParamSampState
+	{
+	private:
+		friend class GpuParams;
+		friend class GpuParamsCore;
+
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
+
+	public:
+		TGpuParamSampState();
+		TGpuParamSampState(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent);
+
+		/** @copydoc TGpuDataParam::set */
+		void set(const SamplerStateType& samplerState);
+
+		/** @copydoc TGpuDataParam::get */
+		SamplerStateType get();
+
+		/**	Checks if param is initialized. */
+		bool operator==(const nullptr_t &nullval) const
+		{
+			return mParamDesc == nullptr;
+		}
+
+	protected:
+		GpuParamsType mParent;
+		GpuParamObjectDesc* mParamDesc;
+	};
+
+	/** @} */
+
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	typedef TGpuDataParam<float, false> GpuParamFloat;
+	typedef TGpuDataParam<Vector2, false> GpuParamVec2;
+	typedef TGpuDataParam<Vector3, false> GpuParamVec3;
+	typedef TGpuDataParam<Vector4, false> GpuParamVec4;
+	typedef TGpuDataParam<int, false> GpuParamInt;
+	typedef TGpuDataParam<Vector2I, false> GpuParamVec2I;
+	typedef TGpuDataParam<Vector3I, false> GpuParamVec3I;
+	typedef TGpuDataParam<Vector4I, false> GpuParamVec4I;
+	typedef TGpuDataParam<Matrix3, false> GpuParamMat3;
+	typedef TGpuDataParam<Matrix4, false> GpuParamMat4;
+	typedef TGpuDataParam<Color, false> GpuParamColor;
+
+	typedef TGpuDataParam<float, true> GpuParamFloatCore;
+	typedef TGpuDataParam<Vector2, true> GpuParamVec2Core;
+	typedef TGpuDataParam<Vector3, true> GpuParamVec3Core;
+	typedef TGpuDataParam<Vector4, true> GpuParamVec4Core;
+	typedef TGpuDataParam<int, true> GpuParamIntCore;
+	typedef TGpuDataParam<Vector2I, true> GpuParamVec2ICore;
+	typedef TGpuDataParam<Vector3I, true> GpuParamVec3ICore;
+	typedef TGpuDataParam<Vector4I, true> GpuParamVec4ICore;
+	typedef TGpuDataParam<Matrix3, true> GpuParamMat3Core;
+	typedef TGpuDataParam<Matrix4, true> GpuParamMat4Core;
+	typedef TGpuDataParam<Color, true> GpuParamColorCore;
+
+	typedef TGpuParamStruct<false> GpuParamStruct;
+	typedef TGpuParamStruct<true> GpuParamStructCore;
+
+	typedef TGpuParamTexture<false> GpuParamTexture;
+	typedef TGpuParamTexture<true> GpuParamTextureCore;
+
+	typedef TGpuParamSampState<false> GpuParamSampState;
+	typedef TGpuParamSampState<true> GpuParamSampStateCore;
+
+	typedef TGpuParamLoadStoreTexture<false> GpuParamLoadStoreTexture;
+	typedef TGpuParamLoadStoreTexture<true> GpuParamLoadStoreTextureCore;
+
+	/** @} */
 }

+ 0 - 73
BansheeCore/Include/BsGpuParamBlock.h

@@ -1,73 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Stores data (e.g. int, float, Vector2) GPU parameters in a raw buffer. 
-	 *			Used primarily for caching GPU parameters on the CPU before they're submitted 
-	 *			to the actual GPU parameter buffer.
-	 */
-	class BS_CORE_EXPORT GpuParamBlock
-	{
-	public:
-		GpuParamBlock(UINT32 size);
-		GpuParamBlock(GpuParamBlock* otherBlock);
-
-		virtual ~GpuParamBlock();
-
-		/**
-		 * @brief	Write some data to the specified offset in the buffer. 
-		 *			Marks the block as dirty.
-		 *			All values are in bytes.
-		 */
-		void write(UINT32 offset, const void* data, UINT32 size);
-
-		/**
-		 * @brief	Read some data from the specified offset in the buffer.
-		 *			All values are in bytes.
-		 */
-		void read(UINT32 offset, void* data, UINT32 size);
-
-		/**
-		 * @brief	Clear specified section of the buffer to zero.
-		 *			All values are in bytes.
-		 */
-		void zeroOut(UINT32 offset, UINT32 size);
-
-		/**
-		 * @brief	Returns size of the internal buffer in bytes.
-		 */
-		UINT32 getSize() const { return mSize; }
-
-		/**
-		 * @brief	Returns a raw pointer to the internal buffer.
-		 */
-		UINT8* getData() const { return mData; }
-
-		/**
-		 * @brief	Uploads the current data to the specified buffer, and marks the block a non-dirty.
-		 * 			
-		 * @note	Core thread only.			
-		 */
-		void uploadToBuffer(const GpuParamBlockBufferPtr& buffer);
-
-		/**
-		 * @brief	Checks if something has been written to the buffer
-		 *			since the last time object was clean.
-		 */
-		bool isDirty() const { return mDirty; }
-
-		/**
-		 * @brief	Marks the object as dirty or clean. Signifies
-		 *			whether or not some new data has been written in the buffer.
-		 */
-		void setDirty(bool dirty) { mDirty = dirty; }
-	protected:
-		UINT8* mData;
-		UINT32 mSize;
-		bool mDirty;
-	};
-}

+ 164 - 120
BansheeCore/Include/BsGpuParamBlockBuffer.h

@@ -1,121 +1,165 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Represents a GPU parameter block buffer. Parameter block buffers
-	 *			are bound to GPU programs which then fetch parameters from those buffers.
-	 *
-	 *			Writing or reading from this buffer will translate directly to API calls
-	 *			that update the GPU.
-	 * 			
-	 * @note	Core thread only.
-	 */
-	class BS_CORE_EXPORT GpuParamBlockBuffer : public CoreObject
-	{
-	public:
-		GpuParamBlockBuffer();
-		virtual ~GpuParamBlockBuffer();
-
-		/**
-		 * @brief	Initializes a buffer with the specified size in bytes and usage.
-		 *			Specify dynamic usage if you plan on modifying the buffer often,
-		 *			otherwise specify static usage.
-		 *
-		 * @see		CoreObject::initialize
-		 * 
-		 * @note	Must be called right after construction.
-		 */
-		void initialize(UINT32 size, GpuParamBlockUsage usage);
-
-		/**
-		 * @brief	Writes all of the specified data to the buffer.
-		 * 			Data size must be the same size as the buffer;
-		 */
-		virtual void writeData(const UINT8* data) = 0;
-
-		/**
-		 * @brief	Copies data from the internal buffer to a pre-allocated array. 
-		 * 			Be aware this generally isn't a very fast operation as reading
-		 *			from the GPU will most definitely involve a CPU-GPU sync point.
-		 *
-		 * @param [in,out]	data	Array where the data will be written to. Must be of
-		 * 							"getSize()" bytes.
-		 */
-		virtual void readData(UINT8* data) const = 0;
-
-		/**
-		 * @brief	Returns the size of the buffer in bytes.
-		 */
-		UINT32 getSize() const { return mSize; }
-
-		/**
-		 * @brief	Returns	a parameter block buffer which is used for caching 
-		 *			the parameter information on the sim thread. Essentially a
-		 *			sim thread copy of the GPU buffer.
-		 *
-		 * @note	Sim thread only.
-		 */
-		GpuParamBlockPtr getParamBlock() const { return mParamBlock; }
-
-		/**
-		 * @brief	Returns	a parameter block buffer which is used for caching 
-		 *			the parameter information on the core thread. Essentially a CPU
-		 *			core thread copy of the GPU buffer.
-		 *
-		 * @note	Core thread only.
-		 */
-		// TODO - Keeping a core param block along with a sim param block is redundant in some cases,
-		// as it might not be used (e.g. if gpu param block buffer is only accessed from core thread)
-		GpuParamBlockPtr getCoreParamBlock() const { return mCoreParamBlock; }
-
-		/**
-		 * @brief	Sets a reference to a core thread CPU buffer that may be used for buffering
-		 *			parameter data on the core thread, before actually writing it to the buffer.
-		 */
-		void setCoreParamBlock(const GpuParamBlockPtr& paramBlock) { mCoreParamBlock = paramBlock; }
-
-	protected:
-		GpuParamBlockUsage mUsage;
-		UINT32 mSize;
-
-		GpuParamBlockPtr mParamBlock;
-		GpuParamBlockPtr mCoreParamBlock;
-	};
-
-	/**
-	 * @brief	Implementation of a GpuParamBlock buffer that doesn't use a GPU buffer
-	 *			for storage. Used with APIs that do not support GPU parameter buffers.
-	 */
-	class BS_CORE_EXPORT GenericGpuParamBlockBuffer : public GpuParamBlockBuffer
-	{
-	public:
-		GenericGpuParamBlockBuffer();
-
-		/**
-		 * @copydoc	GpuParamBlockBuffer::writeData
-		 */
-		void writeData(const UINT8* data);
-
-		/**
-		 * @copydoc GpuParamBlockBuffer::readData.
-		 */
-		void readData(UINT8* data) const;
-
-	protected:
-		UINT8* mData;
-
-		/**
-		 * @copydoc CoreObject::initialize_internal.
-		 */
-		virtual void initialize_internal();
-
-		/**
-		 * @copydoc CoreObject::destroy_internal.
-		 */
-		virtual void destroy_internal();
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	 /** @cond INTERNAL */
+
+	/**
+	 * Core thread version of a GpuParamBlockBuffer.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT GpuParamBlockBufferCore : public CoreObjectCore
+	{
+	public:
+		GpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage);
+		virtual ~GpuParamBlockBufferCore();
+
+		/** Writes all of the specified data to the buffer. Data size must be the same size as the buffer. */
+		virtual void writeToGPU(const UINT8* data) = 0;
+
+		/**
+		 * Copies data from the internal buffer to a pre-allocated array. Be aware this generally isn't a very fast 
+		 * operation as reading from the GPU will most definitely involve a CPU-GPU sync point.
+		 *
+		 * @param [in,out]	data	Array where the data will be written to. Must be of getSize() bytes.
+		 */
+		virtual void readFromGPU(UINT8* data) const = 0;
+
+		/** Flushes any cached data into the actual GPU buffer. */
+		void flushToGPU();
+
+		/**
+		 * Write some data to the specified offset in the buffer. 
+		 *
+		 * @note	All values are in bytes. Actual hardware buffer update is delayed until rendering.
+		 */
+		void write(UINT32 offset, const void* data, UINT32 size);
+
+		/**
+		 * Read some data from the specified offset in the buffer.
+		 *			
+		 * @note	All values are in bytes. This reads from the cached CPU buffer and not directly from the GPU.
+		 */
+		void read(UINT32 offset, void* data, UINT32 size);
+
+		/**
+		 * Clear specified section of the buffer to zero.
+		 *
+		 * @note	All values are in bytes. Actual hardware buffer update is delayed until rendering.
+		 */
+		void zeroOut(UINT32 offset, UINT32 size);
+
+		/**	Returns the size of the buffer in bytes. */
+		UINT32 getSize() const { return mSize; }
+
+		/** @copydoc HardwareBufferCoreManager::createGpuParamBlockBuffer */
+		static SPtr<GpuParamBlockBufferCore> create(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+
+	protected:
+		/** @copydoc CoreObjectCore::syncToCore */
+		virtual void syncToCore(const CoreSyncData& data)  override;
+
+		GpuParamBlockUsage mUsage;
+		UINT32 mSize;
+
+		UINT8* mCachedData;
+		bool mGPUBufferDirty;
+	};
+
+	/**
+	 * Implementation of a GpuParamBlock buffer that doesn't use a GPU buffer for storage. Used with APIs that do not 
+	 * support GPU parameter buffers.
+	 */
+	class BS_CORE_EXPORT GenericGpuParamBlockBufferCore : public GpuParamBlockBufferCore
+	{
+	public:
+		GenericGpuParamBlockBufferCore(UINT32 size, GpuParamBlockUsage usage);
+		~GenericGpuParamBlockBufferCore();
+
+		/** @copydoc GpuParamBlockBufferCore::writeData */
+		void writeToGPU(const UINT8* data) override;
+
+		/** @copydoc GpuParamBlockBufferCore::readData */
+		void readFromGPU(UINT8* data) const override;
+
+	protected:
+		UINT8* mData;
+
+		/** @copydoc CoreObjectCore::initialize */
+		virtual void initialize() override;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Represents a GPU parameter block buffer. Parameter block buffers are bound to GPU programs which then fetch 
+	 * parameters from those buffers.
+	 *
+	 * Writing or reading from this buffer will translate directly to API calls that update the GPU.
+	 * 			
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT GpuParamBlockBuffer : public CoreObject
+	{
+	public:
+		GpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage);
+		virtual ~GpuParamBlockBuffer();
+
+		/**
+		 * Write some data to the specified offset in the buffer. 
+		 *
+		 * @note	All values are in bytes. Actual hardware buffer update is delayed until rendering.
+		 */
+		void write(UINT32 offset, const void* data, UINT32 size);
+
+		/**
+		 * Read some data from the specified offset in the buffer.
+		 *			
+		 * @note	All values are in bytes. This reads from the cached CPU buffer and not from the GPU.
+		 */
+		void read(UINT32 offset, void* data, UINT32 size);
+
+		/**
+		 * Clear specified section of the buffer to zero.
+		 *
+		 * @note	All values are in bytes. Actual hardware buffer update is delayed until rendering.
+		 */
+		void zeroOut(UINT32 offset, UINT32 size);
+
+		/** Returns internal cached data of the buffer. */
+		const UINT8* getCachedData() const { return mCachedData; }
+
+		/**	Returns the size of the buffer in bytes. */
+		UINT32 getSize() const { return mSize; }
+
+		/**	Retrieves a core implementation of a GPU param block buffer usable only from the core thread. */
+		SPtr<GpuParamBlockBufferCore> getCore() const;
+
+		/** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
+		static GpuParamBlockBufferPtr create(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+
+	protected:
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::syncToCore */
+		virtual CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		GpuParamBlockUsage mUsage;
+		UINT32 mSize;
+		UINT8* mCachedData;
+	};
+
+	/** @endcond */
+	/** @} */
 }

+ 56 - 57
BansheeCore/Include/BsGpuParamDesc.h

@@ -1,58 +1,57 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Describes a single GPU program data (e.g. int, float, Vector2) parameter.
-	 */
-	struct GpuParamDataDesc
-	{
-		String name;
-		UINT32 elementSize; /**< In multiples of 4 bytes. */
-		UINT32 arraySize;
-		UINT32 arrayElementStride; /**< In multiples of 4 bytes. */
-		GpuParamDataType type;
-
-		UINT32 paramBlockSlot;
-		UINT32 gpuMemOffset;
-		UINT32 cpuMemOffset;
-	};
-
-	/**
-	 * @brief	Describes a single GPU program object (e.g. texture, sampler state) parameter.
-	 */
-	struct GpuParamObjectDesc
-	{
-		String name;
-		GpuParamObjectType type;
-
-		UINT32 slot;
-	};
-
-	/**
-	 * @brief	Describes a GPU program parameter block (collection of GPU program data parameters).
-	 */
-	struct GpuParamBlockDesc
-	{
-		String name;
-		UINT32 slot;
-		UINT32 blockSize; /**< In multiples of 4 bytes. */
-		bool isShareable;
-	};
-
-	/**
-	 * @brief	Contains all parameter information for a GPU program, including data and object parameters,
-	 *			plus parameter blocks.
-	 */
-	struct GpuParamDesc
-	{
-		Map<String, GpuParamBlockDesc> paramBlocks;
-		Map<String, GpuParamDataDesc> params;
-
-		Map<String, GpuParamObjectDesc> samplers;
-		Map<String, GpuParamObjectDesc> textures;
-		Map<String, GpuParamObjectDesc> buffers;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** Describes a single GPU program data (e.g. int, float, Vector2) parameter. */
+	struct GpuParamDataDesc
+	{
+		String name;
+		UINT32 elementSize; /**< In multiples of 4 bytes. */
+		UINT32 arraySize;
+		UINT32 arrayElementStride; /**< In multiples of 4 bytes. */
+		GpuParamDataType type;
+
+		UINT32 paramBlockSlot;
+		UINT32 gpuMemOffset; /**< In multiples of 4 bytes, or index for parameters not in a buffer. */
+		UINT32 cpuMemOffset; /**< In multiples of 4 bytes. */
+	};
+
+	/**	Describes a single GPU program object (e.g. texture, sampler state) parameter. */
+	struct GpuParamObjectDesc
+	{
+		String name;
+		GpuParamObjectType type;
+
+		UINT32 slot;
+	};
+
+	/**	Describes a GPU program parameter block (collection of GPU program data parameters). */
+	struct GpuParamBlockDesc
+	{
+		String name;
+		UINT32 slot;
+		UINT32 blockSize; /**< In multiples of 4 bytes. */
+		bool isShareable;
+	};
+
+	/** Contains all parameter information for a GPU program, including data and object parameters, plus parameter blocks. */
+	struct GpuParamDesc
+	{
+		Map<String, GpuParamBlockDesc> paramBlocks;
+		Map<String, GpuParamDataDesc> params;
+
+		Map<String, GpuParamObjectDesc> samplers;
+		Map<String, GpuParamObjectDesc> textures;
+		Map<String, GpuParamObjectDesc> buffers;
+	};
+
+	/** @} */
 }

+ 344 - 309
BansheeCore/Include/BsGpuParams.h

@@ -1,310 +1,345 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsGpuParam.h"
-
-namespace BansheeEngine
-{
-	struct GpuParamsInternalData;
-
-	/**
-	 * @brief	Contains descriptions for all parameters in a GPU program and also
-	 *			allows you to write and read those parameters. All parameter values
-	 *			are stored internally on the CPU, and are only submitted to the GPU
-	 *			once the parameters are bound to the pipeline.
-	 *
-	 * @see		CoreThreadAccessor::bindGpuParams
-	 *
-	 * @note	Sim thread only.
-	 */
-	class BS_CORE_EXPORT GpuParams
-	{
-		struct PrivatelyConstruct {};
-	public:
-		/**
-		 * @brief	Creates new GpuParams object using the specified parameter descriptions.
-		 *
-		 * @param	paramDesc			Reference to parameter descriptions that will be used for
-		 *								finding needed parameters.
-		 * @param	transposeMatrices	If true the stored matrices will be transposed before
-		 *								submitted to the GPU (some APIs require different
-		 *								matrix layout).
-		 *
-		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
-		 */
-		GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
-
-		/**
-		 * @brief	Private constructor for internal use. Performs no initialization.
-		 */
-		GpuParams(const GpuParamDescPtr& paramDesc, PrivatelyConstruct& dummy);
-
-		~GpuParams();
-
-		// Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
-		// all the internal buffers too). Trivial to implement but not needed at this time. Un-delete and implement if necessary.
-		GpuParams(const GpuParams& other) = delete;
-		GpuParams& operator=(const GpuParams& rhs) = delete;
-
-		/**
-		 * @brief	Binds a new parameter buffer to the specified slot. Any following parameter reads or
-		 *			writes that are referencing that buffer slot will use the new buffer.
-		 *
-		 * @note	This is useful if you want to share a parameter buffer among multiple GPU programs. 
-		 *			You would only set the values once and then share the buffer among all other GpuParams.
-		 *
-		 *			It is up to the caller to guarantee the provided buffer matches parameter block
-		 *			descriptor for this slot.
-		 */
-		void setParamBlockBuffer(UINT32 slot, const GpuParamBlockBufferPtr& paramBlockBuffer);
-
-		/**
-		 * @brief	Replaces the parameter buffer with the specified name. Any following parameter reads or
-		 *			writes that are referencing that buffer will use the new buffer.
-		 *
-		 * @note	This is useful if you want to share a parameter buffer among multiple GPU programs.
-		 *			You would only set the values once and then share the buffer among all other GpuParams.
-		 *
-		 *			It is up to the caller to guarantee the provided buffer matches parameter block
-		 *			descriptor for this slot.
-		 */
-		void setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlockBuffer);
-
-		/**
-		 * @brief	Returns a description of all stored parameters.
-		 */
-		const GpuParamDesc& getParamDesc() const { return *mParamDesc; }
-
-		/**
-		 * @brief	Returns the size of a data parameter with the specified name, in bytes.
-		 *			Returns 0 if such parameter doesn't exist.
-		 */
-		UINT32 getDataParamSize(const String& name) const;
-
-		/**
-		 * @brief	Checks if parameter with the specified name exists.
-		 */
-		bool hasParam(const String& name) const;
-
-		/**
-		 * @brief	Checks if texture parameter with the specified name exists.
-		 */
-		bool hasTexture(const String& name) const;
-
-		/**
-		 * @brief	Checks if sampler state parameter with the specified name exists.
-		 */
-		bool hasSamplerState(const String& name) const;
-
-		/**
-		 * @brief	Checks if a parameter block with the specified name exists.
-		 */
-		bool hasParamBlock(const String& name) const;
-
-		/**
-		 * @brief	Returns a handle for the parameter with the specified name. 
-		 *			Handle may then be stored and used for quickly setting or retrieving
-		 *			values to/from that parameter.
-		 *
-		 *			Throws exception if parameter with that name and type doesn't exist.
-		 *
-		 *			Parameter handles will be invalidated when their parent GpuParams object changes.
-		 */
-		template<class T> void getParam(const String& name, TGpuDataParam<T>& output) const
-		{
-			BS_EXCEPT(InvalidParametersException, "Unsupported parameter type");
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		template<>
-		void getParam<float>(const String& name, TGpuDataParam<float>& output) const
-		{
-			auto iterFind = mParamDesc->params.find(name);
-
-			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT1)
-				BS_EXCEPT(InvalidParametersException, "Cannot find float parameter with the name '" + name + "'");
-
-			output = GpuParamFloat(&iterFind->second, mInternalData);
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		template<>
-		void getParam<Vector2>(const String& name, TGpuDataParam<Vector2>& output) const
-		{
-			auto iterFind = mParamDesc->params.find(name);
-
-			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT2)
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector (2) parameter with the name '" + name + "'");
-
-			output = GpuParamVec2(&iterFind->second, mInternalData);
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		template<>
-		void getParam<Vector3>(const String& name, TGpuDataParam<Vector3>& output) const
-		{
-			auto iterFind = mParamDesc->params.find(name);
-
-			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT3)
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector (3) parameter with the name '" + name + "'");
-
-			output = GpuParamVec3(&iterFind->second, mInternalData);
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		template<>
-		void getParam<Vector4>(const String& name, TGpuDataParam<Vector4>& output) const
-		{
-			auto iterFind = mParamDesc->params.find(name);
-
-			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_FLOAT4)
-				BS_EXCEPT(InvalidParametersException, "Cannot find vector (4) parameter with the name '" + name + "'");
-
-			output = GpuParamVec4(&iterFind->second, mInternalData);
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		template<>
-		void getParam<Matrix3>(const String& name, TGpuDataParam<Matrix3>& output) const
-		{
-			auto iterFind = mParamDesc->params.find(name);
-
-			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_MATRIX_3X3)
-				BS_EXCEPT(InvalidParametersException, "Cannot find matrix (3x3) parameter with the name '" + name + "'");
-
-			output = GpuParamMat3(&iterFind->second, mInternalData);
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		template<>
-		void getParam<Matrix4>(const String& name, TGpuDataParam<Matrix4>& output) const
-		{
-			auto iterFind = mParamDesc->params.find(name);
-
-			if (iterFind == mParamDesc->params.end() || iterFind->second.type != GPDT_MATRIX_4X4)
-				BS_EXCEPT(InvalidParametersException, "Cannot find matrix (4x4) parameter with the name '" + name + "'");
-
-			output = GpuParamMat4(&iterFind->second, mInternalData);
-		}
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		void getStructParam(const String& name, GpuParamStruct& output) const;
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		void getTextureParam(const String& name, GpuParamTexture& output) const;
-
-		/**
-		 * @copydoc	getParam(const String&, GpuDataParamBase<T>&)
-		 */
-		void getSamplerStateParam(const String& name, GpuParamSampState& output) const;
-
-		/**
-		 * @brief	Uploads all CPU stored parameter buffer data to the GPU buffers.
-		 *
-		 * @note	Core thread only.
-		 */
-		void updateHardwareBuffers();
-
-		/**
-		 * @brief	Gets a parameter block buffer from the specified slot.
-		 */
-		GpuParamBlockBufferPtr getParamBlockBuffer(UINT32 slot) const;
-
-		/**
-		 * @brief	Gets a texture bound to the specified slot.
-		 */
-		HTexture getTexture(UINT32 slot);
-
-		/**
-		 * @brief	Gets a sampler state bound to the specified slot.
-		 */
-		HSamplerState getSamplerState(UINT32 slot);
-
-		/**
-		 * @brief	Returns an exact copy of this object. Internal parameter buffers will also be cloned,
-		 *			but should only be used on the core thread.
-		 *
-		 * @note	Optional frame allocator to allocate the returned data with. If not specified
-		 *			allocation will be done using normal means.
-		 *			Internal method.
-		 */
-		GpuParamsPtr _cloneForCore(FrameAlloc* frameAlloc = nullptr) const;
-
-		/**
-		 * @brief	Checks is the core dirty flag set. This is used by external systems 
-		 *			to know  when internal data has changed and core proxy potentially needs to be updated.
-		 *
-		 * @note	Internal method. Sim thread only.
-		 */
-		bool _isCoreDirty() const;
-
-		/**
-		 * @brief	Marks the core dirty flag as clean.
-		 *
-		 * @note	Internal method. Sim thread only.
-		 */
-		void _markCoreClean();
-
-	private:
-		GpuParamDescPtr mParamDesc;
-		std::shared_ptr<GpuParamsInternalData> mInternalData;
-
-		/**
-		 * @brief	Gets a descriptor for a data parameter with the specified name.
-		 */
-		GpuParamDataDesc* getParamDesc(const String& name) const;
-
-		/**
-		 * @brief	Allocates and constructs internal buffers. Parameter counts must have been previously assigned.
-		 *			If provided, internal data will be allocated using the frame allocator, otherwise using
-		 *			the normal allocator.
-		 */
-		void constructInternalBuffers(FrameAlloc* frameAlloc = nullptr);
-
-		/**
-		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
-		 */
-		void markCoreDirty();
-	};
-
-	/**
-	 * @brief	Structure used for storing GpuParams internal data.
-	 */
-	struct GpuParamsInternalData
-	{
-		GpuParamsInternalData();
-
-		UINT8* mData;
-
-		UINT32 mNumParamBlocks;
-		UINT32 mNumTextures;
-		UINT32 mNumSamplerStates;
-
-		GpuParamBlockPtr* mParamBlocks;
-		GpuParamBlockBufferPtr* mParamBlockBuffers;
-		HTexture* mTextures;
-		HSamplerState* mSamplerStates;
-
-		bool mTransposeMatrices;
-		bool mIsDestroyed;
-		UINT32 mCoreDirtyFlags;
-
-		FrameAlloc* mFrameAlloc;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuParam.h"
+#include "BsCoreObject.h"
+#include "BsIResourceListener.h"
+#include "BsVectorNI.h"
+#include "BsMatrixNxM.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+	/** @cond INTERNAL */
+
+	/** Stores information needed for binding a texture to the pipeline. */
+	struct BoundTextureInfo
+	{
+		BoundTextureInfo()
+			:isLoadStore(false)
+		{ }
+
+		bool isLoadStore;
+		TextureSurface surface;
+	};
+
+	/**	Helper structure whose specializations convert an engine data type into a GPU program data parameter type.  */
+	template<class T> struct TGpuDataParamInfo { };
+	template<> struct TGpuDataParamInfo < float > { enum { TypeId = GPDT_FLOAT1 }; };
+	template<> struct TGpuDataParamInfo < Vector2 > { enum { TypeId = GPDT_FLOAT2 }; };
+	template<> struct TGpuDataParamInfo < Vector3 > { enum { TypeId = GPDT_FLOAT3 }; };
+	template<> struct TGpuDataParamInfo < Vector4 > { enum { TypeId = GPDT_FLOAT4 }; };
+	template<> struct TGpuDataParamInfo < int > { enum { TypeId = GPDT_INT1 }; };
+	template<> struct TGpuDataParamInfo < Vector2I > { enum { TypeId = GPDT_INT2 }; };
+	template<> struct TGpuDataParamInfo < Vector3I > { enum { TypeId = GPDT_INT3 }; };
+	template<> struct TGpuDataParamInfo < Vector4I > { enum { TypeId = GPDT_INT4 }; };
+	template<> struct TGpuDataParamInfo < Matrix2 > { enum { TypeId = GPDT_MATRIX_2X2 }; };
+	template<> struct TGpuDataParamInfo < Matrix2x3 > { enum { TypeId = GPDT_MATRIX_2X3 }; };
+	template<> struct TGpuDataParamInfo < Matrix2x4 > { enum { TypeId = GPDT_MATRIX_2X3 }; };
+	template<> struct TGpuDataParamInfo < Matrix3 > { enum { TypeId = GPDT_MATRIX_3X3 }; };
+	template<> struct TGpuDataParamInfo < Matrix3x2 > { enum { TypeId = GPDT_MATRIX_3X2 }; };
+	template<> struct TGpuDataParamInfo < Matrix3x4 > { enum { TypeId = GPDT_MATRIX_3X4 }; };
+	template<> struct TGpuDataParamInfo < Matrix4 > { enum { TypeId = GPDT_MATRIX_4X4 }; };
+	template<> struct TGpuDataParamInfo < Matrix4x2 > { enum { TypeId = GPDT_MATRIX_4X2 }; };
+	template<> struct TGpuDataParamInfo < Matrix4x3 > { enum { TypeId = GPDT_MATRIX_4X3 }; };
+	template<> struct TGpuDataParamInfo < Color > { enum { TypeId = GPDT_COLOR }; };
+
+	/** @endcond */
+	
+	/** Contains functionality common for both sim and core thread version of GpuParams. */
+	class BS_CORE_EXPORT GpuParamsBase
+	{
+	public:
+		/**
+		 * Creates new GpuParams object using the specified parameter descriptions.
+		 *
+		 * @param[in]	paramDesc			Reference to parameter descriptions that will be used for finding needed 
+		 *									parameters.
+		 * @param[in]	transposeMatrices	If true the stored matrices will be transposed before submitted to the GPU 
+		 *									(some APIs require different matrix layout).
+		 *
+		 * @note	You normally do not want to call this manually. Instead use GpuProgram::createParameters.
+		 */
+		GpuParamsBase(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+		virtual ~GpuParamsBase();
+
+		// Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
+		// all the internal buffers too). Trivial to implement but not needed at this time. Un-delete and implement if necessary.
+		GpuParamsBase(const GpuParamsBase& other) = delete;
+		GpuParamsBase& operator=(const GpuParamsBase& rhs) = delete;
+
+		/** Returns a description of all stored parameters. */
+		const GpuParamDesc& getParamDesc() const { return *mParamDesc; }
+
+		/**
+		 * Returns the size of a data parameter with the specified name, in bytes. Returns 0 if such parameter doesn't exist.
+		 */
+		UINT32 getDataParamSize(const String& name) const;
+
+		/** Checks if parameter with the specified name exists. */
+		bool hasParam(const String& name) const;
+
+		/**	Checks if texture parameter with the specified name exists. */
+		bool hasTexture(const String& name) const;
+
+		/**	Checks if sampler state parameter with the specified name exists. */
+		bool hasSamplerState(const String& name) const;
+
+		/** Checks if a parameter block with the specified name exists. */
+		bool hasParamBlock(const String& name) const;
+
+		/**
+		 * Checks is the texture at the specified slot to be bound as random load/store texture instead of a normal sampled
+		 * texture.
+		 */
+		bool isLoadStoreTexture(UINT32 slot) const;
+
+		/** Changes the type of the texture at the specified slot. */
+		void setIsLoadStoreTexture(UINT32 slot, bool isLoadStore);
+
+		/** Returns information that determines which texture surfaces to bind as load/store parameters. */
+		const TextureSurface& getLoadStoreSurface(UINT32 slot) const;
+
+		/**	Sets information that determines which texture surfaces to bind	as load/store parameters. */
+		void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
+
+		/**	Checks whether matrices should be transformed before being written to the parameter buffer. */
+		bool getTransposeMatrices() const { return mTransposeMatrices; }
+
+		/**
+		 * @copydoc	CoreObject::markCoreDirty
+		 *
+		 * @note	Internal method.
+		 */
+		virtual void _markCoreDirty() { }
+
+		/**
+		 * @copydoc	IResourceListener::markResourcesDirty
+		 *
+		 * @note	Internal method.
+		 */
+		virtual void _markResourcesDirty() { }
+
+	protected:
+		/**	Gets a descriptor for a data parameter with the specified name. */
+		GpuParamDataDesc* getParamDesc(const String& name) const;
+
+		GpuParamDescPtr mParamDesc;
+
+		UINT32 mNumParamBlocks;
+		UINT32 mNumTextures;
+		UINT32 mNumSamplerStates;
+
+		BoundTextureInfo* mTextureInfo;
+
+		bool mTransposeMatrices;
+	};
+
+	/** Templated version of GpuParams that contains functionality for both sim and core thread versions of stored data. */
+	template <bool Core>
+	class BS_CORE_EXPORT TGpuParams : public GpuParamsBase
+	{
+	public:
+		template<bool Core> struct TTypes { };
+
+		template<> struct TTypes < false > 
+		{ 
+			typedef GpuParams GpuParamsType; 
+			typedef HTexture TextureType;
+			typedef SamplerStatePtr SamplerType;
+			typedef SPtr<GpuParamBlockBuffer> ParamsBufferType;
+		};
+
+		template<> struct TTypes < true > 
+		{ 
+			typedef GpuParamsCore GpuParamsType;
+			typedef SPtr<TextureCore> TextureType;
+			typedef SPtr<SamplerStateCore> SamplerType;
+			typedef SPtr<GpuParamBlockBufferCore> ParamsBufferType;
+		};
+
+		typedef typename TTypes<Core>::GpuParamsType GpuParamsType;
+		typedef typename TTypes<Core>::TextureType TextureType;
+		typedef typename TTypes<Core>::SamplerType SamplerType;
+		typedef typename TTypes<Core>::ParamsBufferType ParamsBufferType;
+
+		/** @copydoc GpuParamsBase::GpuParamsBase(const GpuParamDescPtr&, bool) */
+		TGpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+
+		virtual ~TGpuParams();
+
+		/**
+		 * Binds a new parameter buffer to the specified slot. Any following parameter reads or writes that are referencing
+		 * that buffer slot will use the new buffer.
+		 *
+		 * @note	
+		 * This is useful if you want to share a parameter buffer among multiple GPU programs. You would only set the 
+		 * values once and then share the buffer among all other GpuParams.
+		 * @note
+		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
+		 */
+		void setParamBlockBuffer(UINT32 slot, const ParamsBufferType& paramBlockBuffer);
+
+		/**
+		 * Replaces the parameter buffer with the specified name. Any following parameter reads or writes that are 
+		 * referencing that buffer will use the new buffer.
+		 *
+		 * @note	
+		 * This is useful if you want to share a parameter buffer among multiple GPU programs. You would only set the 
+		 * values once and then share the buffer among all other GpuParams.
+		 * @note
+		 * It is up to the caller to guarantee the provided buffer matches parameter block descriptor for this slot.
+		 */
+		void setParamBlockBuffer(const String& name, const ParamsBufferType& paramBlockBuffer);
+
+		/**
+		 * Returns a handle for the parameter with the specified name. Handle may then be stored and used for quickly 
+		 * setting or retrieving values to/from that parameter.
+		 *
+		 * Throws exception if parameter with that name and type doesn't exist.
+		 *
+		 * Parameter handles will be invalidated when their parent GpuParams object changes.
+		 */
+		template<class T> void getParam(const String& name, TGpuDataParam<T, Core>& output) const;
+
+		/** @copydoc getParam(const String&, TGpuDataParam<T, Core>&) */
+		void getStructParam(const String& name, TGpuParamStruct<Core>& output) const;
+
+		/**
+		 * @copydoc	getParam(const String&, TGpuDataParam<T, Core>&)
+		 */
+		void getTextureParam(const String& name, TGpuParamTexture<Core>& output) const;
+
+		/** @copydoc getParam(const String&, TGpuDataParam<T, Core>&) */
+		void getLoadStoreTextureParam(const String& name, TGpuParamLoadStoreTexture<Core>& output) const;
+
+		/** @copydoc getParam(const String&, TGpuDataParam<T, Core>&) */
+		void getSamplerStateParam(const String& name, TGpuParamSampState<Core>& output) const;
+
+		/**	Gets a parameter block buffer from the specified slot. */
+		ParamsBufferType getParamBlockBuffer(UINT32 slot) const;
+
+		/**	Gets a texture bound to the specified slot. */
+		TextureType getTexture(UINT32 slot);
+
+		/**	Gets a sampler state bound to the specified slot. */
+		SamplerType getSamplerState(UINT32 slot);
+
+		/**	Sets a texture at the specified slot. */
+		void setTexture(UINT32 slot, const TextureType& texture);
+
+		/**	Sets a sampler state at the specified slot. */
+		void setSamplerState(UINT32 slot, const SamplerType& sampler);
+
+	protected:
+		/** @copydoc CoreObject::getThisPtr */
+		virtual SPtr<GpuParamsType> _getThisPtr() const = 0;
+
+		ParamsBufferType* mParamBlockBuffers;
+		TextureType* mTextures;
+		SamplerType* mSamplerStates;
+	};
+
+	/** @} */
+
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** @cond INTERNAL */
+
+	/**
+	 * @brief	Core thread version of GpuParams.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT GpuParamsCore : public CoreObjectCore, public TGpuParams<true>
+	{
+	public:
+		~GpuParamsCore() { }
+
+		/** Uploads all CPU stored parameter buffer data to the GPU buffers. */
+		void updateHardwareBuffers();
+
+		/** @copydoc GpuParamsBase::GpuParamsBase */
+		static SPtr<GpuParamsCore> create(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+
+	protected:
+		friend class GpuParams;
+
+		/** @copydoc GpuParamsBase::GpuParamsBase */
+		GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+
+		/** @copydoc CoreObject::getThisPtr */
+		SPtr<GpuParamsCore> _getThisPtr() const override;
+
+		/** @copydoc CoreObjectCore::syncToCore */
+		void syncToCore(const CoreSyncData& data) override;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Contains descriptions for all parameters in a GPU program and also allows you to write and read those parameters. 
+	 * All parameter values are stored internally on the CPU, and are only submitted to the GPU once the parameters are 
+	 * bound to the pipeline.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT GpuParams : public CoreObject, public TGpuParams<false>, public IResourceListener
+	{
+	public:
+		~GpuParams() { }
+
+		/**
+		 * @copydoc	CoreObject::markCoreDirty
+		 *
+		 * @note	Internal method.
+		 */
+		void _markCoreDirty() override;
+
+		/**
+		 * @copydoc	IResourceListener::markResourcesDirty
+		 *
+		 * @note	Internal method.
+		 */
+		void _markResourcesDirty() override;
+
+		/** Retrieves a core implementation of a mesh usable only from the core thread. */
+		SPtr<GpuParamsCore> getCore() const;
+
+		/** @copydoc GpuParamsBase::GpuParamsBase */
+		static SPtr<GpuParams> create(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+
+		/** Contains a lookup table for sizes of all data parameters. Sizes are in bytes. */
+		const static GpuDataParamInfos PARAM_SIZES;
+
+	protected:
+		/** @copydoc GpuParamsBase::GpuParamsBase */
+		GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
+
+		/** @copydoc CoreObject::getThisPtr */
+		SPtr<GpuParams> _getThisPtr() const override;
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::syncToCore */
+		CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		/** @copydoc IResourceListener::getListenerResources */
+		void getListenerResources(Vector<HResource>& resources) override;
+
+		/** @copydoc IResourceListener::notifyResourceLoaded */
+		void notifyResourceLoaded(const HResource& resource) override { markCoreDirty(); }
+
+		/** @copydoc IResourceListener::notifyResourceChanged */
+		void notifyResourceChanged(const HResource& resource) override { markCoreDirty(); }
+	};
+
+	/** @} */
 }

+ 0 - 35
BansheeCore/Include/BsGpuProgInclude.h

@@ -1,35 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Raw text resource that serves as an include file for GPU programs.
-	 */
-	class BS_CORE_EXPORT GpuProgInclude : public Resource
-	{
-	public:
-		/**
-		 * @brief	Text of the include file.
-		 */
-		const String& getString() const { return mString; }
-
-		/**
-		 * @brief	Creates a new include file resource with the specified include string.
-		 */
-		static HGpuProgInclude create(const String& includeString);
-
-		/**
-		 * @brief	Creates an include file resource with the specified include string.
-		 *
-		 * @note	Internal method. Use "create" for normal use.
-		 */
-		static GpuProgIncludePtr _createPtr(const String& includeString);
-	private:
-		GpuProgInclude(const String& includeString);
-
-		String mString;
-	};
-}

+ 0 - 28
BansheeCore/Include/BsGpuProgIncludeImporter.h

@@ -1,28 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsSpecificImporter.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Importer using for importing GPU program (i.e. shader) include files.
-	 * 			Include files are just text files ending with ".gpuproginc" extension.
-	 */
-	class BS_CORE_EXPORT GpuProgIncludeImporter : public SpecificImporter
-	{
-	public:
-		GpuProgIncludeImporter();
-		virtual ~GpuProgIncludeImporter();
-
-		/** @copydoc SpecificImporter::isExtensionSupported */
-		virtual bool isExtensionSupported(const WString& ext) const;
-
-		/** @copydoc SpecificImporter::isMagicNumberSupported */
-		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const; 
-
-		/** @copydoc SpecificImporter::import */
-		virtual ResourcePtr import(const Path& filePath, ConstImportOptionsPtr importOptions);
-	private:
-	};
-}

+ 245 - 207
BansheeCore/Include/BsGpuProgram.h

@@ -1,208 +1,246 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsDrawOps.h"
-#include "BsResource.h"
-#include "BsGpuParamDesc.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Types of programs that may run on GPU.
-	 */
-	enum GpuProgramType
-	{
-		GPT_VERTEX_PROGRAM,
-		GPT_FRAGMENT_PROGRAM,
-		GPT_GEOMETRY_PROGRAM,
-		GPT_DOMAIN_PROGRAM,
-		GPT_HULL_PROGRAM,
-		GPT_COMPUTE_PROGRAM
-	};
-
-	/**
-	 * @brief	GPU program profiles representing supported
-	 *			feature sets.
-	 */
-	enum GpuProgramProfile
-	{
-		GPP_NONE,
-		GPP_PS_1_1,
-		GPP_PS_1_2,
-		GPP_PS_1_3,
-		GPP_PS_1_4,
-		GPP_PS_2_0,
-		GPP_PS_2_x,
-		GPP_PS_2_a,
-		GPP_PS_2_b,
-		GPP_PS_3_0,
-		GPP_PS_3_x,
-		GPP_PS_4_0,
-		GPP_PS_4_1,
-		GPP_PS_5_0,
-		GPP_VS_1_1,
-		GPP_VS_2_0,
-		GPP_VS_2_x,
-		GPP_VS_2_a,
-		GPP_VS_3_0,
-		GPP_VS_4_0,
-		GPP_VS_4_1,
-		GPP_VS_5_0,
-		GPP_GS_4_0,
-		GPP_GS_4_1,
-		GPP_GS_5_0,
-		GPP_HS_5_0,
-		GPP_DS_5_0,
-		GPP_CS_5_0
-	};
-
-	/**
-	 * @brief	Contains a GPU program such as vertex or fragment program which gets
-	 *			compiled from the provided source code.
-	 *
-	 * @note	Core thread only.
-	 */
-	class BS_CORE_EXPORT GpuProgram : public Resource
-	{
-	public:
-		virtual ~GpuProgram();
-
-        /**
-         * @brief	Source used for creating this program.
-         */
-        virtual const String& getSource() const { return mSource; }
-        
-		/**
-		 * @brief	Type of GPU program (e.g. fragment, vertex)
-		 */
-        virtual GpuProgramType getType() const { return mType; }
-
-		/**
-		 * @brief	Profile of the GPU program (e.g. VS_4_0, VS_5_0)
-		 */
-		virtual GpuProgramProfile getProfile() const { return mProfile; }
-
-		/**
-		 * @brief	Name of the program entry method (e.g. "main")
-		 */
-		virtual const String& getEntryPoint() const { return mEntryPoint; }
-
-		/**
-		 * @brief	Returns whether this program can be supported on the current renderer and hardware.
-		 */
-        virtual bool isSupported() const;
-
-		/**
-		 * @brief	Returns true if shader was successfully compiled. 
-		 *
-		 * @note	Thread safe. Only valid after core thread has initialized the program.
-		 */
-		virtual bool isCompiled() const { return mIsCompiled; }
-
-		/**
-		 * @brief	Returns an error message returned by the compiler, if the compilation failed.
-		 *
-		 * @note	Thread safe. Only valid after core thread has initialized the program.
-		 */
-		virtual String getCompileErrorMessage() const { return mCompileError; }
-
-		/**
-		 * @brief	Sets whether this geometry program requires adjacency information
-		 *			from the input primitives.
-		 *
-		 * @note	Only relevant for geometry programs.
-		 */
-		virtual void setAdjacencyInfoRequired(bool required) { mNeedsAdjacencyInfo = required; }
-
-		/**
-		 * @brief	Returns whether this geometry program requires adjacency information
-		 *			from the input primitives.
-		 *
-		 * @note	Only relevant for geometry programs.
-		 */
-		virtual bool isAdjacencyInfoRequired() const { return mNeedsAdjacencyInfo; }
-
-		/**
-		 * @brief	Returns true if matrices need to be transposed before sent to the GPU
-		 *			program as GPU program parameters.
-		 */
-		virtual bool requiresMatrixTranspose() const { return false; }
-
-		/**
-		 * @brief	Creates a new parameters object compatible with this program definition. You
-		 *			may populate the returned object with actual parameter values and bind it
-		 *			to the pipeline to render an object using those values and this program.
-		 */
-		virtual GpuParamsPtr createParameters();
-
-		/**
-		 * @brief	Returns description of all parameters in this GPU program.
-		 */
-		GpuParamDescPtr getParamDesc() const { return mParametersDesc; }
-
-		/**
-		* @brief	Language this shader was created from (e.g. HLSL, GLSL).
-		*/
-        virtual const String& getLanguage() const;
-
-		/**
-		 * @brief	Creates a new GPU program using the provided source code. If compilation fails or program is not supported
-		 *			"isCompiled" with return false, and you will be able to retrieve the error message via "getCompileErrorMessage".
-		 *
-		 * @param	source		Source code to compile the shader from.
-		 * @param	entryPoint	Name of the entry point function, e.g. "main".
-		 * @param	language	Language the source is written in, e.g. "hlsl" or "glsl".
-		 * @param	gptype		Type of the program, e.g. vertex or fragment.
-		 * @param	profile		Program profile specifying supported feature-set. Must match the type.
-		 * @param	includes	Optional includes to append to the source before compiling.
-		 * @param	requiresAdjacency	If true then adjacency information will be provided when rendering using this program.
-		 */
-		static HGpuProgram create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes = nullptr, bool requiresAdjacency = false);
-
-		/**
-		 * @copydoc	create
-		 *
-		 * @note	Internal method. For normal use call "create".
-		 */
-		static GpuProgramPtr _createPtr(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, 
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes = nullptr, bool requiresAdjacency = false);
-
-	protected:
-		friend class GpuProgramManager;
-
-		GpuProgram(const String& source, const String& entryPoint, 
-			GpuProgramType gptype, GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, 
-			bool isAdjacencyInfoRequired = false);
-
-		/**
-		 * @brief	Returns whether required capabilities for this program is supported.
-		 */
-        bool isRequiredCapabilitiesSupported() const;
-
-		/**
-		 * @copydoc Resource::calculateSize
-		 */
-		size_t calculateSize() const { return 0; } // TODO 
-
-	protected:
-		GpuProgramType mType;
-		bool mNeedsAdjacencyInfo;
-		String mEntryPoint;
-		GpuProgramProfile mProfile;
-        String mSource;
-
-		bool mIsCompiled;
-		String mCompileError;
-
-		GpuParamDescPtr mParametersDesc;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class GpuProgramRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCoreObject.h"
+#include "BsIReflectable.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** Types of programs that may run on GPU. */
+	enum GpuProgramType
+	{
+		GPT_VERTEX_PROGRAM,
+		GPT_FRAGMENT_PROGRAM,
+		GPT_GEOMETRY_PROGRAM,
+		GPT_DOMAIN_PROGRAM,
+		GPT_HULL_PROGRAM,
+		GPT_COMPUTE_PROGRAM
+	};
+
+	/**	GPU program profiles representing supported feature sets. */
+	enum GpuProgramProfile
+	{
+		GPP_NONE,
+		GPP_FS_1_1,
+		GPP_FS_1_2,
+		GPP_FS_1_3,
+		GPP_FS_1_4,
+		GPP_FS_2_0,
+		GPP_FS_2_x,
+		GPP_FS_2_a,
+		GPP_FS_2_b,
+		GPP_FS_3_0,
+		GPP_FS_3_x,
+		GPP_FS_4_0,
+		GPP_FS_4_1,
+		GPP_FS_5_0,
+		GPP_VS_1_1,
+		GPP_VS_2_0,
+		GPP_VS_2_x,
+		GPP_VS_2_a,
+		GPP_VS_3_0,
+		GPP_VS_4_0,
+		GPP_VS_4_1,
+		GPP_VS_5_0,
+		GPP_GS_4_0,
+		GPP_GS_4_1,
+		GPP_GS_5_0,
+		GPP_HS_5_0,
+		GPP_DS_5_0,
+		GPP_CS_5_0
+	};
+
+	/** Data describing a GpuProgram. */
+	class BS_CORE_EXPORT GpuProgramProperties
+	{
+	public:
+		GpuProgramProperties(const String& source, const String& entryPoint,
+			GpuProgramType gptype, GpuProgramProfile profile);
+
+		virtual ~GpuProgramProperties() { }
+
+        /** Source used for creating this program. */
+        const String& getSource() const { return mSource; }
+        
+		/**	Type of GPU program (e.g. fragment, vertex). */
+        GpuProgramType getType() const { return mType; }
+
+		/**	Profile of the GPU program (e.g. VS_4_0, VS_5_0). */
+		GpuProgramProfile getProfile() const { return mProfile; }
+
+		/**	Name of the program entry method (e.g. "main"). */
+		const String& getEntryPoint() const { return mEntryPoint; }
+
+	protected:
+		friend class GpuProgramRTTI;
+
+		GpuProgramType mType;
+		String mEntryPoint;
+		GpuProgramProfile mProfile;
+		String mSource;
+	};
+
+	/** @cond INTERNAL */
+
+	/**
+	 * Core thread version of a GpuProgram.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT GpuProgramCore : public CoreObjectCore
+	{
+	public:
+		virtual ~GpuProgramCore() { }
+
+		/** Returns whether this program can be supported on the current renderer and hardware. */
+        virtual bool isSupported() const;
+
+		/** Returns true if shader was successfully compiled. */
+		virtual bool isCompiled() const { return mIsCompiled; }
+
+		/**	Returns an error message returned by the compiler, if the compilation failed. */
+		virtual String getCompileErrorMessage() const { return mCompileError; }
+
+		/**
+		 * Sets whether this geometry program requires adjacency information from the input primitives.
+		 *
+		 * @note	Only relevant for geometry programs.
+		 */
+		virtual void setAdjacencyInfoRequired(bool required) { mNeedsAdjacencyInfo = required; }
+
+		/**
+		 * Returns whether this geometry program requires adjacency information from the input primitives.
+		 *
+		 * @note	Only relevant for geometry programs.
+		 */
+		virtual bool isAdjacencyInfoRequired() const { return mNeedsAdjacencyInfo; }
+
+		/** @copydoc GpuProgram::createParameters */
+		virtual SPtr<GpuParamsCore> createParameters();
+
+		/** @copydoc GpuProgram::getParamDesc */
+		GpuParamDescPtr getParamDesc() const { return mParametersDesc; }
+
+		/**	Returns GPU program input declaration. Only relevant for vertex programs. */
+		SPtr<VertexDeclarationCore> getInputDeclaration() const { return mInputDeclaration; }
+
+		/**	Returns properties that contain information about the GPU program. */
+		const GpuProgramProperties& getProperties() const { return mProperties; }
+
+		/** @copydoc GpuProgram::create */
+		static SPtr<GpuProgramCore> create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
+			GpuProgramProfile profile, bool requiresAdjacency = false);
+
+	protected:
+		GpuProgramCore(const String& source, const String& entryPoint,
+			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+
+		/** Returns whether required capabilities for this program is supported. */
+		bool isRequiredCapabilitiesSupported() const;
+
+		bool mNeedsAdjacencyInfo;
+
+		bool mIsCompiled;
+		String mCompileError;
+
+		GpuParamDescPtr mParametersDesc;
+		SPtr<VertexDeclarationCore> mInputDeclaration;
+		GpuProgramProperties mProperties;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Contains a GPU program such as vertex or fragment program which gets compiled from the provided source code.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT GpuProgram : public IReflectable, public CoreObject
+	{
+	public:
+		virtual ~GpuProgram() { }
+
+		/**
+		 * Returns true if shader was successfully compiled. 
+		 *
+		 * @note	Only valid after core thread has initialized the program.
+		 */
+		bool isCompiled() const;
+
+		/**
+		 * Returns an error message returned by the compiler, if the compilation failed.
+		 *
+		 * @note	Only valid after core thread has initialized the program.
+		 */
+		String getCompileErrorMessage() const;
+
+		/**
+		 * Creates a new parameters object compatible with this program definition. You may populate the returned object 
+		 * with actual parameter values and bind it to the pipeline to render an object using those values and this program.
+		 *
+		 * @note	Only valid after core thread has initialized the program.
+		 */
+		GpuParamsPtr createParameters();
+
+		/**
+		 * Returns description of all parameters in this GPU program.
+		 *
+		 * @note	Only valid after core thread has initialized the program.
+		 */
+		GpuParamDescPtr getParamDesc() const;
+
+		/** Retrieves a core implementation of a gpu program usable only from the core thread. */
+		SPtr<GpuProgramCore> getCore() const;
+
+		/** Returns properties that contain information about the GPU program. */
+		const GpuProgramProperties& getProperties() const { return mProperties; }
+
+		/**
+		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
+		 * isCompiled() with return false, and you will be able to retrieve the error message via getCompileErrorMessage().
+		 *
+		 * @param[in]	source				Source code to compile the shader from.
+		 * @param[in]	entryPoint			Name of the entry point function, e.g. "main".
+		 * @param[in]	language			Language the source is written in, e.g. "hlsl" or "glsl".
+		 * @param[in]	gptype				Type of the program, e.g. vertex or fragment.
+		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
+		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
+		 *									program.
+		 */
+		static GpuProgramPtr create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype,
+			GpuProgramProfile profile, bool requiresAdjacency = false);
+
+	protected:
+		friend class GpuProgramManager;
+
+		GpuProgram(const String& source, const String& entryPoint, const String& language,
+			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const;
+
+		/** @copydoc Resource::calculateSize */
+		size_t calculateSize() const { return 0; } // TODO 
+
+	protected:
+		bool mNeedsAdjacencyInfo;
+		String mLanguage;
+		GpuProgramProperties mProperties;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class GpuProgramRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 0 - 87
BansheeCore/Include/BsGpuProgramImportOptions.h

@@ -1,87 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsImportOptions.h"
-#include "BsGpuProgram.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains import options you may use to control how is a GPU program (i.e. shader)
-	 * 			file imported.
-	 */
-	class BS_CORE_EXPORT GpuProgramImportOptions : public ImportOptions
-	{
-	public:
-		GpuProgramImportOptions();
-
-		/**
-		 * @brief	Sets the name of the GPU program entry point method (e.g. "main").
-		 */
-		void setEntryPoint(const String& entryPoint) { mEntryPoint = entryPoint; }
-
-		/**
-		 * @brief	Sets the language the GPU program is written in (e.g. HLSL9, GLSL, HLSL11).
-		 */
-		void setLanguage(const String& language) { mLanguage = language; }
-
-		/**
-		 * @brief	Sets GPU program profile. Determines minimal feature-set the GPU program
-		 * 			requires in order to function.
-		 */
-		void setProfile(GpuProgramProfile profile) { mProfile = profile; }
-
-		/**
-		 * @brief	Sets GPU program type (e.g. vertex, pixel, etc.).
-		 */
-		void setType(GpuProgramType type) { mType = type; }
-
-		/**
-		 * @brief	Sets optional GPU program include files which may be used
-		 * 			for sharing code across multiple programs.
-		 */
-		void setIncludes(const Vector<HGpuProgInclude>& includes) { mIncludes = includes; }
-
-		/**
-		 * @brief	Gets the name of the GPU program entry point method (e.g. "main").
-		 */
-		const String& getEntryPoint() const { return mEntryPoint; }
-
-		/**
-		 * @brief	Gets the language the GPU program is written in (e.g. HLSL9, GLSL, HLSL11).
-		 */
-		const String& getLanguage() const { return mLanguage; }
-
-		/**
-		 * @brief	Gets GPU program profile. Determines minimal feature-set the GPU program
-		 * 			requires in order to function.
-		 */
-		GpuProgramProfile getProfile() const { return mProfile; }
-
-		/**
-		 * @brief	Gets GPU program type (e.g. vertex, pixel, etc.).
-		 */
-		GpuProgramType getType() const { return mType; }
-
-		/**
-		 * @brief	Gets optional GPU program include files which may be used
-		 * 			for sharing code across multiple programs.
-		 */
-		const Vector<HGpuProgInclude>& getIncludes() const { return mIncludes; }
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class GpuProgramImportOptionsRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-
-	private:
-		String mEntryPoint;
-		String mLanguage;
-		GpuProgramProfile mProfile;
-		GpuProgramType mType;
-		Vector<HGpuProgInclude> mIncludes;
-	};
-}

+ 0 - 56
BansheeCore/Include/BsGpuProgramImportOptionsRTTI.h

@@ -1,56 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGpuProgramImportOptions.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GpuProgramImportOptionsRTTI : public RTTIType<GpuProgramImportOptions, IReflectable, GpuProgramImportOptionsRTTI>
-	{
-	private:
-		String& getEntryPoint(GpuProgramImportOptions* obj) { return obj->mEntryPoint; }
-		void setEntryPoint(GpuProgramImportOptions* obj, String& value) { obj->mEntryPoint = value; }
-
-		String& getLanguage(GpuProgramImportOptions* obj) { return obj->mLanguage; }
-		void setLanguage(GpuProgramImportOptions* obj, String& value) { obj->mLanguage = value; }
-
-		GpuProgramProfile& getProfile(GpuProgramImportOptions* obj) { return obj->mProfile; }
-		void setProfile(GpuProgramImportOptions* obj, GpuProgramProfile& value) { obj->mProfile = value; }
-
-		GpuProgramType& getType(GpuProgramImportOptions* obj) { return obj->mType; }
-		void setType(GpuProgramImportOptions* obj, GpuProgramType& value) { obj->mType = value; }
-
-		HGpuProgInclude& getInclude(GpuProgramImportOptions* obj, UINT32 arrIdx) { return obj->mIncludes[arrIdx]; }
-		void setInclude(GpuProgramImportOptions* obj, UINT32 arrIdx, HGpuProgInclude& value) { obj->mIncludes[arrIdx] = value; }
-		UINT32 getNumIncludes(GpuProgramImportOptions* obj) { return (UINT32)obj->mIncludes.size(); }
-		void setNumIncludes(GpuProgramImportOptions* obj, UINT32 num) { obj->mIncludes.clear(); obj->mIncludes.resize(num); }
-
-	public:
-		GpuProgramImportOptionsRTTI()
-		{
-			addPlainField("mEntryPoint", 0, &GpuProgramImportOptionsRTTI::getEntryPoint, &GpuProgramImportOptionsRTTI::setEntryPoint);
-			addPlainField("mLanguage", 1, &GpuProgramImportOptionsRTTI::getLanguage, &GpuProgramImportOptionsRTTI::setLanguage);
-			addPlainField("mProfile", 2, &GpuProgramImportOptionsRTTI::getProfile, &GpuProgramImportOptionsRTTI::setProfile);
-			addPlainField("mType", 3, &GpuProgramImportOptionsRTTI::getType, &GpuProgramImportOptionsRTTI::setType);
-			addReflectableArrayField("mIncludes", 4, &GpuProgramImportOptionsRTTI::getInclude, &GpuProgramImportOptionsRTTI::getNumIncludes, 
-				&GpuProgramImportOptionsRTTI::setInclude, &GpuProgramImportOptionsRTTI::setNumIncludes);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GpuProgramImportOptions";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GpuProgramImportOptions;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return bs_shared_ptr<GpuProgramImportOptions, PoolAlloc>();
-		}
-	};
-}

+ 0 - 27
BansheeCore/Include/BsGpuProgramImporter.h

@@ -1,27 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsSpecificImporter.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Importer for GPU programs (i.e. shaders). File must end with ".gpuprog" extension,
-	 * 			and actual type of the program is determined via import options.
-	 */
-	class BS_CORE_EXPORT GpuProgramImporter : public SpecificImporter
-	{
-	public:
-		/** @copydoc SpecificImporter::isExtensionSupported */
-		virtual bool isExtensionSupported(const WString& ext) const;
-
-		/** @copydoc SpecificImporter::isMagicNumberSupported */
-		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const; 
-
-		/** @copydoc SpecificImporter::import */
-		virtual ResourcePtr import(const Path& filePath, ConstImportOptionsPtr importOptions);
-
-		/** @copydoc SpecificImporter::createImportOptions */
-		virtual ImportOptionsPtr createImportOptions() const;
-	};
-}

+ 143 - 112
BansheeCore/Include/BsGpuProgramManager.h

@@ -1,113 +1,144 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsException.h"
-#include "BsGpuProgram.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Factory responsible for creating GPU programs of a certain type.
-	 */
-	class BS_CORE_EXPORT GpuProgramFactory
-	{
-	public:
-        GpuProgramFactory() {}
-        virtual ~GpuProgramFactory();
-
-		/**
-		 * @brief	Returns GPU program language this factory is capable creating GPU programs from.
-		 */
-		virtual const String& getLanguage() const = 0;
-
-		/**
-		 * @brief	Creates a new GPU program using the provided source code. If compilation fails or program is not supported
-		 *			"isCompiled" method on the returned program will return false, and you will be able to retrieve the error message 
-		 *			via "getCompileErrorMessage".
-		 *
-		 * @param	source		Source code to compile the shader from.
-		 * @param	entryPoint	Name of the entry point function, e.g. "main".
-		 * @param	gptype		Type of the program, e.g. vertex or fragment.
-		 * @param	profile		Program profile specifying supported feature-set. Must match the type.
-		 * @param	includes	Optional includes to append to the source before compiling.
-		 * @param	requiresAdjacency	If true then adjacency information will be provided when rendering using this program.
-		 */
-		virtual GpuProgramPtr create(const String& source, const String& entryPoint, GpuProgramType gptype, 
-			GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes, bool requiresAdjacencyInformation) = 0;
-
-		/**
-		 * @copydoc	GpuProgramManager::createEmpty
-		 */
-		virtual GpuProgramPtr create(GpuProgramType type) = 0;
-	};
-
-	/**
-	 * @brief	Manager responsible for creating GPU programs. It will automatically
-	 *			try to find the approriate handler for a specific GPU program language
-	 *			and create the program if possible.
-	 *
-	 * @note	Sim thread only.
-	 */
-	class BS_CORE_EXPORT GpuProgramManager : public Module<GpuProgramManager>
-	{
-	public:
-		
-	public:
-		GpuProgramManager();
-		~GpuProgramManager();
-
-		/**
-		 * @brief	Registers a new factory that is able to create GPU programs for a certain language.
-		 *			If any other factory for the same language exists, it will overwrite it.
-		 */
-		void addFactory(GpuProgramFactory* factory);
-
-		/**
-		 * @brief	Unregisters a GPU program factory, essentially making it not possible to create GPU programs
-		 *			using the language the factory supported.
-		 */
-		void removeFactory(GpuProgramFactory* factory);
-
-		/**
-		 * @brief	Query if a GPU program language is supported. (.e.g. "hlsl", "glsl").
-		 */
-		bool isLanguageSupported(const String& lang);
-
-		/**
-		 * @brief	Creates a new GPU program using the provided source code. If compilation fails or program is not supported
-		 *			"isCompiled" method on the returned program will return false, and you will be able to retrieve the error message 
-		 *			via "getCompileErrorMessage".
-		 *
-		 * @param	source		Source code to compile the shader from.
-		 * @param	entryPoint	Name of the entry point function, e.g. "main".
-		 * @param	language	Language the source is written in, e.g. "hlsl" or "glsl".
-		 * @param	gptype		Type of the program, e.g. vertex or fragment.
-		 * @param	profile		Program profile specifying supported feature-set. Must match the type.
-		 * @param	includes	Optional includes to append to the source before compiling.
-		 * @param	requiresAdjacency	If true then adjacency information will be provided when rendering using this program.
-		 */
-		GpuProgramPtr create(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, const Vector<HGpuProgInclude>* includes,
-			bool requiresAdjacency = false);
-
-		/**
-		 * @brief	Creates a completely empty and uninitialized GpuProgram.
-		 * 			Should only be used for specific purposes, like deserialization,
-		 * 			as it requires additional manual initialization that is not required normally.
-		 */
-		GpuProgramPtr createEmpty(const String& language, GpuProgramType type);
-
-	protected:
-		/**
-		 * @brief	Attempts to find a factory for the specified language. Returns null if it cannot find one.
-		 */
-		GpuProgramFactory* getFactory(const String& language);
-
-	protected:
-		typedef Map<String, GpuProgramFactory*> FactoryMap;
-
-		FactoryMap mFactories;
-		GpuProgramFactory* mNullFactory; /**< Factory for dealing with GPU programs that can't be created. */
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsException.h"
+#include "BsGpuProgram.h"
+
+namespace BansheeEngine 
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** Factory responsible for creating GPU programs of a certain type. */
+	class BS_CORE_EXPORT GpuProgramFactory
+	{
+	public:
+        GpuProgramFactory() {}
+		virtual ~GpuProgramFactory() { }
+
+		/**	Returns GPU program language this factory is capable creating GPU programs from. */
+		virtual const String& getLanguage() const = 0;
+
+		/**
+		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
+		 * GpuProgram::isCompiled() method on the returned program will return false, and you will be able to retrieve 
+		 * the error message via GpuProgram::getCompileErrorMessage().
+		 *
+		 * @param[in]	source				Source code to compile the shader from.
+		 * @param[in]	entryPoint			Name of the entry point function, e.g. "main".
+		 * @param[in]	gptype				Type of the program, e.g. vertex or fragment.
+		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
+		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
+		 *									program.
+		 */
+		virtual SPtr<GpuProgramCore> create(const String& source, const String& entryPoint, GpuProgramType gptype, 
+			GpuProgramProfile profile, bool requiresAdjacencyInformation) = 0;
+
+		/** @copydoc GpuProgramManager::createEmpty */
+		virtual SPtr<GpuProgramCore> create(GpuProgramType type) = 0;
+	};
+
+	/**
+	 * Manager responsible for creating GPU programs. It will automatically try to find the appropriate handler for a 
+	 * specific GPU program language and create the program if possible.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT GpuProgramManager : public Module<GpuProgramManager>
+	{
+	public:
+		/**
+		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
+		 * GpuProgram::isCompiled() method on the returned program will return false, and you will be able to retrieve the 
+		 * error message via GpuProgram::getCompileErrorMessage().
+		 *
+		 * @param[in]	source				Source code to compile the shader from.
+		 * @param[in]	entryPoint			Name of the entry point function, e.g. "main".
+		 * @param[in]	language			Language the source is written in, e.g. "hlsl" or "glsl".
+		 * @param[in]	gptype				Type of the program, e.g. vertex or fragment.
+		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
+		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
+		 *									program.
+		 */
+		GpuProgramPtr create(const String& source, const String& entryPoint, const String& language, 
+			GpuProgramType gptype, GpuProgramProfile profile, bool requiresAdjacency = false);
+
+		/**
+		 * Creates a completely empty and uninitialized GpuProgram. Should only be used for specific purposes, like 
+		 * deserialization, as it requires additional manual initialization that is not required normally.
+		 */
+		GpuProgramPtr createEmpty(const String& language, GpuProgramType type);
+	};
+
+	/**
+	 * Manager responsible for creating GPU programs. It will automatically	try to find the appropriate handler for a 
+	 * specific GPU program language and create the program if possible.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT GpuProgramCoreManager : public Module<GpuProgramCoreManager>
+	{
+	public:
+		GpuProgramCoreManager();
+		virtual ~GpuProgramCoreManager();
+
+		/**
+		 * Registers a new factory that is able to create GPU programs for a certain language. If any other factory for the
+		 * same language exists, it will overwrite it.
+		 */
+		void addFactory(GpuProgramFactory* factory);
+
+		/**
+		 * Unregisters a GPU program factory, essentially making it not possible to create GPU programs using the language 
+		 * the factory supported.
+		 */
+		void removeFactory(GpuProgramFactory* factory);
+
+		/** Query if a GPU program language is supported. (.e.g. "hlsl", "glsl"). */
+		bool isLanguageSupported(const String& lang);
+
+		/**
+		 * Creates a new GPU program using the provided source code. If compilation fails or program is not supported
+		 * GpuProgramCore::isCompiled() method on the returned program will return false, and you will be able to retrieve 
+		 * the error message via GpuProgramCore::getCompileErrorMessage().
+		 *
+		 * @param[in]	source				Source code to compile the shader from.
+		 * @param[in]	entryPoint			Name of the entry point function, e.g. "main".
+		 * @param[in]	language			Language the source is written in, e.g. "hlsl" or "glsl".
+		 * @param[in]	gptype				Type of the program, e.g. vertex or fragment.
+		 * @param[in]	profile				Program profile specifying supported feature-set. Must match the type.
+		 * @param[in]	requiresAdjacency	If true then adjacency information will be provided when rendering using this 
+		 *									program.
+		 */
+		SPtr<GpuProgramCore> create(const String& source, const String& entryPoint, const String& language, 
+			GpuProgramType gptype, GpuProgramProfile profile, bool requiresAdjacency = false);
+
+	protected:
+		friend class GpuProgram;
+
+		/**
+		 * Creates a GPU program without initializing it.
+		 *
+		 * @see		create
+		 */
+		SPtr<GpuProgramCore> createInternal(const String& source, const String& entryPoint, const String& language,
+			GpuProgramType gptype, GpuProgramProfile profile, bool requiresAdjacency = false);
+
+		/** Attempts to find a factory for the specified language. Returns null if it cannot find one. */
+		GpuProgramFactory* getFactory(const String& language);
+
+	protected:
+		typedef Map<String, GpuProgramFactory*> FactoryMap;
+
+		FactoryMap mFactories;
+		GpuProgramFactory* mNullFactory; /**< Factory for dealing with GPU programs that can't be created. */
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 72 - 53
BansheeCore/Include/BsGpuProgramRTTI.h

@@ -1,54 +1,73 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGpuProgram.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GpuProgramRTTI : public RTTIType<GpuProgram, Resource, GpuProgramRTTI>
-	{
-	private:
-		BS_SETGET_MEMBER(mSize, UINT32, GpuProgram)
-
-		BS_SETGET_MEMBER(mType, GpuProgramType, GpuProgram);
-		BS_SETGET_MEMBER(mNeedsAdjacencyInfo, bool, GpuProgram);
-		BS_SETGET_MEMBER(mEntryPoint, String, GpuProgram);
-		BS_SETGET_MEMBER(mProfile, GpuProgramProfile, GpuProgram);
-		BS_SETGET_MEMBER(mSource, String, GpuProgram);
-
-	public:
-		GpuProgramRTTI()
-		{
-			BS_ADD_PLAINFIELD(mSize, 0, GpuProgramRTTI)
-
-			BS_ADD_PLAINFIELD(mType, 2, GpuProgramRTTI)
-			BS_ADD_PLAINFIELD(mNeedsAdjacencyInfo, 3, GpuProgramRTTI)
-			BS_ADD_PLAINFIELD(mEntryPoint, 4, GpuProgramRTTI)
-			BS_ADD_PLAINFIELD(mProfile, 5, GpuProgramRTTI)
-			BS_ADD_PLAINFIELD(mSource, 6, GpuProgramRTTI)
-		}
-
-		virtual void onDeserializationEnded(IReflectable* obj)
-		{
-			GpuProgram* gpuProgram = static_cast<GpuProgram*>(obj);
-			gpuProgram->initialize();
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GpuProgram";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GpuProgram;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate abstract class!"); // TODO - Need to initialize this properly
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsGpuProgram.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT GpuProgramRTTI : public RTTIType<GpuProgram, IReflectable, GpuProgramRTTI>
+	{
+	private:
+		GpuProgramType& getType(GpuProgram* obj) { return obj->mProperties.mType; }
+		void setType(GpuProgram* obj, GpuProgramType& val) { obj->mProperties.mType = val; }
+
+		bool& getNeedsAjdInfo(GpuProgram* obj) { return obj->mNeedsAdjacencyInfo; }
+		void setNeedsAjdInfo(GpuProgram* obj, bool& val) { obj->mNeedsAdjacencyInfo = val; }
+
+		String& getEntryPoint(GpuProgram* obj) { return obj->mProperties.mEntryPoint; }
+		void setEntryPoint(GpuProgram* obj, String& val) { obj->mProperties.mEntryPoint = val; }
+
+		GpuProgramProfile& getProfile(GpuProgram* obj) { return obj->mProperties.mProfile; }
+		void setProfile(GpuProgram* obj, GpuProgramProfile& val) { obj->mProperties.mProfile = val; }
+
+		String& getSource(GpuProgram* obj) { return obj->mProperties.mSource; }
+		void setSource(GpuProgram* obj, String& val) { obj->mProperties.mSource = val; }
+
+		String& getLanguage(GpuProgram* obj) { return obj->mLanguage; }
+		void setLanguage(GpuProgram* obj, String& val) { obj->mLanguage = val; }
+
+	public:
+		GpuProgramRTTI()
+		{
+			addPlainField("mType", 2, &GpuProgramRTTI::getType, &GpuProgramRTTI::setType);
+			addPlainField("mNeedsAdjacencyInfo", 3, &GpuProgramRTTI::getNeedsAjdInfo, &GpuProgramRTTI::setNeedsAjdInfo);
+			addPlainField("mEntryPoint", 4, &GpuProgramRTTI::getEntryPoint, &GpuProgramRTTI::setEntryPoint);
+			addPlainField("mProfile", 5, &GpuProgramRTTI::getProfile, &GpuProgramRTTI::setProfile);
+			addPlainField("mSource", 6, &GpuProgramRTTI::getSource, &GpuProgramRTTI::setSource);
+			addPlainField("mLanguage", 7, &GpuProgramRTTI::getLanguage, &GpuProgramRTTI::setLanguage);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			GpuProgram* gpuProgram = static_cast<GpuProgram*>(obj);
+			gpuProgram->initialize();
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "GpuProgram";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_GpuProgram;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return GpuProgramManager::instance().createEmpty("", GPT_VERTEX_PROGRAM); // Params don't matter, they'll get overwritten
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 0 - 50
BansheeCore/Include/BsGpuResource.h

@@ -1,50 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Represents a resource that in some way deals directly with the rendering
-	 *			API and the GPU.
-	 *
-	 * @note	e.g. texture, mesh, buffer, etc.
-	 */
-	class BS_CORE_EXPORT GpuResource : public Resource
-	{
-	public:
-		/**
-		 * @brief	Called just before writeSubresource is queued. Called from sim thread.
-		 *
-		 * @note	Sim thread only.
-		 */
-		virtual void _writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer) { }
-
-		/**
-		 * @brief	Updates a part of the current resource with the provided data. Specific resource
-		 * 			implementations provide a way to retrieve a subresource index.
-		 * 			
-		 * @note	Core thread only.
-		 */
-		virtual void writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer) = 0;
-
-		/**
-		 * @brief	Reads a part of the current resource into the provided "data" parameter.
-		 * 			Data buffer needs to be pre-allocated. Specific resource implementations 
-		 * 			provide a way to retrieve a subresource index and a way to allocate
-		 * 			the GpuResourceData buffer.
-		 * 			
-		 * @note	Core thread only.
-		 */
-		virtual void readSubresource(UINT32 subresourceIdx, GpuResourceData& data) = 0;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class GpuResourceRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
-}

+ 99 - 99
BansheeCore/Include/BsGpuResourceData.h

@@ -1,100 +1,100 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	You can use this class as a storage for reading and writing from/to various GPU resources. 
-	 *			It is meant to be created on sim thread and used on the core thread. This class is abstract
-	 *			and specific resource types need to implement their own type of GpuResourceData.
-	 * 			
-	 * @note	Normal use of this class involves requesting an instance of GpuResourceData from a GpuResource,
-	 *			then scheduling a read or write on that resource using the provided instance.
-	 *			Instance will be locked while it is used by the core thread and sim thread will be allowed to
-	 *			access it when the operation ends. Caller can track AsyncOps regarding the read/write operation
-	 *			to be notified when it is complete.
-	 *
-	 *			If you allocate an internal buffer to store the resource data, the ownership of the buffer
-	 * 			will always remain with the initial instance of the class. If that initial instance
-	 * 			is deleted, any potential copies will point to garbage data.
-	 */
-	class BS_CORE_EXPORT GpuResourceData : public IReflectable
-	{
-	public:
-		GpuResourceData();
-		GpuResourceData(const GpuResourceData& copy);
-		virtual ~GpuResourceData();
-
-		GpuResourceData& operator=(const GpuResourceData& rhs);
-
-		/**
-		 * @brief	Returns pointer to the internal buffer.
-		 */
-		UINT8* getData() const;
-
-		/**
-		 * @brief	Allocates an internal buffer of a certain size. If there is another
-		 * 			buffer already allocated, it will be freed and new one will be allocated.
-		 * 			Buffer size is determined based on parameters used for initializing the class.
-		 */
-		void allocateInternalBuffer();
-
-		/**
-		 * @brief	Allocates an internal buffer of a certain size. If there is another
-		 * 			buffer already allocated, it will be freed and new one will be allocated.
-		 *
-		 * @param	size	The size of the buffer in bytes.
-		 */
-		void allocateInternalBuffer(UINT32 size);
-
-		/**
-		 * @brief	Frees the internal buffer that was allocated using "allocateInternal". Called automatically
-		 * 			when the instance of the class is destroyed.
-		 */
-		void freeInternalBuffer();
-
-		/**
-		 * @brief	Makes the internal data pointer point to some external data. No copying is done, 
-		 * 			so you must ensure that external data exists as long as this class uses it. You are also
-		 * 			responsible for deleting the data when you are done with it.
-		 *
-		 * @note	If any internal data is allocated, it is freed.
-		 */
-		void setExternalBuffer(UINT8* data);
-
-		/**
-		 * @brief	Locks the data and makes it available only to the core thread. 
-		 *
-		 * @note	Internal method.
-		 */
-		void _lock() const;
-
-		/**
-		 * @brief	Unlocks the data and makes it available to all threads. 
-		 *
-		 * @note	Internal method.
-		 */
-		void _unlock() const;
-
-	protected:
-		/**
-		 * @brief	Returns the size of the internal buffer in bytes. This is calculated based
-		 *			on parameters provided upon construction and specific implementation details.
-		 */
-		virtual UINT32 getInternalBufferSize() = 0;
-
-	private:
-		UINT8* mData;
-		bool mOwnsData;
-		mutable bool mLocked;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class GpuResourceDataRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	/**
+	 * You can use this class as a storage for reading and writing from/to various GPU resources. It is meant to be created
+	 * on sim thread and used on the core thread. This class is abstract and specific resource types need to implement their
+	 * own type of GpuResourceData.
+	 * 			
+	 * @note	
+	 * Normal use of this class involves requesting an instance of GpuResourceData from a Resource, then scheduling a read
+	 * or write on that resource using the provided instance. Instance will be locked while it is used by the core thread 
+	 * and sim thread will be allowed to access it when the operation ends. Caller can track AsyncOp%s regarding the 
+	 * read/write operation to be notified when it is complete.
+	 * @note
+	 * If you allocate an internal buffer to store the resource data, the ownership of the buffer will always remain with 
+	 * the initial instance of the class. If that initial instance is deleted, any potential copies will point to garbage 
+	 * data.
+	 */
+	class BS_CORE_EXPORT GpuResourceData : public IReflectable
+	{
+	public:
+		GpuResourceData();
+		GpuResourceData(const GpuResourceData& copy);
+		virtual ~GpuResourceData();
+
+		GpuResourceData& operator=(const GpuResourceData& rhs);
+
+		/** Returns pointer to the internal buffer. */
+		UINT8* getData() const;
+
+		/**
+		 * Allocates an internal buffer of a certain size. If there is another buffer already allocated, it will be freed 
+		 * and new one will be allocated. Buffer size is determined based on parameters used for initializing the class.
+		 */
+		void allocateInternalBuffer();
+
+		/**
+		 * Allocates an internal buffer of a certain size. If there is another buffer already allocated, it will be freed
+		 * and new one will be allocated.
+		 *
+		 * @param[in]	size	The size of the buffer in bytes.
+		 */
+		void allocateInternalBuffer(UINT32 size);
+
+		/**
+		 * Frees the internal buffer that was allocated using allocateInternalBuffer(). Called automatically when the 
+		 * instance of the class is destroyed.
+		 */
+		void freeInternalBuffer();
+
+		/**
+		 * Makes the internal data pointer point to some external data. No copying is done, so you must ensure that external
+		 * data exists as long as this class uses it. You are also responsible for deleting the data when you are done 
+		 * with it.
+		 *
+		 * @note	If any internal data is allocated, it is freed.
+		 */
+		void setExternalBuffer(UINT8* data);
+
+		/** Checks if the internal buffer is locked due to some other thread using it. */
+		bool isLocked() const { return mLocked; }
+
+		/** Locks the data and makes it available only to the core thread. */
+		void _lock() const;
+
+		/**	Unlocks the data and makes it available to all threads.  */
+		void _unlock() const;
+
+	protected:
+		/**
+		 * Returns the size of the internal buffer in bytes. This is calculated based on parameters provided upon 
+		 * construction and specific implementation details.
+		 */
+		virtual UINT32 getInternalBufferSize() const = 0;
+
+	private:
+		UINT8* mData;
+		bool mOwnsData;
+		mutable bool mLocked;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class GpuResourceDataRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 40 - 32
BansheeCore/Include/BsGpuResourceDataRTTI.h

@@ -1,33 +1,41 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGpuResourceData.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GpuResourceDataRTTI : public RTTIType<GpuResourceData, IReflectable, GpuResourceDataRTTI>
-	{
-	public:
-		GpuResourceDataRTTI()
-		{
-
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GpuResourceData";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GpuResourceData;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsGpuResourceData.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT GpuResourceDataRTTI : public RTTIType<GpuResourceData, IReflectable, GpuResourceDataRTTI>
+	{
+	public:
+		GpuResourceDataRTTI()
+		{ }
+
+		const String& getRTTIName() override
+		{
+			static String name = "GpuResourceData";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_GpuResourceData;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 0 - 33
BansheeCore/Include/BsGpuResourceRTTI.h

@@ -1,33 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsGpuResource.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT GpuResourceRTTI : public RTTIType<GpuResource, Resource, GpuResourceRTTI>
-	{
-	public:
-		GpuResourceRTTI()
-		{
-
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "GpuResource";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_GpuResource;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
-		}
-	};
-}

+ 76 - 0
BansheeCore/Include/BsHString.h

@@ -0,0 +1,76 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+namespace BansheeEngine
+{
+	/** @addtogroup Localization
+	 *  @{
+	 */
+
+	/**
+	 * String handle. Provides a wrapper around an Unicode string, primarily for localization purposes.
+	 * 			
+	 * Actual value for this string is looked up in a global string table based on the provided identifier string and 
+	 * currently active language. If such value doesn't exist then the identifier is used as is.
+	 *			
+	 * Use {0}, {1}, etc. in the string value for values that might change dynamically.
+	 */
+	class BS_CORE_EXPORT HString
+	{
+	public:
+		/**
+		 * Creates a new localized string with the specified identifier. If the identifier doesn't previously exist in the 
+		 * string table, identifier value will also be used for initializing the default language version of the string.
+		 *
+		 * @param[in]	identifier		String you can use for later referencing the localized string.
+		 * @param[in]	stringTableId	Unique identifier of the string table to retrieve the string from.
+		 */
+		explicit HString(const WString& identifier, UINT32 stringTableId = 0);
+
+		/**
+		 * Creates a new localized string with the specified identifier and sets the default language version of the 
+		 * string. If a string with that identifier already exists default language string will be updated.
+		 *
+		 * @param[in]	identifier		String you can use for later referencing the localized string.
+		 * @param[in]	default			Default string to assign to the specified identifier. Language to which it will be 
+		 *								assigned depends on the StringTable::DEFAULT_LANGUAGE value.
+		 * @param[in]	stringTableId	Unique identifier of the string table to retrieve the string from.
+		 */
+		explicit HString(const WString& identifier, const WString& default, UINT32 stringTableId = 0);
+
+		/**
+		 * Creates a new empty localized string.
+		 *
+		 * @param[in]	stringTableId	Unique identifier of the string table to retrieve the string from.
+		 */
+		HString(UINT32 stringTableId = 0);
+		HString(const HString& copy);
+		~HString();
+
+		HString& operator=(const HString& rhs);
+
+		operator const WString& () const;
+		const WString& getValue() const;
+
+		/**
+		 * Sets a value of a string parameter. Parameters are specified as bracketed values within the string itself 
+		 * (e.g. {0}, {1}) etc. Use ^ as an escape character.
+		 *
+		 * @note	This is useful for strings that have dynamically changing values, like numbers, embedded in them.
+		 */
+		void setParameter(UINT32 idx, const WString& value);
+		
+		/** Returns an empty string. */
+		static const HString& dummy();
+	private:
+		SPtr<LocalizedStringData> mStringData;
+		WString* mParameters;
+
+		mutable bool mIsDirty;
+		mutable WString mCachedString;
+		mutable WString* mStringPtr;
+	};
+
+	/** @} */
+}

+ 162 - 173
BansheeCore/Include/BsHardwareBuffer.h

@@ -1,173 +1,162 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Abstract class defining common features of hardware buffers. Hardware buffers usually
-	 *			represent areas of memory the GPU or the driver can access directly.
-	 *
-	 * @note	Be aware that reading from non-system memory hardware buffers is usually slow and should be avoided.
-	 */
-	class BS_CORE_EXPORT HardwareBuffer
-    {
-    public:
-        virtual ~HardwareBuffer() {}
-
-		/**
-		 * @brief	Locks a portion of the buffer and returns pointer to the locked area.
-		 *			You must call "unlock" when done.
-		 *
-		 * @param	offset	Offset in bytes from which to lock the buffer.
-		 * @param	length	Length of the area you want to lock, in bytes.
-		 * @param	options	Signifies what you want to do with the returned pointer.
-		 *					Caller must ensure not to do anything he hasn't requested.
-		 *					(e.g. don't try to read from the buffer unless you requested
-		 *					it here).
-		 */
-		virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options)
-        {
-            assert(!isLocked() && "Cannot lock this buffer, it is already locked!");
-            void* ret = lockImpl(offset, length, options);
-            mIsLocked = true;
-
-			mLockStart = offset;
-			mLockSize = length;
-            return ret;
-        }
-
-		/**
-		 * @brief	Locks the entire buffer and returns pointer to the locked area.
-		 *			You must call "unlock" when done.
-		 *
-		 * @param	options	Signifies what you want to do with the returned pointer.
-		 *					Caller must ensure not to do anything he hasn't requested.
-		 *					(e.g. don't try to read from the buffer unless you requested
-		 *					it here).
-		 */
-        void* lock(GpuLockOptions options)
-        {
-            return this->lock(0, mSizeInBytes, options);
-        }
-
-		/**
-		 * @brief	Releases the lock on this buffer. 
-		 */
-		virtual void unlock()
-        {
-            assert(isLocked() && "Cannot unlock this buffer, it is not locked!");
-
-            unlockImpl();
-            mIsLocked = false;
-        }
-
-		/**
-		 * @brief	Reads data from a portion of the buffer and copies it to the destination
-		 *			buffer. Caller must ensure destination buffer is large enough.
-		 *
-		 * @param	offset	Offset in bytes from which to copy the data.
-		 * @param	length	Length of the area you want to copy, in bytes.
-		 * @param	dest	Destination buffer large enough to store the read data.
-		 */
-        virtual void readData(UINT32 offset, UINT32 length, void* dest) = 0;
-
-		/**
-		 * @brief	Writes data into a portion of the buffer from the source memory. 
-		 *
-		 * @param	offset		Offset in bytes from which to copy the data.
-		 * @param	length		Length of the area you want to copy, in bytes.
-		 * @param	source		Source buffer containing the data to write.
-		 * @param	writeFlags	Optional write flags that may affect performance.
-		 */
-        virtual void writeData(UINT32 offset, UINT32 length, const void* source,
-				BufferWriteType writeFlags = BufferWriteType::Normal) = 0;
-
-		/**
-		 * @brief	Copies data from a specific portion of the source buffer into a specific portion
-		 *			of this buffer.
-		 *
-		 * @param	srcBuffer			Buffer to copy from.
-		 * @param	srcOffset			Offset into the source buffer to start copying from, in bytes.
-		 * @param	dstOffset			Offset into this buffer to start copying to, in bytes.
-		 * @param	length				Size of the data to copy, in bytes.
-		 * @param	discardWholeBuffer	Specify true if the data in the current buffer can be entirely discarded. This
-		 *								may improve performance.
-		 */
-		virtual void copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset, 
-			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false)
-		{
-			const void *srcData = srcBuffer.lock(
-				srcOffset, length, GBL_READ_ONLY);
-			this->writeData(dstOffset, length, srcData, discardWholeBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
-			srcBuffer.unlock();
-		}
-
-		/**
-		 * @brief	Copy data from the provided buffer into this buffer. If buffers
-		 *			are not the same size, smaller size will be used.
-		 */
-		virtual void copyData(HardwareBuffer& srcBuffer)
-		{
-			UINT32 sz = std::min(getSizeInBytes(), srcBuffer.getSizeInBytes()); 
-			copyData(srcBuffer, 0, 0, sz, true);
-		}
-			
-		/**
-		 * @brief	Returns the size of this buffer in bytes.
-		 */
-        UINT32 getSizeInBytes(void) const { return mSizeInBytes; }
-
-		/**
-		 * @brief	Returns the Usage flags with which this buffer was created.
-		 */
-        GpuBufferUsage getUsage() const { return mUsage; }
-
-		/**
-		 * @brief	Returns whether this buffer is held in system memory.
-		 */
-		bool isSystemMemory() const { return mSystemMemory; }
-
-		/**
-		 * @brief	Returns whether or not this buffer is currently locked.
-		 */
-        bool isLocked() const { return mIsLocked; }	
-
-	protected:
-		friend class HardwareBufferManager;
-
-		/**
-		 * @brief	Constructs a new buffer.
-		 *
-		 * @param	usage			Determines most common usage of the buffer. Usually has effect on what
-		 *							type of memory will be buffer allocated in but that depends on render API.
-		 *							Specify dynamic if you plan on modifying it often, static otherwise.
-		 * @param	systemMemory	If enabled the the buffer will be kept in the system memory. System memory
-		 *							buffers are often used as a source or destination for copies from/to other
-		 *							buffers. Some APIs don't allow reading from non-system memory buffers.
-		 */
-		HardwareBuffer(GpuBufferUsage usage, bool systemMemory)
-			: mUsage(usage), mIsLocked(false), mSystemMemory(systemMemory)
-		{  }
-
-		/**
-		 * @copydoc	lock
-		 */
-		virtual void* lockImpl(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
-
-		/**
-		 * @copydoc	unlock
-		 */
-		virtual void unlockImpl() = 0;
-
-	protected:
-		UINT32 mSizeInBytes;
-		GpuBufferUsage mUsage;
-		bool mIsLocked;
-		UINT32 mLockStart;
-		UINT32 mLockSize;
-		bool mSystemMemory;
-    };
-}
-
-
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine 
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Abstract class defining common features of hardware buffers. Hardware buffers usually represent areas of memory the 
+	 * GPU or the driver can access directly.
+	 *
+	 * @note	Core thread only.
+	 * @note	Be aware that reading from non-system memory hardware buffers is usually slow and should be avoided.
+	 */
+	class BS_CORE_EXPORT HardwareBuffer
+    {
+    public:
+        virtual ~HardwareBuffer() {}
+
+		/**
+		 * Locks a portion of the buffer and returns pointer to the locked area. You must call unlock() when done.
+		 *
+		 * @param[in]	offset	Offset in bytes from which to lock the buffer.
+		 * @param[in]	length	Length of the area you want to lock, in bytes.
+		 * @param[in]	options	Signifies what you want to do with the returned pointer. Caller must ensure not to do 
+		 *						anything he hasn't requested (e.g. don't try to read from the buffer unless you requested 
+		 *						it here).
+		 */
+		virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options)
+        {
+            assert(!isLocked() && "Cannot lock this buffer, it is already locked!");
+            void* ret = lockImpl(offset, length, options);
+            mIsLocked = true;
+
+			mLockStart = offset;
+			mLockSize = length;
+            return ret;
+        }
+
+		/**
+		 * Locks the entire buffer and returns pointer to the locked area. You must call unlock() when done.
+		 *
+		 * @param[in]	options	Signifies what you want to do with the returned pointer. Caller must ensure not to do 
+		 *						anything he hasn't requested (e.g. don't try to read from the buffer unless you requested
+		 *						it here).
+		 */
+        void* lock(GpuLockOptions options)
+        {
+            return this->lock(0, mSizeInBytes, options);
+        }
+
+		/**	Releases the lock on this buffer.  */
+		virtual void unlock()
+        {
+            assert(isLocked() && "Cannot unlock this buffer, it is not locked!");
+
+            unlockImpl();
+            mIsLocked = false;
+        }
+
+		/**
+		 * Reads data from a portion of the buffer and copies it to the destination buffer. Caller must ensure destination 
+		 * buffer is large enough.
+		 *
+		 * @param[in]	offset	Offset in bytes from which to copy the data.
+		 * @param[in]	length	Length of the area you want to copy, in bytes.
+		 * @param[in]	dest	Destination buffer large enough to store the read data.
+		 */
+        virtual void readData(UINT32 offset, UINT32 length, void* dest) = 0;
+
+		/**
+		 * Writes data into a portion of the buffer from the source memory. 
+		 *
+		 * @param[in]	offset		Offset in bytes from which to copy the data.
+		 * @param[in]	length		Length of the area you want to copy, in bytes.
+		 * @param[in]	source		Source buffer containing the data to write.
+		 * @param[in]	writeFlags	Optional write flags that may affect performance.
+		 */
+        virtual void writeData(UINT32 offset, UINT32 length, const void* source,
+				BufferWriteType writeFlags = BufferWriteType::Normal) = 0;
+
+		/**
+		 * Copies data from a specific portion of the source buffer into a specific portion of this buffer.
+		 *
+		 * @param[in]	srcBuffer			Buffer to copy from.
+		 * @param[in]	srcOffset			Offset into the source buffer to start copying from, in bytes.
+		 * @param[in]	dstOffset			Offset into this buffer to start copying to, in bytes.
+		 * @param[in]	length				Size of the data to copy, in bytes.
+		 * @param[in]	discardWholeBuffer	Specify true if the data in the current buffer can be entirely discarded. This
+		 *									may improve performance.
+		 */
+		virtual void copyData(HardwareBuffer& srcBuffer, UINT32 srcOffset, 
+			UINT32 dstOffset, UINT32 length, bool discardWholeBuffer = false)
+		{
+			const void *srcData = srcBuffer.lock(
+				srcOffset, length, GBL_READ_ONLY);
+			this->writeData(dstOffset, length, srcData, discardWholeBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
+			srcBuffer.unlock();
+		}
+
+		/**
+		 * Copy data from the provided buffer into this buffer. If buffers are not the same size, smaller size will be used.
+		 */
+		virtual void copyData(HardwareBuffer& srcBuffer)
+		{
+			UINT32 sz = std::min(getSizeInBytes(), srcBuffer.getSizeInBytes()); 
+			copyData(srcBuffer, 0, 0, sz, true);
+		}
+			
+		/** Returns the size of this buffer in bytes. */
+        UINT32 getSizeInBytes(void) const { return mSizeInBytes; }
+
+		/**	Returns the Usage flags with which this buffer was created. */
+        GpuBufferUsage getUsage() const { return mUsage; }
+
+		/**	Returns whether this buffer is held in system memory. */
+		bool isSystemMemory() const { return mSystemMemory; }
+
+		/**	Returns whether or not this buffer is currently locked. */
+        bool isLocked() const { return mIsLocked; }	
+
+	protected:
+		friend class HardwareBufferManager;
+
+		/**
+		 * Constructs a new buffer.
+		 *
+		 * @param[in]	usage			Determines most common usage of the buffer. Usually has effect on what type of 
+		 *								memory will be buffer allocated in but that depends on render API. Specify dynamic 
+		 *								if you plan on modifying it often, static otherwise.
+		 * @param[in]	systemMemory	If enabled the the buffer will be kept in the system memory. System memory buffers 
+		 *								are often used as a source or destination for copies from/to other buffers. Some 
+		 *								APIs don't allow reading from non-system memory buffers.
+		 */
+		HardwareBuffer(GpuBufferUsage usage, bool systemMemory)
+			: mUsage(usage), mIsLocked(false), mSystemMemory(systemMemory)
+		{  }
+
+		/** @copydoc lock */
+		virtual void* lockImpl(UINT32 offset, UINT32 length, GpuLockOptions options) = 0;
+
+		/** @copydoc unlock */
+		virtual void unlockImpl() = 0;
+
+	protected:
+		UINT32 mSizeInBytes;
+		GpuBufferUsage mUsage;
+		bool mIsLocked;
+		UINT32 mLockStart;
+		UINT32 mLockSize;
+		bool mSystemMemory;
+    };
+
+	/** @} */
+	/** @endcond */
+}

+ 135 - 107
BansheeCore/Include/BsHardwareBufferManager.h

@@ -1,107 +1,135 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsVertexBuffer.h"
-#include "BsIndexBuffer.h"
-#include "BsVertexDeclaration.h"
-#include "BsGpuParamBlock.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Handles creation of various hardware buffers.
-	 *
-	 * @note	Thread safe.
-	 */
-	class BS_CORE_EXPORT HardwareBufferManager : public Module<HardwareBufferManager>
-	{
-    public:
-        HardwareBufferManager();
-        virtual ~HardwareBufferManager();
-
-		/**
-		 * @brief	Creates a new vertex buffer used for holding number of vertices and other
-		 *			per-vertex data. Buffer can be bound to the pipeline and its data can
-		 *			be passed to the active vertex GPU program.
-		 *
-		 * @param	vertexSize	Size of a single vertex in the buffer, in bytes.
-		 * @param	numVerts	Number of vertices the buffer can hold.
-		 * @param	usage		Usage that tells the hardware how will be buffer be used. 
-		 * @param	streamOut	If true the buffer will be usable for streaming out data from the GPU.
-		 */
-		virtual VertexBufferPtr createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false);
-
-		/**
-		 * @brief	Creates a new index buffer that holds indices referencing vertices in a vertex buffer.
-		 *			Indices are interpreted by the pipeline and vertices are drawn in the order specified in
-		 *			the index buffer.
-		 *
-		 * @param	itype		Index type, determines size of an index.
-		 * @param	numIndexes	Number of indexes can buffer can hold.
-		 * @param	usage		Usage that tells the hardware how will be buffer be used. 
-		 */
-		virtual IndexBufferPtr createIndexBuffer(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
-
-		/**
-		 * @brief	Creates an GPU parameter block that you can use for setting parameters for GPU programs.
-		 *			Parameter blocks may be used for sharing parameter data between multiple GPU programs, requiring
-		 *			you to update only one buffer for all of them, potentially improving performance.
-		 *
-		 * @param	size	Size of the parameter buffer in bytes.
-		 * @param	usage	Usage that tells the hardware how will be buffer be used. 
-		 */
-		virtual GpuParamBlockBufferPtr createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
-
-		/**
-		 * @brief	Creates a generic buffer that can be passed as a parameter to a GPU program. This type of buffer can hold
-		 *			various type of data and can be used for various purposes. See "GpuBufferType" for explanation of
-		 *			different buffer types.
-		 *
-		 * @param	elementCount  	Number of elements in the buffer. 
-		 * @param	elementSize   	Size of each individual element in the buffer, in bytes.
-		 * @param	type		  	Type of the buffer.
-		 * @param	usage		  	Usage that tells the hardware how will be buffer be used. 
-		 * @param	randomGpuWrite	(optional) Allows the GPU to write to the resource.
-		 * @param	useCounter	  	(optional) Binds a counter that can be used from a GPU program on the buffer.
-		 *
-		 * @note	Be aware that due to some render API restrictions some of these settings cannot be used together, 
-		 *			and if so you will receive an assert in debug mode.
-		 */
-		virtual GpuBufferPtr createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
-			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
-
-		/**
-		 * @brief	Creates a new vertex declaration from a list of vertex elements.
-		 */
-		virtual VertexDeclarationPtr createVertexDeclaration(const VertexDeclaration::VertexElementList& elements);
-
-	protected:
-		/**
-		 * @copydoc	createVertexBuffer
-		 */
-		virtual VertexBufferPtr createVertexBufferImpl(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false) = 0;
-
-		/**
-		 * @copydoc	createIndexBuffer
-		 */
-		virtual IndexBufferPtr createIndexBufferImpl(IndexBuffer::IndexType itype, UINT32 numIndexes, GpuBufferUsage usage) = 0;
-
-		/**
-		 * @copydoc	createGpuParamBlockBuffer
-		 */
-		virtual GpuParamBlockBufferPtr createGpuParamBlockBufferImpl() = 0;
-
-		/**
-		 * @copydoc	createGpuBuffer
-		 */
-		virtual GpuBufferPtr createGpuBufferImpl(UINT32 elementCount, UINT32 elementSize, GpuBufferType type, GpuBufferUsage usage, 
-			bool randomGpuWrite = false, bool useCounter = false) = 0;
-
-		/**
-		 * @copydoc	createVertexDeclaration
-		 */
-		virtual VertexDeclarationPtr createVertexDeclarationImpl(const VertexDeclaration::VertexElementList& elements);
-	};
-}
-
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsVertexBuffer.h"
+#include "BsIndexBuffer.h"
+#include "BsVertexDeclaration.h"
+
+namespace BansheeEngine 
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Handles creation of various hardware buffers.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT HardwareBufferManager : public Module<HardwareBufferManager>
+	{
+    public:
+        HardwareBufferManager();
+        virtual ~HardwareBufferManager();
+
+		/**
+		 * Creates a new vertex buffer used for holding number of vertices and other per-vertex data. Buffer can be bound 
+		 * to the pipeline and its data can be passed to the active vertex GPU program.
+		 *
+		 * @param[in]	vertexSize	Size of a single vertex in the buffer, in bytes.
+		 * @param[in]	numVerts	Number of vertices the buffer can hold.
+		 * @param[in]	usage		Usage that tells the hardware how will be buffer be used. 
+		 * @param[in]	streamOut	If true the buffer will be usable for streaming out data from the GPU.
+		 */
+		virtual VertexBufferPtr createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false);
+
+		/**
+		 * Creates a new index buffer that holds indices referencing vertices in a vertex buffer. Indices are interpreted 
+		 * by the pipeline and vertices are drawn in the order specified in the index buffer.
+		 *
+		 * @param[in]	itype		Index type, determines size of an index.
+		 * @param[in]	numIndexes	Number of indexes can buffer can hold.
+		 * @param[in]	usage		Usage that tells the hardware how will be buffer be used. 
+		 */
+		virtual IndexBufferPtr createIndexBuffer(IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
+
+		/**
+		 * Creates an GPU parameter block that you can use for setting parameters for GPU programs. Parameter blocks may be
+		 * used for sharing parameter data between multiple GPU programs, requiring you to update only one buffer for all of
+		 * them, potentially improving performance.
+		 *
+		 * @param[in]	size	Size of the parameter buffer in bytes.
+		 * @param[in]	usage	Usage that tells the hardware how will be buffer be used. 
+		 */
+		virtual GpuParamBlockBufferPtr createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+
+		/**
+		 * Creates a generic buffer that can be passed as a parameter to a GPU program. This type of buffer can hold various 
+		 * type of data and can be used for various purposes. See "GpuBufferType" for explanation of different buffer types.
+		 *
+		 * @param[in]	elementCount  	Number of elements in the buffer. 
+		 * @param[in]	elementSize   	Size of each individual element in the buffer, in bytes.
+		 * @param[in]	type		  	Type of the buffer.
+		 * @param[in]	usage		  	Usage that tells the hardware how will be buffer be used. 
+		 * @param[in]	randomGpuWrite	(optional) Allows the GPU to write to the resource.
+		 * @param[in]	useCounter	  	(optional) Binds a counter that can be used from a GPU program on the buffer.
+		 *
+		 * @note	
+		 * Be aware that due to some render API restrictions some of these settings cannot be used together, and if so you 
+		 * will receive an assert in debug mode.
+		 */
+		virtual GpuBufferPtr createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
+			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+
+		/** Creates a new vertex declaration from a list of vertex elements. */
+		virtual VertexDeclarationPtr createVertexDeclaration(const List<VertexElement>& elements);
+	};
+
+	/**
+	 * Handles creation of various hardware buffers.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT HardwareBufferCoreManager : public Module<HardwareBufferCoreManager>
+	{
+    public:
+		virtual ~HardwareBufferCoreManager() { }
+
+		/** @copydoc HardwareBufferManager::createVertexBuffer */
+		virtual SPtr<VertexBufferCore> createVertexBuffer(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false);
+
+		/** @copydoc HardwareBufferManager::createIndexBuffer */
+		virtual SPtr<IndexBufferCore> createIndexBuffer(IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
+
+		/** @copydoc HardwareBufferManager::createVertexDeclaration */
+		virtual SPtr<VertexDeclarationCore> createVertexDeclaration(const List<VertexElement>& elements);
+
+		/** @copydoc HardwareBufferManager::createGpuParamBlockBuffer */
+		virtual SPtr<GpuParamBlockBufferCore> createGpuParamBlockBuffer(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC);
+
+		/** @copydoc HardwareBufferManager::createGpuBuffer */
+		virtual SPtr<GpuBufferCore> createGpuBuffer(UINT32 elementCount, UINT32 elementSize, 
+			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false);
+
+	protected:
+		friend class IndexBuffer;
+		friend class VertexBuffer;
+		friend class VertexDeclaration;
+		friend class GpuParamBlockBuffer;
+		friend class GpuBuffer;
+
+		/** @copydoc createVertexBuffer */
+		virtual SPtr<VertexBufferCore> createVertexBufferInternal(UINT32 vertexSize, UINT32 numVerts, GpuBufferUsage usage, bool streamOut = false) = 0;
+
+		/** @copydoc createIndexBuffer */
+		virtual SPtr<IndexBufferCore> createIndexBufferInternal(IndexType itype, UINT32 numIndexes, GpuBufferUsage usage) = 0;
+
+		/** @copydoc createGpuParamBlockBuffer */
+		virtual SPtr<GpuParamBlockBufferCore> createGpuParamBlockBufferInternal(UINT32 size, GpuParamBlockUsage usage = GPBU_DYNAMIC) = 0;
+
+		/** @copydoc createGpuBuffer */
+		virtual SPtr<GpuBufferCore> createGpuBufferInternal(UINT32 elementCount, UINT32 elementSize,
+			GpuBufferType type, GpuBufferUsage usage, bool randomGpuWrite = false, bool useCounter = false) = 0;
+
+		/** @copydoc createVertexDeclaration */
+		virtual SPtr<VertexDeclarationCore> createVertexDeclarationInternal(const List<VertexElement>& elements);
+	};
+
+	/** @} */
+	/** @endcond */
+}
+

+ 41 - 0
BansheeCore/Include/BsIResourceListener.h

@@ -0,0 +1,41 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	/** Interface that allows the implementing class to be notified when the resources it is referencing change. */
+	class BS_CORE_EXPORT IResourceListener
+	{
+	public:
+		IResourceListener();
+		virtual ~IResourceListener();
+
+	protected:
+		friend class ResourceListenerManager;
+
+		/**
+		 * Retrieves all the resources that the class depends on.
+		 *
+		 * @note	Derived implementations must add the resources to the provided @p resources array.
+		 */
+		virtual void getListenerResources(Vector<HResource>& resources) = 0;
+
+		/**	Marks the resource dependencies list as dirty and schedules it for rebuild. */
+		virtual void markListenerResourcesDirty();
+
+		/**	Called when a resource has been fully loaded. */
+		virtual void notifyResourceLoaded(const HResource& resource) { }
+
+		/**	Called when the internal resource the resource handle is pointing to changes. */
+		virtual void notifyResourceChanged(const HResource& resource) { }
+	};
+
+	/** @} */
+}

+ 41 - 0
BansheeCore/Include/BsIconUtility.h

@@ -0,0 +1,41 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Utility-Core
+	 *  @{
+	 */
+
+	/**	Manipulates icons in executable files. */
+	class BS_CORE_EXPORT IconUtility
+	{
+	public:
+		/**
+		 * Updates icons in the provided executable. Only icons that already exist in the executable can be updated, no new
+		 * icons can be inserted. Icons must be square.
+		 *
+		 * @param[in]	filePath	Path to the executable.
+		 * @param[in]	icons   	Pixels of images to replace. Each entry maps an icon width (and height, since they're 
+		 *							square) to its pixels.
+		 */
+		static void updateIconExe(const Path& filePath, const Map<UINT32, PixelDataPtr>& icons);
+
+	private:
+		/**
+		 * Updates data of an existing icon with new pixels.
+		 *
+		 * @param[in] 	iconData	Existing icon bytes, in Windows ICO format.
+		 * @param[in]	icons		Pixels of images to replace. Each entry maps an icon width (and height, since they're
+		 *							square) to its pixels.
+		 */
+		static void updateIconData(UINT8* iconData, const Map<UINT32, PixelDataPtr>& icons);
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 32 - 24
BansheeCore/Include/BsImportOptions.h

@@ -1,25 +1,33 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsIReflectable.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Base class for creating import options from. Import options
-	 *			are specific for each importer and control how is data imported.
-	 */
-	class BS_CORE_EXPORT ImportOptions : public IReflectable
-	{
-	public:
-		virtual ~ImportOptions() {}
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class ImportOptionsRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Importer
+	 *  @{
+	 */
+
+	/** 
+	 * Base class for creating import options from. Import options are specific for each importer and control how is data 
+	 * imported.
+	 */
+	class BS_CORE_EXPORT ImportOptions : public IReflectable
+	{
+	public:
+		virtual ~ImportOptions() {}
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class ImportOptionsRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 40 - 31
BansheeCore/Include/BsImportOptionsRTTI.h

@@ -1,32 +1,41 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsImportOptions.h"
-#include "BsRTTIType.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT ImportOptionsRTTI : public RTTIType<ImportOptions, IReflectable, ImportOptionsRTTI>
-	{
-	public:
-		ImportOptionsRTTI()
-		{
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "ImportOptions";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_ImportOptions;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return bs_shared_ptr<ImportOptions, PoolAlloc>();
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsImportOptions.h"
+#include "BsRTTIType.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT ImportOptionsRTTI : public RTTIType<ImportOptions, IReflectable, ImportOptionsRTTI>
+	{
+	public:
+		ImportOptionsRTTI()
+		{ }
+
+		const String& getRTTIName() override
+		{
+			static String name = "ImportOptions";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_ImportOptions;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<ImportOptions>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 110 - 97
BansheeCore/Include/BsImporter.h

@@ -1,98 +1,111 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Module responsible for importing various asset types and converting
-	 * 			them to types usable by the engine.
-	 */
-	class BS_CORE_EXPORT Importer : public Module<Importer>
-	{
-	public:
-		Importer(); 
-		~Importer(); 
-
-		/**
-		 * @brief	Imports a resource at the specified location, and returns the loaded data.
-		 *
-		 * @param	inputFilePath	Pathname of the input file.
-		 * @param	importOptions	(optional) Options for controlling the import. Caller must
-		 *							ensure import options actually match the type of the importer used
-		 *							for the file type.
-		 *
-		 * @see		createImportOptions
-		 */
-		HResource import(const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr);
-
-		/**
-		 * @copydoc import
-		 */
-		template <class T>
-		ResourceHandle<T> import(const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr)
-		{
-			return static_resource_cast<T>(import(inputFilePath, importOptions));
-		}
-
-		/**
-		 * @brief	Imports a resource and replaces the contents of the provided existing resource with new imported data.
-		 *
-		 * @param	inputFilePath	Pathname of the input file.
-		 * @param	importOptions	(optional) Options for controlling the import. Caller must
-		 *							ensure import options actually match the type of the importer used
-		 *							for the file type. 
-		 *
-		 * @see		createImportOptions
-		 */
-		void reimport(HResource& existingResource, const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr);
-
-		/**
-		 * @brief	Automatically detects the importer needed for the provided file and returns valid type of
-		 * 			import options for that importer.
-		 *
-		 * @param	inputFilePath	Pathname of the input file.
-		 *
-		 * @return	The new import options.
-		 * 			
-		 * @note	You will need to type cast the importer options to a valid type,
-		 * 			taking into consideration exact importer you expect to be used for this file type.
-		 * 			If you don't use a proper import options type, an exception will be thrown during import.
-		 * 			
-		 *			nullptr is returned if the file path is not valid, or if a valid importer cannot be found for
-		 *			the specified file.
-		 */
-		ImportOptionsPtr createImportOptions(const Path& inputFilePath);
-
-		/**
-		 * @brief	Checks if we can import a file with the specified extension.
-		 *
-		 * @param	extension	The extension without the leading dot.
-		 */
-		bool supportsFileType(const WString& extension) const;
-
-		/**
-		 * @brief	Checks if we can import a file with the specified magic number.
-		 *
-		 * @param	magicNumber 	The buffer containing the magic number.
-		 * @param	magicNumSize	Size of the magic number buffer.
-		 */
-		bool supportsFileType(const UINT8* magicNumber, UINT32 magicNumSize) const;
-
-		/**
-		 * @brief	Adds a new asset importer for the specified file extension. If an asset importer for that extension
-		 * 			already exists, it is removed and replaced with the current one.
-		 * 			
-		 * @note	Internal method. This method should only be called by asset importers themselves on startup.
-		 *
-		 * @param [in]	importer	The importer that is able to handle files with the specified extension. nullptr if you
-		 * 							want to remove an asset importer for the extension.
-		 */
-		void _registerAssetImporter(SpecificImporter* importer);
-	private:
-		Vector<SpecificImporter*> mAssetImporters;
-
-		SpecificImporter* getImporterForFile(const Path& inputFilePath) const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Importer
+	 *  @{
+	 */
+
+	/** Module responsible for importing various asset types and converting them to types usable by the engine. */
+	class BS_CORE_EXPORT Importer : public Module<Importer>
+	{
+	public:
+		Importer(); 
+		~Importer(); 
+
+		/**
+		 * Imports a resource at the specified location, and returns the loaded data.
+		 *
+		 * @param[in]	inputFilePath	Pathname of the input file.
+		 * @param[in]	importOptions	(optional) Options for controlling the import. Caller must ensure import options 
+		 *								actually match the type of the importer used for the file type.
+		 *
+		 * @see		createImportOptions
+		 */
+		HResource import(const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr);
+
+		/** @copydoc import */
+		template <class T>
+		ResourceHandle<T> import(const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr)
+		{
+			return static_resource_cast<T>(import(inputFilePath, importOptions));
+		}
+
+		/**
+		 * Imports a resource and replaces the contents of the provided existing resource with new imported data.
+		 *
+		 * @param[in]	inputFilePath	Pathname of the input file.
+		 * @param[in]	importOptions	(optional) Options for controlling the import. Caller must ensure import options 
+		 *								actually match the type of the importer used for the file type. 
+		 *
+		 * @see		createImportOptions
+		 */
+		void reimport(HResource& existingResource, const Path& inputFilePath, ConstImportOptionsPtr importOptions = nullptr);
+
+		/**
+		 * Automatically detects the importer needed for the provided file and returns valid type of import options for 
+		 * that importer.
+		 *
+		 * @param[in]	inputFilePath	Pathname of the input file.
+		 *
+		 * @return						The new import options. Null is returned if the file path is not valid, or if a 
+		 *								valid importer cannot be found for the specified file.
+		 * 			
+		 * @note	
+		 * You will need to type cast the importer options to a valid type, taking into consideration exact importer you 
+		 * expect to be used for this file type. If you don't use a proper import options type, an exception will be thrown 
+		 * during import.
+		 */
+		ImportOptionsPtr createImportOptions(const Path& inputFilePath);
+
+		/** @copydoc createImportOptions */
+		template<class T>
+		SPtr<T> createImportOptions(const Path& inputFilePath)
+		{
+			return std::static_pointer_cast<T>(createImportOptions(inputFilePath));
+		}
+
+		/**
+		 * Checks if we can import a file with the specified extension.
+		 *
+		 * @param[in]	extension	The extension without the leading dot.
+		 */
+		bool supportsFileType(const WString& extension) const;
+
+		/**
+		 * Checks if we can import a file with the specified magic number.
+		 *
+		 * @param[in]	magicNumber 	The buffer containing the magic number.
+		 * @param[in]	magicNumSize	Size of the magic number buffer.
+		 */
+		bool supportsFileType(const UINT8* magicNumber, UINT32 magicNumSize) const;
+
+		/**
+		 * Adds a new asset importer for the specified file extension. If an asset importer for that extension already 
+		 * exists, it is removed and replaced with the current one.
+		 *
+		 *
+		 * @param [in]	importer	The importer that is able to handle files with the specified extension. nullptr if you
+		 * 							want to remove an asset importer for the extension.
+		 *
+		 * @note	Internal method. 
+		 * @note	This method should only be called by asset importers themselves on startup. Importer takes ownership
+		 *			of the provided pointer and will release it. Assumes it is allocated using the general allocator.
+		 */
+		void _registerAssetImporter(SpecificImporter* importer);
+	private:
+		Vector<SpecificImporter*> mAssetImporters;
+
+		SpecificImporter* getImporterForFile(const Path& inputFilePath) const;
+	};
+
+	/** Provides easier access to Importer. */
+	BS_CORE_EXPORT Importer& gImporter();
+
+	/** @} */
 }

+ 93 - 48
BansheeCore/Include/BsIndexBuffer.h

@@ -1,49 +1,94 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsHardwareBuffer.h"
-#include "BsCoreObject.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Hardware buffer that hold indices that reference vertices in a vertex buffer.
-	 */
-    class BS_CORE_EXPORT IndexBuffer : public HardwareBuffer, public CoreObject
-    {
-	public:
-		/**
-		 * @brief	Type of the indices used, used for determining size.
-		 */
-		enum IndexType 
-		{
-			IT_16BIT,
-			IT_32BIT
-		};
-
-		~IndexBuffer();
-
-		/**
-		 * @brief	Returns the type of indices stored.
-		 */
-		IndexType getType() const { return mIndexType; }
-
-		/**
-		 * @brief	Returns the number of indices this buffer can hold.
-		 */
-		UINT32 getNumIndices() const { return mNumIndexes; }
-
-		/**
-		 * @brief	Returns the size of a single index in bytes.
-		 */
-		UINT32 getIndexSize() const { return mIndexSize; }
-
-	protected:
-		IndexBuffer(IndexType idxType, UINT32 numIndexes, GpuBufferUsage usage, bool useSystemMemory);
-
-	protected:
-		IndexType mIndexType;
-		UINT32 mNumIndexes;
-		UINT32 mIndexSize;
-    };
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsHardwareBuffer.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**	Type of the indices used, used for determining size. */
+	enum IndexType 
+	{
+		IT_16BIT,
+		IT_32BIT
+	};
+
+	/**	Contains information about an index buffer. */
+	class BS_CORE_EXPORT IndexBufferProperties
+	{
+	public:
+		IndexBufferProperties(IndexType idxType, UINT32 numIndexes);
+
+		/**	Returns the type of indices stored. */
+		IndexType getType() const { return mIndexType; }
+
+		/**	Returns the number of indices this buffer can hold. */
+		UINT32 getNumIndices() const { return mNumIndexes; }
+
+		/**	Returns the size of a single index in bytes. */
+		UINT32 getIndexSize() const { return mIndexSize; }
+
+	protected:
+		friend class IndexBuffer;
+		friend class IndexBufferCore;
+
+		IndexType mIndexType;
+		UINT32 mNumIndexes;
+		UINT32 mIndexSize;
+	};
+
+	/** @cond INTERNAL */
+
+	/** Core thread specific implementation of an IndexBuffer. */
+	class BS_CORE_EXPORT IndexBufferCore : public CoreObjectCore, public HardwareBuffer
+	{
+	public:
+		IndexBufferCore(IndexType idxType, UINT32 numIndexes, GpuBufferUsage usage);
+		virtual ~IndexBufferCore() { }
+
+		/**	Returns information about the index buffer. */
+		const IndexBufferProperties& getProperties() const { return mProperties; }
+
+	protected:
+		IndexBufferProperties mProperties;
+	};
+
+	/** @endcond */
+
+	/** Hardware buffer that hold indices that reference vertices in a vertex buffer. */
+    class BS_CORE_EXPORT IndexBuffer : public CoreObject
+    {
+	public:
+		virtual ~IndexBuffer() { }
+
+		/** Returns information about the index buffer. */
+		const IndexBufferProperties& getProperties() const { return mProperties; }
+
+		/**
+		 * Retrieves a core implementation of an index buffer usable only from the core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		SPtr<IndexBufferCore> getCore() const;
+
+		/** @copydoc HardwareBufferManager::createIndexBuffer */
+		static IndexBufferPtr create(IndexType itype, UINT32 numIndexes, GpuBufferUsage usage);
+
+	protected:
+		friend class HardwareBufferManager;
+
+		IndexBuffer(IndexType idxType, UINT32 numIndexes, GpuBufferUsage usage);
+
+		/** @copydoc CoreObject::createCore */
+		virtual SPtr<CoreObjectCore> createCore() const;
+
+		IndexBufferProperties mProperties;
+		GpuBufferUsage mUsage;
+    };
 }

+ 246 - 207
BansheeCore/Include/BsInput.h

@@ -1,208 +1,247 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsRectI.h"
-#include "BsOSInputHandler.h"
-#include "BsRawInputHandler.h"
-#include "BsInputFwd.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Primary module used for dealing with input. Allows you to receieve 
-	 *			and query raw or OS input for mouse/keyboard/gamepad.
-	 *
-	 *			All inputs are received through an input handler, which can be overriden to 
-	 *			provide custom input functionality.
-	 */
-	class BS_CORE_EXPORT Input : public Module<Input>
-	{
-		/**
-		 * @brief	Possible button states
-		 */
-		enum class ButtonState
-		{
-			Off, /**< Button is not being pressed. */
-			On, /**< Button is being pressed. */
-			ToggledOn, /**< Button has been pressed this frame. */
-			ToggledOff /**< Button has been released this frame. */
-		};
-
-		/**
-		 * @brief	Contains axis and device data per device
-		 */
-		struct DeviceData
-		{
-			DeviceData();
-
-			Vector<RawAxisState> axes;
-			ButtonState keyStates[BC_Count];
-		};
-
-	public:
-		Input();
-		~Input();
-
-		/**
-		 * @brief	Triggered whenever a button is first pressed.
-		 */
-		Event<void(const ButtonEvent&)> onButtonDown;
-
-		/**
-		 * @brief	Triggered whenever a button is first released.
-		 */
-		Event<void(const ButtonEvent&)> onButtonUp;
-
-		/**
-		 * @brief	Triggered whenever user inputs a text character. 
-		 */
-		Event<void(const TextInputEvent&)> onCharInput;
-
-		/**
-		 * @brief	Triggers when some pointing device (mouse cursor, touch) moves.
-		 */
-		Event<void(const PointerEvent&)> onPointerMoved;
-
-		/**
-		 * @brief	Triggers when some pointing device (mouse cursor, touch) button is pressed.
-		 */
-		Event<void(const PointerEvent&)> onPointerPressed;
-
-		/**
-		 * @brief	Triggers when some pointing device (mouse cursor, touch) button is released.
-		 */
-		Event<void(const PointerEvent&)> onPointerReleased;
-
-		/**
-		 * @brief	Triggers when some pointing device (mouse cursor, touch) button is double clicked.
-		 */
-		Event<void(const PointerEvent&)> onPointerDoubleClick;
-
-		// TODO Low priority: Remove this, I can emulate it using virtual input
-		/**
-		 * @brief	Triggers on special input commands.
-		 */
-		Event<void(InputCommandType)> onInputCommand;
-
-		/**
-		 * @brief	Registers a new input handler. Replaces any previous input handler.
-		 *
-		 * @note	Internal method.
-		 */
-		void _registerRawInputHandler(std::shared_ptr<RawInputHandler> inputHandler);
-
-		/**
-		 * @brief	Called every frame. Dispatches any callbacks resulting from input by the user.
-		 *
-		 * @note	Internal method.
-		 */
-		void _update();
-
-		/**
-		 * @brief	Returns value of the specified input axis in range [-1.0, 1.0].
-		 *
-		 * @param	type		Type of axis to query. Usually a type from InputAxis but can be a custom value.
-		 * @param	deviceIdx	Index of the device in case more than one is hooked up (0 - primary).
-		 */
-		float getAxisValue(UINT32 type, UINT32 deviceIdx = 0) const;
-
-		/**
-		 * @brief	Query if the provided button is currently being held (this frame or previous frames).
-		 *
-		 * @param	keyCode		Code of the button to query.
-		 * @param	deviceIdx	Device to query the button on (0 - primary).
-		 */
-		bool isButtonHeld(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
-
-		/**
-		 * @brief	Query if the provided button is currently being released (one true for one frame).
-		 *
-		 * @param	keyCode		Code of the button to query.
-		 * @param	deviceIdx	Device to query the button on (0 - primary).
-		 */
-		bool isButtonUp(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
-
-		/**
-		 * @brief	Query if the provided button is currently being pressed (one true for one frame).
-		 *
-		 * @param	keyCode		Code of the button to query.
-		 * @param	deviceIdx	Device to query the button on (0 - primary).
-		 */
-		bool isButtonDown(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
-
-		/**
-		 * @brief	Enables or disables mouse smoothing. Smoothing makes the changes to
-		 *			mouse axes more gradual.
-		 */
-		void setMouseSmoothing(bool enabled);
-
-	private:
-		/**
-		 * @brief	Triggered by input handler when a button is pressed.
-		 */
-		void buttonDown(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
-
-		/**
-		 * @brief	Triggered by input handler when a button is released.
-		 */
-		void buttonUp(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
-
-		/**
-		 * @brief	Triggered by input handler when a single character is input.
-		 */
-		void charInput(UINT32 chr);
-
-		/**
-		 * @brief	Triggered by input handler when a mouse/joystick axis is moved.
-		 */
-		void axisMoved(UINT32 deviceIdx, const RawAxisState& state, UINT32 axis);
-
-		/**
-		 * @brief	Cursor movement as OS reports it. Used for screen cursor position.
-		 */
-		void cursorMoved(const PointerEvent& event);
-
-		/**
-		 * @brief	Cursor button presses as OS reports it. 
-		 */
-		void cursorPressed(const PointerEvent& event);
-
-		/**
-		 * @brief	Cursor button releases as OS reports it.
-		 */
-		void cursorReleased(const PointerEvent& event);
-		
-		/**
-		 * @brief	Cursor button releases as OS reports it.
-		 */
-		void cursorDoubleClick(const PointerEvent& event);
-
-		/**
-		 * @brief	Input commands as OS reports them.
-		 */
-		void inputCommandEntered(InputCommandType commandType);
-
-		/**
-		 * @brief	Called when window in focus changes, as reported by the OS.
-		 */
-		void inputWindowChanged(RenderWindow& win);
-
-	private:
-		std::shared_ptr<RawInputHandler> mRawInputHandler;
-		std::shared_ptr<OSInputHandler> mOSInputHandler;
-
-		Vector<DeviceData> mDevices;
-
-		/************************************************************************/
-		/* 								STATICS		                      		*/
-		/************************************************************************/
-		static const int HISTORY_BUFFER_SIZE; // Size of buffer used for input smoothing
-		static const float WEIGHT_MODIFIER;
-	};
-
-	/**
-	 * @copydoc	Input
-	 */
-	BS_CORE_EXPORT Input& gInput();
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsOSInputHandler.h"
+#include "BsRawInputHandler.h"
+#include "BsInputFwd.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Input
+	 *  @{
+	 */
+
+	/**
+	 * Primary module used for dealing with input. Allows you to receieve and query raw or OS input for 
+	 * mouse/keyboard/gamepad.
+	 *
+	 * All inputs are received through an input handler, which can be overriden to provide custom input functionality.
+	 */
+	class BS_CORE_EXPORT Input : public Module<Input>
+	{
+		/** Possible button states. */
+		enum class ButtonState
+		{
+			Off, /**< Button is not being pressed. */
+			On, /**< Button is being pressed. */
+			ToggledOn, /**< Button has been pressed this frame. */
+			ToggledOff, /**< Button has been released this frame. */
+			ToggledOnOff, /**< Button has been pressed and released this frame. */
+		};
+
+		/** Contains axis and device data per device. */
+		struct DeviceData
+		{
+			DeviceData();
+
+			Vector<RawAxisState> axes;
+			ButtonState keyStates[BC_Count];
+		};
+
+		/**	Different types of possible input event callbacks. */
+		enum class EventType
+		{
+			ButtonUp, ButtonDown, PointerMoved, PointerUp, PointerDown, PointerDoubleClick, TextInput, Command
+		};
+
+		/**	Stores information about a queued input event that is to be triggered later. */
+		struct QueuedEvent
+		{
+			QueuedEvent(EventType type, UINT32 idx)
+				:type(type), idx(idx)
+			{ }
+
+			EventType type;
+			UINT32 idx;
+		};
+
+	public:
+		Input();
+		~Input();
+
+		/**
+		 * Returns value of the specified input axis. Normally in range [-1.0, 1.0] but can be outside the range for 
+		 * devices with unbound axes (e.g. mouse).
+		 *
+		 * @param[in]	type		Type of axis to query. Usually a type from InputAxis but can be a custom value.
+		 * @param[in]	deviceIdx	Index of the device in case more than one is hooked up (0 - primary).
+		 */
+		float getAxisValue(UINT32 type, UINT32 deviceIdx = 0) const;
+
+		/**
+		 * Query if the provided button is currently being held (this frame or previous frames).
+		 *
+		 * @param[in]	keyCode		Code of the button to query.
+		 * @param[in]	deviceIdx	Device to query the button on (0 - primary).
+		 */
+		bool isButtonHeld(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
+
+		/**
+		 * Query if the provided button is currently being released (only true for one frame).
+		 *
+		 * @param[in]	keyCode		Code of the button to query.
+		 * @param[in]	deviceIdx	Device to query the button on (0 - primary).
+		 */
+		bool isButtonUp(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
+
+		/**
+		 * Query if the provided button is currently being pressed (only true for one frame).
+		 *
+		 * @param[in]	keyCode		Code of the button to query.
+		 * @param[in]	deviceIdx	Device to query the button on (0 - primary).
+		 */
+		bool isButtonDown(ButtonCode keyCode, UINT32 deviceIdx = 0) const;
+
+		/** Returns position of the pointer (e.g. mouse cursor) relative to the screen. */
+		Vector2I getPointerPosition() const;
+
+		/** Returns difference between last and current pointer position. */
+		Vector2I getPointerDelta() const { return mPointerDelta; }
+
+		/**
+		 * Query if the provided pointer button is currently being held (this frame or previous frames).
+		 *
+		 * @param[in]	pointerButton		Code of the button to query.
+		 */
+		bool isPointerButtonHeld(PointerEventButton pointerButton) const;
+
+		/**
+		 * Query if the provided pointer button is currently being released (only true for one frame).
+		 *
+		 * @param[in]	pointerButton		Code of the button to query.
+		 */
+		bool isPointerButtonUp(PointerEventButton pointerButton) const;
+
+		/**
+		 * Query if the provided pointer button is currently being pressed (only true for one frame).
+		 *
+		 * @param[in]	pointerButton		Code of the button to query.
+		 */
+		bool isPointerButtonDown(PointerEventButton pointerButton) const;
+
+		/** Query has the left pointer button has been double-clicked this frame. */
+		bool isPointerDoubleClicked() const;
+
+		/** Enables or disables mouse smoothing. Smoothing makes the changes to mouse axes more gradual. */
+		void setMouseSmoothing(bool enabled);
+
+		/** @cond INTERNAL */
+
+		/**
+		 * Registers a new input handler. Replaces any previous input handler.
+		 *
+		 * @note	Internal method.
+		 */
+		void _registerRawInputHandler(std::shared_ptr<RawInputHandler> inputHandler);
+
+		/**
+		 * Called every frame. Detects button state changes and prepares callback events to trigger via a call to 
+		 * _triggerCallbacks().
+		 *
+		 * @note	Internal method.
+		 */
+		void _update();
+
+		/**
+		 * Triggers any queued input event callbacks.
+		 * 
+		 * @note	Internal method.
+		 */
+		void _triggerCallbacks();
+
+		/** @endcond */
+
+		/** Triggered whenever a button is first pressed. */
+		Event<void(const ButtonEvent&)> onButtonDown;
+
+		/**	Triggered whenever a button is first released. */
+		Event<void(const ButtonEvent&)> onButtonUp;
+
+		/**	Triggered whenever user inputs a text character. */
+		Event<void(const TextInputEvent&)> onCharInput;
+
+		/**	Triggers when some pointing device (mouse cursor, touch) moves. */
+		Event<void(const PointerEvent&)> onPointerMoved;
+
+		/**	Triggers when some pointing device (mouse cursor, touch) button is pressed. */
+		Event<void(const PointerEvent&)> onPointerPressed;
+
+		/**	Triggers when some pointing device (mouse cursor, touch) button is released. */
+		Event<void(const PointerEvent&)> onPointerReleased;
+
+		/**	Triggers when some pointing device (mouse cursor, touch) button is double clicked. */
+		Event<void(const PointerEvent&)> onPointerDoubleClick;
+
+		// TODO Low priority: Remove this, I can emulate it using virtual input
+		/**	Triggers on special input commands. */
+		Event<void(InputCommandType)> onInputCommand;
+
+	private:
+		/**	Triggered by input handler when a button is pressed. */
+		void buttonDown(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
+
+		/**	Triggered by input handler when a button is released. */
+		void buttonUp(UINT32 deviceIdx, ButtonCode code, UINT64 timestamp);
+
+		/**	Triggered by input handler when a single character is input. */
+		void charInput(UINT32 chr);
+
+		/**	Triggered by input handler when a mouse/joystick axis is moved. */
+		void axisMoved(UINT32 deviceIdx, const RawAxisState& state, UINT32 axis);
+
+		/**	Cursor movement as OS reports it. Used for screen cursor position. */
+		void cursorMoved(const PointerEvent& event);
+
+		/**	Cursor button presses as OS reports it. */
+		void cursorPressed(const PointerEvent& event);
+
+		/**	Cursor button releases as OS reports it. */
+		void cursorReleased(const PointerEvent& event);
+		
+		/**	Cursor button releases as OS reports it. */
+		void cursorDoubleClick(const PointerEvent& event);
+
+		/** Input commands as OS reports them. */
+		void inputCommandEntered(InputCommandType commandType);
+
+		/** Called when window in focus changes, as reported by the OS. */
+		void inputWindowChanged(RenderWindow& win);
+
+	private:
+		std::shared_ptr<RawInputHandler> mRawInputHandler;
+		std::shared_ptr<OSInputHandler> mOSInputHandler;
+
+		Vector<DeviceData> mDevices;
+		Vector2I mPointerPosition;
+		Vector2I mPointerDelta;
+		ButtonState mPointerButtonStates[3];
+		bool mPointerDoubleClicked;
+		bool mLastPositionSet;
+
+		Vector<QueuedEvent> mQueuedEvents;
+
+		Vector<TextInputEvent> mTextInputEvents;
+		Vector<InputCommandType> mCommandEvents;
+		Vector<PointerEvent> mPointerDoubleClickEvents;
+		Vector<PointerEvent> mPointerReleasedEvents;
+		Vector<PointerEvent> mPointerPressedEvents;
+		Vector<PointerEvent> mPointerMovedEvents;
+
+		Vector<ButtonEvent> mButtonDownEvents;
+		Vector<ButtonEvent> mButtonUpEvents;
+
+		/************************************************************************/
+		/* 								STATICS		                      		*/
+		/************************************************************************/
+		static const int HISTORY_BUFFER_SIZE; // Size of buffer used for input smoothing
+		static const float WEIGHT_MODIFIER;
+	};
+
+	/** Provides easier access to Input. */
+	BS_CORE_EXPORT Input& gInput();
+
+	/** @} */
 }

+ 411 - 407
BansheeCore/Include/BsInputFwd.h

@@ -1,408 +1,412 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsVector2I.h"
-
-namespace BansheeEngine
-{
-	// Contains all possible keys, including keyboard scan codes, mouse buttons and gamepad buttons
-	// Note: These KeyCodes are only keyboard scan codes. This means that exact scan code identifier might 
-	// not correspond to that exact character on users keyboard, depending on users input locale. 
-	// Only for US locale will these scan code names will match the actual keyboard input. Think of the US key
-	// code names as only a convenience for more easily identifying which location on the keyboard a scan code represents.
-	//
-	// When storing these sequentially make sure to only reference the low order 2 bytes. Two high order bytes are used for various flags.
-	enum ButtonCode
-	{
-		BC_UNASSIGNED  = 0x00,
-		BC_ESCAPE      = 0x01,
-		BC_1           = 0x02,
-		BC_2           = 0x03,
-		BC_3           = 0x04,
-		BC_4           = 0x05,
-		BC_5           = 0x06,
-		BC_6           = 0x07,
-		BC_7           = 0x08,
-		BC_8           = 0x09,
-		BC_9           = 0x0A,
-		BC_0           = 0x0B,
-		BC_MINUS       = 0x0C,    // - on main keyboard
-		BC_EQUALS      = 0x0D,
-		BC_BACK        = 0x0E,    // backspace
-		BC_TAB         = 0x0F,
-		BC_Q           = 0x10,
-		BC_W           = 0x11,
-		BC_E           = 0x12,
-		BC_R           = 0x13,
-		BC_T           = 0x14,
-		BC_Y           = 0x15,
-		BC_U           = 0x16,
-		BC_I           = 0x17,
-		BC_O           = 0x18,
-		BC_P           = 0x19,
-		BC_LBRACKET    = 0x1A,
-		BC_RBRACKET    = 0x1B,
-		BC_RETURN      = 0x1C,    // Enter on main keyboard
-		BC_LCONTROL    = 0x1D,
-		BC_A           = 0x1E,
-		BC_S           = 0x1F,
-		BC_D           = 0x20,
-		BC_F           = 0x21,
-		BC_G           = 0x22,
-		BC_H           = 0x23,
-		BC_J           = 0x24,
-		BC_K           = 0x25,
-		BC_L           = 0x26,
-		BC_SEMICOLON   = 0x27,
-		BC_APOSTROPHE  = 0x28,
-		BC_GRAVE       = 0x29,    // accent
-		BC_LSHIFT      = 0x2A,
-		BC_BACKSLASH   = 0x2B,
-		BC_Z           = 0x2C,
-		BC_X           = 0x2D,
-		BC_C           = 0x2E,
-		BC_V           = 0x2F,
-		BC_B           = 0x30,
-		BC_N           = 0x31,
-		BC_M           = 0x32,
-		BC_COMMA       = 0x33,
-		BC_PERIOD      = 0x34,    // . on main keyboard
-		BC_SLASH       = 0x35,    // / on main keyboard
-		BC_RSHIFT      = 0x36,
-		BC_MULTIPLY    = 0x37,    // * on numeric keypad
-		BC_LMENU       = 0x38,    // left Alt
-		BC_SPACE       = 0x39,
-		BC_CAPITAL     = 0x3A,
-		BC_F1          = 0x3B,
-		BC_F2          = 0x3C,
-		BC_F3          = 0x3D,
-		BC_F4          = 0x3E,
-		BC_F5          = 0x3F,
-		BC_F6          = 0x40,
-		BC_F7          = 0x41,
-		BC_F8          = 0x42,
-		BC_F9          = 0x43,
-		BC_F10         = 0x44,
-		BC_NUMLOCK     = 0x45,
-		BC_SCROLL      = 0x46,    // Scroll Lock
-		BC_NUMPAD7     = 0x47,
-		BC_NUMPAD8     = 0x48,
-		BC_NUMPAD9     = 0x49,
-		BC_SUBTRACT    = 0x4A,    // - on numeric keypad
-		BC_NUMPAD4     = 0x4B,
-		BC_NUMPAD5     = 0x4C,
-		BC_NUMPAD6     = 0x4D,
-		BC_ADD         = 0x4E,    // + on numeric keypad
-		BC_NUMPAD1     = 0x4F,
-		BC_NUMPAD2     = 0x50,
-		BC_NUMPAD3     = 0x51,
-		BC_NUMPAD0     = 0x52,
-		BC_DECIMAL     = 0x53,    // . on numeric keypad
-		BC_OEM_102     = 0x56,    // < > | on UK/Germany keyboards
-		BC_F11         = 0x57,
-		BC_F12         = 0x58,
-		BC_F13         = 0x64,    //                     (NEC PC98)
-		BC_F14         = 0x65,    //                     (NEC PC98)
-		BC_F15         = 0x66,    //                     (NEC PC98)
-		BC_KANA        = 0x70,    // (Japanese keyboard)
-		BC_ABNT_C1     = 0x73,    // / ? on Portugese (Brazilian) keyboards
-		BC_CONVERT     = 0x79,    // (Japanese keyboard)
-		BC_NOCONVERT   = 0x7B,    // (Japanese keyboard)
-		BC_YEN         = 0x7D,    // (Japanese keyboard)
-		BC_ABNT_C2     = 0x7E,    // Numpad . on Portugese (Brazilian) keyboards
-		BC_NUMPADEQUALS= 0x8D,    // = on numeric keypad (NEC PC98)
-		BC_PREVTRACK   = 0x90,    // Previous Track (BC_CIRCUMFLEX on Japanese keyboard)
-		BC_AT          = 0x91,    //                     (NEC PC98)
-		BC_COLON       = 0x92,    //                     (NEC PC98)
-		BC_UNDERLINE   = 0x93,    //                     (NEC PC98)
-		BC_KANJI       = 0x94,    // (Japanese keyboard)
-		BC_STOP        = 0x95,    //                     (NEC PC98)
-		BC_AX          = 0x96,    //                     (Japan AX)
-		BC_UNLABELED   = 0x97,    //                        (J3100)
-		BC_NEXTTRACK   = 0x99,    // Next Track
-		BC_NUMPADENTER = 0x9C,    // Enter on numeric keypad
-		BC_RCONTROL    = 0x9D,
-		BC_MUTE        = 0xA0,    // Mute
-		BC_CALCULATOR  = 0xA1,    // Calculator
-		BC_PLAYPAUSE   = 0xA2,    // Play / Pause
-		BC_MEDIASTOP   = 0xA4,    // Media Stop
-		BC_VOLUMEDOWN  = 0xAE,    // Volume -
-		BC_VOLUMEUP    = 0xB0,    // Volume +
-		BC_WEBHOME     = 0xB2,    // Web home
-		BC_NUMPADCOMMA = 0xB3,    // , on numeric keypad (NEC PC98)
-		BC_DIVIDE      = 0xB5,    // / on numeric keypad
-		BC_SYSRQ       = 0xB7,
-		BC_RMENU       = 0xB8,    // right Alt
-		BC_PAUSE       = 0xC5,    // Pause
-		BC_HOME        = 0xC7,    // Home on arrow keypad
-		BC_UP          = 0xC8,    // UpArrow on arrow keypad
-		BC_PGUP        = 0xC9,    // PgUp on arrow keypad
-		BC_LEFT        = 0xCB,    // LeftArrow on arrow keypad
-		BC_RIGHT       = 0xCD,    // RightArrow on arrow keypad
-		BC_END         = 0xCF,    // End on arrow keypad
-		BC_DOWN        = 0xD0,    // DownArrow on arrow keypad
-		BC_PGDOWN      = 0xD1,    // PgDn on arrow keypad
-		BC_INSERT      = 0xD2,    // Insert on arrow keypad
-		BC_DELETE      = 0xD3,    // Delete on arrow keypad
-		BC_LWIN        = 0xDB,    // Left Windows key
-		BC_RWIN        = 0xDC,    // Right Windows key
-		BC_APPS        = 0xDD,    // AppMenu key
-		BC_POWER       = 0xDE,    // System Power
-		BC_SLEEP       = 0xDF,    // System Sleep
-		BC_WAKE        = 0xE3,    // System Wake
-		BC_WEBSEARCH   = 0xE5,    // Web Search
-		BC_WEBFAVORITES= 0xE6,    // Web Favorites
-		BC_WEBREFRESH  = 0xE7,    // Web Refresh
-		BC_WEBSTOP     = 0xE8,    // Web Stop
-		BC_WEBFORWARD  = 0xE9,    // Web Forward
-		BC_WEBBACK     = 0xEA,    // Web Back
-		BC_MYCOMPUTER  = 0xEB,    // My Computer
-		BC_MAIL        = 0xEC,    // Mail
-		BC_MEDIASELECT = 0xED,     // Media Select
-		BC_MOUSE_LEFT = 0x800000EE, // Mouse buttons - Most important bit signifies this key is a mouse button
-		BC_MOUSE_RIGHT = 0x800000EF,
-		BC_MOUSE_MIDDLE = 0x800000F0,
-		BC_MOUSE_BTN4 = 0x800000F1,
-		BC_MOUSE_BTN5 = 0x800000F2,
-		BC_MOUSE_BTN6 = 0x800000F3,
-		BC_MOUSE_BTN7 = 0x800000F4,
-		BC_MOUSE_BTN8 = 0x800000F5,
-		BC_MOUSE_BTN9 = 0x800000F6,
-		BC_MOUSE_BTN10 = 0x800000F7,
-		BC_MOUSE_BTN11 = 0x800000F8,
-		BC_MOUSE_BTN12 = 0x800000F9,
-		BC_MOUSE_BTN13 = 0x800000FA,
-		BC_MOUSE_BTN14 = 0x800000FB,
-		BC_MOUSE_BTN15 = 0x800000FC,
-		BC_MOUSE_BTN16 = 0x800000FD,
-		BC_MOUSE_BTN17 = 0x800000FE,
-		BC_MOUSE_BTN18 = 0x800000FF,
-		BC_MOUSE_BTN19 = 0x80000101,
-		BC_MOUSE_BTN20 = 0x80000102,
-		BC_MOUSE_BTN21 = 0x80000103,
-		BC_MOUSE_BTN22 = 0x80000104,
-		BC_MOUSE_BTN23 = 0x80000105,
-		BC_MOUSE_BTN24 = 0x80000106,
-		BC_MOUSE_BTN25 = 0x80000107,
-		BC_MOUSE_BTN26 = 0x80000108,
-		BC_MOUSE_BTN27 = 0x80000109,
-		BC_MOUSE_BTN28 = 0x8000010A,
-		BC_MOUSE_BTN29 = 0x8000010B,
-		BC_MOUSE_BTN30 = 0x8000010C,
-		BC_MOUSE_BTN31 = 0x8000010D,
-		BC_MOUSE_BTN32 = 0x8000010E,
-		BC_GAMEPAD_A = 0x4000010F, // Joystick/Gamepad buttons- Second most important bit signifies key is a gamepad button
-		BC_GAMEPAD_B = 0x40000110, // Similar to keyboard names, these are for convenience named after Xbox controller buttons
-		BC_GAMEPAD_X = 0x40000111, // but if some other controller is connected you will need to learn yourself which of these
-		BC_GAMEPAD_Y = 0x40000112, // corresponds to which actual button on the controller.
-		BC_GAMEPAD_LB = 0x40000113,
-		BC_GAMEPAD_RB = 0x40000114,
-		BC_GAMEPAD_LS = 0x40000115,
-		BC_GAMEPAD_RS = 0x40000116,
-		BC_GAMEPAD_BACK = 0x40000117,
-		BC_GAMEPAD_START = 0x40000118,
-		BC_GAMEPAD_DPAD_LEFT = 0x40000119,
-		BC_GAMEPAD_DPAD_RIGHT = 0x4000011A,
-		BC_GAMEPAD_DPAD_UP = 0x4000011B,
-		BC_GAMEPAD_DPAD_DOWN = 0x4000011C,
-		BC_GAMEPAD_BTN1 = 0x4000011D,
-		BC_GAMEPAD_BTN2 = 0x4000011E,
-		BC_GAMEPAD_BTN3 = 0x4000011F,
-		BC_GAMEPAD_BTN4 = 0x40000120,
-		BC_GAMEPAD_BTN5 = 0x40000121,
-		BC_GAMEPAD_BTN6 = 0x40000122,
-		BC_GAMEPAD_BTN7 = 0x40000123,
-		BC_GAMEPAD_BTN8 = 0x40000124,
-		BC_GAMEPAD_BTN9 = 0x40000125,
-		BC_GAMEPAD_BTN10 = 0x40000126,
-		BC_GAMEPAD_BTN11 = 0x40000127,
-		BC_GAMEPAD_BTN12 = 0x40000128,
-		BC_GAMEPAD_BTN13 = 0x40000129,
-		BC_GAMEPAD_BTN14 = 0x4000012A,
-		BC_GAMEPAD_BTN15 = 0x4000012B,
-		BC_GAMEPAD_BTN16 = 0x4000012C,
-		BC_GAMEPAD_BTN17 = 0x4000012D,
-		BC_GAMEPAD_BTN18 = 0x4000012E,
-		BC_GAMEPAD_BTN19 = 0x4000012F,
-		BC_GAMEPAD_BTN20 = 0x40000130,
-		BC_Count = 304,
-		BC_NumKeys = 238, // IMPORTANT: Make sure to update these if you modify the values above
-		BC_NumMouse = 32,
-		BC_NumGamepad = 34,
-	};
-
-	/**
-	 * @brief	Structure containing information about a button input event.
-	 */
-	struct ButtonEvent
-	{
-	public:
-		ButtonEvent()
-			:mIsUsed(false)
-		{ }
-
-		ButtonCode buttonCode; /**< Button code this event is referring to. */
-		UINT64 timestamp; /**< Timestamp in ticks when the event happened. */
-		UINT32 deviceIdx; /**< Index of the device that the event happened on. */
-
-		/**
-		 * @brief	Query is the pressed button a keyboard button.
-		 */
-		bool isKeyboard() const { return (buttonCode & 0xC0000000) == 0; }
-
-		/**
-		 * @brief	Query is the pressed button a mouse button.
-		 */
-		bool isMouse() const { return (buttonCode & 0x80000000) != 0; }
-
-		/**
-		 * @brief	Query is the pressed button a gamepad button.
-		 */
-		bool isGamepad() const { return (buttonCode & 0x40000000) != 0; }
-
-		/**
-		 * @brief	Check if the event has been marked as used. Internally this means nothing
-		 *			but caller might choose to ignore an used event.
-		 */
-		bool isUsed() const { return mIsUsed; }
-
-		/**
-		 * @brief	Mark the event as used. Internally this means nothing
-		 *			but caller might choose to ignore an used event.
-		 */
-		void markAsUsed() const { mIsUsed = true; }
-	private:
-		mutable bool mIsUsed;
-	};
-
-	/**
-	 * @brief	Pointer buttons. Generally these correspond to mouse
-	 * 			buttons, but may be used in some form for touch input as well.
-	 */
-	enum class PointerEventButton
-	{
-		Left, Middle, Right, Count
-	};
-
-	/**
-	 * @brief	Type of pointer event.
-	 */
-	enum class PointerEventType
-	{
-		CursorMoved,
-		ButtonPressed,
-		ButtonReleased,
-		DoubleClick
-	};
-
-	/**
-	 * @brief	Event that gets sent out when user interacts with the screen in some way,
-	 * 			usually by moving the mouse cursor or using touch input.
-	 */
-	struct PointerEvent
-	{
-	public:
-		PointerEvent()
-			:mIsUsed(false), mouseWheelScrollAmount(0.0f), type(PointerEventType::CursorMoved),
-			shift(false), control(false), alt(false), button(PointerEventButton::Left)
-		{
-			buttonStates[0] = false;
-			buttonStates[1] = false;
-			buttonStates[2] = false;
-		}
-
-		Vector2I screenPos; /**< Screen position where the input event occurred. */
-		bool buttonStates[(UINT32)PointerEventButton::Count]; /**< States of the pointer buttons (e.g. mouse buttons). */
-		PointerEventButton button; /**< Button that triggered the pointer event. Might be irrelevant 
-										depending on event type. (e.g. move events don't correspond to a button. */
-		PointerEventType type; /**< Type of the pointer event. */
-
-		bool shift; /**< Is Shift button on the keyboard being held down. */
-		bool control; /**< Is Control button on the keyboard being held down. */
-		bool alt; /**< Is Alt button on the keyboard being held down. */
-
-		float mouseWheelScrollAmount; /**< If mouse wheel is being scrolled, what is the amount. Only relevant on move events. */
-
-		/**
-		 * @brief	Check if the event has been marked as used. Internally this means nothing
-		 *			but caller might choose to ignore an used event.
-		 */
-		bool isUsed() const { return mIsUsed; }
-
-		/**
-		 * @brief	Mark the event as used. Internally this means nothing
-		 *			but caller might choose to ignore an used event.
-		 */
-		void markAsUsed() const { mIsUsed = true; }
-
-	private:
-		mutable bool mIsUsed;
-	};
-
-	/**
-	 * @brief	Types of special input commands.
-	 */
-	enum class InputCommandType
-	{
-		CursorMoveLeft, CursorMoveRight, CursorMoveUp, CursorMoveDown, 
-		SelectLeft, SelectRight, SelectUp, SelectDown,
-		Escape, Delete, Backspace, Return
-	};
-
-	/**
-	 * @brief	Event that gets sent out when user inputs some text. These events may be preceeded by
-	 *			normal button events if user is typing on a keyboard. 
-	 */
-	struct TextInputEvent
-	{
-	public:
-		TextInputEvent()
-			:mIsUsed(false)
-		{ }
-
-		UINT32 textChar; /**< Character the user is inputting. */
-
-		/**
-		 * @brief	Check if the event has been marked as used. Internally this means nothing
-		 *			but caller might choose to ignore an used event.
-		 */
-		bool isUsed() const { return mIsUsed; }
-
-		/**
-		 * @brief	Mark the event as used. Internally this means nothing
-		 *			but caller might choose to ignore an used event.
-		 */
-		void markAsUsed() const { mIsUsed = true; }
-
-	private:
-		mutable bool mIsUsed;
-	};
-
-	/**
-	 * @brief	Types of input devices.
-	 */
-	enum class InputDevice
-	{
-		Keyboard,
-		Mouse,
-		Gamepad,
-		Count // Keep at end
-	};
-
-	/**
-	 * @brief	Common input axis types.
-	 */
-	enum class InputAxis
-	{
-		MouseX, /**< Mouse axis X. */
-		MouseY, /**< Mouse axis Y. */
-		MouseZ, /**< Mouse wheel/scroll axis. */
-		LeftStickX, /**< Gamepad left stick X */
-		LeftStickY, /**<  Gamepad left stick Y */
-		RightStickX, /**< Gamepad right stick X */
-		RightStickY, /**< Gamepad right stick Y */
-		LeftTrigger, /**< Gamepad left trigger */
-		RightTrigger, /**< Gamepad right trigger */
-		Count // Keep at end
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsVector2I.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Input
+	 *  @{
+	 */
+
+	/**
+	 * Contains all possible input buttons, including keyboard scan codes, mouse buttons and gamepad buttons.
+	 *
+	 * @note
+	 * These codes are only keyboard scan codes. This means that exact scan code identifier might not correspond to that 
+	 * exact character on users keyboard, depending on users input locale. Only for US locale will these scan code names 
+	 * will match the actual keyboard input. Think of the US key code names as only a convenience for more easily 
+	 * identifying which location on the keyboard a scan code represents.
+	 * @note
+	 * When storing these sequentially make sure to only reference the low order 2 bytes. Two high order bytes are used for 
+	 * various flags.
+	 */
+	enum ButtonCode
+	{
+		BC_UNASSIGNED  = 0x00,
+		BC_ESCAPE      = 0x01,
+		BC_1           = 0x02,
+		BC_2           = 0x03,
+		BC_3           = 0x04,
+		BC_4           = 0x05,
+		BC_5           = 0x06,
+		BC_6           = 0x07,
+		BC_7           = 0x08,
+		BC_8           = 0x09,
+		BC_9           = 0x0A,
+		BC_0           = 0x0B,
+		BC_MINUS       = 0x0C,    // - on main keyboard
+		BC_EQUALS      = 0x0D,
+		BC_BACK        = 0x0E,    // backspace
+		BC_TAB         = 0x0F,
+		BC_Q           = 0x10,
+		BC_W           = 0x11,
+		BC_E           = 0x12,
+		BC_R           = 0x13,
+		BC_T           = 0x14,
+		BC_Y           = 0x15,
+		BC_U           = 0x16,
+		BC_I           = 0x17,
+		BC_O           = 0x18,
+		BC_P           = 0x19,
+		BC_LBRACKET    = 0x1A,
+		BC_RBRACKET    = 0x1B,
+		BC_RETURN      = 0x1C,    // Enter on main keyboard
+		BC_LCONTROL    = 0x1D,
+		BC_A           = 0x1E,
+		BC_S           = 0x1F,
+		BC_D           = 0x20,
+		BC_F           = 0x21,
+		BC_G           = 0x22,
+		BC_H           = 0x23,
+		BC_J           = 0x24,
+		BC_K           = 0x25,
+		BC_L           = 0x26,
+		BC_SEMICOLON   = 0x27,
+		BC_APOSTROPHE  = 0x28,
+		BC_GRAVE       = 0x29,    // accent
+		BC_LSHIFT      = 0x2A,
+		BC_BACKSLASH   = 0x2B,
+		BC_Z           = 0x2C,
+		BC_X           = 0x2D,
+		BC_C           = 0x2E,
+		BC_V           = 0x2F,
+		BC_B           = 0x30,
+		BC_N           = 0x31,
+		BC_M           = 0x32,
+		BC_COMMA       = 0x33,
+		BC_PERIOD      = 0x34,    // . on main keyboard
+		BC_SLASH       = 0x35,    // / on main keyboard
+		BC_RSHIFT      = 0x36,
+		BC_MULTIPLY    = 0x37,    // * on numeric keypad
+		BC_LMENU       = 0x38,    // left Alt
+		BC_SPACE       = 0x39,
+		BC_CAPITAL     = 0x3A,
+		BC_F1          = 0x3B,
+		BC_F2          = 0x3C,
+		BC_F3          = 0x3D,
+		BC_F4          = 0x3E,
+		BC_F5          = 0x3F,
+		BC_F6          = 0x40,
+		BC_F7          = 0x41,
+		BC_F8          = 0x42,
+		BC_F9          = 0x43,
+		BC_F10         = 0x44,
+		BC_NUMLOCK     = 0x45,
+		BC_SCROLL      = 0x46,    // Scroll Lock
+		BC_NUMPAD7     = 0x47,
+		BC_NUMPAD8     = 0x48,
+		BC_NUMPAD9     = 0x49,
+		BC_SUBTRACT    = 0x4A,    // - on numeric keypad
+		BC_NUMPAD4     = 0x4B,
+		BC_NUMPAD5     = 0x4C,
+		BC_NUMPAD6     = 0x4D,
+		BC_ADD         = 0x4E,    // + on numeric keypad
+		BC_NUMPAD1     = 0x4F,
+		BC_NUMPAD2     = 0x50,
+		BC_NUMPAD3     = 0x51,
+		BC_NUMPAD0     = 0x52,
+		BC_DECIMAL     = 0x53,    // . on numeric keypad
+		BC_OEM_102     = 0x56,    // < > | on UK/Germany keyboards
+		BC_F11         = 0x57,
+		BC_F12         = 0x58,
+		BC_F13         = 0x64,    //                     (NEC PC98)
+		BC_F14         = 0x65,    //                     (NEC PC98)
+		BC_F15         = 0x66,    //                     (NEC PC98)
+		BC_KANA        = 0x70,    // (Japanese keyboard)
+		BC_ABNT_C1     = 0x73,    // / ? on Portugese (Brazilian) keyboards
+		BC_CONVERT     = 0x79,    // (Japanese keyboard)
+		BC_NOCONVERT   = 0x7B,    // (Japanese keyboard)
+		BC_YEN         = 0x7D,    // (Japanese keyboard)
+		BC_ABNT_C2     = 0x7E,    // Numpad . on Portugese (Brazilian) keyboards
+		BC_NUMPADEQUALS= 0x8D,    // = on numeric keypad (NEC PC98)
+		BC_PREVTRACK   = 0x90,    // Previous Track (BC_CIRCUMFLEX on Japanese keyboard)
+		BC_AT          = 0x91,    //                     (NEC PC98)
+		BC_COLON       = 0x92,    //                     (NEC PC98)
+		BC_UNDERLINE   = 0x93,    //                     (NEC PC98)
+		BC_KANJI       = 0x94,    // (Japanese keyboard)
+		BC_STOP        = 0x95,    //                     (NEC PC98)
+		BC_AX          = 0x96,    //                     (Japan AX)
+		BC_UNLABELED   = 0x97,    //                        (J3100)
+		BC_NEXTTRACK   = 0x99,    // Next Track
+		BC_NUMPADENTER = 0x9C,    // Enter on numeric keypad
+		BC_RCONTROL    = 0x9D,
+		BC_MUTE        = 0xA0,    // Mute
+		BC_CALCULATOR  = 0xA1,    // Calculator
+		BC_PLAYPAUSE   = 0xA2,    // Play / Pause
+		BC_MEDIASTOP   = 0xA4,    // Media Stop
+		BC_VOLUMEDOWN  = 0xAE,    // Volume -
+		BC_VOLUMEUP    = 0xB0,    // Volume +
+		BC_WEBHOME     = 0xB2,    // Web home
+		BC_NUMPADCOMMA = 0xB3,    // , on numeric keypad (NEC PC98)
+		BC_DIVIDE      = 0xB5,    // / on numeric keypad
+		BC_SYSRQ       = 0xB7,
+		BC_RMENU       = 0xB8,    // right Alt
+		BC_PAUSE       = 0xC5,    // Pause
+		BC_HOME        = 0xC7,    // Home on arrow keypad
+		BC_UP          = 0xC8,    // UpArrow on arrow keypad
+		BC_PGUP        = 0xC9,    // PgUp on arrow keypad
+		BC_LEFT        = 0xCB,    // LeftArrow on arrow keypad
+		BC_RIGHT       = 0xCD,    // RightArrow on arrow keypad
+		BC_END         = 0xCF,    // End on arrow keypad
+		BC_DOWN        = 0xD0,    // DownArrow on arrow keypad
+		BC_PGDOWN      = 0xD1,    // PgDn on arrow keypad
+		BC_INSERT      = 0xD2,    // Insert on arrow keypad
+		BC_DELETE      = 0xD3,    // Delete on arrow keypad
+		BC_LWIN        = 0xDB,    // Left Windows key
+		BC_RWIN        = 0xDC,    // Right Windows key
+		BC_APPS        = 0xDD,    // AppMenu key
+		BC_POWER       = 0xDE,    // System Power
+		BC_SLEEP       = 0xDF,    // System Sleep
+		BC_WAKE        = 0xE3,    // System Wake
+		BC_WEBSEARCH   = 0xE5,    // Web Search
+		BC_WEBFAVORITES= 0xE6,    // Web Favorites
+		BC_WEBREFRESH  = 0xE7,    // Web Refresh
+		BC_WEBSTOP     = 0xE8,    // Web Stop
+		BC_WEBFORWARD  = 0xE9,    // Web Forward
+		BC_WEBBACK     = 0xEA,    // Web Back
+		BC_MYCOMPUTER  = 0xEB,    // My Computer
+		BC_MAIL        = 0xEC,    // Mail
+		BC_MEDIASELECT = 0xED,     // Media Select
+		BC_MOUSE_LEFT = 0x800000EE, // Mouse buttons - Most important bit signifies this key is a mouse button
+		BC_MOUSE_RIGHT = 0x800000EF,
+		BC_MOUSE_MIDDLE = 0x800000F0,
+		BC_MOUSE_BTN4 = 0x800000F1,
+		BC_MOUSE_BTN5 = 0x800000F2,
+		BC_MOUSE_BTN6 = 0x800000F3,
+		BC_MOUSE_BTN7 = 0x800000F4,
+		BC_MOUSE_BTN8 = 0x800000F5,
+		BC_MOUSE_BTN9 = 0x800000F6,
+		BC_MOUSE_BTN10 = 0x800000F7,
+		BC_MOUSE_BTN11 = 0x800000F8,
+		BC_MOUSE_BTN12 = 0x800000F9,
+		BC_MOUSE_BTN13 = 0x800000FA,
+		BC_MOUSE_BTN14 = 0x800000FB,
+		BC_MOUSE_BTN15 = 0x800000FC,
+		BC_MOUSE_BTN16 = 0x800000FD,
+		BC_MOUSE_BTN17 = 0x800000FE,
+		BC_MOUSE_BTN18 = 0x800000FF,
+		BC_MOUSE_BTN19 = 0x80000101,
+		BC_MOUSE_BTN20 = 0x80000102,
+		BC_MOUSE_BTN21 = 0x80000103,
+		BC_MOUSE_BTN22 = 0x80000104,
+		BC_MOUSE_BTN23 = 0x80000105,
+		BC_MOUSE_BTN24 = 0x80000106,
+		BC_MOUSE_BTN25 = 0x80000107,
+		BC_MOUSE_BTN26 = 0x80000108,
+		BC_MOUSE_BTN27 = 0x80000109,
+		BC_MOUSE_BTN28 = 0x8000010A,
+		BC_MOUSE_BTN29 = 0x8000010B,
+		BC_MOUSE_BTN30 = 0x8000010C,
+		BC_MOUSE_BTN31 = 0x8000010D,
+		BC_MOUSE_BTN32 = 0x8000010E,
+		BC_GAMEPAD_A = 0x4000010F, // Joystick/Gamepad buttons- Second most important bit signifies key is a gamepad button
+		BC_GAMEPAD_B = 0x40000110, // Similar to keyboard names, these are for convenience named after Xbox controller buttons
+		BC_GAMEPAD_X = 0x40000111, // but if some other controller is connected you will need to learn yourself which of these
+		BC_GAMEPAD_Y = 0x40000112, // corresponds to which actual button on the controller.
+		BC_GAMEPAD_LB = 0x40000113,
+		BC_GAMEPAD_RB = 0x40000114,
+		BC_GAMEPAD_LS = 0x40000115,
+		BC_GAMEPAD_RS = 0x40000116,
+		BC_GAMEPAD_BACK = 0x40000117,
+		BC_GAMEPAD_START = 0x40000118,
+		BC_GAMEPAD_DPAD_LEFT = 0x40000119,
+		BC_GAMEPAD_DPAD_RIGHT = 0x4000011A,
+		BC_GAMEPAD_DPAD_UP = 0x4000011B,
+		BC_GAMEPAD_DPAD_DOWN = 0x4000011C,
+		BC_GAMEPAD_BTN1 = 0x4000011D,
+		BC_GAMEPAD_BTN2 = 0x4000011E,
+		BC_GAMEPAD_BTN3 = 0x4000011F,
+		BC_GAMEPAD_BTN4 = 0x40000120,
+		BC_GAMEPAD_BTN5 = 0x40000121,
+		BC_GAMEPAD_BTN6 = 0x40000122,
+		BC_GAMEPAD_BTN7 = 0x40000123,
+		BC_GAMEPAD_BTN8 = 0x40000124,
+		BC_GAMEPAD_BTN9 = 0x40000125,
+		BC_GAMEPAD_BTN10 = 0x40000126,
+		BC_GAMEPAD_BTN11 = 0x40000127,
+		BC_GAMEPAD_BTN12 = 0x40000128,
+		BC_GAMEPAD_BTN13 = 0x40000129,
+		BC_GAMEPAD_BTN14 = 0x4000012A,
+		BC_GAMEPAD_BTN15 = 0x4000012B,
+		BC_GAMEPAD_BTN16 = 0x4000012C,
+		BC_GAMEPAD_BTN17 = 0x4000012D,
+		BC_GAMEPAD_BTN18 = 0x4000012E,
+		BC_GAMEPAD_BTN19 = 0x4000012F,
+		BC_GAMEPAD_BTN20 = 0x40000130,
+		BC_Count = 304,
+		BC_NumKeys = 238, // IMPORTANT: Make sure to update these if you modify the values above
+		BC_NumMouse = 32,
+		BC_NumGamepad = 34,
+	};
+
+	/**	Contains data about a button input event. */
+	struct ButtonEvent
+	{
+	public:
+		ButtonEvent()
+			:mIsUsed(false)
+		{ }
+
+		ButtonCode buttonCode; /**< Button code this event is referring to. */
+		UINT64 timestamp; /**< Timestamp in ticks when the event happened. */
+		UINT32 deviceIdx; /**< Index of the device that the event originated from. */
+
+		/**	Query is the pressed button a keyboard button. */
+		bool isKeyboard() const { return (buttonCode & 0xC0000000) == 0; }
+
+		/** Query is the pressed button a mouse button. */
+		bool isMouse() const { return (buttonCode & 0x80000000) != 0; }
+
+		/** Query is the pressed button a gamepad button. */
+		bool isGamepad() const { return (buttonCode & 0x40000000) != 0; }
+
+		/**
+		 * Check if the event has been marked as used. Internally this means nothing but caller might choose to ignore an 
+		 * used event.
+		 */
+		bool isUsed() const { return mIsUsed; }
+
+		/** Mark the event as used. Internally this means nothing but caller might choose to ignore an used event. */
+		void markAsUsed() const { mIsUsed = true; }
+	private:
+		mutable bool mIsUsed;
+	};
+
+	/**
+	 * Pointer buttons. Generally these correspond to mouse buttons, but may be used in some form for touch input as well.
+	 */
+	enum class PointerEventButton
+	{
+		Left, Middle, Right, Count
+	};
+
+	/**	Type of pointer event.*/
+	enum class PointerEventType
+	{
+		CursorMoved,
+		ButtonPressed,
+		ButtonReleased,
+		DoubleClick
+	};
+
+	/**
+	 * Event that gets sent out when user interacts with the screen in some way, usually by moving the mouse cursor or
+	 * using touch input.
+	 */
+	struct PointerEvent
+	{
+	public:
+		PointerEvent()
+			:mIsUsed(false), mouseWheelScrollAmount(0.0f), type(PointerEventType::CursorMoved),
+			shift(false), control(false), alt(false), button(PointerEventButton::Left)
+		{
+			buttonStates[0] = false;
+			buttonStates[1] = false;
+			buttonStates[2] = false;
+		}
+
+		Vector2I screenPos; /**< Screen position where the input event occurred. */
+		Vector2I delta; /**< Change in movement since last sent event. */
+		bool buttonStates[(UINT32)PointerEventButton::Count]; /**< States of the pointer buttons (e.g. mouse buttons). */
+		PointerEventButton button; /**< Button that triggered the pointer event. Might be irrelevant 
+										depending on event type. (e.g. move events don't correspond to a button. */
+		PointerEventType type; /**< Type of the pointer event. */
+
+		bool shift; /**< Is shift button on the keyboard being held down. */
+		bool control; /**< Is control button on the keyboard being held down. */
+		bool alt; /**< Is alt button on the keyboard being held down. */
+
+		float mouseWheelScrollAmount; /**< If mouse wheel is being scrolled, what is the amount. Only relevant for move events. */
+
+		/**
+		 * Check if the event has been marked as used. Internally this means nothing but caller might choose to ignore an 
+		 * used event.
+		 */
+		bool isUsed() const { return mIsUsed; }
+
+		/** Mark the event as used. Internally this means nothing but caller might choose to ignore an used event. */
+		void markAsUsed() const { mIsUsed = true; }
+
+	private:
+		mutable bool mIsUsed;
+	};
+
+	/**	Types of special input commands. */
+	enum class InputCommandType
+	{
+		CursorMoveLeft, CursorMoveRight, CursorMoveUp, CursorMoveDown, 
+		SelectLeft, SelectRight, SelectUp, SelectDown,
+		Escape, Delete, Backspace, Return, Confirm
+	};
+
+	/**
+	 * Event that gets sent out when user inputs some text. These events may be preceeded by normal button events if user 
+	 * is typing on a keyboard. 
+	 */
+	struct TextInputEvent
+	{
+	public:
+		TextInputEvent()
+			:mIsUsed(false)
+		{ }
+
+		UINT32 textChar; /**< Character the that was input. */
+
+		/**
+		 * @brief	Check if the event has been marked as used. Internally this means nothing
+		 *			but caller might choose to ignore an used event.
+		 */
+		bool isUsed() const { return mIsUsed; }
+
+		/**
+		 * @brief	Mark the event as used. Internally this means nothing
+		 *			but caller might choose to ignore an used event.
+		 */
+		void markAsUsed() const { mIsUsed = true; }
+
+	private:
+		mutable bool mIsUsed;
+	};
+
+	/**	Types of input devices. */
+	enum class InputDevice
+	{
+		Keyboard,
+		Mouse,
+		Gamepad,
+		Count // Keep at end
+	};
+
+	/**	Common input axis types. */
+	enum class InputAxis
+	{
+		MouseX, /**< Mouse axis X. */
+		MouseY, /**< Mouse axis Y. */
+		MouseZ, /**< Mouse wheel/scroll axis. */
+		LeftStickX, /**< Gamepad left stick X */
+		LeftStickY, /**<  Gamepad left stick Y */
+		RightStickX, /**< Gamepad right stick X */
+		RightStickY, /**< Gamepad right stick Y */
+		LeftTrigger, /**< Gamepad left trigger */
+		RightTrigger, /**< Gamepad right trigger */
+		Count // Keep at end
+	};
+
+	/**	Modifiers used with along with keyboard buttons. */
+	enum class ButtonModifier
+	{
+		None = 0x00,
+		Shift = 0x01,
+		Ctrl = 0x02,
+		Alt = 0x04,
+		ShiftCtrl = 0x03,
+		CtrlAlt = 0x06,
+		ShiftAlt = 0x05,
+		ShiftCtrlAlt = 0x07
+	};
+
+	/** @} */
 }

+ 801 - 575
BansheeCore/Include/BsMaterial.h

@@ -1,576 +1,802 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsResource.h"
-#include "BsGpuParam.h"
-#include "BsMaterialProxy.h"
-#include "BsVector2.h"
-#include "BsVector3.h"
-#include "BsVector4.h"
-#include "BsMatrix3.h"
-#include "BsMatrix4.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Type of material dirty flags
-	 */
-	enum class MaterialDirtyFlag
-	{
-		Material = 0x01, /**< Internal material data is dirty. */
-		Proxy = 0x02, /**< Active proxy needs to be updated. */
-		Params = 0x04 /**< Parameters are dirty. */
-	};
-
-	/**
-	 * @brief	Helper class containing parameters for all types
-	 * 			of GPU programs used in a pass.
-	 */
-	class BS_CORE_EXPORT PassParameters
-	{
-	public:
-		GpuParamsPtr mVertParams;
-		GpuParamsPtr mFragParams;
-		GpuParamsPtr mGeomParams;
-		GpuParamsPtr mHullParams;
-		GpuParamsPtr mDomainParams;
-		GpuParamsPtr mComputeParams;
-
-		/**
-		 * @brief	Returns a set of GPU parameters based on an index.
-		 *
-		 * @note	Useful when needing to iterate over all sets of GPU parameters.
-		 */
-		GpuParamsPtr& getParamByIdx(UINT32 idx)
-		{
-			GpuParamsPtr* paramArray[] = {&mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams};
-
-			return *paramArray[idx];
-		}
-
-		/**
-		 * @brief	Sets GPU parameters based on an index.
-		 *
-		 * @note	Useful when needing to iterate over all sets of GPU parameters.
-		 */
-		void setParamByIdx(UINT32 idx, const GpuParamsPtr& params)
-		{
-			GpuParamsPtr* paramArray[] = {&mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams};
-
-			(*paramArray[idx]) = params;
-		}
-
-		/**
-		 * @brief	Returns the total number of stored sets of 
-		 * 			GPU parameters in this object.
-		 */
-		UINT32 getNumParams() const { return 6; }
-	};
-
-	/**
-	 * @brief	Material represents a shader and parameters used to set up
-	 * 			that shader. It provides a simple interface for manipulating the
-	 * 			parameters.
-	 */
-	class BS_CORE_EXPORT Material : public Resource
-	{
-	public:
-		/**
-		 * @brief	Data used to described a structure defined within a shader.
-		 */
-		struct StructData
-		{
-			StructData()
-				:size(0), data(nullptr)
-			{ }
-
-			StructData(UINT32 _size)
-				:size(_size)
-			{
-				data = std::shared_ptr<void>(bs_alloc<ScratchAlloc>(_size), &bs_free<ScratchAlloc>);
-			}
-
-			/**
-			 * @brief	Writes the specified data to the internal buffer. Caller
-			 * 			must ensure size of the provided buffer is correct.
-			 */
-			void write(void* _data)
-			{
-				memcpy(data.get(), _data, size);
-			}
-
-			std::shared_ptr<void> data;
-			UINT32 size;
-		};
-
-		~Material();
-
-		/**
-		 * @brief	Sets a shader that will be used by the material. Best technique within the
-		 * 			provided shader will be used for the material.
-		 *
-		 * @note	Shader must be set before doing any other operations with the material.
-		 * 			
-		 * 			After setting the shader if change any systems that a shader technique is 
-		 * 			dependent upon (render system, renderer, etc), you will need to call this 
-		 * 			method again on all your Materials to make sure technique used is updated.
-		 */
-		void setShader(ShaderPtr shader);
-
-		/**
-		 * @brief	Returns the currently active shader.
-		 */
-		ShaderPtr getShader() const { return mShader; }
-
-		/** @brief	Assigns a texture to the shader parameter with the specified name. */
-		void setTexture(const String& name, const HTexture& value) { return getParamTexture(name).set(value); }
-
-		/** @brief	Assigns a sampler state to the shader parameter with the specified name. */
-		void setSamplerState(const String& name, const HSamplerState& value) { return getParamSamplerState(name).set(value); }
-
-		/**   
-		 *  @brief	Assigns a float value to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setFloat(const String& name, float value, UINT32 arrayIdx = 0)	{ return getParamFloat(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a color to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0);
-
-		/**   
-		 *  @brief	Assigns a 2D vector to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0)	{ return getParamVec2(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 3D vector to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0)	{ return getParamVec3(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 4D vector to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0)	{ return getParamVec4(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 3x3 matrix to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0)	{ return getParamMat3(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a 4x4 matrix to the shader parameter with the specified name. 
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0)	{ return getParamMat4(name).set(value, arrayIdx); }
-
-		/**   
-		 *  @brief	Assigns a structure to the shader parameter with the specified name.
-		 *  		
-		 *			Structure is provided as a raw buffer and caller must ensure structure in buffer
-		 *			matches what the shader expects.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index to assign the value to.
-		 */
-		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
-
-		/**
-		 * @brief	Assign a parameter block buffer with the specified name.
-		 *
-		 * @note	Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
-		 * 			potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
-		 * 			in the buffers need only be set once and then reused multiple times.
-		 */
-		void setParamBlockBuffer(const String& name, const GpuParamBlockBufferPtr& paramBlock);
-
-		/** @brief	Returns a texture assigned with the parameter with the specified name. */
-		HTexture getTexture(const String& name) const { return getParamTexture(name).get(); }
-
-		/** @brief	Returns a sampler state assigned with the parameter with the specified name. */
-		HSamplerState getSamplerState(const String& name) const	{ return getParamSamplerState(name).get(); }
-
-		/**
-		 * @brief	Returns a float value assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 2D vector assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 3D vector assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 4D vector assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 3x3 matrix assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a 4x4 matrix assigned with the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
-
-		/**
-		 * @brief	Returns a buffer representing a structure assigned to the parameter with the specified name.
-		 *
-		 *			Optionally if the parameter is an array you may provide an array index you which to retrieve.
-		 */
-		StructData getStructData(const String& name, UINT32 arrayIdx = 0) const;
-
-		/**
-		 * @brief	Returns a float GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamFloat getParamFloat(const String& name) const;
-
-		/**
-		 * @brief	Returns a 2D vector GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamVec2 getParamVec2(const String& name) const;
-
-		/**
-		 * @brief	Returns a 3D vector GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamVec3 getParamVec3(const String& name) const;
-
-		/**
-		 * @brief	Returns a 4D vector GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamVec4 getParamVec4(const String& name) const;
-
-		/**
-		 * @brief	Returns a 3x3 matrix GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamMat3 getParamMat3(const String& name) const;
-
-		/**
-		 * @brief	Returns a 4x4 matrix GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamMat4 getParamMat4(const String& name) const;
-
-		/**
-		 * @brief	Returns a structure GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamStruct getParamStruct(const String& name) const;
-
-		/**
-		 * @brief	Returns a texture GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamTexture getParamTexture(const String& name) const;
-
-		/**
-		 * @brief	Returns a sampler state GPU parameter. This parameter may be used for
-		 * 			more efficiently getting/setting GPU parameter values than calling
-		 * 			Material::get* / Material::set* methods. 
-		 *
-		 * @note	Expected behavior is that you would retrieve this parameter when
-		 * 			initially constructing the material, and then use it throughout material
-		 * 			lifetime to assign and retrieve parameter values.
-		 * 			
-		 *			If material shader changes this handle will be invalidated.
-		 */
-		GpuParamSampState getParamSamplerState(const String& name) const;
-
-		/**
-		 * @brief	Returns the number of passes that are used
-		 * 			by the shader contained in the material.
-		 */
-		UINT32 getNumPasses() const;
-
-		/**
-		 * @brief	Retrieves a specific shader pass.
-		 */
-		PassPtr getPass(UINT32 passIdx) const;
-
-		/**
-		 * @brief	Returns a set of parameters for all GPU programs
-		 * 			in the specified shader pass.
-		 */
-		PassParametersPtr getPassParameters(UINT32 passIdx) const;
-
-		/**
-		 * @brief	Creates a new empty material.
-		 * 			
-		 * @note	Make sure you call Material::setShader before using it.
-		 */
-		static HMaterial create();
-
-		/**
-		 * @brief	Creates a new material with the specified shader.
-		 */
-		static HMaterial create(ShaderPtr shader);
-
-		/************************************************************************/
-		/* 								CORE PROXY                      		*/
-		/************************************************************************/
-
-		/**
-		 * @brief	Checks is the core dirty flag set. This is used by external systems 
-		 *			to know when internal data has changed and core thread potentially needs to be notified.
-		 *
-		 * @note	Sim thread only.
-		 */
-		bool _isCoreDirty(MaterialDirtyFlag flag) const;
-
-		/**
-		 * @brief	Marks the core dirty flag as clean.
-		 *
-		 * @note	Sim thread only.
-		 */
-		void _markCoreClean(MaterialDirtyFlag flag);
-
-		/**
-		 * @brief	Gets the currently active proxy of this material.
-		 */
-		MaterialProxyPtr _getActiveProxy() const { return mActiveProxy; }
-
-		/**
-		 * @brief	Sets an active proxy for this material.
-		 */
-		void _setActiveProxy(const MaterialProxyPtr& proxy) { mActiveProxy = proxy; }
-
-		/**
-		 * @brief	Returns updated GPU parameters since the last time the parameters were marked clean.
-		 */
-		Vector<MaterialProxy::ParamsBindInfo> _getDirtyProxyParams();
-
-		/**
-		 * @brief	Creates a new core proxy from the currently set material data. Core proxies ensure
-		 *			that the core thread has all the necessary material data, while avoiding the need
-		 *			to manage Material itself on the core thread.
-		 *
-		 * @note	Sim thread only. 
-		 *			You generally need to update the core thread with a new proxy whenever core 
-		 *			dirty flag is set.
-		 */
-		MaterialProxyPtr _createProxy();
-	protected:
-		/**
-		 * @copydoc	Resource::destroy_internal
-		 */
-		void destroy_internal();
-
-		/**
-		 * @brief	Allows you to retrieve a handle to a parameter that you can then use for quickly
-		 * 			setting and retrieving parameter data. This allows you to set/get parameter data
-		 * 			without all the cost of extra lookups otherwise required.
-		 * 			
-		 * @note	All of these handles will be invalidated if material shader ever changes. It is up to the
-		 * 			caller to keep track of that.
-		 */
-		template <typename T>
-		void getParam(const String& name, TGpuDataParam<T>& output) const
-		{
-			throwIfNotInitialized();
-
-			auto iterFind = mValidParams.find(name);
-			if(iterFind == mValidParams.end())
-			{
-				LOGWRN("Material doesn't have a parameter named " + name);
-				return;
-			}
-
-			const String& gpuVarName = iterFind->second;
-			GpuParamsPtr params = findParamsWithName(gpuVarName);
-
-			params->getParam<T>(gpuVarName, output);
-		}
-
-	private:
-		friend class MaterialManager;
-
-		ShaderPtr mShader;
-		TechniquePtr mBestTechnique;
-		INT32 mCoreDirtyFlags;
-
-		Set<String> mValidShareableParamBlocks;
-		Map<String, String> mValidParams; // Also maps Shader param name -> gpu variable name
-
-		Vector<PassParametersPtr> mParametersPerPass;
-		Vector<GpuParamBlockBufferPtr> mParamBuffers;
-
-		MaterialProxyPtr mActiveProxy;
-
-		Material();
-
-		/**
-		 * @brief	Throw an exception if no shader is set, or no acceptable
-		 * 			technique was found.
-		 */
-		void throwIfNotInitialized() const;
-
-		/**
-		 * @brief	Marks the core data as dirty.
-		 */
-		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
-
-		/**
-		 * @brief	Retrieves a list of all shader GPU parameters, and the GPU program variable names they map to.
-		 */
-		const Map<String, String>& getValidParamNames() const { return mValidParams; }
-
-		/**
-		 * @brief	Initializes the material by using the best technique from the currently set shader. Shader
-		 * 			must contain the technique that matches the current renderer and render system.
-		 */
-		void initBestTechnique();
-
-		/**
-		 * @brief	Constructs a map containing all data parameters (e.g. float, vector3, color).
-		 * 			Map contains parameter names and descriptions.
-		 */
-		Map<String, const GpuParamDataDesc*> determineValidDataParameters(const Vector<GpuParamDescPtr>& paramDescs) const;
-
-		/**
-		 * @brief	Constructs a list containing all object parameter (e.g. texture, sampler state) names.
-		 */
-		Set<String> determineValidObjectParameters(const Vector<GpuParamDescPtr>& paramDescs) const;
-
-		/**
-		 * @brief	Constructs a list containing all shareable parameter block names. Shareable blocks may be shared between
-		 * 			different GPU programs, passes or even materials. 
-		 */
-		Set<String> determineValidShareableParamBlocks(const Vector<GpuParamDescPtr>& paramDescs) const;
-
-		/**
-		 * @brief	Constructs a map that maps parameter names to a parameter block.
-		 */
-		Map<String, String> determineParameterToBlockMapping(const Vector<GpuParamDescPtr>& paramDescs);
-
-		/**
-		 * @brief	Checks are the specified two parameters equal
-		 *
-		 * @param	paramA			   	The parameter a to compare.
-		 * @param	paramB			   	The parameter b to compare.
-		 * @param	ignoreBufferOffsets	(optional) If true, parameter offsets into the parameter buffer will be ignored
-		 * 								when comparing.
-		 */
-		bool areParamsEqual(const GpuParamDataDesc& paramA, const GpuParamDataDesc& paramB, bool ignoreBufferOffsets = false) const;
-
-		/**
-		 * @brief	Frees all parameter block buffers.
-		 */
-		void freeParamBuffers();
-
-		/**
-		 * @brief	Finds a set of GPU parameters containing a data (e.g. float, vector2) parameter with the provided name.
-		 */
-		GpuParamsPtr findParamsWithName(const String& name) const;
-
-		/**
-		 * @brief	Finds a set of GPU parameters containing a texture parameter with the provided name.
-		 */
-		GpuParamsPtr findTexWithName(const String& name) const;
-
-		/**
-		 * @brief	Finds a set of GPU parameters containing a sampler state parameter with the provided name.
-		 */
-		GpuParamsPtr findSamplerStateWithName(const String& name) const;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-		
-	public:
-		friend class MaterialRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+#include "BsIResourceListener.h"
+#include "BsMaterialParam.h"
+#include "BsVector2.h"
+#include "BsVector3.h"
+#include "BsVector4.h"
+#include "BsMatrix3.h"
+#include "BsMatrix4.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	class MaterialParams;
+
+	/** Helper class containing parameters for all types of GPU programs used in a pass. */
+	template<bool Core>
+	class TPassParameters
+	{
+	public:
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+
+		/**
+		 * Returns a set of GPU parameters based on an index.
+		 *
+		 * @note	Useful when needing to iterate over all sets of GPU parameters.
+		 */
+		GpuParamsType& getParamByIdx(UINT32 idx)
+		{
+			GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
+
+			return *paramArray[idx];
+		}
+
+		/**
+		 * Sets GPU parameters based on an index.
+		 *
+		 * @note	Useful when needing to iterate over all sets of GPU parameters.
+		 */
+		void setParamByIdx(UINT32 idx, const GpuParamsType& params)
+		{
+			GpuParamsType* paramArray[] = { &mVertParams, &mFragParams, &mGeomParams, &mHullParams, &mDomainParams, &mComputeParams };
+
+			(*paramArray[idx]) = params;
+		}
+
+		GpuParamsType mVertParams;
+		GpuParamsType mFragParams;
+		GpuParamsType mGeomParams;
+		GpuParamsType mHullParams;
+		GpuParamsType mDomainParams;
+		GpuParamsType mComputeParams;
+	};
+
+	template<bool Core> struct TGpuParamBlockBufferPtrType { };
+	template<> struct TGpuParamBlockBufferPtrType<false> { typedef SPtr<GpuParamBlockBuffer> Type; };
+	template<> struct TGpuParamBlockBufferPtrType<true> { typedef SPtr<GpuParamBlockBufferCore> Type; };
+
+	template<bool Core> struct TGpuProgramType { };
+	template<> struct TGpuProgramType<false> { typedef GpuProgramPtr Type; };
+	template<> struct TGpuProgramType<true> { typedef SPtr<GpuProgramCore> Type; };
+
+	/** Contains sim thread pass parameters for each shader stage. */
+	class BS_CORE_EXPORT PassParameters : public TPassParameters<false>
+	{
+	public:
+		static const UINT32 NUM_PARAMS;
+	};
+
+	/** Contains core thread pass parameters for each shader stage. */
+	class BS_CORE_EXPORT PassParametersCore : public TPassParameters<true>
+	{
+	public:
+		static const UINT32 NUM_PARAMS;
+	};
+
+	/**
+	 * Material that controls how objects are rendered. It is represented by a shader and parameters used to set up that
+	 * shader. It provides a simple interface for manipulating the parameters.
+	 */
+	class BS_CORE_EXPORT MaterialBase
+	{
+	public:
+		/** Data used to described a structure defined within a shader. */
+		struct StructData
+		{
+			StructData()
+				:size(0), data(nullptr)
+			{ }
+
+			StructData(UINT32 _size)
+				:size(_size)
+			{
+				data = std::shared_ptr<void>(bs_alloc(_size), &bs_free);
+			}
+
+			/**
+			 * Writes the specified data to the internal buffer. Caller must ensure size of the provided buffer is correct.
+			 */
+			void write(void* _data)
+			{
+				memcpy(data.get(), _data, size);
+			}
+
+			std::shared_ptr<void> data;
+			UINT32 size;
+		};
+
+		virtual ~MaterialBase() { }
+
+	protected:
+		/** Retrieves a list of all shader GPU parameters, and the GPU program variable names they map to. */
+		const Map<String, String>& getValidParamNames() const { return mValidParams; }
+
+		/** @copydoc CoreObject::markCoreDirty */
+		virtual void _markCoreDirty() { }
+
+		/** @copydoc CoreObject::markDependenciesDirty */
+		virtual void _markDependenciesDirty() { }
+
+		/** @copydoc IResourceListener::markResourcesDirty */
+		virtual void _markResourcesDirty() { }
+
+		/** Returns all GPU parameter descriptions in the specified technique. */
+		static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<Technique>& technique);
+
+		/** Returns all GPU parameter descriptions in the specified technique. */
+		static Vector<GpuParamDescPtr> getAllParamDescs(const SPtr<TechniqueCore>& technique);
+
+		Set<String> mValidShareableParamBlocks;
+		Map<String, String> mValidParams; // Also maps Shader param name -> gpu variable name
+	};
+
+	/** @copydoc MaterialBase */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterial : public MaterialBase
+	{
+	public:
+		template<bool Core> struct TPassType {};
+		template<> struct TPassType < false > { typedef SPtr<Pass> Type; };
+		template<> struct TPassType < true > { typedef SPtr<PassCore> Type; };
+
+		template<bool Core> struct TTechniqueType {};
+		template<> struct TTechniqueType < false > { typedef SPtr<Technique> Type; };
+		template<> struct TTechniqueType < true > { typedef SPtr<TechniqueCore> Type; };
+
+		template<bool Core> struct TShaderType {};
+		template<> struct TShaderType < false > { typedef HShader Type; };
+		template<> struct TShaderType < true > { typedef SPtr<ShaderCore> Type; };
+
+		template<bool Core> struct TGpuParamBlockBufferType {};
+		template<> struct TGpuParamBlockBufferType < false > { typedef GpuParamBlockBuffer Type; };
+		template<> struct TGpuParamBlockBufferType < true > { typedef GpuParamBlockBufferCore Type; };
+
+		template<bool Core> struct TPassParamsType {};
+		template<> struct TPassParamsType < false > { typedef PassParameters Type; };
+		template<> struct TPassParamsType < true > { typedef PassParametersCore Type; };
+
+		typedef typename TGpuParamsPtrType<Core>::Type GpuParamsType;
+		typedef typename TGpuParamTextureType<Core>::Type TextureType;
+		typedef typename TGpuParamSamplerStateType<Core>::Type SamplerStateType;
+		typedef typename TGpuParamBlockBufferPtrType<Core>::Type ParamBlockPtrType;
+		typedef typename TGpuParamBlockBufferType<Core>::Type ParamBlockType;
+		typedef typename TGpuProgramType<Core>::Type GpuProgramType;
+		typedef typename TPassType<Core>::Type PassType;
+		typedef typename TTechniqueType<Core>::Type TechniqueType;
+		typedef typename TShaderType<Core>::Type ShaderType;
+		typedef typename TPassParamsType<Core>::Type PassParamsType;
+
+		virtual ~TMaterial() { }
+
+		/** Returns the currently active shader. */
+		ShaderType getShader() const { return mShader; }
+
+		/** Returns the number of passes that are used by the shader used in the material. */
+		UINT32 getNumPasses() const;
+
+		/** Retrieves a specific shader pass. */
+		PassType getPass(UINT32 passIdx) const;
+
+		/**   
+		 * Assigns a float value to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setFloat(const String& name, float value, UINT32 arrayIdx = 0)	{ return getParamFloat(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a color to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setColor(const String& name, const Color& value, UINT32 arrayIdx = 0) { return getParamColor(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 2D vector to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setVec2(const String& name, const Vector2& value, UINT32 arrayIdx = 0)	{ return getParamVec2(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 3D vector to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setVec3(const String& name, const Vector3& value, UINT32 arrayIdx = 0)	{ return getParamVec3(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 4D vector to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setVec4(const String& name, const Vector4& value, UINT32 arrayIdx = 0)	{ return getParamVec4(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 3x3 matrix to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setMat3(const String& name, const Matrix3& value, UINT32 arrayIdx = 0)	{ return getParamMat3(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a 4x4 matrix to the shader parameter with the specified name. 
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setMat4(const String& name, const Matrix4& value, UINT32 arrayIdx = 0)	{ return getParamMat4(name).set(value, arrayIdx); }
+
+		/**   
+		 * Assigns a structure to the shader parameter with the specified name.
+		 *  		
+		 * Structure is provided as a raw buffer and caller must ensure structure in buffer matches what the shader expects.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index to assign the value to.
+		 */
+		void setStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx = 0) { return getParamStruct(name).set(value, size, arrayIdx); }
+
+		/** Assigns a texture to the shader parameter with the specified name. */
+		void setTexture(const String& name, const TextureType& value) { return getParamTexture(name).set(value); }
+
+		/** Assigns a texture to be used for random load/store operations to the shader parameter with the specified name. */
+		void setLoadStoreTexture(const String& name, const TextureType& value, const TextureSurface& surface)
+		{ 
+			return getParamLoadStoreTexture(name).set(value, surface); 
+		}
+
+		/** Assigns a sampler state to the shader parameter with the specified name. */
+		void setSamplerState(const String& name, const SamplerStateType& value) { return getParamSamplerState(name).set(value); }
+
+		/**
+		 * Returns a float value assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		float getFloat(const String& name, UINT32 arrayIdx = 0) const { return getParamFloat(name).get(arrayIdx); }
+
+		/**
+		 * Returns a color assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Color getColor(const String& name, UINT32 arrayIdx = 0) const { return getParamColor(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 2D vector assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Vector2 getVec2(const String& name, UINT32 arrayIdx = 0) const { return getParamVec2(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 3D vector assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Vector3 getVec3(const String& name, UINT32 arrayIdx = 0) const { return getParamVec3(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 4D vector assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Vector4 getVec4(const String& name, UINT32 arrayIdx = 0) const { return getParamVec4(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 3x3 matrix assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Matrix3 getMat3(const String& name, UINT32 arrayIdx = 0) const { return getParamMat3(name).get(arrayIdx); }
+
+		/**
+		 * Returns a 4x4 matrix assigned with the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		Matrix4 getMat4(const String& name, UINT32 arrayIdx = 0) const { return getParamMat4(name).get(arrayIdx); }
+
+		/** Returns a texture assigned with the parameter with the specified name. */
+		TextureType getTexture(const String& name) const { return getParamTexture(name).get(); }
+
+		/** Returns a sampler state assigned with the parameter with the specified name. */
+		SamplerStateType getSamplerState(const String& name) const	{ return getParamSamplerState(name).get(); }
+
+		/**
+		 * Returns a buffer representing a structure assigned to the parameter with the specified name.
+		 *
+		 * Optionally if the parameter is an array you may provide an array index you which to retrieve.
+		 */
+		MaterialBase::StructData getStructData(const String& name, UINT32 arrayIdx = 0) const
+		{
+			TMaterialParamStruct<Core> structParam = getParamStruct(name);
+
+			MaterialBase::StructData data(structParam.getElementSize());
+			structParam.get(data.data.get(), structParam.getElementSize(), arrayIdx);
+
+			return data;
+		}
+
+		/**
+		 * Returns a float GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<float, Core> getParamFloat(const String& name) const
+		{
+			TMaterialDataParam<float, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a color GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, 
+		 * and then use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Color, Core> getParamColor(const String& name) const
+		{
+			TMaterialDataParam<Color, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 2D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Vector2, Core> getParamVec2(const String& name) const
+		{
+			TMaterialDataParam<Vector2, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 3D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Vector3, Core> getParamVec3(const String& name) const
+		{
+			TMaterialDataParam<Vector3, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 4D vector GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Vector4, Core> getParamVec4(const String& name) const
+		{
+			TMaterialDataParam<Vector4, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 3x3 matrix GPU parameter. This parameter may be used for more efficiently getting/setting GPU 
+		 * parameter values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Matrix3, Core> getParamMat3(const String& name) const
+		{
+			TMaterialDataParam<Matrix3, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a 4x4 matrix GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note	
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialDataParam<Matrix4, Core> getParamMat4(const String& name) const
+		{
+			TMaterialDataParam<Matrix4, Core> gpuParam;
+			getParam(name, gpuParam);
+
+			return gpuParam;
+		}
+
+		/**
+		 * Returns a structure GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamStruct<Core> getParamStruct(const String& name) const;
+
+		/**
+		 * Returns a texture GPU parameter. This parameter may be used for more efficiently getting/setting GPU parameter 
+		 * values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamTexture<Core> getParamTexture(const String& name) const;
+
+		/**
+		 * Returns a GPU parameter for binding a load/store texture. This parameter may be used for more efficiently 
+		 * getting/setting GPU parameter values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamLoadStoreTexture<Core> getParamLoadStoreTexture(const String& name) const;
+
+		/**
+		 * Returns a sampler state GPU parameter. This parameter may be used for more efficiently getting/setting GPU 
+		 * parameter values than calling Material::get* / Material::set* methods. 
+		 *
+		 * @note	
+		 * Expected behavior is that you would retrieve this parameter when initially constructing the material, and then 
+		 * use it throughout material lifetime to assign and retrieve parameter values.
+		 * @note			
+		 * If material shader changes this handle will be invalidated.
+		 */
+		TMaterialParamSampState<Core> getParamSamplerState(const String& name) const;
+
+		/** Returns a set of parameters for all GPU programs in the specified shader pass. */
+		SPtr<PassParamsType> getPassParameters(UINT32 passIdx) const { return mParametersPerPass[passIdx]; }
+
+		/**
+		 * Assign a parameter block buffer with the specified name.
+		 *
+		 * @note	
+		 * Parameter block buffers can be used as quick way of setting multiple parameters on a material at once, or
+		 * potentially sharing parameters between multiple materials. This reduces driver overhead as the parameters
+		 * in the buffers need only be set once and then reused multiple times.
+		 */
+		void setParamBlockBuffer(const String& name, const ParamBlockPtrType& paramBlock);
+
+		/**
+		 * Allows you to retrieve a handle to a parameter that you can then use for quickly setting and retrieving parameter
+		 * data. This allows you to set/get parameter data without all the cost of extra lookups otherwise required.
+		 * 			
+		 * @note	
+		 * All of these handles will be invalidated if material shader ever changes. It is up to the caller to keep track 
+		 * of that.
+		 */
+		template <typename T>
+		void getParam(const String& name, TMaterialDataParam<T, Core>& output) const;
+
+	protected:
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		template <typename T>
+		TMaterialDataParam<T, false> createDataParam(const String& name, 
+			const SPtr<Vector<TGpuDataParam<T, false>>>& gpuParams) const
+		{
+			return TMaterialDataParam<T, false>(name, getCachedParams(), gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		template <typename T>
+		TMaterialDataParam<T, true> createDataParam(const String& name, 
+			const SPtr<Vector<TGpuDataParam<T, true>>>& gpuParams) const
+		{
+			return TMaterialDataParam<T, true>(gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamStruct<false> createStructParam(const String& name, 
+			const SPtr<Vector<TGpuParamStruct<false>>>& gpuParams) const
+		{
+			return TMaterialParamStruct<false>(name, getCachedParams(), gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamStruct<true> createStructParam(const String& name, 
+			const SPtr<Vector<TGpuParamStruct<true>>>& gpuParams) const
+		{
+			return TMaterialParamStruct<true>(gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamTexture<false> createTextureParam(const String& name, 
+			const SPtr<Vector<TGpuParamTexture<false>>>& gpuParams) const
+		{
+			return TMaterialParamTexture<false>(name, getCachedParams(), gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamTexture<true> createTextureParam(const String& name,
+			const SPtr<Vector<TGpuParamTexture<true>>>& gpuParams) const
+		{
+			return TMaterialParamTexture<true>(gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamLoadStoreTexture<false> createLoadStoreTextureParam(const String& name, 
+			const SPtr<Vector<TGpuParamLoadStoreTexture<false>>>& gpuParams) const
+		{
+			return TMaterialParamLoadStoreTexture<false>(name, getCachedParams(), gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamLoadStoreTexture<true> createLoadStoreTextureParam(const String& name,
+			const SPtr<Vector<TGpuParamLoadStoreTexture<true>>>& gpuParams) const
+		{
+			return TMaterialParamLoadStoreTexture<true>(gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamSampState<false> createSamplerStateParam(const String& name, 
+			const SPtr<Vector<TGpuParamSampState<false>>>& gpuParams) const
+		{
+			return TMaterialParamSampState<false>(name, getCachedParams(), gpuParams);
+		}
+
+		/** 
+		 * Creates a material param out of multiple GPU params. Caller must ensure all GPU params reference the same 
+		 * parameter. 
+		 */
+		TMaterialParamSampState<true> createSamplerStateParam(const String& name,
+			const SPtr<Vector<TGpuParamSampState<true>>>& gpuParams) const
+		{
+			return TMaterialParamSampState<true>(gpuParams);
+		}
+
+		/**
+		 * Assigns a value from a raw buffer to the parameter with the specified name. Buffer must be of sizeof(T) * 
+		 * numElements size and initialized.
+		 *
+		 * @note	Provided parameter must exist, no checking is done.
+		 */
+		template <typename T>
+		void setParamValue(const String& name, UINT8* buffer, UINT32 numElements);
+
+		/** Called during initialization, creates enough space to cache all parameters (not used on core thread). */
+		void createCachedParams(const SPtr<ShaderCore>& shader) { /* Do nothing */}
+
+		/** Called during initialization, creates enough space to cache all parameters. */
+		virtual void createCachedParams(const HShader& shader) { }
+
+		/** Returns a list of all values assigned to material parameters. */
+		virtual SPtr<MaterialParams> getCachedParams() const { return nullptr; }
+
+		/**
+		 * Initializes the material by using the best technique from the currently set shader. Shader must contain the 
+		 * technique that matches the current renderer and render system.
+		 */
+		void initBestTechnique();
+
+		/** Assigns all the default parameters specified in the shader to the material. */
+		void initDefaultParameters();
+
+		/** Throw an exception if no shader is set, or no acceptable technique was found. */
+		void throwIfNotInitialized() const;
+
+		Vector<SPtr<PassParamsType>> mParametersPerPass;
+		ShaderType mShader;
+		TechniqueType mBestTechnique;
+	};
+
+	/** @} */
+
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/** @cond INTERNAL */
+
+	/** @copydoc MaterialBase */
+	class BS_CORE_EXPORT MaterialCore : public CoreObjectCore, public TMaterial<true>
+	{
+	public:
+		~MaterialCore() { }
+
+		/** @copydoc Material::setShader */
+		void setShader(const SPtr<ShaderCore>& shader);
+
+		/** Creates a new material with the specified shader. */
+		static SPtr<MaterialCore> create(const SPtr<ShaderCore>& shader);
+
+	private:
+		friend class Material;
+
+		MaterialCore() { }
+		MaterialCore(const SPtr<ShaderCore>& shader);
+		MaterialCore(const SPtr<ShaderCore>& shader, const SPtr<TechniqueCore>& bestTechnique, 
+			const Set<String>& validShareableParamBlocks, const Map<String, String>& validParams, 
+			const Vector<SPtr<PassParametersCore>>& passParams);
+
+		/** @copydoc CoreObjectCore::syncToCore */
+		void syncToCore(const CoreSyncData& data) override;
+	};
+
+	/** @endcond */
+
+	/** @copydoc MaterialBase */
+	class BS_CORE_EXPORT Material : public Resource, public TMaterial<false>, public IResourceListener
+	{
+	public:
+		~Material() { }
+
+		/**
+		 * Sets a shader that will be used by the material. Best technique within the provided shader will be used for the 
+		 * material.
+		 *
+		 * @note	
+		 * Shader must be set before doing any other operations with the material.
+		 * @note			
+		 * After setting the shader if change any systems that a shader technique is dependent upon (render system, 
+		 * renderer, etc), you will need to call this method again on all your Materials to make sure technique used is 
+		 * updated.
+		 */
+		void setShader(const HShader& shader);
+
+		/** Retrieves an implementation of a material usable only from the core thread. */
+		SPtr<MaterialCore> getCore() const;
+
+		/** @copydoc CoreObject::initialize */
+		void initialize() override;
+
+		/** Creates a deep copy of the material and returns the new object. */
+		HMaterial Material::clone();
+
+		/**
+		 * Creates a new empty material.
+		 * 			
+		 * @note	Make sure you call Material::setShader before using it.
+		 */
+		static HMaterial create();
+
+		/** Creates a new material with the specified shader. */
+		static HMaterial create(const HShader& shader);
+
+	private:
+		friend class MaterialManager;
+
+		Material();
+		Material(const HShader& shader);
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::syncToCore */
+		CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		/** @copydoc CoreObject::getCoreDependencies */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+		/** @copydoc CoreObject::markCoreDirty */
+		void _markCoreDirty() override;
+
+		/** @copydoc CoreObject::markDependenciesDirty */
+		void _markDependenciesDirty() override;
+
+		/** @copydoc IResourceListener::markResourcesDirty */
+		void _markResourcesDirty() override;
+
+		/** @copydoc IResourceListener::getListenerResources */
+		void getListenerResources(Vector<HResource>& resources) override;
+
+		/** @copydoc IResourceListener::notifyResourceLoaded */
+		void notifyResourceLoaded(const HResource& resource) override;
+
+		/** @copydoc IResourceListener::notifyResourceChanged */
+		void notifyResourceChanged(const HResource& resource) override;
+
+		/** @copydoc Resource::getResourceDependencies */
+		void getResourceDependencies(FrameVector<HResource>& dependencies) const override;
+
+		/**	Performs material initialization when all resources are ready. */
+		void initializeIfLoaded();
+
+		/** @copydoc Material::createCachedParams */
+		void createCachedParams(const HShader& shader) override;
+
+		/** @copydoc Material::getCachedParams */
+		SPtr<MaterialParams> getCachedParams() const override { return mCachedParams; }
+
+		/** 
+		 * Uses the provided list of parameters to try to set every parameter in this material. Parameter whose name, type
+		 * or size don't match are ignored and will not be set.
+		 */
+		void setParams(const SPtr<MaterialParams>& params);
+
+		UINT32 mLoadFlags;
+		SPtr<MaterialParams> mCachedParams;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+		
+	public:
+		friend class MaterialRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 38 - 25
BansheeCore/Include/BsMaterialManager.h

@@ -1,26 +1,39 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Material manager handles material creation.
-	 */
-	class BS_CORE_EXPORT MaterialManager : public Module<MaterialManager>
-	{
-	public:
-		/**
-		 * @brief	Creates a new material without any assigned shader.
-		 *
-		 * @note	Make sure to call Material::setShader before using it.
-		 */
-		MaterialPtr create() const;
-
-		/**
-		 * @brief	Creates a new material with the specified shader.
-		 */
-		MaterialPtr create(ShaderPtr shader) const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/**	Material manager handles material creation. */
+	class BS_CORE_EXPORT MaterialManager : public Module<MaterialManager>
+	{
+	public:
+		/**
+		 * Creates a new material without any assigned shader.
+		 *
+		 * @note	Make sure to call Material::setShader() before using it.
+		 */
+		MaterialPtr create() const;
+
+		/** Creates a new material with the specified shader. */
+		MaterialPtr create(const HShader& shader) const;
+
+		/**
+		 * Creates a new empty material without initializing it.
+		 *
+		 * @note	You must manually call Material::initialize() after creation.
+		 */
+		MaterialPtr createEmpty() const;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 303 - 0
BansheeCore/Include/BsMaterialParam.h

@@ -0,0 +1,303 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuParam.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	class MaterialParams;
+
+	/**
+	 * A handle that allows you to set a Material parameter. Internally keeps a reference to the material parameters so that
+	 * possibly expensive lookup of parameter name can be avoided each time the parameter is accessed, and instead the 
+	 * handle can be cached.
+	 * 			
+	 * @note	
+	 * This is pretty much identical to GPU parameter version (e.g. TGpuDataParam), except that this will get/set parameter 
+	 * values on all GPU programs attached to the material, while TGpuDataParam works only for single GPU program's 
+	 * parameters. Also, additional parameters that might be optimized out in the GPU program will still exist here as long 
+	 * as they're  defined in the shader used by the material, which is not the case with TGpuDataParam.
+	 * @note
+	 * For core-thread version of this class no shader-based caching is done, and instead this represents just a wrapper
+	 * for multiple GPU parameters.
+	 * 
+	 * @see		Material
+	 */
+	template<class T, bool Core>
+	class BS_CORE_EXPORT TMaterialDataParam
+	{ };
+
+	/** @copydoc TMaterialDataParam */
+	template<class T>
+	class BS_CORE_EXPORT TMaterialDataParam<T, false>
+	{
+	public:
+		TMaterialDataParam(const String& name, const SPtr<MaterialParams>& params, 
+			const SPtr<Vector<TGpuDataParam<T, false>>>& gpuParams);
+		TMaterialDataParam() { }
+
+		/** @copydoc TGpuDataParam::set */
+		void set(const T& value, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuDataParam::get */
+		T get(UINT32 arrayIdx = 0);
+
+	protected:
+		UINT32 mParamIndex;
+		UINT32 mArraySize;
+		SPtr<MaterialParams> mMaterialParams;
+		SPtr<Vector<TGpuDataParam<T, false>>> mGPUParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<class T>
+	class BS_CORE_EXPORT TMaterialDataParam<T, true>
+	{
+	public:
+		TMaterialDataParam(const SPtr<Vector<TGpuDataParam<T, true>>>& params);
+		TMaterialDataParam() { }
+
+		/** @copydoc TGpuDataParam::set */
+		void set(const T& value, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuDataParam::get */
+		T get(UINT32 arrayIdx = 0);
+
+	protected:
+		SPtr<Vector<TGpuDataParam<T, true>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamStruct
+	{ };
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamStruct<false>
+	{
+	public:
+		TMaterialParamStruct(const String& name, const SPtr<MaterialParams>& params,
+			const SPtr<Vector<TGpuParamStruct<false>>>& gpuParams);
+		TMaterialParamStruct() { }
+
+		/** @copydoc TGpuParamStruct::set */
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuParamStruct::get */
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuParamStruct::getElementSize */
+		UINT32 getElementSize() const;
+
+	protected:
+		UINT32 mParamIndex;
+		UINT32 mArraySize;
+		SPtr<MaterialParams> mMaterialParams;
+		SPtr<Vector<TGpuParamStruct<false>>> mGPUParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamStruct<true>
+	{
+	public:
+		TMaterialParamStruct(const SPtr<Vector<TGpuParamStruct<true>>>& params);
+		TMaterialParamStruct() { }
+
+		/** @copydoc TGpuParamStruct::set */
+		void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuParamStruct::get */
+		void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0);
+
+		/** @copydoc TGpuParamStruct::getElementSize */
+		UINT32 getElementSize() const;
+
+	protected:
+		SPtr<Vector<TGpuParamStruct<true>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamTexture
+	{ };
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamTexture<false>
+	{
+	public:
+		TMaterialParamTexture(const String& name, const SPtr<MaterialParams>& params, 
+			const SPtr<Vector<TGpuParamTexture<false>>>& gpuParams);
+		TMaterialParamTexture() { }
+
+		/** @copydoc GpuParamTexture::set */
+		void set(const HTexture& texture);
+
+		/** @copydoc GpuParamTexture::get */
+		HTexture get();
+
+	protected:
+		UINT32 mParamIndex;
+		SPtr<MaterialParams> mMaterialParams;
+		SPtr<Vector<TGpuParamTexture<false>>> mGPUParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamTexture<true>
+	{
+	public:
+		TMaterialParamTexture(const SPtr<Vector<TGpuParamTexture<true>>>& params);
+		TMaterialParamTexture() { }
+
+		/** @copydoc GpuParamTexture::set */
+		void set(const SPtr<TextureCore>& texture);
+
+		/** @copydoc GpuParamTexture::get */
+		SPtr<TextureCore> get();
+
+	protected:
+		SPtr<Vector<TGpuParamTexture<true>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamLoadStoreTexture
+	{ };
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamLoadStoreTexture<false>
+	{
+	public:
+		TMaterialParamLoadStoreTexture(const String& name, const SPtr<MaterialParams>& params,
+			const SPtr<Vector<TGpuParamLoadStoreTexture<false>>>& gpuParams);
+		TMaterialParamLoadStoreTexture() { }
+
+		/** @copydoc GpuParamLoadStoreTexture::set */
+		void set(const HTexture& texture, const TextureSurface& surface);
+
+		/** @copydoc GpuParamLoadStoreTexture::get */
+		HTexture get();
+
+	protected:
+		UINT32 mParamIndex;
+		SPtr<MaterialParams> mMaterialParams;
+		SPtr<Vector<TGpuParamLoadStoreTexture<false>>> mGPUParams;
+	};
+
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamLoadStoreTexture<true>
+	{
+	public:
+		TMaterialParamLoadStoreTexture(const SPtr<Vector<TGpuParamLoadStoreTexture<true>>>& params);
+		TMaterialParamLoadStoreTexture() { }
+
+		/** @copydoc GpuParamLoadStoreTexture::set */
+		void set(const SPtr<TextureCore>& texture, const TextureSurface& surface);
+
+		/** @copydoc GpuParamLoadStoreTexture::get */
+		SPtr<TextureCore> get();
+
+	protected:
+		SPtr<Vector<TGpuParamLoadStoreTexture<true>>> mParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<bool Core>
+	class BS_CORE_EXPORT TMaterialParamSampState
+	{ };
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamSampState<false>
+	{
+	public:
+		TMaterialParamSampState(const String& name, const SPtr<MaterialParams>& params, 
+			const SPtr<Vector<TGpuParamSampState<false>>>& gpuParams);
+		TMaterialParamSampState() { }
+
+		/** @copydoc GpuParamSampState::set */
+		void set(const SPtr<SamplerState>& sampState);
+
+		/** @copydoc GpuParamSampState::get */
+		SPtr<SamplerState> get();
+
+	protected:
+		UINT32 mParamIndex;
+		SPtr<MaterialParams> mMaterialParams;
+		SPtr<Vector<TGpuParamSampState<false>>> mGPUParams;
+	};
+
+	/** @copydoc TMaterialDataParam */
+	template<>
+	class BS_CORE_EXPORT TMaterialParamSampState<true>
+	{
+	public:
+		TMaterialParamSampState(const SPtr<Vector<TGpuParamSampState<true>>>& params);
+		TMaterialParamSampState() { }
+
+		/** @copydoc GpuParamSampState::set */
+		void set(const SPtr<SamplerStateCore>& sampState);
+
+		/** @copydoc GpuParamSampState::get */
+		SPtr<SamplerStateCore> get();
+
+	protected:
+		SPtr<Vector<TGpuParamSampState<true>>> mParams;
+	};
+
+	/** @} */
+
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	typedef TMaterialDataParam<float, false> MaterialParamFloat;
+	typedef TMaterialDataParam<Vector2, false> MaterialParamVec2;
+	typedef TMaterialDataParam<Vector3, false> MaterialParamVec3;
+	typedef TMaterialDataParam<Vector4, false> MaterialParamVec4;
+	typedef TMaterialDataParam<int, false> MaterialParamInt;
+	typedef TMaterialDataParam<Vector2I, false> MaterialParamVec2I;
+	typedef TMaterialDataParam<Vector3I, false> MaterialParamVec3I;
+	typedef TMaterialDataParam<Vector4I, false> MaterialParamVec4I;
+	typedef TMaterialDataParam<Matrix3, false> MaterialParamMat3;
+	typedef TMaterialDataParam<Matrix4, false> MaterialParamMat4;
+	typedef TMaterialDataParam<Color, false> MaterialParamColor;
+
+	typedef TMaterialDataParam<float, true> MaterialParamFloatCore;
+	typedef TMaterialDataParam<Vector2, true> MaterialParamVec2Core;
+	typedef TMaterialDataParam<Vector3, true> MaterialParamVec3Core;
+	typedef TMaterialDataParam<Vector4, true> MaterialParamVec4Core;
+	typedef TMaterialDataParam<int, true> MaterialParamIntCore;
+	typedef TMaterialDataParam<Vector2I, true> MaterialParamVec2ICore;
+	typedef TMaterialDataParam<Vector3I, true> MaterialParamVec3ICore;
+	typedef TMaterialDataParam<Vector4I, true> MaterialParamVec4ICore;
+	typedef TMaterialDataParam<Matrix3, true> MaterialParamMat3Core;
+	typedef TMaterialDataParam<Matrix4, true> MaterialParamMat4Core;
+	typedef TMaterialDataParam<Color, true> MaterialParamColorCore;
+
+	typedef TMaterialParamStruct<false> MaterialParamStruct;
+	typedef TMaterialParamStruct<true> MaterialParamStructCore;
+
+	typedef TMaterialParamTexture<false> MaterialParamTexture;
+	typedef TMaterialParamTexture<true> MaterialParamTextureCore;
+
+	typedef TMaterialParamLoadStoreTexture<false> MaterialParamLoadStoreTexture;
+	typedef TMaterialParamLoadStoreTexture<true> MaterialParamLoadStoreTextureCore;
+
+	typedef TMaterialParamSampState<false> MaterialParamSampState;
+	typedef TMaterialParamSampState<true> MaterialParamSampStateCore;
+
+	/** @} */
+}

+ 396 - 0
BansheeCore/Include/BsMaterialParams.h

@@ -0,0 +1,396 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
+#include "BsStaticAlloc.h"
+#include "BsVector2.h"
+#include "BsVector3.h"
+#include "BsVector4.h"
+#include "BsVector2I.h"
+#include "BsVectorNI.h"
+#include "BsColor.h"
+#include "BsMatrix3.h"
+#include "BsMatrix4.h"
+#include "BsMatrixNxM.h"
+#include "BsGpuParams.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/** 
+	 * Contains all parameter values set in a Material. This is similar to GpuParams which also stores parameter values,
+	 * however GpuParams are built for use on the GPU-side and don't store parameters that don't exist in a compiled GPU
+	 * program. This object on the other hand stores all parameters defined in a shader, regardless or not if they actually
+	 * exist in the GPU program. Additionally GpuParams are defined per-program (e.g. vertex, fragment) while this object
+	 * exists for the entire material.
+	 *
+	 * @note
+	 * This introduces redundancy as parameters stored by GpuParams and this object are duplicated. If this is an issue the
+	 * implementation can be modified to only store parameters not included in GpuParams.
+	 * @note
+	 * The reason why parameters in this class and GpuParams differ is most often compiler optimizations. If a compiler
+	 * optimizes out a variable in a GPU program we should still be able to store it, either for later when the variable
+	 * will be introduced, or for other techniques that might have that variable implemented.
+	 */
+	class BS_CORE_EXPORT MaterialParams : public IReflectable
+	{
+	public:
+		/** Type of material parameter. */
+		enum class ParamType
+		{
+			Data, Texture, Sampler
+		};
+
+		/** Result codes for getParam method. */
+		enum class GetParamResult
+		{
+			Success,
+			NotFound,
+			InvalidType,
+			IndexOutOfBounds
+		};
+
+		/** Meta-data about a parameter. */
+		struct ParamData
+		{
+			ParamType type;
+			GpuParamDataType dataType;
+			UINT32 index;
+			UINT32 arraySize;
+		};
+
+		/** Raw data for a single structure parameter. */
+		class BS_CORE_EXPORT StructParamData : public IReflectable
+		{
+		public:
+			UINT8* data;
+			UINT32 dataSize;
+
+			friend class StructParamDataRTTI;
+			static RTTITypeBase* getRTTIStatic();
+			virtual RTTITypeBase* getRTTI() const override;
+		};
+
+		/** Data for a single texture parameter. */
+		class BS_CORE_EXPORT TextureParamData : public IReflectable
+		{
+		public:
+			HTexture value;
+			bool isLoadStore;
+			TextureSurface surface;
+
+			friend class TextureParamDataRTTI;
+			static RTTITypeBase* getRTTIStatic();
+			virtual RTTITypeBase* getRTTI() const override;
+		};
+
+		/** Creates a new material params object and initializes enough room for parameters from the provided shader. */
+		MaterialParams(const HShader& shader);
+		~MaterialParams();
+
+		/** 
+		 * Returns the value of a shader data parameter with the specified name at the specified array index. If the
+		 * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	arrayIdx	If the parameter is an array, index of the entry to access.
+		 * @param[out]	output		If successful, value of the parameter.
+		 *
+		 * @tparam		T			Native type of the parameter.
+		 */
+		template <typename T>
+		void getDataParam(const String& name, UINT32 arrayIdx, T& output) const
+		{
+			GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId;
+
+			const ParamData* param = nullptr;
+			auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, &param);
+			if (result != GetParamResult::Success)
+				return;
+
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES[dataType];
+			UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+			output = *(T*)(mDataParamsBuffer[param->index + arrayIdx * paramTypeSize]);
+
+			memcpy(output, &mDataParamsBuffer[param->index + arrayIdx * paramTypeSize], sizeof(paramTypeSize));
+		}
+
+		/** 
+		 * Sets the value of a shader data parameter with the specified name at the specified array index. If the
+		 * parameter name, index or type is not valid a warning will be logged and output value will not be set.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	arrayIdx	If the parameter is an array, index of the entry to access.
+		 * @param[in]	input		New value of the parameter.
+		 *
+		 * @tparam		T			Native type of the parameter.
+		 */
+		template <typename T>
+		void setDataParam(const String& name, UINT32 arrayIdx, const T& input) const
+		{
+			GpuParamDataType dataType = TGpuDataParamInfo<T>::TypeId;
+
+			const ParamData* param = nullptr;
+			auto result = getParamData(name, ParamType::Data, dataType, arrayIdx, &param);
+			if (result != GetParamResult::Success)
+				return;
+
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES[dataType];
+			UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
+			memcpy(&mDataParamsBuffer[param->index + arrayIdx * paramTypeSize], input, sizeof(paramTypeSize));
+		}
+
+		/** 
+		 * Returns the value of a shader structure parameter with the specified name at the specified array index. If the
+		 * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[out]	value		Pre-allocated buffer of @p size bytes where the value will be retrieved.
+		 * @param[in]	size		Size of the buffer into which to write the value. Must match parameter struct's size.
+		 * @param[in]	arrayIdx	If the parameter is an array, index of the entry to access.
+		 */
+		void getStructData(const String& name, void* value, UINT32 size, UINT32 arrayIdx) const;
+
+		/** 
+		 * Sets the value of a shader structure parameter with the specified name at the specified array index. If the
+		 * parameter name, index or type is not valid a warning will be logged and output value will not be retrieved.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	value		Buffer of @p size bytes containing the new value of the structure.
+		 * @param[in]	size		Size of the buffer from which to retrieve the value. Must match parameter struct's size.
+		 * @param[in]	arrayIdx	If the parameter is an array, index of the entry to access.
+		 */
+		void setStructData(const String& name, const void* value, UINT32 size, UINT32 arrayIdx);
+
+		/** 
+		 * Returns the value of a shader texture parameter with the specified name. If the parameter name or type is not 
+		 * valid a warning will be logged and output value will not be retrieved.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[out]	value		Output value of the parameter.
+		 */
+		void getTexture(const String& name, HTexture& value) const;
+
+		/** 
+		 * Sets the value of a shader texture parameter with the specified name. If the parameter name or type is not 
+		 * valid a warning will be logged and output value will not be set.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	value		New value of the parameter.
+		 */
+		void setTexture(const String& name, const HTexture& value);
+
+		/** 
+		 * Returns the value of a shader load/store texture parameter with the specified name. If the parameter name or 
+		 * type is not valid a warning will be logged and output value will not be retrieved.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[out]	value		Output value of the parameter.
+		 * @param[out]	surface		Surface describing which part of the texture is being accessed.
+		 */
+		void getLoadStoreTexture(const String& name, HTexture& value, TextureSurface& surface) const;
+
+		/** 
+		 * Sets the value of a shader load/store texture parameter with the specified name. If the parameter name or 
+		 * type is not valid a warning will be logged and the value will not be set.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	value		New value of the parameter.
+		 * @param[in]	surface		Surface describing which part of the texture is being accessed.
+		 */
+		void setLoadStoreTexture(const String& name, const HTexture& value, const TextureSurface& surface);
+
+		/** 
+		 * Sets the value of a shader sampler state parameter with the specified name. If the parameter name or type is not 
+		 * valid a warning will be logged and output value will not be set.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[out]	value		Output value of the parameter.
+		 */
+		void getSamplerState(const String& name, SamplerStatePtr& value) const;
+
+		/** 
+		 * Sets the value of a shader sampler state parameter with the specified name. If the parameter name or type is not 
+		 * valid a warning will be logged and output value will not be set.
+		 * 
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	value		New value of the parameter.
+		 */
+		void setSamplerState(const String& name, const SamplerStatePtr& value);
+
+		/** 
+		 * Returns data about a parameter and reports an error if there is a type or size mismatch, or if the parameter
+		 * does exist.
+		 *
+		 * @param[in]	name		Name of the shader parameter.
+		 * @param[in]	type		Type of the parameter retrieve. Error will be logged if actual type of the parameter 
+		 *							doesn't match.
+		 * @param[in]	dataType	Only relevant if the parameter is a data type. Determines exact data type of the parameter
+		 *							to retrieve. 
+		 * @param[in]	arrayIdx	Array index of the entry to retrieve. 
+		 * @param[out]	output		Object describing the parameter with an index to its data. If the parameter was not found
+		 *							this value is undefined. This value will still be valid if parameter was found but
+		 *							some other error was reported.
+		 *
+		 * @return					Success or error state of the request.
+		 */
+		GetParamResult getParamData(const String& name, ParamType type, GpuParamDataType dataType, UINT32 arrayIdx, 
+			const ParamData** output) const;
+
+		/**
+		 * Logs an error that was reported by getParamData().
+		 *
+		 * @param[in]	name		Name of the shader parameter for which the error occurred.
+		 * @param[in]	arrayIdx	Array index for which the error occurred. 
+		 */
+		void reportGetParamError(GetParamResult errorCode, const String& name, UINT32 arrayIdx) const;
+
+		/** 
+		 * Equivalent to getStructData(const String&, UINT32, T&) except it uses the internal parameter index
+		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		template <typename T>
+		void getDataParam(UINT32 index, UINT32 arrayIdx, T& output) const
+		{
+			GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId;
+
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType];
+			UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
+			assert(sizeof(output) == paramTypeSize);
+			memcpy(&output, &mDataParamsBuffer[index + arrayIdx * paramTypeSize], paramTypeSize);
+		}
+
+		/** 
+		 * Equivalent to setDataParam(const String&, UINT32, T&) except it uses the internal parameter index
+		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		template <typename T>
+		void setDataParam(UINT32 index, UINT32 arrayIdx, const T& input) const
+		{
+			GpuParamDataType dataType = (GpuParamDataType)TGpuDataParamInfo<T>::TypeId;
+
+			const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[dataType];
+			UINT32 paramTypeSize = typeInfo.numColumns * typeInfo.numRows * typeInfo.baseTypeSize;
+
+			assert(sizeof(input) == paramTypeSize);
+			memcpy(&mDataParamsBuffer[index + arrayIdx * paramTypeSize], &input, paramTypeSize);
+		}
+
+		/** 
+		 * Equivalent to getStructData(const String&, UINT32, void*, UINT32) except it uses the internal parameter index
+		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void getStructData(UINT32 index, void* value, UINT32 size) const;
+
+		/** 
+		 * Equivalent to setStructData(const String&, UINT32, void*, UINT32) except it uses the internal parameter index
+		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void setStructData(UINT32 index, const void* value, UINT32 size);
+
+		/** 
+		 * Returns a size of a struct parameter in bytes, using the internal parameter index. Caller must guarantee the 
+		 * index is valid. 
+		 */
+		UINT32 getStructSize(UINT32 index) const;
+
+		/** 
+		 * Equivalent to getTexture(const String&, HTexture&) except it uses the internal parameter index directly, 
+		 * avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void getTexture(UINT32 index, HTexture& value) const;
+
+		/** 
+		 * Equivalent to setTexture(const String&, HTexture&) except it uses the internal parameter index directly, 
+		 * avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void setTexture(UINT32 index, const HTexture& value);
+
+		/** 
+		 * Equivalent to getLoadStoreTexture(const String&, HTexture&, TextureSurface&) except it uses the internal 
+		 * parameter index directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void getLoadStoreTexture(UINT32 index, HTexture& value, TextureSurface& surface) const;
+
+		/** 
+		 * Equivalent to setLoadStoreTexture(const String&, HTexture&, TextureSurface&) except it uses the internal 
+		 * parameter index directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void setLoadStoreTexture(UINT32 index, const HTexture& value, const TextureSurface& surface);
+
+		/** 
+		 * Checks is a texture with the specified index a load/store texture or a normal one. Caller must guarantee the 
+		 * index is valid.
+		 */
+		bool getIsTextureLoadStore(UINT32 index) const;
+
+		/** 
+		 * Equivalent to getSamplerState(const String&, SamplerStatePtr&) except it uses the internal parameter index 
+		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void getSamplerState(UINT32 index, SamplerStatePtr& value) const;
+
+		/** 
+		 * Equivalent to setSamplerState(const String&, SamplerStatePtr&) except it uses the internal parameter index 
+		 * directly, avoiding the name lookup. Caller must guarantee the index is valid.
+		 */
+		void setSamplerState(UINT32 index, const SamplerStatePtr& value);
+
+		/** 
+		 * Returns the default texture (one assigned when no other is provided), if available for the specified index. 
+		 * Index is the internal parameter index and the caller must guarantee the index is valid.
+		 */
+		void getDefaultTexture(UINT32 index, HTexture& value) const;
+
+		/** 
+		 * Returns the default sampler state (one assigned when no other is provided), if available for the specified index.
+		 * Index is the internal parameter index and the caller must guarantee the index is valid.
+		 */
+		void getDefaultSamplerState(UINT32 index, SamplerStatePtr& value) const;
+
+	private:
+		const static UINT32 STATIC_BUFFER_SIZE = 256;
+
+		UnorderedMap<String, ParamData> mParams;
+
+		UINT8* mDataParamsBuffer = nullptr;
+		StructParamData* mStructParams = nullptr;
+		TextureParamData* mTextureParams = nullptr;
+		SamplerStatePtr* mSamplerStateParams = nullptr;
+		HTexture* mDefaultTextureParams = nullptr;
+		SamplerStatePtr* mDefaultSamplerStateParams = nullptr;
+
+		UINT32 mDataSize = 0;
+		UINT32 mNumStructParams = 0;
+		UINT32 mNumTextureParams = 0;
+		UINT32 mNumSamplerParams = 0;
+
+		mutable StaticAlloc<STATIC_BUFFER_SIZE, STATIC_BUFFER_SIZE> mAlloc;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		MaterialParams() { } // Only for serialization
+
+		friend class MaterialParamsRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @cond SPECIALIZATIONS */
+	BS_ALLOW_MEMCPY_SERIALIZATION(MaterialParams::ParamData);
+	/** @endcond */
+
+	/** @} */
+	/** @endcond */
+}

+ 275 - 0
BansheeCore/Include/BsMaterialParamsRTTI.h

@@ -0,0 +1,275 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsMaterialParams.h"
+#include "BsSamplerState.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT TextureParamDataRTTI : public RTTIType<MaterialParams::TextureParamData, IReflectable, TextureParamDataRTTI>
+	{
+	public:
+		HTexture& getTexture(MaterialParams::TextureParamData* obj) { return obj->value; }
+		void setTexture(MaterialParams::TextureParamData* obj, HTexture& value) { obj->value = value; }
+
+		bool& getIsLoadStore(MaterialParams::TextureParamData* obj) { return obj->isLoadStore; }
+		void setIsLoadStore(MaterialParams::TextureParamData* obj, bool& value) { obj->isLoadStore = value; }
+
+		TextureSurface& getSurface(MaterialParams::TextureParamData* obj) { return obj->surface; }
+		void setSurface(MaterialParams::TextureParamData* obj, TextureSurface& value) { obj->surface = value; }
+
+		TextureParamDataRTTI()
+		{
+			addReflectableField("texture", 0, &TextureParamDataRTTI::getTexture, &TextureParamDataRTTI::setTexture);
+			addPlainField("isLoadStore", 1, &TextureParamDataRTTI::getIsLoadStore, &TextureParamDataRTTI::setIsLoadStore);
+			addPlainField("surface", 2, &TextureParamDataRTTI::getSurface, &TextureParamDataRTTI::setSurface);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "TextureParamData";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_TextureParamData;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<MaterialParams::TextureParamData>();
+		}
+	};
+
+	class BS_CORE_EXPORT StructParamDataRTTI : public RTTIType<MaterialParams::StructParamData, IReflectable, StructParamDataRTTI>
+	{
+	public:
+		ManagedDataBlock getDataBuffer(MaterialParams::StructParamData* obj)
+		{
+			return ManagedDataBlock(obj->data, obj->dataSize);
+		}
+
+		void setDataBuffer(MaterialParams::StructParamData* obj, ManagedDataBlock value)
+		{
+			// Do nothing as the buffer was already assigned when it was allocated
+		}
+
+		static UINT8* allocateDataBuffer(MaterialParams::StructParamData* obj, UINT32 numBytes)
+		{
+			obj->data = (UINT8*)bs_alloc(numBytes);
+			obj->dataSize = numBytes;
+
+			return obj->data;
+		}
+
+		StructParamDataRTTI()
+		{
+			addDataBlockField("dataBuffer", 0, &StructParamDataRTTI::getDataBuffer,
+				&StructParamDataRTTI::setDataBuffer, 0, &StructParamDataRTTI::allocateDataBuffer);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "StructParamData";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_StructParamData;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<MaterialParams::StructParamData>();
+		}
+	};
+
+	class BS_CORE_EXPORT MaterialParamsRTTI : public RTTIType<MaterialParams, IReflectable, MaterialParamsRTTI>
+	{
+	public:
+		struct MaterialParam
+		{
+			String name;
+			MaterialParams::ParamData data;
+		};
+
+		MaterialParam& getParamData(MaterialParams* obj, UINT32 idx)
+		{
+			Vector<MaterialParam>& params = any_cast_ref<Vector<MaterialParam>>(obj->mRTTIData);
+			return params[idx];
+		}
+
+		void setParamData(MaterialParams* obj, UINT32 idx, MaterialParam& param)
+		{
+			obj->mParams[param.name] = param.data;
+		}
+
+		UINT32 getParamDataArraySize(MaterialParams* obj)
+		{
+			Vector<MaterialParam>& params = any_cast_ref<Vector<MaterialParam>>(obj->mRTTIData);
+			return (UINT32)params.size();
+		}
+
+		void setParamDataArraySize(MaterialParams* obj, UINT32 size)
+		{
+			// Do nothing
+		}
+
+		ManagedDataBlock getDataBuffer(MaterialParams* obj)
+		{
+			return ManagedDataBlock(obj->mDataParamsBuffer, obj->mDataSize);
+		}
+
+		void setDataBuffer(MaterialParams* obj, ManagedDataBlock value)
+		{
+			// Do nothing as the buffer was already assigned when it was allocated
+		}
+
+		static UINT8* allocateDataBuffer(MaterialParams* obj, UINT32 numBytes)
+		{
+			obj->mDataParamsBuffer = obj->mAlloc.alloc(numBytes);
+			obj->mDataSize = numBytes;
+
+			return obj->mDataParamsBuffer;
+		}
+
+		MaterialParams::StructParamData& getStructParam(MaterialParams* obj, UINT32 idx) { return obj->mStructParams[idx]; }
+		void setStructParam(MaterialParams* obj, UINT32 idx, MaterialParams::StructParamData& param)
+		{
+			MaterialParams::StructParamData& newStructParam = obj->mStructParams[idx];
+			newStructParam.data = (UINT8*)obj->mAlloc.alloc(param.dataSize);
+			memcpy(newStructParam.data, param.data, param.dataSize);
+			newStructParam.dataSize = param.dataSize;
+
+			bs_free(param.data);
+			param.data = nullptr;
+		}
+		UINT32 getStructArraySize(MaterialParams* obj) { return (UINT32)obj->mNumStructParams; }
+		void setStructArraySize(MaterialParams* obj, UINT32 size)
+		{
+			obj->mNumStructParams = size;
+			obj->mStructParams = obj->mAlloc.construct<MaterialParams::StructParamData>(size);
+		}
+
+		MaterialParams::TextureParamData& getTextureParam(MaterialParams* obj, UINT32 idx) { return obj->mTextureParams[idx]; }
+		void setTextureParam(MaterialParams* obj, UINT32 idx, MaterialParams::TextureParamData& param) { obj->mTextureParams[idx] = param; }
+		UINT32 getTextureArraySize(MaterialParams* obj) { return (UINT32)obj->mNumTextureParams; }
+		void setTextureArraySize(MaterialParams* obj, UINT32 size)
+		{
+			obj->mNumTextureParams = size;
+			obj->mTextureParams = obj->mAlloc.construct<MaterialParams::TextureParamData>(size);
+		}
+
+		SamplerStatePtr getSamplerStateParam(MaterialParams* obj, UINT32 idx) { return obj->mSamplerStateParams[idx]; }
+		void setSamplerStateParam(MaterialParams* obj, UINT32 idx, SamplerStatePtr param) { obj->mSamplerStateParams[idx] = param; }
+		UINT32 getSamplerStateArraySize(MaterialParams* obj) { return (UINT32)obj->mNumSamplerParams; }
+		void setSamplerStateArraySize(MaterialParams* obj, UINT32 size)
+		{
+			obj->mNumSamplerParams = size;
+			obj->mSamplerStateParams = obj->mAlloc.construct<SamplerStatePtr>(size);
+		}
+
+		MaterialParamsRTTI()
+		{
+			addPlainArrayField("paramData", 0, &MaterialParamsRTTI::getParamData, &MaterialParamsRTTI::getParamDataArraySize, 
+				&MaterialParamsRTTI::setParamData, &MaterialParamsRTTI::setParamDataArraySize);
+
+			addDataBlockField("dataBuffer", 1, &MaterialParamsRTTI::getDataBuffer,
+				&MaterialParamsRTTI::setDataBuffer, 0, &MaterialParamsRTTI::allocateDataBuffer);
+
+			addReflectableArrayField("structParams", 2, &MaterialParamsRTTI::getStructParam,
+				&MaterialParamsRTTI::getStructArraySize, &MaterialParamsRTTI::setStructParam, &MaterialParamsRTTI::setStructArraySize);
+
+			addReflectableArrayField("textureParams", 3, &MaterialParamsRTTI::getTextureParam,
+				&MaterialParamsRTTI::getTextureArraySize, &MaterialParamsRTTI::setTextureParam, &MaterialParamsRTTI::setTextureArraySize);
+
+			addReflectablePtrArrayField("samplerStateParams", 4, &MaterialParamsRTTI::getSamplerStateParam,
+				&MaterialParamsRTTI::getSamplerStateArraySize, &MaterialParamsRTTI::setSamplerStateParam, &MaterialParamsRTTI::setSamplerStateArraySize);
+		}
+
+		void onSerializationStarted(IReflectable* obj) override
+		{
+			MaterialParams* paramsObj = static_cast<MaterialParams*>(obj);
+			Vector<MaterialParam> params;
+
+			for(auto& entry : paramsObj->mParams)
+				params.push_back({ entry.first, entry.second });
+
+			paramsObj->mRTTIData = params;
+		}
+
+		void onSerializationEnded(IReflectable* obj) override
+		{
+			MaterialParams* paramsObj = static_cast<MaterialParams*>(obj);
+			paramsObj->mRTTIData = nullptr;
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "MaterialParams";
+			return name;
+		}
+
+		UINT32 getRTTIId() override 
+		{ 
+			return TID_MaterialParams; 
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<MaterialParams>();
+		}
+	};
+
+	template<> struct RTTIPlainType<MaterialParamsRTTI::MaterialParam>
+	{	
+		enum { id = TID_MaterialRTTIParam }; enum { hasDynamicSize = 1 };
+
+		static void toMemory(const MaterialParamsRTTI::MaterialParam& data, char* memory)
+		{ 
+			UINT32 size = getDynamicSize(data);
+
+			memory = rttiWriteElem(size, memory);
+			memory = rttiWriteElem(data.name, memory);
+			memory = rttiWriteElem(data.data, memory);
+		}
+
+		static UINT32 fromMemory(MaterialParamsRTTI::MaterialParam& data, char* memory)
+		{ 
+			UINT32 size = 0;
+			
+			memory = rttiReadElem(size, memory);
+			memory = rttiReadElem(data.name, memory);
+			memory = rttiReadElem(data.data, memory);
+
+			return size;
+		}
+
+		static UINT32 getDynamicSize(const MaterialParamsRTTI::MaterialParam& data)
+		{ 
+			UINT64 dataSize = rttiGetElemSize(data.name) + rttiGetElemSize(data.data) + sizeof(UINT32);
+
+#if BS_DEBUG_MODE
+			if(dataSize > std::numeric_limits<UINT32>::max())
+			{
+				__string_throwDataOverflowException();
+			}
+#endif
+
+			return (UINT32)dataSize;
+		}	
+	}; 
+
+	/** @} */
+	/** @endcond */
+}

+ 0 - 74
BansheeCore/Include/BsMaterialProxy.h

@@ -1,74 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains data about a single pass in a material used by the
-	 *			material proxy.
-	 */
-	struct BS_CORE_EXPORT MaterialProxyPass
-	{
-		HGpuProgram vertexProg;
-		HGpuProgram fragmentProg;
-		HGpuProgram geometryProg;
-		HGpuProgram hullProg;
-		HGpuProgram domainProg;
-		HGpuProgram computeProg;
-
-		UINT32 vertexProgParamsIdx;
-		UINT32 fragmentProgParamsIdx;
-		UINT32 geometryProgParamsIdx;
-		UINT32 hullProgParamsIdx;
-		UINT32 domainProgParamsIdx;
-		UINT32 computeProgParamsIdx;
-
-		HBlendState blendState;
-		HRasterizerState rasterizerState;
-		HDepthStencilState depthStencilState;
-		UINT32 stencilRefValue;
-	};
-
-	/**
-	 * @brief	Contains material information as seen by the core thread.
-	 *			(Used for rendering and such.)
-	 */
-	struct BS_CORE_EXPORT MaterialProxy
-	{
-		/**
-		 * @brief	Contains a hardware GPU parameter buffer and index of the parameters and the slot
-		 *			it binds to in a material proxy.
-		 */
-		struct BS_CORE_EXPORT BufferBindInfo
-		{
-			BufferBindInfo(UINT32 paramsIdx, UINT32 slotIdx, const GpuParamBlockBufferPtr& buffer)
-				:paramsIdx(paramsIdx), slotIdx(slotIdx), buffer(buffer)
-			{ }
-
-			UINT32 paramsIdx;
-			UINT32 slotIdx;
-			GpuParamBlockBufferPtr buffer;
-		};
-
-		/**
-		 * @brief	Contains GPU parameters and index of the parameters it binds to in the material proxy.
-		 */
-		struct BS_CORE_EXPORT ParamsBindInfo
-		{
-			ParamsBindInfo(UINT32 paramsIdx, const GpuParamsPtr& params)
-				:paramsIdx(paramsIdx), params(params)
-			{ }
-
-			UINT32 paramsIdx;
-			GpuParamsPtr params;
-		};
-
-		Vector<MaterialProxyPass> passes;
-		Vector<GpuParamsPtr> params;
-
-		ShaderProxyPtr shader;
-
-		Vector<BufferBindInfo> rendererBuffers;
-	};
-}

+ 49 - 590
BansheeCore/Include/BsMaterialRTTI.h

@@ -1,591 +1,50 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsVector2.h"
-#include "BsVector3.h"
-#include "BsVector4.h"
-#include "BsMatrix3.h"
-#include "BsMatrix4.h"
-#include "BsMaterial.h"
-#include "BsGpuParams.h"
-#include "BsShader.h"
-#include "BsDebug.h"
-#include "BsException.h"
-
-namespace BansheeEngine
-{
-	/************************************************************************/
-	/* 					HELPER STRUCTS TO HELP SERIALIZING                  */
-	/************************************************************************/
-
-	class BS_CORE_EXPORT MaterialFloatParam : public IReflectable
-	{
-	public:
-		String name;
-		float value;
-		UINT32 arrayIdx;
-
-		friend class MaterialFloatParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialVec2Param : public IReflectable
-	{
-	public:
-		String name;
-		Vector2 value;
-		UINT32 arrayIdx;
-
-		friend class MaterialVec2ParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialVec3Param : public IReflectable
-	{
-	public:
-		String name;
-		Vector3 value;
-		UINT32 arrayIdx;
-
-		friend class MaterialVec3ParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialVec4Param : public IReflectable
-	{
-	public:
-		String name;
-		Vector4 value;
-		UINT32 arrayIdx;
-
-		friend class MaterialVec4ParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialMat3Param : public IReflectable
-	{
-	public:
-		String name;
-		Matrix3 value;
-		UINT32 arrayIdx;
-
-		friend class MaterialMat3ParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialMat4Param : public IReflectable
-	{
-	public:
-		String name;
-		Matrix4 value;
-		UINT32 arrayIdx;
-
-		friend class MaterialMat4ParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialStructParam : public IReflectable
-	{
-	public:
-		String name;
-		Material::StructData value;
-		UINT32 arrayIdx;
-		UINT32 elementSize;
-
-		friend class MaterialStructParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialTextureParam : public IReflectable
-	{
-	public:
-		String name;
-		HTexture value;
-
-		friend class MaterialTextureParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialSamplerStateParam : public IReflectable
-	{
-	public:
-		String name;
-		HSamplerState value;
-
-		friend class MaterialSamplerStateParamRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	class BS_CORE_EXPORT MaterialParams : public IReflectable
-	{
-	public:
-		Vector<MaterialFloatParam> floatParams;
-		Vector<MaterialVec2Param> vec2Params;
-		Vector<MaterialVec3Param> vec3Params;
-		Vector<MaterialVec4Param> vec4Params;
-		Vector<MaterialMat3Param> mat3Params;
-		Vector<MaterialMat4Param> mat4Params;
-		Vector<MaterialStructParam> structParams;
-		Vector<MaterialTextureParam> textureParams;
-		Vector<MaterialSamplerStateParam> samplerStateParams;
-
-		friend class MaterialParamsRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-	};
-
-	/************************************************************************/
-	/* 				RTTI FOR HELPER STRUCTS TO HELP SERIALIZING             */
-	/************************************************************************/
-
-	class BS_CORE_EXPORT MaterialFloatParamRTTI : public RTTIType<MaterialFloatParam, IReflectable, MaterialFloatParamRTTI>
-	{
-	public:
-		String& getName(MaterialFloatParam* obj) { return obj->name; }
-		void setName(MaterialFloatParam* obj, String& name) { obj->name = name; }
-
-		float& getValue(MaterialFloatParam* obj) { return obj->value; }
-		void setValue(MaterialFloatParam* obj, float& value) { obj->value = value; }
-
-		UINT32& getArrayIdx(MaterialFloatParam* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialFloatParam* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		MaterialFloatParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialFloatParamRTTI::getName, &MaterialFloatParamRTTI::setName);
-			addPlainField("value", 1, &MaterialFloatParamRTTI::getValue, &MaterialFloatParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialFloatParamRTTI::getArrayIdx, &MaterialFloatParamRTTI::setArrayIdx);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialFloatParam";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamFloat; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialFloatParam, ScratchAlloc>(); 
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialVec2ParamRTTI : public RTTIType<MaterialVec2Param, IReflectable, MaterialVec2ParamRTTI>
-	{
-	public:
-		String& getName(MaterialVec2Param* obj) { return obj->name; }
-		void setName(MaterialVec2Param* obj, String& name) { obj->name = name; }
-
-		Vector2& getValue(MaterialVec2Param* obj) { return obj->value; }
-		void setValue(MaterialVec2Param* obj, Vector2& value) { obj->value = value; }
-
-		UINT32& getArrayIdx(MaterialVec2Param* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialVec2Param* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		MaterialVec2ParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialVec2ParamRTTI::getName, &MaterialVec2ParamRTTI::setName);
-			addPlainField("value", 1, &MaterialVec2ParamRTTI::getValue, &MaterialVec2ParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialVec2ParamRTTI::getArrayIdx, &MaterialVec2ParamRTTI::setArrayIdx);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialVec2Param";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamVec2; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialVec2Param, ScratchAlloc>(); 
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialVec3ParamRTTI : public RTTIType<MaterialVec3Param, IReflectable, MaterialVec3ParamRTTI>
-	{
-	public:
-		String& getName(MaterialVec3Param* obj) { return obj->name; }
-		void setName(MaterialVec3Param* obj, String& name) { obj->name = name; }
-
-		Vector3& getValue(MaterialVec3Param* obj) { return obj->value; }
-		void setValue(MaterialVec3Param* obj, Vector3& value) { obj->value = value; }
-
-		UINT32& getArrayIdx(MaterialVec3Param* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialVec3Param* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		MaterialVec3ParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialVec3ParamRTTI::getName, &MaterialVec3ParamRTTI::setName);
-			addPlainField("value", 1, &MaterialVec3ParamRTTI::getValue, &MaterialVec3ParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialVec3ParamRTTI::getArrayIdx, &MaterialVec3ParamRTTI::setArrayIdx);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialVec3Param";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamVec3; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialVec3Param, ScratchAlloc>(); 
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialVec4ParamRTTI : public RTTIType<MaterialVec4Param, IReflectable, MaterialVec4ParamRTTI>
-	{
-	public:
-		String& getName(MaterialVec4Param* obj) { return obj->name; }
-		void setName(MaterialVec4Param* obj, String& name) { obj->name = name; }
-
-		Vector4& getValue(MaterialVec4Param* obj) { return obj->value; }
-		void setValue(MaterialVec4Param* obj, Vector4& value) { obj->value = value; }
-
-		UINT32& getArrayIdx(MaterialVec4Param* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialVec4Param* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		MaterialVec4ParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialVec4ParamRTTI::getName, &MaterialVec4ParamRTTI::setName);
-			addPlainField("value", 1, &MaterialVec4ParamRTTI::getValue, &MaterialVec4ParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialVec4ParamRTTI::getArrayIdx, &MaterialVec4ParamRTTI::setArrayIdx);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialVec4Param";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamVec4; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{
-			return bs_shared_ptr<MaterialVec4Param, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialMat3ParamRTTI : public RTTIType<MaterialMat3Param, IReflectable, MaterialMat3ParamRTTI>
-	{
-	public:
-		String& getName(MaterialMat3Param* obj) { return obj->name; }
-		void setName(MaterialMat3Param* obj, String& name) { obj->name = name; }
-
-		Matrix3& getValue(MaterialMat3Param* obj) { return obj->value; }
-		void setValue(MaterialMat3Param* obj, Matrix3& value) { obj->value = value; }
-
-		UINT32& getArrayIdx(MaterialMat3Param* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialMat3Param* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		MaterialMat3ParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialMat3ParamRTTI::getName, &MaterialMat3ParamRTTI::setName);
-			addPlainField("value", 1, &MaterialMat3ParamRTTI::getValue, &MaterialMat3ParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialMat3ParamRTTI::getArrayIdx, &MaterialMat3ParamRTTI::setArrayIdx);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialMat3Param";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamMat3; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialMat3Param, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialMat4ParamRTTI : public RTTIType<MaterialMat4Param, IReflectable, MaterialMat4ParamRTTI>
-	{
-	public:
-		String& getName(MaterialMat4Param* obj) { return obj->name; }
-		void setName(MaterialMat4Param* obj, String& name) { obj->name = name; }
-
-		Matrix4& getValue(MaterialMat4Param* obj) { return obj->value; }
-		void setValue(MaterialMat4Param* obj, Matrix4& value) { obj->value = value; }
-
-		UINT32& getArrayIdx(MaterialMat4Param* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialMat4Param* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		MaterialMat4ParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialMat4ParamRTTI::getName, &MaterialMat4ParamRTTI::setName);
-			addPlainField("value", 1, &MaterialMat4ParamRTTI::getValue, &MaterialMat4ParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialMat4ParamRTTI::getArrayIdx, &MaterialMat4ParamRTTI::setArrayIdx);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialMat4Param";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamMat4; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialMat4Param, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialStructParamRTTI : public RTTIType<MaterialStructParam, IReflectable, MaterialStructParamRTTI>
-	{
-	public:
-		String& getName(MaterialStructParam* obj) { return obj->name; }
-		void setName(MaterialStructParam* obj, String& name) { obj->name = name; }
-
-		ManagedDataBlock getValue(MaterialStructParam* obj) 
-		{ 
-			ManagedDataBlock returnValue(obj->value.size);
-
-			UINT8* data = returnValue.getData();
-			memcpy(data, obj->value.data.get(), obj->value.size);
-
-			return returnValue; 
-		}
-
-		void setValue(MaterialStructParam* obj, ManagedDataBlock value) 
-		{ 
-			obj->value = Material::StructData(value.getSize()); 
-			obj->value.write(value.getData());
-			
-		}
-
-		UINT32& getArrayIdx(MaterialStructParam* obj) { return obj->arrayIdx; }
-		void setArrayIdx(MaterialStructParam* obj, UINT32& value) { obj->arrayIdx = value; }
-
-		UINT32& getElementSize(MaterialStructParam* obj) { return obj->elementSize; }
-		void setElementSize(MaterialStructParam* obj, UINT32& value) { obj->elementSize = value; }
-
-		MaterialStructParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialStructParamRTTI::getName, &MaterialStructParamRTTI::setName);
-			addDataBlockField("value", 1, &MaterialStructParamRTTI::getValue, &MaterialStructParamRTTI::setValue);
-			addPlainField("arrayIdx", 2, &MaterialStructParamRTTI::getArrayIdx, &MaterialStructParamRTTI::setArrayIdx);
-			addPlainField("elementSize", 3, &MaterialStructParamRTTI::getElementSize, &MaterialStructParamRTTI::setElementSize);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialStructParam";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamStruct; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialStructParam, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialTextureParamRTTI : public RTTIType<MaterialTextureParam, IReflectable, MaterialTextureParamRTTI>
-	{
-	public:
-		String& getName(MaterialTextureParam* obj) { return obj->name; }
-		void setName(MaterialTextureParam* obj, String& name) { obj->name = name; }
-
-		HTexture& getValue(MaterialTextureParam* obj) { return obj->value; }
-		void setValue(MaterialTextureParam* obj, HTexture& value) { obj->value = value; }
-
-		MaterialTextureParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialTextureParamRTTI::getName, &MaterialTextureParamRTTI::setName);
-			addReflectableField("value", 1, &MaterialTextureParamRTTI::getValue, &MaterialTextureParamRTTI::setValue);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialTextureParam";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamTexture; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialTextureParam, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialSamplerStateParamRTTI : public RTTIType<MaterialSamplerStateParam, IReflectable, MaterialSamplerStateParamRTTI>
-	{
-	public:
-		String& getName(MaterialSamplerStateParam* obj) { return obj->name; }
-		void setName(MaterialSamplerStateParam* obj, String& name) { obj->name = name; }
-
-		HSamplerState& getValue(MaterialSamplerStateParam* obj) { return obj->value; }
-		void setValue(MaterialSamplerStateParam* obj, HSamplerState& value) { obj->value = value; }
-
-		MaterialSamplerStateParamRTTI()
-		{
-			addPlainField("name", 0, &MaterialSamplerStateParamRTTI::getName, &MaterialSamplerStateParamRTTI::setName);
-			addReflectableField("value", 1, &MaterialSamplerStateParamRTTI::getValue, &MaterialSamplerStateParamRTTI::setValue);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialSamplerStateParam";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParamSamplerState; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialSamplerStateParam, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialParamsRTTI : public RTTIType<MaterialParams, IReflectable, MaterialParamsRTTI>
-	{
-	public:
-		MaterialFloatParam& getFloatParam(MaterialParams* obj, UINT32 idx) { return obj->floatParams[idx]; }
-		void setFloatParam(MaterialParams* obj, UINT32 idx, MaterialFloatParam& param) { obj->floatParams[idx] = param; }
-		UINT32 getFloatArraySize(MaterialParams* obj) { return (UINT32)obj->floatParams.size(); }
-		void setFloatArraySize(MaterialParams* obj, UINT32 size) { obj->floatParams.resize(size); }
-
-		MaterialVec2Param& getVec2Param(MaterialParams* obj, UINT32 idx) { return obj->vec2Params[idx]; }
-		void setVec2Param(MaterialParams* obj, UINT32 idx, MaterialVec2Param& param) { obj->vec2Params[idx] = param; }
-		UINT32 getVec2ArraySize(MaterialParams* obj) { return (UINT32)obj->vec2Params.size(); }
-		void setVec2ArraySize(MaterialParams* obj, UINT32 size) { obj->vec2Params.resize(size); }
-
-		MaterialVec3Param& getVec3Param(MaterialParams* obj, UINT32 idx) { return obj->vec3Params[idx]; }
-		void setVec3Param(MaterialParams* obj, UINT32 idx, MaterialVec3Param& param) { obj->vec3Params[idx] = param; }
-		UINT32 getVec3ArraySize(MaterialParams* obj) { return (UINT32)obj->vec3Params.size(); }
-		void setVec3ArraySize(MaterialParams* obj, UINT32 size) { obj->vec3Params.resize(size); }
-
-		MaterialVec4Param& getVec4Param(MaterialParams* obj, UINT32 idx) { return obj->vec4Params[idx]; }
-		void setVec4Param(MaterialParams* obj, UINT32 idx, MaterialVec4Param& param) { obj->vec4Params[idx] = param; }
-		UINT32 getVec4ArraySize(MaterialParams* obj) { return (UINT32)obj->vec4Params.size(); }
-		void setVec4ArraySize(MaterialParams* obj, UINT32 size) { obj->vec4Params.resize(size); }
-
-		MaterialMat3Param& getMat3Param(MaterialParams* obj, UINT32 idx) { return obj->mat3Params[idx]; }
-		void setMat3Param(MaterialParams* obj, UINT32 idx, MaterialMat3Param& param) { obj->mat3Params[idx] = param; }
-		UINT32 getMat3ArraySize(MaterialParams* obj) { return (UINT32)obj->mat3Params.size(); }
-		void setMat3ArraySize(MaterialParams* obj, UINT32 size) { obj->mat3Params.resize(size); }
-
-		MaterialMat4Param& getMat4Param(MaterialParams* obj, UINT32 idx) { return obj->mat4Params[idx]; }
-		void setMat4Param(MaterialParams* obj, UINT32 idx, MaterialMat4Param& param) { obj->mat4Params[idx] = param; }
-		UINT32 getMat4ArraySize(MaterialParams* obj) { return (UINT32)obj->mat4Params.size(); }
-		void setMat4ArraySize(MaterialParams* obj, UINT32 size) { obj->mat4Params.resize(size); }
-
-		MaterialStructParam& getStructParam(MaterialParams* obj, UINT32 idx) { return obj->structParams[idx]; }
-		void setStructParam(MaterialParams* obj, UINT32 idx, MaterialStructParam& param) { obj->structParams[idx] = param; }
-		UINT32 getStructArraySize(MaterialParams* obj) { return (UINT32)obj->structParams.size(); }
-		void setStructArraySize(MaterialParams* obj, UINT32 size) { obj->structParams.resize(size); }
-
-		MaterialTextureParam& getTextureParam(MaterialParams* obj, UINT32 idx) { return obj->textureParams[idx]; }
-		void setTextureParam(MaterialParams* obj, UINT32 idx, MaterialTextureParam& param) { obj->textureParams[idx] = param; }
-		UINT32 getTextureArraySize(MaterialParams* obj) { return (UINT32)obj->textureParams.size(); }
-		void setTextureArraySize(MaterialParams* obj, UINT32 size) { obj->textureParams.resize(size); }
-
-		MaterialSamplerStateParam& getSamplerStateParam(MaterialParams* obj, UINT32 idx) { return obj->samplerStateParams[idx]; }
-		void setSamplerStateParam(MaterialParams* obj, UINT32 idx, MaterialSamplerStateParam& param) { obj->samplerStateParams[idx] = param; }
-		UINT32 getSamplerStateArraySize(MaterialParams* obj) { return (UINT32)obj->samplerStateParams.size(); }
-		void setSamplerStateArraySize(MaterialParams* obj, UINT32 size) { obj->samplerStateParams.resize(size); }
-
-		MaterialParamsRTTI()
-		{
-			addReflectableArrayField("floatParams", 0, &MaterialParamsRTTI::getFloatParam, 
-				&MaterialParamsRTTI::getFloatArraySize, &MaterialParamsRTTI::setFloatParam, &MaterialParamsRTTI::setFloatArraySize);
-
-			addReflectableArrayField("vec2Params", 1, &MaterialParamsRTTI::getVec2Param, 
-				&MaterialParamsRTTI::getVec2ArraySize, &MaterialParamsRTTI::setVec2Param, &MaterialParamsRTTI::setVec2ArraySize);
-
-			addReflectableArrayField("vec3Params", 2, &MaterialParamsRTTI::getVec3Param, 
-				&MaterialParamsRTTI::getVec3ArraySize, &MaterialParamsRTTI::setVec3Param, &MaterialParamsRTTI::setVec3ArraySize);
-
-			addReflectableArrayField("vec4Params", 3, &MaterialParamsRTTI::getVec4Param, 
-				&MaterialParamsRTTI::getVec4ArraySize, &MaterialParamsRTTI::setVec4Param, &MaterialParamsRTTI::setVec4ArraySize);
-
-			addReflectableArrayField("mat3Params", 4, &MaterialParamsRTTI::getMat3Param, 
-				&MaterialParamsRTTI::getMat3ArraySize, &MaterialParamsRTTI::setMat3Param, &MaterialParamsRTTI::setMat3ArraySize);
-
-			addReflectableArrayField("mat4Params", 5, &MaterialParamsRTTI::getMat4Param, 
-				&MaterialParamsRTTI::getMat4ArraySize, &MaterialParamsRTTI::setMat4Param, &MaterialParamsRTTI::setMat4ArraySize);
-
-			addReflectableArrayField("structParams", 6, &MaterialParamsRTTI::getStructParam, 
-				&MaterialParamsRTTI::getStructArraySize, &MaterialParamsRTTI::setStructParam, &MaterialParamsRTTI::setStructArraySize);
-
-			addReflectableArrayField("textureParams", 7, &MaterialParamsRTTI::getTextureParam, 
-				&MaterialParamsRTTI::getTextureArraySize, &MaterialParamsRTTI::setTextureParam, &MaterialParamsRTTI::setTextureArraySize);
-
-			addReflectableArrayField("samplerStateParams", 8, &MaterialParamsRTTI::getSamplerStateParam, 
-				&MaterialParamsRTTI::getSamplerStateArraySize, &MaterialParamsRTTI::setSamplerStateParam, &MaterialParamsRTTI::setSamplerStateArraySize);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "MaterialParams";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId() { return TID_MaterialParams; }
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{ 
-			return bs_shared_ptr<MaterialParams, ScratchAlloc>();
-		}
-	};
-
-	class BS_CORE_EXPORT MaterialRTTI : public RTTIType<Material, Resource, MaterialRTTI>
-	{
-	private:
-		ShaderPtr getShader(Material* obj)
-		{
-			return obj->mShader;
-		}
-
-		void setShader(Material* obj, ShaderPtr val)
-		{
-			obj->mShader = val;
-		}
-
-		std::shared_ptr<MaterialParams> getMaterialParams(Material* obj)
-		{
-			if(obj->mRTTIData.empty())
-				return nullptr;
-
-			return any_cast<std::shared_ptr<MaterialParams>>(obj->mRTTIData);
-		}
-
-		void setMaterialParams(Material* obj, std::shared_ptr<MaterialParams> value)
-		{
-			obj->mRTTIData = value;
-		}
-
-	public:
-		MaterialRTTI()
-		{
-			addReflectablePtrField("mShader", 0, &MaterialRTTI::getShader, &MaterialRTTI::setShader);
-			addReflectablePtrField("mMaterialParams", 1, &MaterialRTTI::getMaterialParams, &MaterialRTTI::setMaterialParams);
-		}
-
-		virtual void onSerializationStarted(IReflectable* obj);
-		virtual void onSerializationEnded(IReflectable* obj);
-		virtual void onDeserializationStarted(IReflectable* obj);
-		virtual void onDeserializationEnded(IReflectable* obj);
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "Material";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_Material;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject();
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsMaterial.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT MaterialRTTI : public RTTIType<Material, Resource, MaterialRTTI>
+	{
+	private:
+		HShader& getShader(Material* obj) { return obj->mShader; }
+		void setShader(Material* obj, HShader& val) { obj->mShader = val; }
+
+		std::shared_ptr<MaterialParams> getMaterialParams(Material* obj) { return obj->mCachedParams; }
+		void setMaterialParams(Material* obj, std::shared_ptr<MaterialParams> value) { obj->mRTTIData = value; }
+
+	public:
+		MaterialRTTI()
+		{
+			addReflectableField("mShader", 0, &MaterialRTTI::getShader, &MaterialRTTI::setShader);
+			addReflectablePtrField("mMaterialParams", 2, &MaterialRTTI::getMaterialParams, &MaterialRTTI::setMaterialParams);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override;
+
+		const String& getRTTIName() override
+		{
+			static String name = "Material";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_Material;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 360 - 242
BansheeCore/Include/BsMesh.h

@@ -1,243 +1,361 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsMeshBase.h"
-#include "BsMeshData.h"
-#include "BsVertexData.h"
-#include "BsDrawOps.h"
-#include "BsSubMesh.h"
-#include "BsBounds.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Primary class for holding geometry. Stores data in the form of a vertex 
-	 *			buffers and optionally index buffer, which may be bound to the pipeline for drawing.
-	 *			May contain multiple sub-meshes.
-	 */
-	class BS_CORE_EXPORT Mesh : public MeshBase
-	{
-	public:
-		virtual ~Mesh();
-
-		/**
-		 * @copydoc	MeshBase::initialize
-		 */
-		virtual void initialize();
-
-		/**
-		 * @copydoc GpuResource::_writeSubresourceSim
-		 */
-		virtual void _writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer);
-
-		/**
-		 * @copydoc GpuResource::writeSubresource
-		 */
-		virtual void writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer);
-
-		/**
-		 * @copydoc GpuResource::readSubresource
-		 */
-		virtual void readSubresource(UINT32 subresourceIdx, GpuResourceData& data);
-
-		/**
-		 * @brief	Allocates a buffer you may use for storage when reading a subresource. You
-		 * 			need to allocate such a buffer if you are calling "readSubresource".
-		 * 			
-		 * @param	subresourceIdx	Only 0 is supported. You can only update entire mesh at once.
-		 *
-		 * @note	This method is thread safe.
-		 */
-		MeshDataPtr allocateSubresourceBuffer(UINT32 subresourceIdx) const;
-
-		/**
-		 * @brief	Returns bounds of the geometry contained in the vertex buffers for all sub-meshes.
-		 */
-		const Bounds& getBounds() const { return mBounds; }
-
-		/**
-		 * @copydoc MeshBase::getVertexData
-		 */
-		virtual std::shared_ptr<VertexData> _getVertexData() const;
-
-		/**
-		 * @copydoc MeshBase::getIndexData
-		 */
-		virtual IndexBufferPtr _getIndexBuffer() const;
-
-		/**
-		 * @brief	Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh.
-		 */
-		static HMesh dummy();
-
-		/************************************************************************/
-		/* 								CORE PROXY                      		*/
-		/************************************************************************/
-
-		/**
-		 * @copydoc	MeshBase::_createProxy
-		 */
-		MeshProxyPtr _createProxy(UINT32 subMeshIdx);
-
-	protected:
-		friend class MeshManager;
-
-		Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, 
-			MeshBufferType bufferType = MeshBufferType::Static, DrawOperationType drawOp = DOT_TRIANGLE_LIST,
-			IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc,
-			const Vector<SubMesh>& subMeshes, MeshBufferType bufferType = MeshBufferType::Static,
-			IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		Mesh(const MeshDataPtr& initialMeshData, MeshBufferType bufferType = MeshBufferType::Static, 
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		Mesh(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes, MeshBufferType bufferType = MeshBufferType::Static);
-
-		std::shared_ptr<VertexData> mVertexData; // Core thread
-		IndexBufferPtr mIndexBuffer; // Core thread
-
-		Bounds mBounds; // Core thread
-		VertexDataDescPtr mVertexDesc; // Immutable
-		MeshBufferType mBufferType; // Immutable
-		IndexBuffer::IndexType mIndexType; // Immutable
-
-		MeshDataPtr mTempInitialMeshData; // Immutable
-
-		/**
-		 * @copydoc Resource::initialize_internal()
-		 */
-		virtual void initialize_internal();
-
-		/**
-		 * @copydoc Resource::destroy_internal()
-		 */
-		virtual void destroy_internal();
-
-		/**
-		 * @brief	Updates bounds by calculating them from the vertices in the provided mesh data object.
-		 */
-		void updateBounds(const MeshData& meshData);
-
-		/**
-		 * @brief	Calculates bounds surrounding the vertices in the provided buffer.
-		 *
-		 * @param	verticesPtr	Pointer to the buffer containing the positions of vertices to calculate bounds for.
-		 * @param	numVertices	Number of vertices in the provided buffer.
-		 * @param	stride		How many bytes are needed to advance from one vertex to another.
-		 */
-		Bounds calculateBounds(UINT8* verticesPtr, UINT32 numVertices, UINT32 stride) const;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	private:
-		Mesh(); // Serialization only
-
-	public:
-		friend class MeshRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-
-		/************************************************************************/
-		/* 								STATICS		                     		*/
-		/************************************************************************/
-		
-	public:
-		/**
-		 * @brief	Creates a new empty mesh. Created mesh will have no sub-meshes.
-		 *
-		 * @param	numVertices		Number of vertices in the mesh.
-		 * @param	numIndices		Number of indices in the mesh. 
-		 * @param	vertexDesc		Vertex description structure that describes how are vertices organized in the
-		 *							vertex buffer. When binding a mesh to the pipeline you must ensure vertex description
-		 *							at least partially matches the input description of the currently bound vertex GPU program.
-		 * @param	bufferType		Specify static for buffers you don't plan on updating other reading from often. Otherwise specify
-		 *							dynamic. This parameter affects performance.
-		 * @param	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default option is triangles,
-		 *							where three indices represent a single triangle.
-		 * @param	indexType		Size of indices, use smaller size for better performance, however be careful not to go over
-		 *							the number of vertices limited by the size.
-		 */
-		static HMesh create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, MeshBufferType bufferType = MeshBufferType::Static,
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @brief	Creates a new empty mesh. Created mesh will have specified sub-meshes you may render independently.
-		 *
-		 * @param	numVertices		Number of vertices in the mesh.
-		 * @param	numIndices		Number of indices in the mesh. 
-		 * @param	vertexDesc		Vertex description structure that describes how are vertices organized in the
-		 *							vertex buffer. When binding a mesh to the pipeline you must ensure vertex description
-		 *							at least partially matches the input description of the currently bound vertex GPU program.
-		 * @param	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes rendered.
-		 *							Sub-meshes may be rendered independently.
-		 * @param	bufferType		Specify static for buffers you don't plan on updating other reading from often. Otherwise specify
-		 *							dynamic. This parameter affects performance.
-		 * @param	indexType		Size of indices, use smaller size for better performance, however be careful not to go over
-		 *							the number of vertices limited by the size.
-		 */
-		static HMesh create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes,
-			MeshBufferType bufferType = MeshBufferType::Static, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @brief	Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
-		 *			by the mesh data exactly. Created mesh will have no sub-meshes.
-		 *
-		 * @param	initialMeshData	Vertex and index data used for initializing the mesh. 
-		 * @param	bufferType		Specify static for buffers you don't plan on updating other reading from often. Otherwise specify
-		 *							dynamic. This parameter affects performance.
-		 * @param	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default option is triangles,
-		 *							where three indices represent a single triangle.
-		 */
-		static HMesh create(const MeshDataPtr& initialMeshData, MeshBufferType bufferType = MeshBufferType::Static, 
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/**
-		 * @brief	Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
-		 *			by the mesh data exactly. Created mesh will have specified sub-meshes you may render independently.
-		 *
-		 * @param	initialMeshData	Vertex and index data used for initializing the mesh. 
-		 * @param	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes rendered.
-		 *							Sub-meshes may be rendered independently.
-		 * @param	bufferType		Specify static for buffers you don't plan on updating other reading from often. Otherwise specify
-		 *							dynamic. This parameter affects performance.
-		 */
-		static HMesh create(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes, MeshBufferType bufferType = MeshBufferType::Static);
-
-		/**
-		 * @copydoc	create(UINT32, UINT32, const VertexDataDescPtr&, MeshBufferType, DrawOperationType, IndexBuffer::IndexType)
-		 *
-		 * @note	Internal method. Use "create" for normal use.
-		 */
-		static MeshPtr _createPtr(UINT32 numVertices, UINT32 numIndices, 
-			const VertexDataDescPtr& vertexDesc, MeshBufferType bufferType = MeshBufferType::Static,
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @copydoc	create(UINT32, UINT32, const VertexDataDescPtr&, const Vector<SubMesh>&, MeshBufferType, IndexBuffer::IndexType)
-		 *
-		 * @note	Internal method. Use "create" for normal use.
-		 */
-		static MeshPtr _createPtr(UINT32 numVertices, UINT32 numIndices, 
-			const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes,
-			MeshBufferType bufferType = MeshBufferType::Static, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @copydoc	create(const MeshDataPtr&, MeshBufferType, DrawOperationType)
-		 *
-		 * @note	Internal method. Use "create" for normal use.
-		 */
-		static MeshPtr _createPtr(const MeshDataPtr& initialMeshData, MeshBufferType bufferType = MeshBufferType::Static,
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/**
-		 * @copydoc	create(const MeshDataPtr&, const Vector<SubMesh>&, MeshBufferType)
-		 *
-		 * @note	Internal method. Use "create" for normal use.
-		 */
-		static MeshPtr _createPtr(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes,
-			MeshBufferType bufferType = MeshBufferType::Static);
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsMeshBase.h"
+#include "BsMeshData.h"
+#include "BsVertexData.h"
+#include "BsDrawOps.h"
+#include "BsSubMesh.h"
+#include "BsBounds.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Resources
+	 *  @{
+	 */
+
+	/** @cond INTERNAL */
+
+	/**
+	 * Core thread portion of a Mesh.
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT MeshCore : public MeshCoreBase
+	{
+	public:
+		MeshCore(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc,
+			const Vector<SubMesh>& subMeshes, int usage, IndexType indexType,
+			MeshDataPtr initialMeshData);
+
+		~MeshCore();
+
+		/** @copydoc CoreObjectCore::initialize */
+		virtual void initialize() override;
+
+		/** @copydoc MeshCoreBase::getVertexData */
+		virtual SPtr<VertexData> getVertexData() const override;
+
+		/** @copydoc MeshCoreBase::getIndexBuffer */
+		virtual SPtr<IndexBufferCore> getIndexBuffer() const override;
+
+		/** @copydoc MeshCoreBase::getVertexDesc */
+		virtual SPtr<VertexDataDesc> getVertexDesc() const override;
+
+		/**
+		 * Updates a part of the current mesh with the provided data.
+		 *
+		 * @param[in]	subresourceIdx		Index of the subresource to update, if the mesh has more than one.
+		 * @param[in]	data				Data to update the mesh with.
+		 * @param[in]	discardEntireBuffer When true the existing contents of the resource you are updating will be 
+		 *									discarded. This can make the operation faster. Resources with certain buffer 
+		 *									types might require this flag to be in a specific state otherwise the operation 
+		 *									will fail.
+		 * @param[in]	updateBounds		If true the internal bounds of the mesh will be recalculated based on the 
+		 *									provided data.
+		 */
+		virtual void writeSubresource(UINT32 subresourceIdx, const MeshData& data, bool discardEntireBuffer, bool updateBounds = true);
+
+		/**
+		 * Reads a part of the current resource into the provided @p data parameter.	Data buffer needs to be pre-allocated.
+		 *
+		 * @param[in]	subresourceIdx		Index of the subresource to update, if the mesh has more than one.
+		 * @param[out]	data				Buffer that will receive the data. Should be allocated with 
+		 *									allocateSubresourceBuffer() to ensure it is of valid type and size.
+		 */
+		virtual void readSubresource(UINT32 subresourceIdx, MeshData& data);
+
+		/**
+		 * Creates a new empty mesh. Created mesh will have no sub-meshes.
+		 *
+		 * @param[in]	numVertices		Number of vertices in the mesh.
+		 * @param[in]	numIndices		Number of indices in the mesh. 
+		 * @param[in]	vertexDesc		Vertex description structure that describes how are vertices organized in the
+		 *								vertex buffer. When binding a mesh to the pipeline you must ensure vertex 
+		 *								description at least partially matches the input description of the currently 
+		 *								bound vertex GPU program.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 * @param[in]	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default
+		 *								option is a triangle list, where three indices represent a single triangle.
+		 * @param[in]	indexType		Size of indices, use smaller size for better performance, however be careful not to
+		 *								go over the number of vertices limited by the size.
+		 */
+		static SPtr<MeshCore> create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT);
+
+		/**
+		 * Creates a new empty mesh. Created mesh will have specified sub-meshes you may render independently.
+		 *
+		 * @param[in]	numVertices		Number of vertices in the mesh.
+		 * @param[in]	numIndices		Number of indices in the mesh. 
+		 * @param[in]	vertexDesc		Vertex description structure that describes how are vertices organized in the
+		 *								vertex buffer. When binding a mesh to the pipeline you must ensure vertex 
+		 *								description at least partially matches the input description of the currently bound
+		 *								vertex GPU program.
+		 * @param[in]	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes 
+		 *								rendered. Sub-meshes may be rendered independently.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 * @param[in]	indexType		Size of indices, use smaller size for better performance, however be careful not 
+		 *								to go over the number of vertices limited by the size.
+		 */
+		static SPtr<MeshCore> create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes,
+			int usage = MU_STATIC, IndexType indexType = IT_32BIT);
+
+		/**
+		 * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
+		 * by the mesh data exactly. Mesh will have no sub-meshes.
+		 *
+		 * @param[in]	initialMeshData	Vertex and index data to initialize the mesh with.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 * @param[in]	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default 
+		 *								option is a triangle strip, where three indices represent a single triangle.
+		 */
+		static SPtr<MeshCore> create(const MeshDataPtr& initialMeshData, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/**
+		 * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
+		 * by the mesh data exactly. Mesh will have specified the sub-meshes.
+		 *
+		 * @param[in]	initialMeshData	Vertex and index data used for initializing the mesh. 
+		 * @param[in]	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes 
+		 *								rendered. Sub-meshes may be rendered independently.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 */
+		static SPtr<MeshCore> create(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes, int usage = MU_STATIC);
+
+	protected:
+		friend class Mesh;
+
+		/** Updates bounds by calculating them from the vertices in the provided mesh data object. */
+		void updateBounds(const MeshData& meshData);
+
+		std::shared_ptr<VertexData> mVertexData;
+		SPtr<IndexBufferCore> mIndexBuffer;
+
+		VertexDataDescPtr mVertexDesc;
+		int mUsage;
+		IndexType mIndexType;
+		MeshDataPtr mTempInitialMeshData;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Primary class for holding geometry. Stores data in the form of a vertex buffers and optionally index buffer, which 
+	 * may be bound to the pipeline for drawing. May contain multiple sub-meshes.
+	 *
+	 * @note	Sim thread.
+	 */
+	class BS_CORE_EXPORT Mesh : public MeshBase
+	{
+	public:
+		virtual ~Mesh();
+
+		/** @copydoc MeshBase::initialize */
+		virtual void initialize() override;
+
+		/**
+		 * Updates the mesh with new data. The actual write will be queued for later execution on the core thread. Provided 
+		 * data buffer will be locked until the operation completes.
+		 *
+		 * @param[in]	accessor	Accessor to queue the operation on.
+		 * @return					Async operation object you can use to track operation completion.
+		 *
+		 * @see		MeshCore::writeSubresource
+		 */
+		AsyncOp writeSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const MeshDataPtr& data, 
+			bool discardEntireBuffer);
+
+		/**
+		 * Reads internal mesh data to the provided previously allocated buffer. The read is queued for execution on the 
+		 * core thread and not executed immediately. Provided data buffer will be locked until the operation completes.
+		 *
+		 * @param[in]	accessor	Accessor to queue the operation on.
+		 * @return					Async operation object you can use to track operation completion.
+		 *
+		 * @see		MeshCore::readSubresource
+		 */
+		AsyncOp readSubresource(CoreAccessor& accessor, UINT32 subresourceIdx, const MeshDataPtr& data);
+
+		/**
+		 * Allocates a buffer you may use for storage when reading a subresource. You need to allocate such a buffer if you
+		 * are calling readSubresource().
+		 * 			
+		 * @param[in]	subresourceIdx	Only 0 is supported. You can only update entire mesh at once.
+		 *
+		 * @note	Thread safe.
+		 */
+		MeshDataPtr allocateSubresourceBuffer(UINT32 subresourceIdx) const;
+
+		/**
+		 * Reads data from the cached system memory mesh buffer into the provided buffer. 
+		 * 		  
+		 * @param[in]	dest		Previously allocated buffer to read data into.
+		 *
+		 * @note	
+		 * The data read is the cached mesh data. Any data written to the mesh from the GPU or core thread will not be 
+		 * reflected in this data. Use readSubresource() if you require those changes. 
+		 * @note
+		 * The mesh must have been created with MU_CPUCACHED usage otherwise this method will not return any data.
+		 */
+		void readData(MeshData& dest);
+
+		/** Retrieves a core implementation of a mesh usable only from the core thread. */
+		SPtr<MeshCore> getCore() const;
+
+		/**	Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh. */
+		static HMesh dummy();
+
+	protected:
+		friend class MeshManager;
+
+		Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, 
+			int usage = MU_STATIC, DrawOperationType drawOp = DOT_TRIANGLE_LIST,
+			IndexType indexType = IT_32BIT);
+
+		Mesh(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc,
+			const Vector<SubMesh>& subMeshes, int usage = MU_STATIC,
+			IndexType indexType = IT_32BIT);
+
+		Mesh(const MeshDataPtr& initialMeshData, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		Mesh(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes, int usage = MU_STATIC);
+
+		/**	Updates bounds by calculating them from the vertices in the provided mesh data object. */
+		void updateBounds(const MeshData& meshData);
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/**
+		 * Creates buffers used for caching of CPU mesh data.
+		 *
+		 * @note	Make sure to initialize all mesh properties before calling this.
+		 */
+		void createCPUBuffer();
+
+		/**	Updates the cached CPU buffers with new data. */
+		void updateCPUBuffer(UINT32 subresourceIdx, const MeshData& data);
+
+		mutable MeshDataPtr mCPUData;
+
+		VertexDataDescPtr mVertexDesc;
+		int mUsage;
+		IndexType mIndexType;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	private:
+		Mesh(); // Serialization only
+
+	public:
+		friend class MeshRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+
+		/************************************************************************/
+		/* 								STATICS		                     		*/
+		/************************************************************************/
+		
+	public:
+		/**
+		 * Creates a new empty mesh. Created mesh will have no sub-meshes.
+		 *
+		 * @param[in]	numVertices		Number of vertices in the mesh.
+		 * @param[in]	numIndices		Number of indices in the mesh. 
+		 * @param[in]	vertexDesc		Vertex description structure that describes how are vertices organized in the
+		 *								vertex buffer. When binding a mesh to the pipeline you must ensure vertex 
+		 *								description at least partially matches the input description of the currently bound
+		 *								vertex GPU program.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 * @param[in]	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default 
+		 *								option is a triangle list, where three indices represent a single triangle.
+		 * @param[in]	indexType		Size of indices, use smaller size for better performance, however be careful not to
+		 *								go over the number of vertices limited by the size.
+		 */
+		static HMesh create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT);
+
+		/**
+		 * Creates a new empty mesh. Created mesh will have specified sub-meshes you may render independently.
+		 *
+		 * @param[in]	numVertices		Number of vertices in the mesh.
+		 * @param[in]	numIndices		Number of indices in the mesh. 
+		 * @param[in]	vertexDesc		Vertex description structure that describes how are vertices organized in the
+		 *								vertex buffer. When binding a mesh to the pipeline you must ensure vertex 
+		 *								description at least partially matches the input description of the currently bound
+		 *								vertex GPU program.
+		 * @param[in]	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes 
+		 *								rendered. Sub-meshes may be rendered independently.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 * @param[in]	indexType		Size of indices, use smaller size for better performance, however be careful not to
+		 *								go over the number of vertices limited by the size.
+		 */
+		static HMesh create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes,
+			int usage = MU_STATIC, IndexType indexType = IT_32BIT);
+
+		/**
+		 * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described
+		 * by the mesh data exactly. Mesh will have no sub-meshes.
+		 *
+		 * @param[in]	initialMeshData	Vertex and index data to initialize the mesh with.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 * @param[in]	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default 
+		 *								option is a triangle strip, where three indices represent a single triangle.
+		 */
+		static HMesh create(const MeshDataPtr& initialMeshData, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/**
+		 * Creates a new mesh from an existing mesh data. Created mesh will match the vertex and index buffers described by
+		 * the mesh data exactly. Mesh will have specified the sub-meshes.
+		 *
+		 * @param[in]	initialMeshData	Vertex and index data used for initializing the mesh. 
+		 * @param[in]	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes 
+		 *								rendered. Sub-meshes may be rendered independently.
+		 * @param[in]	usage			Optimizes performance depending on planned usage of the mesh.
+		 */
+		static HMesh create(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes, int usage = MU_STATIC);
+
+		/**
+		 * @copydoc	create(UINT32, UINT32, const VertexDataDescPtr&, int, DrawOperationType, IndexType)
+		 *
+		 * @note	Internal method. Use create() for normal use.
+		 */
+		static MeshPtr _createPtr(UINT32 numVertices, UINT32 numIndices, 
+			const VertexDataDescPtr& vertexDesc, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT);
+
+		/**
+		 * @copydoc	create(UINT32, UINT32, const VertexDataDescPtr&, const Vector<SubMesh>&, int, IndexType)
+		 *
+		 * @note	Internal method. Use create() for normal use.
+		 */
+		static MeshPtr _createPtr(UINT32 numVertices, UINT32 numIndices, 
+			const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes,
+			int usage = MU_STATIC, IndexType indexType = IT_32BIT);
+
+		/**
+		 * @copydoc	create(const MeshDataPtr&, int, DrawOperationType)
+		 *
+		 * @note	Internal method. Use create() for normal use.
+		 */
+		static MeshPtr _createPtr(const MeshDataPtr& initialMeshData, int usage = MU_STATIC,
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/**
+		 * @copydoc	create(const MeshDataPtr&, const Vector<SubMesh>&, int)
+		 *
+		 * @note	Internal method. Use create() for normal use.
+		 */
+		static MeshPtr _createPtr(const MeshDataPtr& initialMeshData, const Vector<SubMesh>& subMeshes,
+			int usage = MU_STATIC);
+	};
+
+	/** @} */
 }

+ 189 - 204
BansheeCore/Include/BsMeshBase.h

@@ -1,205 +1,190 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsGpuResource.h"
-#include "BsBounds.h"
-#include "BsDrawOps.h"
-#include "BsSubMesh.h"
-#include "BsMeshProxy.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Type of mesh dirty flags
-	 */
-	enum class MeshDirtyFlag
-	{
-		Mesh = 0x01, /**< Internal mesh data is dirty. */
-		Proxy = 0x02 /**< Active proxy needs to be updated. */
-	};
-
-
-	/**
-	 * @brief	Type of buffers used by a mesh. These options usually affect performance and 
-	 *			you should specify static if you don't plan on modifying the mesh often,
-	 *			otherwise specify dynamic.
-	 */
-	enum class MeshBufferType
-	{
-		Static,
-		Dynamic
-	};
-
-	/**
-	 * @brief	Base class all mesh implementations derive from. Meshes hold geometry information,
-	 *			normally in the form of one or serveral index or vertex buffers. Different mesh implementations
-	 *			might choose to manage those buffers differently.
-	 *
-	 * @note	Core thread only unless noted otherwise.
-	 */
-	class BS_CORE_EXPORT MeshBase : public GpuResource
-	{
-	public:
-		/**
-		 * @brief	Constructs a new mesh with no sub-meshes.
-		 *
-		 * @param	numVertices		Number of vertices in the mesh.
-		 * @param	numIndices		Number of indices in the mesh. 
-		 * @param	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default option is triangles,
-		 *							where three indices represent a single triangle.
-		 */
-		MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/**
-		 * @brief	Constructs a new mesh with one or multiple sub-meshes. (When using just one sub-mesh it is equivalent
-		 *			to using the other overload).
-		 *
-		 * @param	numVertices		Number of vertices in the mesh.
-		 * @param	numIndices		Number of indices in the mesh.
-		 * @param	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes rendered.
-		 */
-		MeshBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
-
-		virtual ~MeshBase();
-
-		/**
-		 * @brief	Retrieves a sub-mesh containing data used for rendering a
-		 * 			certain portion of this mesh. If no sub-meshes are specified manually
-		 *			a special sub-mesh containing all indices is returned.
-		 *
-		 * @note	Thread safe.
-		 */
-		const SubMesh& getSubMesh(UINT32 subMeshIdx = 0) const;
-
-		/**
-		 * @brief	Retrieves a total number of sub-meshes in this mesh.
-		 *
-		 * @note	Thread safe.
-		 */
-		UINT32 getNumSubMeshes() const;
-
-		/**
-		 * @brief	Returns maximum number of vertices the mesh may store.
-		 *
-		 * @note	Thread safe.
-		 */
-		UINT32 getNumVertices() const { return mNumVertices; }
-
-		/**
-		 * @brief	Returns maximum number of indices the mesh may store.
-		 *
-		 * @note	Thread safe.
-		 */
-		UINT32 getNumIndices() const { return mNumIndices; }
-
-		/**
-		 * @brief	Get vertex data used for rendering.
-		 *  
-		 * @note	Core thread only. Internal method.
-		 */
-		virtual std::shared_ptr<VertexData> _getVertexData() const = 0;
-
-		/**
-		 * @brief	Get index data used for rendering.
-		 *  
-		 * @note	Core thread only. Internal method.
-		 */
-		virtual IndexBufferPtr _getIndexBuffer() const = 0;
-
-		/**
-		 * @brief	Returns an offset into the vertex buffers that is returned
-		 * 			by getVertexData that signifies where this meshes vertices
-		 * 			begin.
-		 * 			
-		 * @note	Used when multiple meshes share the same buffers.
-		 * 			
-		 *			Core thread only. Internal method.
-		 */
-		virtual UINT32 _getVertexOffset() const { return 0; }
-
-		/**
-		 * @brief	Returns an offset into the index buffer that is returned
-		 * 			by getIndexData that signifies where this meshes indices
-		 * 			begin.
-		 * 			
-		 * @note	Used when multiple meshes share the same buffers.
-		 * 			
-		 *			Core thread only. Internal method.
-		 */
-		virtual UINT32 _getIndexOffset() const { return 0; }
-
-		/**
-		 * @brief	Called whenever this mesh starts being used on the GPU.
-		 * 			
-		 * @note	Needs to be called after all commands referencing this 
-		 * 			mesh have been sent to the GPU.
-		 * 			
-		 *			Core thread only. Internal method.
-		 */
-		virtual void _notifyUsedOnGPU() { }
-
-		/************************************************************************/
-		/* 								CORE PROXY                      		*/
-		/************************************************************************/
-
-		/**
-		 * @brief	Checks is the core dirty flag set. This is used by external systems 
-		 *			to know when internal data has changed and core thread potentially needs to be notified.
-		 *
-		 * @note	Sim thread only.
-		 */
-		bool _isCoreDirty(MeshDirtyFlag flag) const { return (mCoreDirtyFlags & (UINT32)flag) != 0; }
-
-		/**
-		 * @brief	Marks the core dirty flag as clean.
-		 *
-		 * @note	Sim thread only.
-		 */
-		void _markCoreClean(MeshDirtyFlag flag) { mCoreDirtyFlags &= ~(UINT32)flag; }
-
-		/**
-		 * @brief	Gets the currently active proxy of this material.
-		 */
-		MeshProxyPtr _getActiveProxy(UINT32 i) const { return mActiveProxies[i]; }
-
-		/**
-		 * @brief	Sets an active proxy for this material.
-		 */
-		void _setActiveProxy(UINT32 i, const MeshProxyPtr& proxy) { mActiveProxies[i] = proxy; }
-
-		/**
-		 * @brief	Creates a new core proxy from the current mesh data. Core proxy contains a snapshot of 
-		 *			mesh data normally managed on the sim thread (e.g. bounds).
-		 *
-		 * @note	Sim thread only. 
-		 *			You generally need to update the core thread with a new proxy whenever core 
-		 *			dirty flag is set.
-		 */
-		virtual MeshProxyPtr _createProxy(UINT32 subMeshIdx) = 0;
-
-	protected:
-		/**
-		 * @brief	Marks the core data as dirty.
-		 */
-		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
-
-	protected:
-		Vector<SubMesh> mSubMeshes; // Immutable
-		UINT32 mNumVertices; // Immutable
-		UINT32 mNumIndices; // Immutable
-		Vector<MeshProxyPtr> mActiveProxies;
-
-		UINT32 mCoreDirtyFlags;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	private:
-		MeshBase(); // Serialization only
-
-	public:
-		friend class MeshBaseRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsResource.h"
+#include "BsBounds.h"
+#include "BsDrawOps.h"
+#include "BsSubMesh.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Resources
+	 *  @{
+	 */
+
+	/**
+	 * Planned usage for the mesh. These options usually affect performance and you should specify static if you don't plan
+	 * on modifying the mesh often, otherwise specify dynamic.
+	 */
+	enum MeshUsage
+	{
+		MU_STATIC, /**< Specify for a mesh that is not often updated from the CPU. */
+		MU_DYNAMIC, /**< Specify for a mesh that is often updated from the CPU. */
+		MU_CPUCACHED = 0x1000 /**< All mesh data will also be cached in CPU memory, making it readable with GPU reads. */
+	};
+
+	/** Properties of a Mesh. Shared between sim and core thread versions of a Mesh. */
+	class BS_CORE_EXPORT MeshProperties
+	{
+	public:
+		MeshProperties();
+		MeshProperties(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp);
+		MeshProperties(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
+
+		/**
+		 * Retrieves a sub-mesh containing data used for rendering a certain portion of this mesh. If no sub-meshes are
+		 * specified manually a special sub-mesh containing all indices is returned.
+		 */
+		const SubMesh& getSubMesh(UINT32 subMeshIdx = 0) const;
+
+		/** Retrieves a total number of sub-meshes in this mesh. */
+		UINT32 getNumSubMeshes() const;
+
+		/**	Returns maximum number of vertices the mesh may store. */
+		UINT32 getNumVertices() const { return mNumVertices; }
+
+		/**	Returns maximum number of indices the mesh may store. */
+		UINT32 getNumIndices() const { return mNumIndices; }
+
+		/**	Returns bounds of the geometry contained in the vertex buffers for all sub-meshes. */
+		const Bounds& getBounds() const { return mBounds; }
+
+	protected:
+		friend class MeshBase;
+		friend class MeshCoreBase;
+		friend class Mesh;
+		friend class MeshCore;
+		friend class TransientMesh;
+		friend class TransientMeshCore;
+		friend class MeshBaseRTTI;
+
+		Vector<SubMesh> mSubMeshes;
+		UINT32 mNumVertices;
+		UINT32 mNumIndices;
+		Bounds mBounds;
+	};
+
+	/** @} */
+
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+	/** @cond INTERNAL */
+
+	/**
+	 * Core version of a class used as a basis for all implemenations of meshes.
+	 *
+	 * @see		MeshBase
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT MeshCoreBase : public CoreObjectCore
+	{
+	public:
+		MeshCoreBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
+		virtual ~MeshCoreBase() { }
+
+		/**	Get vertex data used for rendering. */
+		virtual SPtr<VertexData> getVertexData() const = 0;
+
+		/**	Get index data used for rendering. */
+		virtual SPtr<IndexBufferCore> getIndexBuffer() const = 0;
+
+		/**
+		 * Returns an offset into the vertex buffers that is returned by getVertexData() that signifies where this meshes
+		 * vertices begin.
+		 * 			
+		 * @note	Used when multiple meshes share the same buffers.
+		 */
+		virtual UINT32 getVertexOffset() const { return 0; }
+
+		/**
+		 * Returns an offset into the index buffer that is returned by getIndexData() that signifies where this meshes
+		 * indices begin.
+		 * 			
+		 * @note	Used when multiple meshes share the same buffers.
+		 */
+		virtual UINT32 getIndexOffset() const { return 0; }
+
+		/** Returns a structure that describes how are the vertices stored in the mesh's vertex buffer. */
+		virtual SPtr<VertexDataDesc> getVertexDesc() const = 0;
+
+		/**
+		 * Called whenever this mesh starts being used on the GPU.
+		 * 			
+		 * @note	Needs to be called after all commands referencing this mesh have been sent to the GPU.
+		 */
+		virtual void _notifyUsedOnGPU() { }
+
+		/**	Returns properties that contain information about the mesh. */
+		const MeshProperties& getProperties() const { return mProperties; }
+
+	protected:
+		/** @copydoc CoreObjectCore::syncToCore */
+		virtual void syncToCore(const CoreSyncData& data) override;
+
+		MeshProperties mProperties;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Base class all mesh implementations derive from. Meshes hold geometry information, normally in the form of one or 
+	 * several index or vertex buffers. Different mesh implementations might choose to manage those buffers differently.
+	 *
+	 * @note	Sim thread.
+	 */
+	class BS_CORE_EXPORT MeshBase : public Resource
+	{
+	public:
+		/**
+		 * Constructs a new mesh with no sub-meshes.
+		 *
+		 * @param[in]	numVertices		Number of vertices in the mesh.
+		 * @param[in]	numIndices		Number of indices in the mesh. 
+		 * @param[in]	drawOp			Determines how should the provided indices be interpreted by the pipeline. Default 
+		 *								option is triangles, where three indices represent a single triangle.
+		 */
+		MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/**
+		 * Constructs a new mesh with one or multiple sub-meshes. (When using just one sub-mesh it is equivalent to using
+		 * the other overload).
+		 *
+		 * @param[in]	numVertices		Number of vertices in the mesh.
+		 * @param[in]	numIndices		Number of indices in the mesh.
+		 * @param[in]	subMeshes		Defines how are indices separated into sub-meshes, and how are those sub-meshes 
+		 *								rendered.
+		 */
+		MeshBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes);
+
+		virtual ~MeshBase();
+
+		/**	Returns properties that contain information about the mesh. */
+		const MeshProperties& getProperties() const { return mProperties; }
+
+		/**	Retrieves a core implementation of a mesh usable only from the core thread. */
+		SPtr<MeshCoreBase> getCore() const;
+
+	protected:
+		/** @copydoc CoreObject::syncToCore */
+		virtual CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		MeshProperties mProperties;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	private:
+		MeshBase() { } // Serialization only
+
+	public:
+		friend class MeshBaseRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 61 - 51
BansheeCore/Include/BsMeshBaseRTTI.h

@@ -1,52 +1,62 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsCoreApplication.h"
-#include "BsMeshBase.h"
-#include "BsException.h"
-
-namespace BansheeEngine
-{
-	BS_ALLOW_MEMCPY_SERIALIZATION(SubMesh);
-
-	class MeshBaseRTTI : public RTTIType<MeshBase, GpuResource, MeshBaseRTTI>
-	{
-		SubMesh& getSubMesh(MeshBase* obj, UINT32 arrayIdx) { return obj->mSubMeshes[arrayIdx]; }
-		void setSubMesh(MeshBase* obj, UINT32 arrayIdx, SubMesh& value) { obj->mSubMeshes[arrayIdx] = value; }
-		UINT32 getNumSubmeshes(MeshBase* obj) { return (UINT32)obj->mSubMeshes.size(); }
-		void setNumSubmeshes(MeshBase* obj, UINT32 numElements) { obj->mSubMeshes.resize(numElements); obj->mActiveProxies.resize(numElements); }
-
-		UINT32& getNumVertices(MeshBase* obj) { return obj->mNumVertices; }
-		void setNumVertices(MeshBase* obj, UINT32& value) { obj->mNumVertices = value; }
-
-		UINT32& getNumIndices(MeshBase* obj) { return obj->mNumIndices; }
-		void setNumIndices(MeshBase* obj, UINT32& value) { obj->mNumIndices = value; }
-
-	public:
-		MeshBaseRTTI()
-		{
-			addPlainField("mNumVertices", 0, &MeshBaseRTTI::getNumVertices, &MeshBaseRTTI::setNumVertices);
-			addPlainField("mNumIndices", 1, &MeshBaseRTTI::getNumIndices, &MeshBaseRTTI::setNumIndices);
-
-			addPlainArrayField("mSubMeshes", 2, &MeshBaseRTTI::getSubMesh, 
-				&MeshBaseRTTI::getNumSubmeshes, &MeshBaseRTTI::setSubMesh, &MeshBaseRTTI::setNumSubmeshes);
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{
-			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
-		}
-
-		virtual const String& getRTTIName() 
-		{
-			static String name = "MeshBase";
-			throw name;
-		}
-
-		virtual UINT32 getRTTIId() 
-		{
-			return TID_MeshBase;
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCoreApplication.h"
+#include "BsMeshBase.h"
+#include "BsException.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(SubMesh);
+
+	class MeshBaseRTTI : public RTTIType<MeshBase, Resource, MeshBaseRTTI>
+	{
+		SubMesh& getSubMesh(MeshBase* obj, UINT32 arrayIdx) { return obj->mProperties.mSubMeshes[arrayIdx]; }
+		void setSubMesh(MeshBase* obj, UINT32 arrayIdx, SubMesh& value) { obj->mProperties.mSubMeshes[arrayIdx] = value; }
+		UINT32 getNumSubmeshes(MeshBase* obj) { return (UINT32)obj->mProperties.mSubMeshes.size(); }
+		void setNumSubmeshes(MeshBase* obj, UINT32 numElements) { obj->mProperties.mSubMeshes.resize(numElements); }
+
+		UINT32& getNumVertices(MeshBase* obj) { return obj->mProperties.mNumVertices; }
+		void setNumVertices(MeshBase* obj, UINT32& value) { obj->mProperties.mNumVertices = value; }
+
+		UINT32& getNumIndices(MeshBase* obj) { return obj->mProperties.mNumIndices; }
+		void setNumIndices(MeshBase* obj, UINT32& value) { obj->mProperties.mNumIndices = value; }
+
+	public:
+		MeshBaseRTTI()
+		{
+			addPlainField("mNumVertices", 0, &MeshBaseRTTI::getNumVertices, &MeshBaseRTTI::setNumVertices);
+			addPlainField("mNumIndices", 1, &MeshBaseRTTI::getNumIndices, &MeshBaseRTTI::setNumIndices);
+
+			addPlainArrayField("mSubMeshes", 2, &MeshBaseRTTI::getSubMesh, 
+				&MeshBaseRTTI::getNumSubmeshes, &MeshBaseRTTI::setSubMesh, &MeshBaseRTTI::setNumSubmeshes);
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "MeshBase";
+			throw name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_MeshBase;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 307 - 296
BansheeCore/Include/BsMeshData.h

@@ -1,297 +1,308 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsGpuResourceData.h"
-#include "BsVertexBuffer.h"
-#include "BsIndexBuffer.h"
-#include "BsVertexDeclaration.h"
-#include "BsDrawOps.h"
-#include "BsSubMesh.h"
-#include "BsBounds.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Iterator that allows you to easily populate or read vertex elements
-	 *			in MeshData.
-	 */
-	template<class T>
-	class VertexElemIter
-	{
-	public:
-		VertexElemIter()
-			:mData(nullptr), mEnd(nullptr), mByteStride(0), mNumElements(0)
-		{
-
-		}
-
-		VertexElemIter(UINT8* data, UINT32 byteStride, UINT32 numElements)
-			:mData(data), mByteStride(byteStride), mNumElements(numElements)
-		{
-			mEnd = mData + byteStride * numElements;
-		}
-
-		/**
-		 * @brief	Adds a new value to the iterators current position and
-		 *			advances the iterator.
-		 */
-		void addValue(T& value)
-		{
-			setValue(value);
-			moveNext();
-		}
-
-		/**
-		 * @brief	Sets a new value at the iterators current position.
-		 */
-		void setValue(T& value)
-		{
-			memcpy(mData, &value, sizeof(T));
-		}
-
-		/**
-		 * @brief	Returns the value at the iterators current position.
-		 */
-		T& getValue()
-		{
-			return *((T*)mData);
-		}
-
-		/**
-		 * @brief	Moves the iterator to the next position. Returns true
-		 *			if there are more elements.
-		 */
-		bool moveNext()
-		{
-#ifdef BS_DEBUG_MODE
-			if(mData >= mEnd)
-			{
-				BS_EXCEPT(InternalErrorException, "Vertex element iterator out of buffer bounds.");
-			}
-#endif
-
-			mData += mByteStride;
-
-			return mData < mEnd;
-		}
-
-		/**
-		 * @brief	Returns the number of elements this iterator can iterate over.
-		 */
-		UINT32 getNumElements() const { return mNumElements; }
-
-	private:
-		UINT8* mData;
-		UINT8* mEnd;
-		UINT32 mByteStride;
-		UINT32 mNumElements;
-	};
-
-	/**
-	 * @brief	Used for initializing, updating and reading mesh data from Meshes.
-	 */
-	class BS_CORE_EXPORT MeshData : public GpuResourceData
-	{
-	public:
-		/**
-		 * @brief	Constructs a new object that can hold number of vertices described by the provided vertex data description. As well
-		 *			as a number of indices of the provided type.
-		 */
-		MeshData(UINT32 numVertices, UINT32 numIndexes, const VertexDataDescPtr& vertexData, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-		~MeshData();
-
-		/**
-		 * @brief	Copies data from "data" parameter into the internal buffer for the specified semantic.
-		 *
-		 * @param	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
-		 * @param	data			Vertex data, containing at least "size" bytes.
-		 * @param	size			The size of the data. Must be the size of the vertex element type * number of vertices.
-		 * @param	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index to differentiate between them.
-		 * @param	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
-		 */
-		void setVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
-
-		/**
-		 * @brief	Returns an iterator you can use for easily retrieving or setting Vector2 vertex elements. This is the preferred
-		 * 			method of assigning or reading vertex data. 
-		 * 			
-		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
-		 */
-		VertexElemIter<Vector2> getVec2DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
-
-		/**
-		 * @brief	Returns an iterator you can use for easily retrieving or setting Vector3 vertex elements. This is the preferred
-		 * 			method of assigning or reading vertex data. 
-		 * 			
-		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
-		 */
-		VertexElemIter<Vector3> getVec3DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
-
-		/**
-		 * @brief	Returns an iterator you can use for easily retrieving or setting Vector4 vertex elements. This is the preferred
-		 * 			method of assigning or reading vertex data. 
-		 * 			
-		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
-		 */
-		VertexElemIter<Vector4> getVec4DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
-
-		/**
-		 * @brief	Returns an iterator you can use for easily retrieving or setting DWORD vertex elements. This is the preferred
-		 * 			method of assigning or reading vertex data. 
-		 * 			
-		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
-		 */
-		VertexElemIter<UINT32> getDWORDDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
-
-		/**
-		 * @brief	Returns the total number of vertices this object can hold.
-		 */
-		UINT32 getNumVertices() const { return mNumVertices; }
-
-		/**
-		 * @brief	Returns the total number of indices this object can hold.
-		 */
-		UINT32 getNumIndices() const;
-
-		/**
-		 * @brief	Returns a 16-bit pointer to the start of the internal index buffer.
-		 */
-		UINT16* getIndices16() const;
-
-		/**
-		 * @brief	Returns a 32-bit pointer to the start of the internal index buffer.
-		 */
-		UINT32* getIndices32() const;
-
-		/**
-		 * @brief	Returns the size of an index element in bytes.
-		 */
-		UINT32 getIndexElementSize() const;
-
-		/**
-		 * @brief	Returns the type of an index element.
-		 */
-		IndexBuffer::IndexType getIndexType() const { return mIndexType; }
-
-		/**
-		 * @brief	Returns the pointer to the first element of the specified type. If you want to
-		 * 			iterate over all elements you need to call getVertexStride() to get the number
-		 * 			of bytes you need to advance between each element.
-		 *
-		 * @param	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
-		 * @param	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index to differentiate between them.
-		 * @param	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
-		 *
-		 * @return	null if it fails, else the element data.
-		 */
-		UINT8* getElementData(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
-
-		/**
-		 * @brief	Returns an offset into the internal buffer where this element with the provided semantic starts. 
-		 *			Offset is provided in number of bytes.
-		 * 
-		 * @param	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
-		 * @param	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index to differentiate between them.
-		 * @param	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be represented as a single vertex buffer.
-		 */
-		UINT32 getElementOffset(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
-
-		/**
-		 * @brief	Returns an object that describes data contained in a single vertex.
-		 */
-		const VertexDataDescPtr& getVertexDesc() const { return mVertexData; }
-
-		/**
-		 * @brief	Combines a number of submeshes and their mesh data into one large mesh data buffer.
-		 *
-		 * @param	elements	Data containing vertices and indices referenced by the submeshes. Number of elements
-		 *						must be the same as number of submeshes.
-		 * @param	subMeshes	Submeshes representing vertex and index range to take from mesh data and combine. Number of
-		 *						submeshes must match the number of provided MeshData elements.
-		 * @param	[out] subMeshes		Outputs all combined sub-meshes with their new index and vertex offsets referencing
-		 *								the newly created MeshData.
-		 *
-		 * @returns	Combined mesh data containing all vertices and indexes references by the provided sub-meshes.
-		 */
-		static MeshDataPtr combine(const Vector<MeshDataPtr>& elements, const Vector<Vector<SubMesh>>& allSubMeshes,
-			Vector<SubMesh>& subMeshes);
-
-	protected:
-		/**
-		 * @brief	Returns the size of the internal buffer in bytes.
-		 */
-		UINT32 getInternalBufferSize();
-
-	private:
-		/**
-		 * @brief	Returns a pointer to the start of the index buffer.
-		 */
-		UINT8* getIndexData() const { return getData(); }
-
-		/**
-		 * @brief	Returns a pointer to the start of the specified vertex stream.
-		 */
-		UINT8* getStreamData(UINT32 streamIdx) const;
-
-		/**
-		 * @brief	Returns an offset in bytes to the start of the index buffer from the start of the
-		 *			internal buffer.
-		 */
-		UINT32 getIndexBufferOffset() const;
-
-		/**
-		 * @brief	Returns an offset in bytes to the start of the stream from the start of the
-		 *			internal buffer.
-		 */
-		UINT32 getStreamOffset(UINT32 streamIdx = 0) const;
-
-		/**
-		 * @brief	Returns the size of the index buffer in bytes.
-		 */
-		UINT32 getIndexBufferSize() const;
-
-		/**
-		 * @brief	Returns the size of the specified stream in bytes.
-		 */
-		UINT32 getStreamSize(UINT32 streamIdx) const;
-
-		/**
-		 * @brief	Returns the size of all the streams in bytes.
-		 */
-		UINT32 getStreamSize() const;
-
-		/**
-		 * @brief	Returns the data needed for iterating over the requested vertex element.
-		 *
-		 * @param	semantic   		Semantic of the element we are looking for.
-		 * @param	semanticIdx 	If there are multiple semantics with the same name, use different index to differentiate between them.
-		 * @param	streamIdx   	Zero-based index of the stream the element resides in.
-		 * @param [out] data		Pointer to the start of this elements data.
-		 * @param [out] stride		Number of bytes between vertex elements of this type.
-		 */
-		void getDataForIterator(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8*& data, UINT32& stride) const;
-
-	private:
-		friend class Mesh;
-		friend class MeshHeap;
-
-		UINT32 mDescBuilding;
-
-		UINT32 mNumVertices;
-		UINT32 mNumIndices;
-		IndexBuffer::IndexType mIndexType;
-
-		VertexDataDescPtr mVertexData;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	private:
-		MeshData(); // Serialization only
-
-	public:
-		friend class MeshDataRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuResourceData.h"
+#include "BsVertexBuffer.h"
+#include "BsIndexBuffer.h"
+#include "BsVertexDeclaration.h"
+#include "BsDrawOps.h"
+#include "BsSubMesh.h"
+#include "BsBounds.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Resources
+	 *  @{
+	 */
+
+	/** Iterator that allows you to easily populate or read vertex elements in MeshData. */
+	template<class T>
+	class VertexElemIter
+	{
+	public:
+		VertexElemIter()
+			:mData(nullptr), mEnd(nullptr), mByteStride(0), mNumElements(0)
+		{
+
+		}
+
+		VertexElemIter(UINT8* data, UINT32 byteStride, UINT32 numElements)
+			:mData(data), mByteStride(byteStride), mNumElements(numElements)
+		{
+			mEnd = mData + byteStride * numElements;
+		}
+
+		/**	Adds a new value to the iterators current position and advances the iterator. */
+		void addValue(const T& value)
+		{
+			setValue(value);
+			moveNext();
+		}
+
+		/**	Sets a new value at the iterators current position. */
+		void setValue(const T& value)
+		{
+			memcpy(mData, &value, sizeof(T));
+		}
+
+		/**	Returns the value at the iterators current position. */
+		T& getValue()
+		{
+			return *((T*)mData);
+		}
+
+		/**	Moves the iterator to the next position. Returns true if there are more elements. */
+		bool moveNext()
+		{
+#ifdef BS_DEBUG_MODE
+			if(mData >= mEnd)
+			{
+				BS_EXCEPT(InternalErrorException, "Vertex element iterator out of buffer bounds.");
+			}
+#endif
+
+			mData += mByteStride;
+
+			return mData < mEnd;
+		}
+
+		/**	Returns the number of elements this iterator can iterate over. */
+		UINT32 getNumElements() const { return mNumElements; }
+
+	private:
+		UINT8* mData;
+		UINT8* mEnd;
+		UINT32 mByteStride;
+		UINT32 mNumElements;
+	};
+
+	/** Contains per-vertex bone weights and indexes used for skinning, for up to four bones. */
+	struct BoneWeight
+	{
+		int index0;
+		int index1;
+		int index2;
+		int index3;
+
+		float weight0;
+		float weight1;
+		float weight2;
+		float weight3;
+	};
+
+	/** Contains mesh vertex and index data used for initializing, updating and reading mesh data from Mesh. */
+	class BS_CORE_EXPORT MeshData : public GpuResourceData
+	{
+	public:
+		/**
+		 * Constructs a new object that can hold number of vertices described by the provided vertex data description. As 
+		 * well as a number of indices of the provided type.
+		 */
+		MeshData(UINT32 numVertices, UINT32 numIndexes, const VertexDataDescPtr& vertexData, IndexType indexType = IT_32BIT);
+		~MeshData();
+
+		/**
+		 * Copies data from @p data parameter into the internal buffer for the specified semantic.
+		 *
+		 * @param[in]	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
+		 * @param[in]	data			Vertex data, containing at least @p size bytes.
+		 * @param[in]	size			The size of the data. Must be the size of the vertex element type * number of 
+		 *								vertices.
+		 * @param[in]	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index
+		 *								to differentiate between them.
+		 * @param[in]	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be 
+		 *								represented as a single vertex buffer.
+		 */
+		void setVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
+
+		/**
+		 * Copies data from the internal buffer to the pre-allocated buffer for the specified semantic.
+		 *
+		 * @param[in]	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
+		 * @param[in]	data			Buffer that will receive vertex data, of at least @p size bytes.
+		 * @param[in]	size			The size of the data. Must be the size of the vertex element type * number of 
+		 *								vertices.
+		 * @param[in]	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index
+		 *								to differentiate between them.
+		 * @param[in]	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be 
+		 *								represented as a single vertex buffer.
+		 */
+		void getVertexData(VertexElementSemantic semantic, UINT8* data, UINT32 size, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
+
+		/**
+		 * Returns an iterator you can use for easily retrieving or setting Vector2 vertex elements. This is the preferred
+		 * method of assigning or reading vertex data. 
+		 * 			
+		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
+		 */
+		VertexElemIter<Vector2> getVec2DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
+
+		/**
+		 * Returns an iterator you can use for easily retrieving or setting Vector3 vertex elements. This is the preferred
+		 * method of assigning or reading vertex data. 
+		 * 			
+		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
+		 */
+		VertexElemIter<Vector3> getVec3DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
+
+		/**
+		 * Returns an iterator you can use for easily retrieving or setting Vector4 vertex elements. This is the preferred
+		 * method of assigning or reading vertex data. 
+		 * 			
+		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
+		 */
+		VertexElemIter<Vector4> getVec4DataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
+
+		/**
+		 * Returns an iterator you can use for easily retrieving or setting DWORD vertex elements. This is the preferred
+		 * method of assigning or reading vertex data. 
+		 * 			
+		 * @note	If vertex data of this type/semantic/index/stream doesn't exist and exception will be thrown.
+		 */
+		VertexElemIter<UINT32> getDWORDDataIter(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0);
+
+		/** Returns the total number of vertices this object can hold. */
+		UINT32 getNumVertices() const { return mNumVertices; }
+
+		/** Returns the total number of indices this object can hold. */
+		UINT32 getNumIndices() const;
+
+		/**	Returns a 16-bit pointer to the start of the internal index buffer. */
+		UINT16* getIndices16() const;
+
+		/**	Returns a 32-bit pointer to the start of the internal index buffer. */
+		UINT32* getIndices32() const;
+
+		/**	Returns the size of an index element in bytes. */
+		UINT32 getIndexElementSize() const;
+
+		/**	Returns the type of an index element. */
+		IndexType getIndexType() const { return mIndexType; }
+
+		/**
+		 * Returns the pointer to the first element of the specified type. If you want to iterate over all elements you 
+		 * need to call getVertexStride() to get the number	of bytes you need to advance between each element.
+		 *
+		 * @param[in]	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
+		 * @param[in]	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index 
+		 *								to differentiate between them.
+		 * @param[in]	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be 
+		 *								represented as a single vertex buffer.
+		 * @return						null if it fails, else the element data.
+		 */
+		UINT8* getElementData(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
+
+		/**
+		 * Returns an offset into the internal buffer where this element with the provided semantic starts. Offset is 
+		 * provided in number of bytes.
+		 * 
+		 * @param[in]	semantic   		Semantic that allows the engine to connect the data to a shader input slot.
+		 * @param[in]	semanticIdx 	(optional) If there are multiple semantics with the same name, use different index 
+		 *								to differentiate between them.
+		 * @param[in]	streamIdx   	(optional) Zero-based index of the stream. Each stream will internally be 
+		 *								represented as a single vertex buffer.
+		 */
+		UINT32 getElementOffset(VertexElementSemantic semantic, UINT32 semanticIdx = 0, UINT32 streamIdx = 0) const;
+
+		/** Returns an object that describes data contained in a single vertex. */
+		const VertexDataDescPtr& getVertexDesc() const { return mVertexData; }
+
+		/**	Return the size (in bytes) of the entire buffer. */
+		UINT32 getSize() const { return getInternalBufferSize(); }
+
+		/**	Calculates the bounds of all vertices stored in the internal buffer. */
+		Bounds calculateBounds() const;
+
+		/**
+		 * Combines a number of submeshes and their mesh data into one large mesh data buffer.
+		 *
+		 * @param[in]	elements	Data containing vertices and indices referenced by the submeshes. Number of elements
+		 *							must be the same as number of submeshes.
+		 * @param[in]	subMeshes	Submeshes representing vertex and index range to take from mesh data and combine. 
+		 *							Number of submeshes must match the number of provided MeshData elements.
+		 * @param[out]	subMeshes	Outputs all combined sub-meshes with their new index and vertex offsets referencing
+		 *							the newly created MeshData.
+		 * @return					Combined mesh data containing all vertices and indexes references by the provided 
+		 *							sub-meshes.
+		 */
+		static MeshDataPtr combine(const Vector<MeshDataPtr>& elements, const Vector<Vector<SubMesh>>& allSubMeshes,
+			Vector<SubMesh>& subMeshes);
+
+		/**
+		 * Constructs a new object that can hold number of vertices described by the provided vertex data description. As 
+		 * well as a number of indices of the provided type.
+		 */
+		static MeshDataPtr create(UINT32 numVertices, UINT32 numIndexes, const VertexDataDescPtr& vertexData, 
+			IndexType indexType = IT_32BIT)
+		{
+			return bs_shared_ptr_new<MeshData>(numVertices, numIndexes, vertexData, indexType);
+		}
+
+	protected:
+		/**	Returns the size of the internal buffer in bytes. */
+		UINT32 getInternalBufferSize() const override;
+
+	private:
+		/**	Returns a pointer to the start of the index buffer. */
+		UINT8* getIndexData() const { return getData(); }
+
+		/**	Returns a pointer to the start of the specified vertex stream. */
+		UINT8* getStreamData(UINT32 streamIdx) const;
+
+		/**	Returns an offset in bytes to the start of the index buffer from the start of the internal buffer. */
+		UINT32 getIndexBufferOffset() const;
+
+		/**	Returns an offset in bytes to the start of the stream from the start of the internal buffer. */
+		UINT32 getStreamOffset(UINT32 streamIdx = 0) const;
+
+		/**	Returns the size of the index buffer in bytes. */
+		UINT32 getIndexBufferSize() const;
+
+		/**	Returns the size of the specified stream in bytes. */
+		UINT32 getStreamSize(UINT32 streamIdx) const;
+
+		/**	Returns the size of all the streams in bytes. */
+		UINT32 getStreamSize() const;
+
+		/**
+		 * Returns the data needed for iterating over the requested vertex element.
+		 *
+		 * @param[in]	semantic   		Semantic of the element we are looking for.
+		 * @param[in]	semanticIdx 	If there are multiple semantics with the same name, use different index to 
+		 *								differentiate between them.
+		 * @param[in]	streamIdx   	Zero-based index of the stream the element resides in.
+		 * @param[out] data				Pointer to the start of this elements data.
+		 * @param[out] stride			Number of bytes between vertex elements of this type.
+		 */
+		void getDataForIterator(VertexElementSemantic semantic, UINT32 semanticIdx, UINT32 streamIdx, UINT8*& data, UINT32& stride) const;
+
+	private:
+		friend class Mesh;
+		friend class MeshCore;
+		friend class MeshHeap;
+		friend class MeshHeapCore;
+
+		UINT32 mDescBuilding;
+
+		UINT32 mNumVertices;
+		UINT32 mNumIndices;
+		IndexType mIndexType;
+
+		VertexDataDescPtr mVertexData;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	private:
+		MeshData(); // Serialization only
+
+	public:
+		friend class MeshDataRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
 }

+ 84 - 74
BansheeCore/Include/BsMeshDataRTTI.h

@@ -1,75 +1,85 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsMeshData.h"
-#include "BsManagedDataBlock.h"
-#include "BsVertexDeclaration.h"
-
-namespace BansheeEngine
-{
-	BS_ALLOW_MEMCPY_SERIALIZATION(IndexBuffer::IndexType);
-
-	class BS_CORE_EXPORT MeshDataRTTI : public RTTIType<MeshData, GpuResourceData, MeshDataRTTI>
-	{
-	private:
-		VertexDataDescPtr getVertexData(MeshData* obj) { return obj->mVertexData; }
-		void setVertexData(MeshData* obj, VertexDataDescPtr value) { obj->mVertexData = value; }
-
-		IndexBuffer::IndexType& getIndexType(MeshData* obj) { return obj->mIndexType; }
-		void setIndexType(MeshData* obj, IndexBuffer::IndexType& value) { obj->mIndexType = value; }
-
-		UINT32& getNumVertices(MeshData* obj) { return obj->mNumVertices; }
-		void setNumVertices(MeshData* obj, UINT32& value) { obj->mNumVertices = value; }
-
-		UINT32& getNumIndices(MeshData* obj) { return obj->mNumIndices; }
-		void setNumIndices(MeshData* obj, UINT32& value) { obj->mNumIndices = value; }
-
-		ManagedDataBlock getData(MeshData* obj) 
-		{ 
-			ManagedDataBlock dataBlock((UINT8*)obj->getData(), obj->getInternalBufferSize());
-			return dataBlock; 
-		}
-
-		void setData(MeshData* obj, ManagedDataBlock val) 
-		{ 
-			// Nothing to do here, the pointer we provided already belongs to PixelData
-			// so the data is already written
-		}
-
-		static UINT8* allocateData(MeshData* obj, UINT32 numBytes)
-		{
-			obj->allocateInternalBuffer(numBytes);
-
-			return obj->getData();
-		}
-
-	public:
-		MeshDataRTTI()
-		{
-			addReflectablePtrField("mVertexData", 0, &MeshDataRTTI::getVertexData, &MeshDataRTTI::setVertexData);
-
-			addPlainField("mIndexType", 1, &MeshDataRTTI::getIndexType, &MeshDataRTTI::setIndexType);
-			addPlainField("mNumVertices", 2, &MeshDataRTTI::getNumVertices, &MeshDataRTTI::setNumVertices);
-			addPlainField("mNumIndices", 3, &MeshDataRTTI::getNumIndices, &MeshDataRTTI::setNumIndices);
-
-			addDataBlockField("data", 4, &MeshDataRTTI::getData, &MeshDataRTTI::setData, 0, &MeshDataRTTI::allocateData);
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{
-			return bs_shared_ptr<MeshData, PoolAlloc>(new (bs_alloc<MeshData, PoolAlloc>()) MeshData());
-		}
-
-		virtual const String& getRTTIName() 
-		{
-			static String name = "MeshData";
-			throw name;
-		}
-
-		virtual UINT32 getRTTIId() 
-		{
-			return TID_MeshData;
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsMeshData.h"
+#include "BsManagedDataBlock.h"
+#include "BsVertexDeclaration.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(IndexType);
+
+	class BS_CORE_EXPORT MeshDataRTTI : public RTTIType<MeshData, GpuResourceData, MeshDataRTTI>
+	{
+	private:
+		VertexDataDescPtr getVertexData(MeshData* obj) { return obj->mVertexData; }
+		void setVertexData(MeshData* obj, VertexDataDescPtr value) { obj->mVertexData = value; }
+
+		IndexType& getIndexType(MeshData* obj) { return obj->mIndexType; }
+		void setIndexType(MeshData* obj, IndexType& value) { obj->mIndexType = value; }
+
+		UINT32& getNumVertices(MeshData* obj) { return obj->mNumVertices; }
+		void setNumVertices(MeshData* obj, UINT32& value) { obj->mNumVertices = value; }
+
+		UINT32& getNumIndices(MeshData* obj) { return obj->mNumIndices; }
+		void setNumIndices(MeshData* obj, UINT32& value) { obj->mNumIndices = value; }
+
+		ManagedDataBlock getData(MeshData* obj) 
+		{ 
+			ManagedDataBlock dataBlock((UINT8*)obj->getData(), obj->getInternalBufferSize());
+			return dataBlock; 
+		}
+
+		void setData(MeshData* obj, ManagedDataBlock val) 
+		{ 
+			// Nothing to do here, the pointer we provided already belongs to PixelData
+			// so the data is already written
+		}
+
+		static UINT8* allocateData(MeshData* obj, UINT32 numBytes)
+		{
+			obj->allocateInternalBuffer(numBytes);
+
+			return obj->getData();
+		}
+
+	public:
+		MeshDataRTTI()
+		{
+			addReflectablePtrField("mVertexData", 0, &MeshDataRTTI::getVertexData, &MeshDataRTTI::setVertexData);
+
+			addPlainField("mIndexType", 1, &MeshDataRTTI::getIndexType, &MeshDataRTTI::setIndexType);
+			addPlainField("mNumVertices", 2, &MeshDataRTTI::getNumVertices, &MeshDataRTTI::setNumVertices);
+			addPlainField("mNumIndices", 3, &MeshDataRTTI::getNumIndices, &MeshDataRTTI::setNumIndices);
+
+			addDataBlockField("data", 4, &MeshDataRTTI::getData, &MeshDataRTTI::setData, 0, &MeshDataRTTI::allocateData);
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr<MeshData>(new (bs_alloc<MeshData>()) MeshData());
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "MeshData";
+			throw name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_MeshData;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 231 - 242
BansheeCore/Include/BsMeshHeap.h

@@ -1,243 +1,232 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsCoreObject.h"
-#include "BsDrawOps.h"
-#include "BsIndexBuffer.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Mesh heap allows you to quickly allocate and deallocate a large amounts of temporary 
-	 *			meshes without the large overhead of normal Mesh creation.
-	 * 			Only requirement is that meshes share the same vertex description and index type.
-	 * 			
-	 * @note	This class should be considered as a replacement for a normal Mesh if you are constantly 
-	 * 			updating the mesh (e.g. every frame) and you are not able to discard entire mesh contents 
-	 * 			on each update. Not using discard flag on normal meshes may introduce GPU-CPU sync points
-	 * 			which may severely limit performance. Primary purpose of this class is to avoid
-	 * 			those sync points by not forcing you to discard contents.
-	 * 			
-	 *			Downside is that this class may allocate 2-3x (or more) memory than it is actually needed
-	 *			for your data.
-	 *			
-	 *			Sim thread except where noted otherwise.
-	 */
-	class BS_CORE_EXPORT MeshHeap : public CoreObject
-	{
-		/**
-		 * @brief	Signifies how is a data chunk used.
-		 */
-		enum class UseFlags
-		{
-			Used, /**< Data chunk is used by both CPU and GPU. */
-			CPUFree, /**< Data chunk was released by CPU but not GPU. */
-			GPUFree, /**< Data chunk was released by GPU but not CPU. */
-			Free /**< Data chunk was released by both CPU and GPU. */
-		};
-
-		/**
-		 * @brief	Represents a continuous chunk of memory.
-		 */
-		struct ChunkData
-		{
-			UINT32 start, size;
-		};
-
-		/**
-		 * @brief	Represents an allocated piece of data representing a mesh.
-		 */
-		struct AllocatedData
-		{
-			UINT32 vertChunkIdx;
-			UINT32 idxChunkIdx;
-
-			UseFlags useFlags;
-			UINT32 eventQueryIdx;
-			TransientMeshPtr mesh;
-		};
-
-		/**
-		 * @brief	Data about a GPU query.
-		 */
-		struct QueryData
-		{
-			EventQueryPtr query;
-			UINT32 queryId;
-		};
-
-	public:
-		~MeshHeap();
-
-		/**
-		 * @brief	Allocates a new mesh in the heap, expanding the heap if needed. Mesh will be initialized
-		 *			with the provided meshData. You may use the returned transient mesh for drawing.
-		 *
-		 * @note	Offsets provided by MeshData are ignored. MeshHeap will determine
-		 * 			where the data will be written internally.
-		 */
-		TransientMeshPtr alloc(const MeshDataPtr& meshData, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/**
-		 * @brief	Deallocates the provided mesh and makes that room on the heap re-usable as soon as the GPU
-		 *			is also done with the mesh.
-		 */
-		void dealloc(const TransientMeshPtr& mesh);
-
-		/**
-		 * @brief	Creates a new mesh heap.
-		 *
-		 * @param	numVertices	Initial number of vertices the heap may store. This will grow automatically if needed.
-		 * @param	numIndices	Initial number of indices the heap may store. This will grow automatically if needed.
-		 * @param	vertexDesc	Description of the stored vertices.
-		 * @param	indexType	Type of the stored indices.
-		 */
-		static MeshHeapPtr create(UINT32 numVertices, UINT32 numIndices, 
-			const VertexDataDescPtr& vertexDesc, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-	private:
-		friend class TransientMesh;
-
-		/**
-		 * @copydoc	create
-		 */
-		MeshHeap(UINT32 numVertices, UINT32 numIndices, 
-			const VertexDataDescPtr& vertexDesc, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @copydoc CoreObject::initialize_internal()
-		 */
-		virtual void initialize_internal();
-
-		/**
-		 * @copydoc CoreObject::destroy_internal()
-		 */
-		virtual void destroy_internal();
-
-		/**
-		 * @brief	Allocates a new mesh in the heap, expanding the heap if needed. 
-		 *
-		 * @param	meshId		Mesh for which we are allocating the data.
-		 * @param	meshData	Data to initialize the new mesh with.
-		 *
-		 * @note	Core thread.
-		 */
-		void allocInternal(TransientMeshPtr mesh, const MeshDataPtr& meshData);
-
-		/**
-		 * @brief	Deallocates the provided mesh Freed memory
-		 *			will be re-used as soon as the GPU is done with the mesh
-		 *
-		 * @note	Core thread.
-		 */
-		void deallocInternal(TransientMeshPtr mesh);
-
-		/**
-		 * @brief	Resizes the vertex buffers so they max contain the provided
-		 *			number of vertices.
-		 *
-		 * @note	Core thread.
-		 */
-		void growVertexBuffer(UINT32 numVertices);
-
-		/**
-		 * @brief	Resizes the index buffer so they max contain the provided
-		 *			number of indices.
-		 *
-		 * @note	Core thread.
-		 */
-		void growIndexBuffer(UINT32 numIndices);
-
-		/**
-		 * @brief	Creates a new event query or returns an existing one from the pool
-		 *			if available. Returned value is an index into mEventQueries array.
-		 *
-		 * @note	Core thread.
-		 */
-		UINT32 createEventQuery();
-
-		/**
-		 * @brief	Frees the event query with the specified index and returns it to the
-		 *			pool so it may be reused later.
-		 *
-		 * @note	Core thread.
-		 */
-		void freeEventQuery(UINT32 idx);
-
-		/**
-		 * @brief	Gets internal vertex data for all the meshes.
-		 */
-		std::shared_ptr<VertexData> _getVertexData() const;
-
-		/**
-		 * @brief	Gets internal index data for all the meshes.
-		 */
-		IndexBufferPtr _getIndexBuffer() const;
-
-		/**
-		 * @brief	Returns the offset in vertices from the start of the buffer
-		 *			to the first vertex of the mesh with the provided ID.
-		 */
-		UINT32 getVertexOffset(UINT32 meshId) const;
-
-		/**
-		 * @brief	Returns the offset in indices from the start of the buffer
-		 *			to the first index of the mesh with the provided ID.
-		 */
-		UINT32 getIndexOffset(UINT32 meshId) const;
-
-		/**
-		 * @brief	Called by the render system when a mesh gets queued to the GPU.
-		 */
-		void notifyUsedOnGPU(UINT32 meshId);
-
-		/**
-		 * @brief	Called by an GPU event query when GPU processes the query. Normally
-		 *			signals the heap that the GPU is done with the mesh.
-		 */
-		static void queryTriggered(MeshHeapPtr thisPtr, UINT32 meshId, UINT32 queryId);
-
-		/**
-		 * @brief	Attempts to reorganize the vertex and index buffer chunks in order to 
-		 *			in order to make free memory contigous.
-		 *
-		 * @note	This will not actually copy any data from index/vertex buffers, and will only
-		 *			modify the chunk descriptors.
-		 */
-		void mergeWithNearbyChunks(UINT32 chunkVertIdx, UINT32 chunkIdxIdx);
-
-	private:
-		UINT32 mNumVertices; // Core thread
-		UINT32 mNumIndices; // Core thread
-
-		Vector<UINT8*> mCPUVertexData; // Core thread
-		UINT8* mCPUIndexData; // Core thread
-
-		std::shared_ptr<VertexData> mVertexData; // Core thread
-		IndexBufferPtr mIndexBuffer; // Core thread
-
-		Map<UINT32, AllocatedData> mMeshAllocData; // Core thread
-
-		VertexDataDescPtr mVertexDesc; // Immutable
-		IndexBuffer::IndexType mIndexType; // Immutable
-
-		Map<UINT32, TransientMeshPtr> mMeshes; // Sim thread
-		UINT32 mNextFreeId; // Sim thread
-
-		Vector<ChunkData> mVertChunks; // Core thread
-		Vector<ChunkData> mIdxChunks; // Core thread
-
-		Stack<UINT32> mEmptyVertChunks; // Core thread
-		Stack<UINT32> mEmptyIdxChunks; // Core thread
-
-		List<UINT32> mFreeVertChunks; // Core thread
-		List<UINT32> mFreeIdxChunks; // Core thread
-
-		Vector<QueryData> mEventQueries; // Core thread
-		Stack<UINT32> mFreeEventQueries; // Core thread
-
-		UINT32 mNextQueryId;
-
-		static const float GrowPercent;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCoreObject.h"
+#include "BsDrawOps.h"
+#include "BsIndexBuffer.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Resources
+	 *  @{
+	 */
+
+	/**
+	 * Core thread version of MeshHeap.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT MeshHeapCore : public CoreObjectCore
+	{
+		/**	Signifies how is a data chunk used. */
+		enum class UseFlags
+		{
+			Used, /**< Data chunk is used by both CPU and GPU. */
+			CPUFree, /**< Data chunk was released by CPU but not GPU. */
+			GPUFree, /**< Data chunk was released by GPU but not CPU. */
+			Free /**< Data chunk was released by both CPU and GPU. */
+		};
+
+		/**	Represents a continuous chunk of memory. */
+		struct ChunkData
+		{
+			UINT32 start, size;
+		};
+
+		/**	Represents an allocated piece of data representing a mesh. */
+		struct AllocatedData
+		{
+			UINT32 vertChunkIdx;
+			UINT32 idxChunkIdx;
+
+			UseFlags useFlags;
+			UINT32 eventQueryIdx;
+			SPtr<TransientMeshCore> mesh;
+		};
+
+		/**	Data about a GPU query. */
+		struct QueryData
+		{
+			EventQueryPtr query;
+			UINT32 queryId;
+		};
+
+	public:
+		~MeshHeapCore();
+
+	private:
+		friend class MeshHeap;
+		friend class TransientMesh;
+		friend class TransientMeshCore;
+
+		MeshHeapCore(UINT32 numVertices, UINT32 numIndices, 
+			const VertexDataDescPtr& vertexDesc, IndexType indexType = IT_32BIT);
+
+		/** @copydoc CoreObjectCore::initialize() */
+		virtual void initialize() override;
+
+		/**
+		 * Allocates a new mesh in the heap, expanding the heap if needed. 
+		 *
+		 * @param[in]	meshId		Mesh for which we are allocating the data.
+		 * @param[in]	meshData	Data to initialize the new mesh with.
+		 */
+		void alloc(SPtr<TransientMeshCore> mesh, const MeshDataPtr& meshData);
+
+		/** Deallocates the provided mesh. Freed memory will be re-used as soon as the GPU is done with the mesh. */
+		void dealloc(SPtr<TransientMeshCore> mesh);
+
+		/** Resizes the vertex buffers so they max contain the provided number of vertices. */
+		void growVertexBuffer(UINT32 numVertices);
+
+		/** Resizes the index buffer so they max contain the provided number of indices. */
+		void growIndexBuffer(UINT32 numIndices);
+
+		/**
+		 * Creates a new event query or returns an existing one from the pool if available. Returned value is an index 
+		 * into event query array.
+		 */
+		UINT32 createEventQuery();
+
+		/** Frees the event query with the specified index and returns it to the pool so it may be reused later. */
+		void freeEventQuery(UINT32 idx);
+
+		/**	Gets internal vertex data for all the meshes. */
+		SPtr<VertexData> getVertexData() const;
+
+		/**	Gets internal index data for all the meshes. */
+		SPtr<IndexBufferCore> getIndexBuffer() const;
+
+		/** Returns a structure that describes how are the vertices stored in the mesh's vertex buffer. */
+		SPtr<VertexDataDesc> getVertexDesc() const;
+
+		/**
+		 * Returns the offset in vertices from the start of the buffer to the first vertex of the mesh with the provided ID.
+		 */
+		UINT32 getVertexOffset(UINT32 meshId) const;
+
+		/**
+		 * Returns the offset in indices from the start of the buffer to the first index of the mesh with the provided ID.
+		 */
+		UINT32 getIndexOffset(UINT32 meshId) const;
+
+		/** Called by the render system when a mesh gets queued to the GPU. */
+		void notifyUsedOnGPU(UINT32 meshId);
+
+		/**
+		 * Called by an GPU event query when GPU processes the query. Normally signals the heap that the GPU is done with 
+		 * the mesh.
+		 */
+		static void queryTriggered(SPtr<MeshHeapCore> thisPtr, UINT32 meshId, UINT32 queryId);
+
+		/**
+		 * Attempts to reorganize the vertex and index buffer chunks in order to in order to make free memory contigous.
+		 *
+		 * @note	
+		 * This will not actually copy any data from index/vertex buffers, and will only modify the chunk descriptors.
+		 */
+		void mergeWithNearbyChunks(UINT32 chunkVertIdx, UINT32 chunkIdxIdx);
+
+	private:
+		UINT32 mNumVertices;
+		UINT32 mNumIndices;
+
+		Vector<UINT8*> mCPUVertexData;
+		UINT8* mCPUIndexData;
+
+		SPtr<VertexData> mVertexData;
+		SPtr<IndexBufferCore> mIndexBuffer;
+
+		Map<UINT32, AllocatedData> mMeshAllocData;
+
+		VertexDataDescPtr mVertexDesc;
+		IndexType mIndexType;
+
+		Vector<ChunkData> mVertChunks;
+		Vector<ChunkData> mIdxChunks;
+
+		Stack<UINT32> mEmptyVertChunks;
+		Stack<UINT32> mEmptyIdxChunks;
+
+		List<UINT32> mFreeVertChunks;
+		List<UINT32> mFreeIdxChunks;
+
+		Vector<QueryData> mEventQueries; 
+		Stack<UINT32> mFreeEventQueries;
+
+		UINT32 mNextQueryId;
+
+		static const float GrowPercent;
+	};
+
+	/** @endcond */
+
+	/**
+	 * Mesh heap allows you to quickly allocate and deallocate a large amounts of temporary meshes without the large 
+	 * overhead of normal Mesh creation. Only requirement is that meshes share the same vertex description and index type.
+	 * 			
+	 * @note	
+	 * This class should be considered as a replacement for a normal Mesh if you are constantly updating the mesh (e.g. 
+	 * every frame) and you are not able to discard entire mesh contents on each update. Not using discard flag on normal 
+	 * meshes may introduce GPU-CPU sync points which may severely limit performance. Primary purpose of this class is to 
+	 * avoid those sync points by not forcing you to discard contents.
+	 * Downside is that this class may allocate 2-3x (or more) memory than it is actually needed for your data.
+	 * @note
+	 * Sim thread only
+	 */
+	class BS_CORE_EXPORT MeshHeap : public CoreObject
+	{
+	public:
+		/**
+		 * Allocates a new mesh in the heap, expanding the heap if needed. Mesh will be initialized with the provided 
+		 * @p meshData. You may use the returned transient mesh for drawing.
+		 *
+		 * @note	
+		 * Offsets provided by MeshData are ignored. MeshHeap will determine where the data will be written internally.
+		 */
+		TransientMeshPtr alloc(const MeshDataPtr& meshData, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/**
+		 * Deallocates the provided mesh and makes that room on the heap re-usable as soon as the GPU is also done with the 
+		 * mesh.
+		 */
+		void dealloc(const TransientMeshPtr& mesh);
+
+		/** Retrieves a core implementation of a mesh heap usable only from the core thread. */
+		SPtr<MeshHeapCore> getCore() const;
+
+		/**
+		 * Creates a new mesh heap.
+		 *
+		 * @param[in]	numVertices	Initial number of vertices the heap may store. This will grow automatically if needed.
+		 * @param[in]	numIndices	Initial number of indices the heap may store. This will grow automatically if needed.
+		 * @param[in]	vertexDesc	Description of the stored vertices.
+		 * @param[in]	indexType	Type of the stored indices.
+		 */
+		static MeshHeapPtr create(UINT32 numVertices, UINT32 numIndices, 
+			const VertexDataDescPtr& vertexDesc, IndexType indexType = IT_32BIT);
+
+	private:
+		/** @copydoc create */
+		MeshHeap(UINT32 numVertices, UINT32 numIndices, 
+			const VertexDataDescPtr& vertexDesc, IndexType indexType = IT_32BIT);
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+	private:
+		UINT32 mNumVertices;
+		UINT32 mNumIndices;
+
+		VertexDataDescPtr mVertexDesc;
+		IndexType mIndexType;
+
+		Map<UINT32, TransientMeshPtr> mMeshes;
+		UINT32 mNextFreeId;
+	};
+
+	/** @} */
 }

+ 89 - 0
BansheeCore/Include/BsMeshImportOptions.h

@@ -0,0 +1,89 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsImportOptions.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Importer
+	 *  @{
+	 */
+
+	/**
+	 * Contains import options you may use to control how is a mesh imported from some external format into engine format.
+	 */
+	class BS_CORE_EXPORT MeshImportOptions : public ImportOptions
+	{
+	public:
+		MeshImportOptions();
+
+		/**	Sets whether the texture data is also stored in CPU memory. */
+		void setCPUReadable(bool readable) { mCPUReadable = readable; }
+		
+		/**	Retrieves whether the texture data is also stored in CPU memory. */
+		bool getCPUReadable() const { return mCPUReadable; }
+
+		/**	Sets a value that controls should mesh normals be imported if available. */
+		void setImportNormals(bool import) { mImportNormals = import; }
+
+		/**	Retrieves a value that controls should mesh normals be imported if available. */
+		bool getImportNormals() const { return mImportNormals; }
+
+		/**	Sets a value that controls should mesh tangents/bitangents be imported if available. */
+		void setImportTangents(bool import) { mImportTangents = import; }
+
+		/**	Retrieves a value that controls should mesh tangent/bitangent be imported if available. */
+		bool getImportTangents() const { return mImportTangents; }
+
+		/**	Sets a value that controls should mesh blend shapes be imported	if available. */
+		void setImportBlendShapes(bool import) { mImportBlendShapes = import; }
+
+		/**	Retrieves a value that controls should mesh blend shapes be imported if available. */
+		bool getImportBlendShapes() const { return mImportBlendShapes; }
+
+		/**	
+		 * Sets a value that controls should mesh skin data like bone weights, indices and bind poses be imported if 
+		 * available.
+		 */
+		void setImportSkin(bool import) { mImportSkin = import; }
+
+		/**
+		 * Retrieves a value that controls should mesh skin data like bone weights, indices and bind poses be imported if 
+		 * available.
+		 */
+		bool getImportSkin() const { return mImportSkin; }
+
+		/** Sets a value that controls should animation clips be imported if available. */
+		void setImportAnimation(bool import) { mImportAnimation = import; }
+
+		/**	Retrieves a value that controls should animation clips be imported if available. */
+		bool getImportAnimation() const { return mImportAnimation; }
+
+		/**	Sets a value that will uniformly scale the imported mesh by the specified value. */
+		void setImportScale(float import) { mImportScale = import; }
+
+		/**	Retrieves a value that will uniformly scale the imported mesh by the specified value. */
+		float getImportScale() const { return mImportScale; }
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class MeshImportOptionsRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+
+	private:
+		bool mCPUReadable;
+		bool mImportNormals;
+		bool mImportTangents;
+		bool mImportBlendShapes;
+		bool mImportSkin;
+		bool mImportAnimation;
+		float mImportScale;
+	};
+
+	/** @} */
+}

+ 71 - 0
BansheeCore/Include/BsMeshImportOptionsRTTI.h

@@ -0,0 +1,71 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsMeshImportOptions.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT MeshImportOptionsRTTI : public RTTIType < MeshImportOptions, ImportOptions, MeshImportOptionsRTTI >
+	{
+	private:
+		bool& getCPUReadable(MeshImportOptions* obj) { return obj->mCPUReadable; }
+		void setCPUReadable(MeshImportOptions* obj, bool& value) { obj->mCPUReadable = value; }
+		
+		bool& getImportNormals(MeshImportOptions* obj) { return obj->mImportNormals; }
+		void setImportNormals(MeshImportOptions* obj, bool& value) { obj->mImportNormals = value; }
+		
+		bool& getImportTangents(MeshImportOptions* obj) { return obj->mImportTangents; }
+		void setImportTangents(MeshImportOptions* obj, bool& value) { obj->mImportTangents = value; }
+		
+		bool& getImportBlendShapes(MeshImportOptions* obj) { return obj->mImportBlendShapes; }
+		void setImportBlendShapes(MeshImportOptions* obj, bool& value) { obj->mImportBlendShapes = value; }
+		
+		bool& getImportSkin(MeshImportOptions* obj) { return obj->mImportSkin; }
+		void setImportSkin(MeshImportOptions* obj, bool& value) { obj->mImportSkin = value; }
+		
+		bool& getImportAnimation(MeshImportOptions* obj) { return obj->mImportAnimation; }
+		void setImportAnimation(MeshImportOptions* obj, bool& value) { obj->mImportAnimation = value; }
+
+		float& getImportScale(MeshImportOptions* obj) { return obj->mImportScale; }
+		void setImportScale(MeshImportOptions* obj, float& value) { obj->mImportScale = value; }
+
+	public:
+		MeshImportOptionsRTTI()
+		{
+			addPlainField("mCPUReadable", 0, &MeshImportOptionsRTTI::getCPUReadable, &MeshImportOptionsRTTI::setCPUReadable);
+			addPlainField("mImportNormals", 1, &MeshImportOptionsRTTI::getImportNormals, &MeshImportOptionsRTTI::setImportNormals);
+			addPlainField("mImportTangents", 2, &MeshImportOptionsRTTI::getImportTangents, &MeshImportOptionsRTTI::setImportTangents);
+			addPlainField("mImportBlendShapes", 3, &MeshImportOptionsRTTI::getImportBlendShapes, &MeshImportOptionsRTTI::setImportBlendShapes);
+			addPlainField("mImportSkin", 4, &MeshImportOptionsRTTI::getImportSkin, &MeshImportOptionsRTTI::setImportSkin);
+			addPlainField("mImportAnimation", 5, &MeshImportOptionsRTTI::getImportAnimation, &MeshImportOptionsRTTI::setImportAnimation);
+			addPlainField("mImportScale", 6, &MeshImportOptionsRTTI::getImportScale, &MeshImportOptionsRTTI::setImportScale);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "MeshImportOptions";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_MeshImportOptions;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return bs_shared_ptr_new<MeshImportOptions>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 60 - 66
BansheeCore/Include/BsMeshManager.h

@@ -1,67 +1,61 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsModule.h"
-#include "BsMesh.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Manager that handles creation of Meshes.
-	 */
-	class BS_CORE_EXPORT MeshManager : public Module<MeshManager>
-	{
-	public:
-		MeshManager();
-		~MeshManager();
-
-		/**
-		 * @copydoc	Mesh::create(UINT32, UINT32, const VertexDataDescPtr&, MeshBufferType, DrawOperationType, IndexBuffer::IndexType)
-		 */
-		MeshPtr create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, MeshBufferType bufferType = MeshBufferType::Static, 
-			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @copydoc	Mesh::create(UINT32, UINT32, const VertexDataDescPtr&, const Vector<SubMesh>&, MeshBufferType, IndexBuffer::IndexType)
-		 */
-		MeshPtr create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes, 
-			MeshBufferType bufferType = MeshBufferType::Static, IndexBuffer::IndexType indexType = IndexBuffer::IT_32BIT);
-
-		/**
-		 * @copyodc	Mesh::create(const MeshDataPtr&, MeshBufferType, DrawOperationType)
-		 */
-		MeshPtr create(const MeshDataPtr& initialData, MeshBufferType bufferType = MeshBufferType::Static, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
-
-		/**
-		 * @copyodc	Mesh::create(const MeshDataPtr&, const Vector<SubMesh>&, MeshBufferType)
-		 */
-		MeshPtr create(const MeshDataPtr& initialData, const Vector<SubMesh>& subMeshes, MeshBufferType bufferType = MeshBufferType::Static);
-
-		/**
-		 * @brief	Creates a new empty and uninitialized mesh. You will need to manually initialize the mesh before using it.
-		 *	
-		 * @note	This should only be used for special cases and is not meant for normal use.
-		 */
-		MeshPtr createEmpty();
-
-		/**
-		 * @brief	Returns some dummy mesh data with one triangle you may use for initializing a mesh.
-		 */
-		MeshDataPtr getDummyMeshData() const { return mDummyMeshData; }
-
-		/**
-		 * @brief	Returns a dummy mesh containing one triangle.
-		 */
-		HMesh getDummyMesh() const { return mDummyMesh; }
-
-	protected:
-		/**
-		 * @copydoc		Module::onStartUp
-		 */
-		virtual void onStartUp();
-
-	private:
-		MeshDataPtr mDummyMeshData;
-		HMesh mDummyMesh;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsModule.h"
+#include "BsMesh.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/** Manager that handles creation of Mesh%es. */
+	class BS_CORE_EXPORT MeshManager : public Module<MeshManager>
+	{
+	public:
+		MeshManager();
+		~MeshManager();
+
+		/** @copydoc Mesh::create(UINT32, UINT32, const VertexDataDescPtr&, int, DrawOperationType, IndexType) */
+		MeshPtr create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, int usage = MU_STATIC, 
+			DrawOperationType drawOp = DOT_TRIANGLE_LIST, IndexType indexType = IT_32BIT);
+
+		/** @copydoc Mesh::create(UINT32, UINT32, const VertexDataDescPtr&, const Vector<SubMesh>&, int, IndexType) */
+		MeshPtr create(UINT32 numVertices, UINT32 numIndices, const VertexDataDescPtr& vertexDesc, const Vector<SubMesh>& subMeshes, 
+			int usage = MU_STATIC, IndexType indexType = IT_32BIT);
+
+		/** @copyodc Mesh::create(const MeshDataPtr&, int, DrawOperationType) */
+		MeshPtr create(const MeshDataPtr& initialData, int usage = MU_STATIC, DrawOperationType drawOp = DOT_TRIANGLE_LIST);
+
+		/** @copyodc Mesh::create(const MeshDataPtr&, const Vector<SubMesh>&, int) */
+		MeshPtr create(const MeshDataPtr& initialData, const Vector<SubMesh>& subMeshes, int usage = MU_STATIC);
+
+		/**
+		 * Creates a new empty and uninitialized mesh. You will need to manually initialize the mesh before using it.
+		 *	
+		 * @note	This should only be used for special cases and is not meant for normal use.
+		 */
+		MeshPtr createEmpty();
+
+		/** Returns some dummy mesh data with one triangle you may use for initializing a mesh. */
+		MeshDataPtr getDummyMeshData() const { return mDummyMeshData; }
+
+		/**	Returns a dummy mesh containing one triangle. */
+		HMesh getDummyMesh() const { return mDummyMesh; }
+
+	protected:
+		/** @copydoc Module::onStartUp */
+		virtual void onStartUp() override;
+
+	private:
+		MeshDataPtr mDummyMeshData;
+		HMesh mDummyMesh;
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 0 - 19
BansheeCore/Include/BsMeshProxy.h

@@ -1,19 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsSubMesh.h"
-#include "BsBounds.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * Contains part of Mesh data that is used on the core thread for rendering.
-	 */
-	struct BS_CORE_EXPORT MeshProxy
-	{
-		std::weak_ptr<MeshBase> mesh;
-		SubMesh subMesh;
-		Bounds bounds;
-		UINT32 submeshIdx;
-	};
-}

+ 80 - 72
BansheeCore/Source/BsMeshRTTI.h → BansheeCore/Include/BsMeshRTTI.h

@@ -1,73 +1,81 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsCoreApplication.h"
-#include "BsMesh.h"
-#include "BsMeshManager.h"
-#include "BsCoreThread.h"
-
-namespace BansheeEngine
-{
-	class MeshRTTI : public RTTIType<Mesh, MeshBase, MeshRTTI>
-	{
-		VertexDataDescPtr getVertexDesc(Mesh* obj) { return obj->mVertexDesc; }
-		void setVertexDesc(Mesh* obj, VertexDataDescPtr value) { obj->mVertexDesc = value; }
-
-		IndexBuffer::IndexType& getIndexType(Mesh* obj) { return obj->mIndexType; }
-		void setIndexType(Mesh* obj, IndexBuffer::IndexType& value) { obj->mIndexType = value; }
-
-		UINT32& getBufferType(Mesh* obj) { return (UINT32&)obj->mBufferType; }
-		void setBufferType(Mesh* obj, UINT32& value) { obj->mBufferType = (MeshBufferType)value; }
-
-		MeshDataPtr getMeshData(Mesh* obj) 
-		{ 
-			MeshDataPtr meshData = obj->allocateSubresourceBuffer(0);
-			GpuResourcePtr sharedMeshPtr = std::static_pointer_cast<GpuResource>(obj->getThisPtr());
-
-			meshData->_lock();
-			gCoreThread().queueReturnCommand(std::bind(&RenderSystem::readSubresource, RenderSystem::instancePtr(), 
-				sharedMeshPtr, 0, std::static_pointer_cast<GpuResourceData>(meshData), std::placeholders::_1), true);
-
-			return meshData;
-		}
-
-		void setMeshData(Mesh* obj, MeshDataPtr meshData) 
-		{ 
-			obj->mTempInitialMeshData = meshData;
-		}
-
-	public:
-		MeshRTTI()
-		{
-			addReflectablePtrField("mVertexDesc", 0, &MeshRTTI::getVertexDesc, &MeshRTTI::setVertexDesc);
-
-			addPlainField("mIndexType", 1, &MeshRTTI::getIndexType, &MeshRTTI::setIndexType);
-			addPlainField("mBufferType", 2, &MeshRTTI::getBufferType, &MeshRTTI::setBufferType);
-
-			addReflectablePtrField("mMeshData", 3, &MeshRTTI::getMeshData, &MeshRTTI::setMeshData);
-		}
-
-		virtual void onDeserializationEnded(IReflectable* obj)
-		{
-			Mesh* mesh = static_cast<Mesh*>(obj);
-			mesh->initialize();
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject() 
-		{
-			return MeshManager::instance().createEmpty();
-		}
-
-		virtual const String& getRTTIName() 
-		{
-			static String name = "Mesh";
-			throw name;
-		}
-
-		virtual UINT32 getRTTIId() 
-		{
-			return TID_Mesh;
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCoreApplication.h"
+#include "BsMesh.h"
+#include "BsMeshManager.h"
+#include "BsCoreThread.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class MeshRTTI : public RTTIType<Mesh, MeshBase, MeshRTTI>
+	{
+		VertexDataDescPtr getVertexDesc(Mesh* obj) { return obj->mVertexDesc; }
+		void setVertexDesc(Mesh* obj, VertexDataDescPtr value) { obj->mVertexDesc = value; }
+
+		IndexType& getIndexType(Mesh* obj) { return obj->mIndexType; }
+		void setIndexType(Mesh* obj, IndexType& value) { obj->mIndexType = value; }
+
+		int& getBufferType(Mesh* obj) { return (int&)obj->mUsage; }
+		void setBufferType(Mesh* obj, int& value) { obj->mUsage = value; }
+
+		MeshDataPtr getMeshData(Mesh* obj) 
+		{ 
+			MeshDataPtr meshData = obj->allocateSubresourceBuffer(0);
+
+			obj->readSubresource(gCoreAccessor(), 0, meshData);
+			gCoreAccessor().submitToCoreThread(true);
+
+			return meshData;
+		}
+
+		void setMeshData(Mesh* obj, MeshDataPtr meshData) 
+		{ 
+			obj->mCPUData = meshData;
+		}
+
+	public:
+		MeshRTTI()
+		{
+			addReflectablePtrField("mVertexDesc", 0, &MeshRTTI::getVertexDesc, &MeshRTTI::setVertexDesc);
+
+			addPlainField("mIndexType", 1, &MeshRTTI::getIndexType, &MeshRTTI::setIndexType);
+			addPlainField("mUsage", 2, &MeshRTTI::getBufferType, &MeshRTTI::setBufferType);
+
+			addReflectablePtrField("mMeshData", 3, &MeshRTTI::getMeshData, &MeshRTTI::setMeshData);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			Mesh* mesh = static_cast<Mesh*>(obj);
+			mesh->initialize();
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return MeshManager::instance().createEmpty();
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "Mesh";
+			throw name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_Mesh;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 85 - 0
BansheeCore/Include/BsMeshUtility.h

@@ -0,0 +1,85 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Utility-Core
+	 *  @{
+	 */
+
+	/** Performs various operations on mesh geometry. */
+	class BS_CORE_EXPORT MeshUtility
+	{
+	public:
+		/**
+		 * Calculates per-vertex normals based on the provided vertices and indices.
+		 *
+		 * @param[in]	vertices	Set of vertices containing vertex positions.
+		 * @param[in]	indices		Set of indices containing indexes into vertex array for each triangle.
+		 * @param[in]	numVertices	Number of vertices in the @p vertices array.
+		 * @param[in]	numIndices	Number of indices in the @p indices array. Must be a multiple of three.
+		 * @param[out]	normals		Pre-allocated buffer that will contain the calculated normals. Must be the same size
+		 *							as the vertex array.
+		 * @param[in]	indexSize	Size of a single index in the indices array, in bytes.
+		 *
+		 * @note	
+		 * Vertices should be split before calling this method if there are any discontinuities. (e.g. a vertex on a corner
+		 * of a cube should be split into three vertices used by three triangles in order for the normals to be valid.)
+		 */
+		static void calculateNormals(Vector3* vertices, UINT8* indices, UINT32 numVertices, 
+			UINT32 numIndices, Vector3* normals, UINT32 indexSize = 4);
+
+		/**
+		 * Calculates per-vertex tangents and bitangents based on the provided vertices, uv coordinates and indices.
+		 *
+		 * @param[in]	vertices	Set of vertices containing vertex positions.
+		 * @param[in]	normals		Set of normals to use when calculating tangents. Must the the same length as the number
+		 *							of vertices.
+		 * @param[in]	uv			Set of UV coordinates to use when calculating tangents. Must the the same length as the
+		 *							number of vertices.
+		 * @param[in]	indices		Set of indices containing indexes into vertex array for each triangle.
+		 * @param[in]	numVertices	Number of vertices in the @p vertices, @p normals and @p uv arrays.
+		 * @param[in]	numIndices	Number of indices in the @p indices array. Must be a multiple of three.
+		 * @param[out]	tangents	Pre-allocated buffer that will contain the calculated tangents. Must be the same size
+		 *							as the vertex array.
+		 * @param[out]	bitangents	Pre-allocated buffer that will contain the calculated bitangents. Must be the same size
+		 *							as the vertex array.
+		 * @param[in]	indexSize	Size of a single index in the indices array, in bytes.
+		 *
+		 * @note	
+		 * Vertices should be split before calling this method if there are any discontinuities. (e.g. a vertex on a corner
+		 * of a cube should be split into three vertices used by three triangles in order for the normals to be valid.)
+		 */
+		static void calculateTangents(Vector3* vertices, Vector3* normals, Vector2* uv, UINT8* indices, UINT32 numVertices, 
+			UINT32 numIndices, Vector3* tangents, Vector3* bitangents, UINT32 indexSize = 4);
+
+		/**
+		 * Calculates per-vertex tangent space (normal, tangent, bitangent) based on the provided vertices, uv coordinates
+		 * and indices.
+		 *
+		 * @param[in]	vertices	Set of vertices containing vertex positions.
+		 * @param[in]	uv			Set of UV coordinates to use when calculating tangents.
+		 * @param[in]	indices		Set of indices containing indexes into vertex array for each triangle.
+		 * @param[in]	numVertices	Number of vertices in the "vertices" array.
+		 * @param[in]	numIndices	Number of indices in the "indices" array. Must be a multiple of three.
+		 * @param[out]	normals		Pre-allocated buffer that will contain the calculated normals. Must be the same size
+		 *							as the vertex array.
+		 * @param[out]	tangents	Pre-allocated buffer that will contain the calculated tangents. Must be the same size
+		 *							as the vertex array.
+		 * @param[out]	bitangents	Pre-allocated buffer that will contain the calculated bitangents. Must be the same size
+		 *							as the vertex array.
+		 * @param[in]	indexSize	Size of a single index in the indices array, in bytes.
+		 *
+		 * @note	
+		 * Vertices should be split before calling this method if there are any discontinuities. (e.g. a vertex on a corner
+		 * of a cube should be split into three vertices used by three triangles in order for the normals to be valid.)
+		 */
+		static void calculateTangentSpace(Vector3* vertices, Vector2* uv, UINT8* indices, UINT32 numVertices, 
+			UINT32 numIndices, Vector3* normals, Vector3* tangents, Vector3* bitangents, UINT32 indexSize = 4);
+	};
+
+	/** @} */
+}

+ 106 - 28
BansheeCore/Include/BsMultiRenderTexture.h

@@ -1,3 +1,5 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #pragma once
 
 #include "BsCorePrerequisites.h"
@@ -5,10 +7,13 @@
 
 namespace BansheeEngine
 {
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
 	/**
-	 * @brief	Descriptor class used for initializing a MultiRenderTexture.
-	 *			Contains descriptors for each individual color render surface and 
-	 *			their common depth/stencil surface.
+	 * Descriptor class used for initializing a MultiRenderTexture. Contains descriptors for each individual color render 
+	 * surface and their common depth/stencil surface.
 	 */
 	struct BS_CORE_EXPORT MULTI_RENDER_TEXTURE_DESC
 	{
@@ -17,42 +22,58 @@ namespace BansheeEngine
 	};
 
 	/**
-	 * @brief	Object representing multiple render textures. You may bind this to the pipeline
-	 *			in order to render to all or some of the textures at once.
+	 * @see		MULTI_RENDER_TEXTURE_DESC
+	 *
+	 * @note	References core textures instead of texture handles.
 	 */
-	class BS_CORE_EXPORT MultiRenderTexture : public RenderTarget
+	struct BS_CORE_EXPORT MULTI_RENDER_TEXTURE_CORE_DESC
+	{
+		Vector<RENDER_SURFACE_CORE_DESC> colorSurfaces;
+		RENDER_SURFACE_CORE_DESC depthStencilSurface;
+	};
+
+	/** Contains various properties that describe a render texture. */
+	class BS_CORE_EXPORT MultiRenderTextureProperties : public RenderTargetProperties
 	{
 	public:
-		virtual ~MultiRenderTexture();
+		MultiRenderTextureProperties(const MULTI_RENDER_TEXTURE_DESC& desc);
+		MultiRenderTextureProperties(const MULTI_RENDER_TEXTURE_CORE_DESC& desc);
+		virtual ~MultiRenderTextureProperties() { }
 
-		/**
-		 * @copydoc	RenderTarget::initialize
-		 */
-		void initialize(const MULTI_RENDER_TEXTURE_DESC& desc);
+	protected:
+		friend class MultiRenderTextureCore;
+		friend class MultiRenderTexture;
 
-		/**
-		 * @copydoc RenderTarget::isWindow.
-		 */
-		bool isWindow() const { return true; }
+		void construct(const TextureProperties* props);
+	};
 
-		/**
-		 * @copydoc RenderTarget::requiresTextureFlipping.
-		 */
-		bool requiresTextureFlipping() const { return false; }
+	/** @cond INTERNAL */
+
+	/**
+	 * Object representing multiple render textures. You may bind this to the pipeline in order to render to all or some 
+	 * of the textures at once.
+	 *
+	 * @note	Core thread only.
+	 */
+	class BS_CORE_EXPORT MultiRenderTextureCore : public RenderTargetCore
+	{
+	public:
+		virtual ~MultiRenderTextureCore();
+
+		/** @copydoc CoreObjectCore::initialize */
+		virtual void initialize() override;
+
+		/** Returns properties that describe the render texture. */
+		const MultiRenderTextureProperties& getProperties() const;
 
 	protected:
-		MultiRenderTexture();
+		MultiRenderTextureCore(const MULTI_RENDER_TEXTURE_CORE_DESC& desc);
 
-		/**
-		 * @copydoc RenderTarget::destroy_internal()
-		 */
-		virtual void destroy_internal();
+		/** @copydoc CoreObjectCore::syncToCore */
+		virtual void syncToCore(const CoreSyncData& data) override;
 
 	private:
-		/**
-		 * @brief	Checks that all render surfaces and depth/stencil surface match. If they do not match
-		 *			an exception is thrown.
-		 */
+		/** Checks that all render surfaces and depth/stencil surface match. If they do not match an exception is thrown. */
 		void throwIfBuffersDontMatch() const;
 
 		// TODO - Not implemented
@@ -61,5 +82,62 @@ namespace BansheeEngine
 	protected:
 		Vector<TextureViewPtr> mColorSurfaces;
 		TextureViewPtr mDepthStencilSurface;
+
+		MULTI_RENDER_TEXTURE_CORE_DESC mDesc;
 	};
+
+	/** @endcond */
+
+	/**
+	 * Object representing multiple render textures. You may bind this to the pipeline in order to render to all or some of 
+	 * the textures at once.
+	 *
+	 * @note	Sim thread only.
+	 */
+	class BS_CORE_EXPORT MultiRenderTexture : public RenderTarget
+	{
+	public:
+		virtual ~MultiRenderTexture() { }
+
+		/**
+		 * Returns a color surface texture you may bind as an input to an GPU program.
+		 *
+		 * @note	Be aware that you cannot bind a render texture for reading and writing at the same time.
+		 */
+		const HTexture& getBindableColorTexture(UINT32 idx) const { return mBindableColorTex[idx]; }
+
+		/**
+		 * Returns a depth/stencil surface texture you may bind as an input to an GPU program.
+		 *
+		 * @note	Be aware that you cannot bind a render texture for reading and writing at the same time.
+		 */
+		const HTexture& getBindableDepthStencilTexture() const { return mBindableDepthStencilTex; }
+
+		/** Retrieves a core implementation of a render texture usable only from the core thread. */
+		SPtr<MultiRenderTextureCore> getCore() const;
+
+		/** @copydoc TextureManager::createMultiRenderTexture */
+		static MultiRenderTexturePtr create(const MULTI_RENDER_TEXTURE_DESC& desc);
+
+		/**	Returns properties that describe the render texture. */
+		const MultiRenderTextureProperties& getProperties() const;
+
+		/**	Returns the number of color surfaces used by the render texture. */
+		UINT32 getColorSurfaceCount() const;
+
+	protected:
+		MultiRenderTexture(const MULTI_RENDER_TEXTURE_DESC& desc);
+
+		/** @copydoc RenderTarget::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObjectCore::syncToCore */
+		virtual CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		MULTI_RENDER_TEXTURE_DESC mDesc;
+		Vector<HTexture> mBindableColorTex;
+		HTexture mBindableDepthStencilTex;
+	};
+
+	/** @} */
 }

+ 162 - 165
BansheeCore/Include/BsOSInputHandler.h

@@ -1,166 +1,163 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsPlatform.h"
-#include "BsEvent.h"
-#include "BsVector2I.h"
-
-namespace BansheeEngine
-{
-	/**
-		* @brief	Represents a specific way of acquiring OS input. InputManager (which provides a higher level input)
-		* 			must have at least one OSInputHandler attached. Attach events handler to the provided signals to handle input.
-		* 			
-		* @note		Unlike RawInputHandler this class receives input from the operating system, and is used for receiving
-		* 			text input, cursor position and similar.
-		*/
-	class BS_CORE_EXPORT OSInputHandler
-	{
-		/**
-		 * @brief	Contains information regarding a button state change event.
-		 */
-		struct ButtonStateChange
-		{
-			Vector2I cursorPos;
-			OSPointerButtonStates btnStates;
-			OSMouseButton button;
-			bool pressed;
-		};
-
-		/**
-		 * @brief	Contains information regarding a double click event.
-		 */
-		struct DoubleClick
-		{
-			Vector2I cursorPos;
-			OSPointerButtonStates btnStates;
-		};
-
-	public:
-		OSInputHandler();
-		virtual ~OSInputHandler();
-
-		/**
-		 * @brief	Triggers when user inputs a character. The character might be a result of pressing
-		 * 			multiple keys, so character input will not necessarily correspond with button presses.
-		 * 			Provide character code of the input character.
-		 */
-		Event<void(UINT32)> onCharInput;
-
-		/**
-		 * @brief	Triggers whenever user scrolls the mouse wheel. Returns the screen
-		 * 			position of the mouse cursor and delta amount of mouse scroll (can be negative or positive).
-		 */
-		Event<void(const Vector2I&, float)> onMouseWheelScrolled;
-
-		/**
-		 * @brief	Triggers whenever user moves the mouse cursor.
-		 */
-		Event<void(const PointerEvent&)> onCursorMoved;
-
-		/**
-		 * @brief	Triggers whenever user presses one of the mouse buttons.
-		 */
-		Event<void(const PointerEvent&)> onCursorPressed;
-
-		/**
-		 * @brief	Triggers whenever user releases one of the mouse buttons.
-		 */
-		Event<void(const PointerEvent&)> onCursorReleased;
-
-		/**
-		 * @brief	Triggers when user clicks a mouse button quickly twice in a row.
-		 */
-		Event<void(const PointerEvent&)> onDoubleClick;
-
-		/**
-		 * @brief	Triggers when user inputa a special input command, like commands user
-		 * 			for manipulating text input.
-		 */
-		Event<void(InputCommandType)> onInputCommand;
-
-		/**
-		 * @brief	Called once per frame. Capture input here if needed.
-		 * 			
-		 * @note	Internal method.
-		 */
-		virtual void _update();
-
-		/**
-		 * @brief	Called whenever the active window changes.
-		 *
-		 * @param	win	Newly active window.
-		 * 				
-		 * @note	Internal method.
-		 */
-		virtual void _inputWindowChanged(const RenderWindow& win) {}
-
-	private:
-		BS_MUTEX(mOSInputMutex);
-		Vector2I mLastCursorPos;
-		Vector2I mCursorPosition;
-		float mMouseScroll;
-		WString mInputString;
-		Queue<ButtonStateChange> mButtonStates;
-		Queue<DoubleClick> mDoubleClicks;
-		Queue<InputCommandType> mInputCommands;
-		OSPointerButtonStates mMouseMoveBtnState;
-
-		HEvent mCharInputConn;
-		HEvent mCursorMovedConn;
-		HEvent mCursorPressedConn;
-		HEvent mCursorReleasedConn;
-		HEvent mCursorDoubleClickConn;
-		HEvent mInputCommandConn;
-		HEvent mMouseWheelScrolledConn;
-
-		/**
-		 * @brief	Called from the message loop to notify user has entered a character.
-		 * 			
-		 * @see		onCharInput
-		 */
-		void charInput(UINT32 character);
-
-		/**
-		 * @brief	Called from the message loop to notify user has moved the cursor.
-		 * 			
-		 * @see		onCursorMoved
-		 */
-		void cursorMoved(const Vector2I& cursorPos, OSPointerButtonStates& btnStates);
-
-		/**
-		 * @brief	Called from the message loop to notify user has pressed a mouse button.
-		 * 			
-		 * @see		onCursorPressed
-		 */
-		void cursorPressed(const Vector2I& cursorPos, OSMouseButton button, OSPointerButtonStates& btnStates);
-
-		/**
-		 * @brief	Called from the message loop to notify user has released a mouse button.
-		 * 			
-		 * @see		onCursorReleased
-		 */
-		void cursorReleased(const Vector2I& cursorPos, OSMouseButton button, OSPointerButtonStates& btnStates);
-
-		/**
-		 * @brief	Called from the message loop to notify user has double-clicked a mouse button.
-		 * 
-		 * @see		onDoubleClick
-		 */
-		void cursorDoubleClick(const Vector2I& cursorPos, OSPointerButtonStates& btnStates);
-
-		/**
-		 * @brief	Called from the message loop to notify user has entered an input command.
-		 * 			
-		 * @see		onInputCommand
-		 */
-		void inputCommandEntered(InputCommandType commandType);
-
-		/**
-		 * @brief	Called from the message loop to notify user has scrolled the mouse wheel.
-		 * 			
-		 * @see		onMouseWheelScrolled
-		 */
-		void mouseWheelScrolled(float scrollPos);
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsPlatform.h"
+#include "BsEvent.h"
+#include "BsVector2I.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Input
+	 *  @{
+	 */
+
+	/**
+	 * Represents a specific way of acquiring OS input. Input class (which provides a higher level input) must have at 
+	 * least one OSInputHandler attached. Attach events handler to the provided signals to handle input.
+	 * 			
+	 * @note		
+	 * Unlike RawInputHandler this class receives input from the operating system, and is used for receiving text input, 
+	 * cursor position and similar.
+	 */
+	class BS_CORE_EXPORT OSInputHandler
+	{
+		/**	Contains information regarding a button state change event. */
+		struct ButtonStateChange
+		{
+			Vector2I cursorPos;
+			OSPointerButtonStates btnStates;
+			OSMouseButton button;
+			bool pressed;
+		};
+
+		/**	Contains information regarding a double click event. */
+		struct DoubleClick
+		{
+			Vector2I cursorPos;
+			OSPointerButtonStates btnStates;
+		};
+
+	public:
+		OSInputHandler();
+		virtual ~OSInputHandler();
+
+		/**
+		 * Called once per frame. Capture input here if needed.
+		 * 			
+		 * @note	Internal method.
+		 */
+		virtual void _update();
+
+		/**
+		 * Called whenever the active window changes.
+		 *
+		 * @param[in]	win	Newly active window.
+		 * 				
+		 * @note	Internal method.
+		 */
+		virtual void _inputWindowChanged(const RenderWindow& win) { }
+
+		/**
+		 * Triggers when user inputs a character. The character might be a result of pressing multiple keys, so character 
+		 * input will not necessarily correspond with button presses. Provide character code of the input character.
+		 */
+		Event<void(UINT32)> onCharInput;
+
+		/**
+		 * Triggers whenever user scrolls the mouse wheel. Returns the screen position of the mouse cursor and delta amount 
+		 * of mouse scroll (can be negative or positive).
+		 */
+		Event<void(const Vector2I&, float)> onMouseWheelScrolled;
+
+		/** Triggers whenever user moves the mouse cursor. */
+		Event<void(const PointerEvent&)> onCursorMoved;
+
+		/**	Triggers whenever user presses one of the mouse buttons. */
+		Event<void(const PointerEvent&)> onCursorPressed;
+
+		/**	Triggers whenever user releases one of the mouse buttons. */
+		Event<void(const PointerEvent&)> onCursorReleased;
+
+		/**	Triggers when user clicks a mouse button quickly twice in a row. */
+		Event<void(const PointerEvent&)> onDoubleClick;
+
+		/**	Triggers when user inputa a special input command, like commands user for manipulating text input. */
+		Event<void(InputCommandType)> onInputCommand;
+
+	private:
+		BS_MUTEX(mOSInputMutex);
+		Vector2I mLastCursorPos;
+		Vector2I mCursorPosition;
+		Vector2I mDelta;
+		bool mLastCursorPosSet;
+		float mMouseScroll;
+		WString mInputString;
+		Queue<ButtonStateChange> mButtonStates;
+		Queue<DoubleClick> mDoubleClicks;
+		Queue<InputCommandType> mInputCommands;
+		OSPointerButtonStates mMouseMoveBtnState;
+
+		HEvent mCharInputConn;
+		HEvent mCursorMovedConn;
+		HEvent mCursorPressedConn;
+		HEvent mCursorReleasedConn;
+		HEvent mCursorDoubleClickConn;
+		HEvent mInputCommandConn;
+		HEvent mMouseWheelScrolledConn;
+
+		/**
+		 * Called from the message loop to notify user has entered a character.
+		 * 			
+		 * @see		onCharInput
+		 */
+		void charInput(UINT32 character);
+
+		/**
+		 * Called from the message loop to notify user has moved the cursor.
+		 * 			
+		 * @see		onCursorMoved
+		 */
+		void cursorMoved(const Vector2I& cursorPos, OSPointerButtonStates& btnStates);
+
+		/**
+		 * Called from the message loop to notify user has pressed a mouse button.
+		 * 			
+		 * @see		onCursorPressed
+		 */
+		void cursorPressed(const Vector2I& cursorPos, OSMouseButton button, OSPointerButtonStates& btnStates);
+
+		/**
+		 * Called from the message loop to notify user has released a mouse button.
+		 * 			
+		 * @see		onCursorReleased
+		 */
+		void cursorReleased(const Vector2I& cursorPos, OSMouseButton button, OSPointerButtonStates& btnStates);
+
+		/**
+		 * Called from the message loop to notify user has double-clicked a mouse button.
+		 * 
+		 * @see		onDoubleClick
+		 */
+		void cursorDoubleClick(const Vector2I& cursorPos, OSPointerButtonStates& btnStates);
+
+		/**
+		 * Called from the message loop to notify user has entered an input command.
+		 * 			
+		 * @see		onInputCommand
+		 */
+		void inputCommandEntered(InputCommandType commandType);
+
+		/**
+		 * Called from the message loop to notify user has scrolled the mouse wheel.
+		 * 			
+		 * @see		onMouseWheelScrolled
+		 */
+		void mouseWheelScrolled(float scrollPos);
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 75 - 75
BansheeCore/Include/BsOcclusionQuery.h

@@ -1,76 +1,76 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	* @brief	Represents a query that counts number of samples rendered by the GPU
-	*			while the query is active.
-	*
-	* @note		Core thread only.
-	*/
-	class BS_CORE_EXPORT OcclusionQuery
-	{
-	public:
-		OcclusionQuery(bool binary);
-		virtual ~OcclusionQuery() {}
-
-		/**
-		* @brief	Starts the query. Any draw calls after this call will have any rendered samples
-		*			counted in the query.
-		*
-		* @note		Place any commands you want to measure after this call. Call "end" when done.
-		*/
-		virtual void begin() = 0;
-
-		/**
-		* @brief	Stops the query. 
-		*
-		* @note		Be aware that queries are executed on the GPU and the results will not be immediately available.
-		*/
-		virtual void end() = 0;
-
-		/**
-		* @brief	Check if GPU has processed the query.
-		*/
-		virtual bool isReady() const = 0;
-
-		/**
-		 * @brief	Returns the number of samples that passed the depth and stencil test between
-		 *			query start and end.
-		 *
-		 * @note	If the query is binary, this will return 0 or 1. 1 meaning one or more samples were rendered,
-		 *			but will not give you the exact count.
-		 */
-		virtual UINT32 getNumSamples() = 0;
-
-		/**
-		 * @brief	Triggered when the query has completed. Argument provided
-		 *			is the number of samples counted by the query.
-		 */
-		Event<void(UINT32)> onComplete;
-
-		/**
-		 * @brief	Creates a new occlusion query. 
-		 *
-		 * @param binary	If query is binary it will not give you an exact count of samples rendered, but will instead
-		 *					just return 0 (no samples were rendered) or 1 (one or more samples were rendered). Binary
-		 *					queries can return sooner as they potentially do not need to wait until all of the geometry is rendered.
-		 */
-		static OcclusionQueryPtr create(bool binary);
-
-	protected:
-		friend class QueryManager;
-
-		/**
-		* @brief	Returns true if the has still not been completed by the GPU.
-		*/
-		bool isActive() const { return mActive; }
-		void setActive(bool active) { mActive = active; }
-
-	protected:
-		bool mActive;
-		bool mBinary;
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Represents a query that counts number of samples rendered by the GPU while the query is active.
+	 *
+	 * @note		Core thread only.
+	 */
+	class BS_CORE_EXPORT OcclusionQuery
+	{
+	public:
+		OcclusionQuery(bool binary);
+		virtual ~OcclusionQuery() {}
+
+		/**
+		 * Starts the query. Any draw calls after this call will have any rendered samples counted in the query.
+		 *
+		 * @note	Place any commands you want to measure after this call. Call end() when done.
+		 */
+		virtual void begin() = 0;
+
+		/**
+		 * Stops the query. 
+		 *
+		 * @note	Be aware that queries are executed on the GPU and the results will not be immediately available.
+		 */
+		virtual void end() = 0;
+
+		/** Check if GPU has processed the query. */
+		virtual bool isReady() const = 0;
+
+		/**
+		 * Returns the number of samples that passed the depth and stencil test between query start and end.
+		 *
+		 * @note	
+		 * If the query is binary, this will return 0 or 1. 1 meaning one or more samples were rendered, but will not give
+		 * you the exact count.
+		 */
+		virtual UINT32 getNumSamples() = 0;
+
+		/** Triggered when the query has completed. Argument provided is the number of samples counted by the query. */
+		Event<void(UINT32)> onComplete;
+
+		/**
+		 * Creates a new occlusion query. 
+		 *
+		 * @param[in] binary	If query is binary it will not give you an exact count of samples rendered, but will instead
+		 *						just return 0 (no samples were rendered) or 1 (one or more samples were rendered). Binary
+		 *						queries can return sooner as they potentially do not need to wait until all of the geometry
+		 *						is rendered.
+		 */
+		static OcclusionQueryPtr create(bool binary);
+
+	protected:
+		friend class QueryManager;
+
+		/**	Returns true if the has still not been completed by the GPU. */
+		bool isActive() const { return mActive; }
+		void setActive(bool active) { mActive = active; }
+
+	protected:
+		bool mActive;
+		bool mBinary;
+	};
+
+	/** @} */
 }

+ 112 - 0
BansheeCore/Include/BsParamBlocks.h

@@ -0,0 +1,112 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGpuParamDesc.h"
+#include "BsGpuParams.h"
+#include "BsRenderAPI.h"
+#include "BsGpuParamBlockBuffer.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Renderer
+	 *  @{
+	 */
+
+/** 
+ * Starts a new custom parameter block. Custom parameter blocks allow you to create C++ structures that map directly
+ * to GPU program buffers (e.g. uniform buffer in OpenGL or constant buffer in DX). Must be followed by BS_PARAM_BLOCK_END.
+ */
+#define BS_PARAM_BLOCK_BEGIN(Name)																							\
+	struct Name																												\
+	{																														\
+		Name()																												\
+		{																													\
+			Vector<GpuParamDataDesc> params = getEntries();																	\
+			RenderAPICore& rapi = RenderAPICore::instance();																\
+																															\
+			mBlockDesc = rapi.generateParamBlockDesc(#Name, params);														\
+																															\
+			SPtr<GpuParamDesc> paramsDesc = bs_shared_ptr_new<GpuParamDesc>();												\
+			paramsDesc->paramBlocks[#Name] = mBlockDesc;																	\
+			for (auto& param : params)																						\
+				paramsDesc->params[param.name] = param;																		\
+																															\
+			mParams = GpuParamsCore::create(paramsDesc, rapi.getGpuProgramHasColumnMajorMatrices());						\
+																															\
+			mBuffer = GpuParamBlockBufferCore::create(mBlockDesc.blockSize * sizeof(UINT32));								\
+			mParams->setParamBlockBuffer(#Name, mBuffer);																	\
+			initEntries();																									\
+		}																													\
+																															\
+		const SPtr<GpuParamBlockBufferCore>& getBuffer() const { return mBuffer; }											\
+		const GpuParamBlockDesc& getDesc() const { return mBlockDesc; }														\
+																															\
+	private:																												\
+		struct META_FirstEntry {};																							\
+		static void META_GetPrevEntries(Vector<GpuParamDataDesc>& params, META_FirstEntry id) { }							\
+		void META_InitPrevEntry(const SPtr<GpuParamsCore>& params, META_FirstEntry id) { }									\
+																															\
+		typedef META_FirstEntry 
+
+/**
+ * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls.
+ */
+#define BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, NumElements)																	\
+		META_Entry_##Name;																									\
+																															\
+		struct META_NextEntry_##Name {};																					\
+		static void META_GetPrevEntries(Vector<GpuParamDataDesc>& params, META_NextEntry_##Name id)							\
+		{																													\
+			META_GetPrevEntries(params, META_Entry_##Name##());																\
+																															\
+			params.push_back(GpuParamDataDesc());																			\
+			GpuParamDataDesc& newEntry = params.back();																		\
+			newEntry.name = #Name;																							\
+			newEntry.type = (GpuParamDataType)TGpuDataParamInfo<Type>::TypeId;												\
+			newEntry.arraySize = NumElements;																				\
+		}																													\
+																															\
+		void META_InitPrevEntry(const SPtr<GpuParamsCore>& params, META_NextEntry_##Name id)								\
+		{																													\
+			META_InitPrevEntry(params, META_Entry_##Name##());																\
+			params->getParam(#Name, Name);																					\
+		}																													\
+																															\
+	public:																													\
+		TGpuDataParam<Type, true> Name;																						\
+																															\
+	private:																												\
+		typedef META_NextEntry_##Name
+
+/** 
+ * Registers a new entry in a parameter block. Must be called in between BS_PARAM_BLOCK_BEGIN and BS_PARAM_BLOCK_END calls. 
+ */
+#define BS_PARAM_BLOCK_ENTRY(Type, Name) BS_PARAM_BLOCK_ENTRY_ARRAY(Type, Name, 1)
+
+/** Ends parameter block definition. See BS_PARAM_BLOCK_BEGIN. */
+#define BS_PARAM_BLOCK_END																									\
+		META_LastEntry;																										\
+																															\
+		static Vector<GpuParamDataDesc> getEntries()																		\
+		{																													\
+			Vector<GpuParamDataDesc> entries;																				\
+			META_GetPrevEntries(entries, META_LastEntry());																	\
+			return entries;																									\
+		}																													\
+																															\
+		void initEntries()																									\
+		{																													\
+			META_InitPrevEntry(mParams, META_LastEntry());																	\
+		}																													\
+																															\
+		SPtr<GpuParamsCore> mParams;																						\
+		SPtr<GpuParamBlockBufferCore> mBuffer;																				\
+		GpuParamBlockDesc mBlockDesc;																						\
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 208 - 96
BansheeCore/Include/BsPass.h

@@ -1,97 +1,209 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsCoreThreadAccessor.h"
-#include "BsColor.h"
-#include "BsIReflectable.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Class defining a single pass of a technique (of a material), i.e.
-	 * 			a single rendering call. 
-	 * 			
-	 *			Pass may contain multiple GPU programs (vertex, fragment, geometry, etc.), and
-	 *			a set of pipeline states (blend, rasterizer, etc.).
-	 */
-	class BS_CORE_EXPORT Pass : public IReflectable
-    {
-    public:
-		Pass();
-        Pass(const Pass& oth);
-        Pass& operator=(const Pass& oth);
-        virtual ~Pass();
-
-        bool hasVertexProgram() const { return mVertexProgram != nullptr; }
-        bool hasFragmentProgram() const { return mFragmentProgram != nullptr; }
-        bool hasGeometryProgram() const { return mGeometryProgram != nullptr; }
-		bool hasHullProgram() const { return mHullProgram != nullptr; }
-		bool hasDomainProgram() const { return mDomainProgram != nullptr; }
-		bool hasComputeProgram() const { return mComputeProgram != nullptr; }
-
-		/**
-		 * @brief	Returns true if this pass has some element of transparency.
-		 */
-		bool isTransparent() const;
-
-		void setBlendState(HBlendState& blendState);
-		HBlendState getBlendState() const;
-
-		void setRasterizerState(HRasterizerState& rasterizerState);
-		HRasterizerState getRasterizerState() const;
-
-		void setDepthStencilState(HDepthStencilState& depthStencilState);
-		HDepthStencilState getDepthStencilState() const;
-
-		/**
-		 * @brief	Sets the stencil reference value that is used when performing operations using the
-		 * 			stencil buffer.
-		 */
-		void setStencilRefValue(UINT32 refValue);
-
-		/**
-		 * @brief	Gets the stencil reference value that is used when performing operations using the
-		 * 			stencil buffer.
-		 */
-		UINT32 getStencilRefValue() const;
-
-		void setVertexProgram(HGpuProgram gpuProgram) { mVertexProgram = gpuProgram; }
-		const HGpuProgram& getVertexProgram() const { return mVertexProgram; }
-
-		void setFragmentProgram(HGpuProgram gpuProgram) { mFragmentProgram = gpuProgram; }
-		const HGpuProgram& getFragmentProgram() const { return mFragmentProgram; }
-
-		void setGeometryProgram(HGpuProgram gpuProgram) { mGeometryProgram = gpuProgram; }
-		const HGpuProgram& getGeometryProgram() const { return mGeometryProgram; }
-
-		void setHullProgram(HGpuProgram gpuProgram) { mHullProgram = gpuProgram; }
-		const HGpuProgram& getHullProgram(void) const { return mHullProgram; }
-
-		void setDomainProgram(HGpuProgram gpuProgram) { mDomainProgram = gpuProgram;}
-		const HGpuProgram& getDomainProgram(void) const { return mDomainProgram; }
-
-		void setComputeProgram(HGpuProgram gpuProgram) { mComputeProgram = gpuProgram; }
-		const HGpuProgram& getComputeProgram(void) const { return mComputeProgram; }
-
-	protected:
-		HBlendState mBlendState;
-		HRasterizerState mRasterizerState;
-		HDepthStencilState mDepthStencilState;
-		UINT32 mStencilRefValue;
-
-		HGpuProgram mVertexProgram;
-		HGpuProgram mFragmentProgram;
-		HGpuProgram mGeometryProgram;
-		HGpuProgram mHullProgram;
-		HGpuProgram mDomainProgram;
-		HGpuProgram mComputeProgram;
-
-		/************************************************************************/
-		/* 								RTTI		                     		*/
-		/************************************************************************/
-	public:
-		friend class PassRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;	
-    };
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsColor.h"
+#include "BsIReflectable.h"
+#include "BsCoreObject.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Material
+	 *  @{
+	 */
+
+	/** Descriptor structure used for initializing a shader pass. */
+	struct PASS_DESC
+	{
+		BlendStatePtr blendState;
+		RasterizerStatePtr rasterizerState;
+		DepthStencilStatePtr depthStencilState;
+		UINT32 stencilRefValue;
+
+		GpuProgramPtr vertexProgram;
+		GpuProgramPtr fragmentProgram;
+		GpuProgramPtr geometryProgram;
+		GpuProgramPtr hullProgram;
+		GpuProgramPtr domainProgram;
+		GpuProgramPtr computeProgram;
+	};
+
+	/** @cond INTERNAL */
+
+	/** Descriptor structure used for initializing a core thread variant of a shader pass. */
+	struct PASS_DESC_CORE
+	{
+		SPtr<BlendStateCore> blendState;
+		SPtr<RasterizerStateCore> rasterizerState;
+		SPtr<DepthStencilStateCore> depthStencilState;
+		UINT32 stencilRefValue;
+
+		SPtr<GpuProgramCore> vertexProgram;
+		SPtr<GpuProgramCore> fragmentProgram;
+		SPtr<GpuProgramCore> geometryProgram;
+		SPtr<GpuProgramCore> hullProgram;
+		SPtr<GpuProgramCore> domainProgram;
+		SPtr<GpuProgramCore> computeProgram;
+	};
+
+	/** @endcond */
+	/** @} */
+
+	/** @addtogroup Implementation
+	 *  @{
+	 */
+
+	/** Contains all data used by a pass, templated so it may contain both core and sim thread data. */
+	template<bool Core>
+	struct TPassTypes
+	{ };
+
+	template<>
+	struct TPassTypes < false >
+	{
+		typedef BlendStatePtr BlendStateType;
+		typedef RasterizerStatePtr RasterizerStateType;
+		typedef DepthStencilStatePtr DepthStencilStateType;
+		typedef GpuProgramPtr GpuProgramType;
+		typedef PASS_DESC PassDescType;
+	};
+
+	template<>
+	struct TPassTypes < true >
+	{
+		typedef SPtr<BlendStateCore> BlendStateType;
+		typedef SPtr<RasterizerStateCore> RasterizerStateType;
+		typedef SPtr<DepthStencilStateCore> DepthStencilStateType;
+		typedef SPtr<GpuProgramCore> GpuProgramType;
+		typedef PASS_DESC_CORE PassDescType;
+	};
+
+	/**
+	 * Class defining a single pass of a technique (of a material), i.e. a single rendering call.
+	 *
+	 * Pass may contain multiple GPU programs (vertex, fragment, geometry, etc.), and a set of pipeline states (blend, 
+	 * rasterizer, etc.).
+	 *
+	 * @note	Templated so it can be used for both core and non-core versions of a pass.
+	 */
+	template<bool Core>
+	class BS_CORE_EXPORT TPass
+    {
+    public:
+		typedef typename TPassTypes<Core>::BlendStateType BlendStateType;
+		typedef typename TPassTypes<Core>::RasterizerStateType RasterizerStateType;
+		typedef typename TPassTypes<Core>::DepthStencilStateType DepthStencilStateType;
+		typedef typename TPassTypes<Core>::GpuProgramType GpuProgramType;
+		typedef typename TPassTypes<Core>::PassDescType PassDescType;
+
+		virtual ~TPass() { }
+
+        bool hasVertexProgram() const { return mData.vertexProgram != nullptr; }
+		bool hasFragmentProgram() const { return mData.fragmentProgram != nullptr; }
+		bool hasGeometryProgram() const { return mData.geometryProgram != nullptr; }
+		bool hasHullProgram() const { return mData.hullProgram != nullptr; }
+		bool hasDomainProgram() const { return mData.domainProgram != nullptr; }
+		bool hasComputeProgram() const { return mData.computeProgram != nullptr; }
+
+		/**	Returns true if this pass has some element of transparency. */
+		bool hasBlending() const;
+
+		BlendStateType getBlendState() const { return mData.blendState; }
+		RasterizerStateType getRasterizerState() const { return mData.rasterizerState; }
+		DepthStencilStateType getDepthStencilState() const { return mData.depthStencilState; }
+
+		/** Gets the stencil reference value that is used when performing operations using the stencil buffer. */
+		UINT32 getStencilRefValue() const { return mData.stencilRefValue; }
+
+		const GpuProgramType& getVertexProgram() const { return mData.vertexProgram; }
+		const GpuProgramType& getFragmentProgram() const { return mData.fragmentProgram; }
+		const GpuProgramType& getGeometryProgram() const { return mData.geometryProgram; }
+		const GpuProgramType& getHullProgram(void) const { return mData.hullProgram; }
+		const GpuProgramType& getDomainProgram(void) const { return mData.domainProgram; }
+		const GpuProgramType& getComputeProgram(void) const { return mData.computeProgram; }
+
+	protected:
+		TPass();
+		TPass(const PassDescType& desc);
+
+		PassDescType mData;
+    };
+
+	/** @} */
+
+	/** @addtogroup Material
+	 *  @{
+	 */
+	/** @cond INTERNAL */
+
+	/**
+	 * @copydoc	PassBase
+	 *
+	 * @note	Core thread.
+	 */
+	class BS_CORE_EXPORT PassCore : public CoreObjectCore, public TPass<true>
+    {
+    public:
+		virtual ~PassCore() { }
+
+		/**	Creates a new empty pass. */
+		static SPtr<PassCore> create(const PASS_DESC_CORE& desc);
+
+	protected:
+		friend class Pass;
+		friend class TechniqueCore;
+
+		PassCore() { }
+		PassCore(const PASS_DESC_CORE& desc);
+
+		/** @copydoc CoreObjectCore::syncToCore */
+		void syncToCore(const CoreSyncData& data) override;
+    };
+	/** @endcond */
+
+	/**
+	 * @copydoc	PassBase
+	 *
+	 * @note	Sim thread.
+	 */
+	class BS_CORE_EXPORT Pass : public IReflectable, public CoreObject, public TPass<false>
+    {
+    public:
+		virtual ~Pass() { }
+
+		/** Retrieves an implementation of a pass usable only from the core thread. */
+		SPtr<PassCore> getCore() const;
+
+		/**	Creates a new empty pass. */
+		static PassPtr create(const PASS_DESC& desc);
+
+	protected:
+		friend class Technique;
+
+		Pass() { }
+		Pass(const PASS_DESC& desc);
+
+		/** @copydoc CoreObject::syncToCore */
+		CoreSyncData syncToCore(FrameAlloc* allocator) override;
+
+		/** @copydoc CoreObject::createCore */
+		SPtr<CoreObjectCore> createCore() const override;
+
+		/** @copydoc CoreObject::syncToCore */
+		void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
+
+		/**	Creates a new empty pass but doesn't initialize it. */
+		static PassPtr createEmpty();
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class PassRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+    };
+
+	/** @} */
 }

+ 89 - 68
BansheeCore/Include/BsPassRTTI.h

@@ -1,69 +1,90 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRTTIType.h"
-#include "BsPass.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT PassRTTI : public RTTIType<Pass, IReflectable, PassRTTI>
-	{
-	private:
-		HBlendState& getBlendState(Pass* obj) { return obj->mBlendState; }
-		void setBlendState(Pass* obj, HBlendState& val) { obj->mBlendState = val; } 
-
-		HRasterizerState& getRasterizerState(Pass* obj) { return obj->mRasterizerState; }
-		void setRasterizerState(Pass* obj, HRasterizerState& val) { obj->mRasterizerState = val; } 
-
-		HDepthStencilState& getDepthStencilState(Pass* obj) { return obj->mDepthStencilState; }
-		void setDepthStencilState(Pass* obj, HDepthStencilState& val) { obj->mDepthStencilState = val; } 
-
-		HGpuProgram& getVertexProgram(Pass* obj) { return obj->mVertexProgram; }
-		void setVertexProgram(Pass* obj, HGpuProgram& val) { obj->mVertexProgram = val; } 
-
-		HGpuProgram& getFragmentProgram(Pass* obj) { return obj->mFragmentProgram; }
-		void setFragmentProgram(Pass* obj, HGpuProgram& val) { obj->mFragmentProgram = val; } 
-
-		HGpuProgram& getGeometryProgram(Pass* obj) { return obj->mGeometryProgram; }
-		void setGeometryProgram(Pass* obj, HGpuProgram& val) { obj->mGeometryProgram = val; } 
-
-		HGpuProgram& getHullProgram(Pass* obj) { return obj->mHullProgram; }
-		void setHullProgram(Pass* obj, HGpuProgram& val) { obj->mHullProgram = val; } 
-
-		HGpuProgram& getDomainProgram(Pass* obj) { return obj->mDomainProgram; }
-		void setDomainProgram(Pass* obj, HGpuProgram& val) { obj->mDomainProgram = val; } 
-
-		HGpuProgram& getComputeProgram(Pass* obj) { return obj->mComputeProgram; }
-		void setComputeProgram(Pass* obj, HGpuProgram& val) { obj->mComputeProgram = val; } 
-	public:
-		PassRTTI()
-		{
-			addReflectableField("mBlendState", 0, &PassRTTI::getBlendState, &PassRTTI::setBlendState);
-			addReflectableField("mRasterizerState", 1, &PassRTTI::getRasterizerState, &PassRTTI::setRasterizerState);
-			addReflectableField("mDepthStencilState", 2, &PassRTTI::getDepthStencilState, &PassRTTI::setDepthStencilState);
-
-			addReflectableField("mVertexProgram", 3, &PassRTTI::getVertexProgram, &PassRTTI::setVertexProgram);
-			addReflectableField("mFragmentProgram", 4, &PassRTTI::getFragmentProgram, &PassRTTI::setFragmentProgram);
-			addReflectableField("mGeometryProgram", 5, &PassRTTI::getGeometryProgram, &PassRTTI::setGeometryProgram);
-			addReflectableField("mHullProgram", 6, &PassRTTI::getHullProgram, &PassRTTI::setHullProgram);
-			addReflectableField("mDomainProgram", 7, &PassRTTI::getDomainProgram, &PassRTTI::setDomainProgram);
-			addReflectableField("mComputeProgram", 8, &PassRTTI::getComputeProgram, &PassRTTI::setComputeProgram);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "Pass";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_Pass;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			return bs_shared_ptr<Pass, PoolAlloc>();
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsPass.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT PassRTTI : public RTTIType<Pass, IReflectable, PassRTTI>
+	{
+	private:
+		BlendStatePtr getBlendState(Pass* obj) { return obj->mData.blendState; }
+		void setBlendState(Pass* obj, BlendStatePtr val) { obj->mData.blendState = val; }
+
+		RasterizerStatePtr getRasterizerState(Pass* obj) { return obj->mData.rasterizerState; }
+		void setRasterizerState(Pass* obj, RasterizerStatePtr val) { obj->mData.rasterizerState = val; }
+
+		DepthStencilStatePtr getDepthStencilState(Pass* obj) { return obj->mData.depthStencilState; }
+		void setDepthStencilState(Pass* obj, DepthStencilStatePtr val) { obj->mData.depthStencilState = val; }
+
+		UINT32& getStencilRefValue(Pass* obj) { return obj->mData.stencilRefValue; }
+		void setStencilRefValue(Pass* obj, UINT32& val) { obj->mData.stencilRefValue = val; }
+
+		GpuProgramPtr getVertexProgram(Pass* obj) { return obj->mData.vertexProgram; }
+		void setVertexProgram(Pass* obj, GpuProgramPtr val) { obj->mData.vertexProgram = val; }
+
+		GpuProgramPtr getFragmentProgram(Pass* obj) { return obj->mData.fragmentProgram; }
+		void setFragmentProgram(Pass* obj, GpuProgramPtr val) { obj->mData.fragmentProgram = val; }
+
+		GpuProgramPtr getGeometryProgram(Pass* obj) { return obj->mData.geometryProgram; }
+		void setGeometryProgram(Pass* obj, GpuProgramPtr val) { obj->mData.geometryProgram = val; }
+
+		GpuProgramPtr getHullProgram(Pass* obj) { return obj->mData.hullProgram; }
+		void setHullProgram(Pass* obj, GpuProgramPtr val) { obj->mData.hullProgram = val; }
+
+		GpuProgramPtr getDomainProgram(Pass* obj) { return obj->mData.domainProgram; }
+		void setDomainProgram(Pass* obj, GpuProgramPtr val) { obj->mData.domainProgram = val; }
+
+		GpuProgramPtr getComputeProgram(Pass* obj) { return obj->mData.computeProgram; }
+		void setComputeProgram(Pass* obj, GpuProgramPtr val) { obj->mData.computeProgram = val; }
+	public:
+		PassRTTI()
+		{
+			addReflectablePtrField("mBlendState", 0, &PassRTTI::getBlendState, &PassRTTI::setBlendState);
+			addReflectablePtrField("mRasterizerState", 1, &PassRTTI::getRasterizerState, &PassRTTI::setRasterizerState);
+			addReflectablePtrField("mDepthStencilState", 2, &PassRTTI::getDepthStencilState, &PassRTTI::setDepthStencilState);
+
+			addReflectablePtrField("mVertexProgram", 3, &PassRTTI::getVertexProgram, &PassRTTI::setVertexProgram);
+			addReflectablePtrField("mFragmentProgram", 4, &PassRTTI::getFragmentProgram, &PassRTTI::setFragmentProgram);
+			addReflectablePtrField("mGeometryProgram", 5, &PassRTTI::getGeometryProgram, &PassRTTI::setGeometryProgram);
+			addReflectablePtrField("mHullProgram", 6, &PassRTTI::getHullProgram, &PassRTTI::setHullProgram);
+			addReflectablePtrField("mDomainProgram", 7, &PassRTTI::getDomainProgram, &PassRTTI::setDomainProgram);
+			addReflectablePtrField("mComputeProgram", 8, &PassRTTI::getComputeProgram, &PassRTTI::setComputeProgram);
+
+			addPlainField("mStencilRefValue", 9, &PassRTTI::getStencilRefValue, &PassRTTI::setStencilRefValue);
+		}
+
+		void onDeserializationEnded(IReflectable* obj) override
+		{
+			Pass* pass = static_cast<Pass*>(obj);
+			pass->initialize();
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "Pass";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_Pass;
+		}
+
+		std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			return Pass::createEmpty();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 92 - 102
BansheeCore/Include/BsPixelBuffer.h

@@ -1,103 +1,93 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsHardwareBuffer.h"
-#include "BsPixelUtil.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Represents a hardware buffer that stores a single pixel surface.
-	 *			This may be a 1D, 2D or 3D surface, but unlike a texture it consists
-	 *			only of a single surface (no mip maps, cube map faces or similar).
-	 *
-	 * @note	Core thread only
-	 */
-    class BS_CORE_EXPORT PixelBuffer : public HardwareBuffer
-    {
-    public:
-		/**
-		 * @brief	Constructs a new pixel buffer with the provided settings.
-		 *
-		 * @param	width			Width of the pixel buffer in pixels.
-		 * @param	height			Height of the pixel buffer in pixels.
-		 * @param	depth			Depth of the pixel buffer in pixels (number of 2D slices).
-		 * @param	format			Format of each pixel in the buffer.
-		 * @param	usage			Usage signaling the render system how we plan on using the buffer.
-		 * @param	useSystemMemory	True if buffer should be allocated in system memory.
-		 */
-        PixelBuffer(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, 
-			GpuBufferUsage usage, bool useSystemMemory);
-        ~PixelBuffer();
-
-		// Make the other lock overloads visible.
-        using HardwareBuffer::lock;	
-
-		/**
-		 * @brief	Locks a certain region of the pixel buffer for reading and returns a pointer
-		 *			to the locked region.
-		 *
-		 * @param	lockBox		Region of the surface to lock.
-		 * @param	options		Lock options that hint the hardware on what you intend to do with the locked data.
-		 *
-		 * @note	Returned object is only valid while the lock is active.
-		 */
-		virtual const PixelData& lock(const PixelVolume& lockBox, GpuLockOptions options);
-		
-		/**
-		 * @copydoc	HardwareBuffer::lock
-		 */
-        virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options);
-		
-		/**
-		 * @copydoc	HardwareBuffer::readData
-		 */
-		virtual void readData(UINT32 offset, UINT32 length, void* pDest);
-
-		/**
-		 * @copydoc	HardwareBuffer::writeData
-		 */
-		virtual void writeData(UINT32 offset, UINT32 length, const void* pSource, BufferWriteType writeFlags = BufferWriteType::Normal);
-
-		/**
-		 * @brief	Returns width of the surface in pixels.
-		 */
-        UINT32 getWidth() const { return mWidth; }
-
-		/**
-		 * @brief	Returns height of the surface in pixels.
-		 */
-        UINT32 getHeight() const { return mHeight; }
-
-		/**
-		 * @brief	Returns depth of the surface in pixels.
-		 */
-        UINT32 getDepth() const { return mDepth; }
-
-		/**
-		 * @brief	Returns format of the pixels in the surface.
-		 */
-        PixelFormat getFormat() const { return mFormat; }
-
-	protected:
-		friend class RenderTexture;
-
-		/**
-		 * @brief	Internal implementation of the "lock" method.
-		 */
-		virtual PixelData lockImpl(PixelVolume lockBox, GpuLockOptions options) = 0;
-
-		/**
-		 * @copydoc	HardwareBuffer::lockImpl
-		 */
-		virtual void* lockImpl(UINT32 offset, UINT32 length, GpuLockOptions options);
-
-	protected:
-		UINT32 mWidth, mHeight, mDepth;
-		UINT32 mRowPitch, mSlicePitch;
-		PixelFormat mFormat;
-
-		PixelData mCurrentLock;
-		PixelVolume mLockedBox;
-    };
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsHardwareBuffer.h"
+#include "BsPixelUtil.h"
+
+namespace BansheeEngine 
+{
+	/** @cond INTERNAL */
+	/** @addtogroup RenderAPI
+	 *  @{
+	 */
+
+	/**
+	 * Represents a hardware buffer that stores a single pixel surface. This may be a 1D, 2D or 3D surface, but unlike a 
+	 * texture it consists only of a single surface (no mip maps, cube map faces or similar).
+	 *
+	 * @note	Core thread only
+	 */
+    class BS_CORE_EXPORT PixelBuffer : public HardwareBuffer
+    {
+    public:
+		/**
+		 * Constructs a new pixel buffer with the provided settings.
+		 *
+		 * @param[in]	width			Width of the pixel buffer in pixels.
+		 * @param[in]	height			Height of the pixel buffer in pixels.
+		 * @param[in]	depth			Depth of the pixel buffer in pixels (number of 2D slices).
+		 * @param[in]	format			Format of each pixel in the buffer.
+		 * @param[in]	usage			Usage signaling the render system how we plan on using the buffer.
+		 * @param[in]	useSystemMemory	True if buffer should be allocated in system memory.
+		 */
+        PixelBuffer(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format, 
+			GpuBufferUsage usage, bool useSystemMemory);
+        ~PixelBuffer();
+
+		// Make the other lock overloads visible.
+        using HardwareBuffer::lock;	
+
+		/**
+		 * Locks a certain region of the pixel buffer for reading and returns a pointer to the locked region.
+		 *
+		 * @param[in]	lockBox		Region of the surface to lock.
+		 * @param[in]	options		Lock options that hint the hardware on what you intend to do with the locked data.
+		 *
+		 * @note	Returned object is only valid while the lock is active.
+		 */
+		virtual const PixelData& lock(const PixelVolume& lockBox, GpuLockOptions options);
+		
+		/** @copydoc HardwareBuffer::lock */
+        virtual void* lock(UINT32 offset, UINT32 length, GpuLockOptions options);
+		
+		/** @copydoc HardwareBuffer::readData */
+		virtual void readData(UINT32 offset, UINT32 length, void* pDest);
+
+		/** @copydoc HardwareBuffer::writeData */
+		virtual void writeData(UINT32 offset, UINT32 length, const void* pSource, BufferWriteType writeFlags = BufferWriteType::Normal);
+
+		/**	Returns width of the surface in pixels. */
+        UINT32 getWidth() const { return mWidth; }
+
+		/**	Returns height of the surface in pixels. */
+        UINT32 getHeight() const { return mHeight; }
+
+		/**	Returns depth of the surface in pixels. */
+        UINT32 getDepth() const { return mDepth; }
+
+		/**	Returns format of the pixels in the surface. */
+        PixelFormat getFormat() const { return mFormat; }
+
+	protected:
+		friend class RenderTexture;
+
+		/**	Internal implementation of the lock() method. */
+		virtual PixelData lockImpl(PixelVolume lockBox, GpuLockOptions options) = 0;
+
+		/** @copydoc HardwareBuffer::lockImpl */
+		virtual void* lockImpl(UINT32 offset, UINT32 length, GpuLockOptions options);
+
+	protected:
+		UINT32 mWidth, mHeight, mDepth;
+		UINT32 mRowPitch, mSlicePitch;
+		PixelFormat mFormat;
+
+		PixelData mCurrentLock;
+		PixelVolume mLockedBox;
+    };
+
+	/** @} */
+	/** @endcond */
 }

+ 380 - 335
BansheeCore/Include/BsPixelData.h

@@ -1,336 +1,381 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsPixelVolume.h"
-#include "BsGpuResourceData.h"
-#include "BsIReflectable.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	The pixel format usable by images, textures and render surfaces.
-	 */
-    enum PixelFormat
-    {
-        // Unknown pixel format.
-        PF_UNKNOWN = 0,
-        // 8-bit pixel format, all bits red.
-        PF_R8 = 1,
-		// 2 byte pixel format, 1 byte red, 1 byte green.
-		PF_R8G8 = 2,
-        // 24-bit pixel format, 8 bits for red, green and blue.
-        PF_R8G8B8 = 3,
-        // 24-bit pixel format, 8 bits for blue, green and red.
-        PF_B8G8R8 = 4,
-        // 32-bit pixel format, 8 bits for alpha, red, green and blue.
-        PF_A8R8G8B8 = 5,
-        // 32-bit pixel format, 8 bits for blue, green, red and alpha.
-        PF_A8B8G8R8 = 6,
-        // 32-bit pixel format, 8 bits for blue, green, red and alpha.
-        PF_B8G8R8A8 = 7,
-		// 32-bit pixel format, 8 bits for red, green, blue and alpha.
-		PF_R8G8B8A8 = 8,
-        // 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue.
-        // Like PF_A8R8G8B8, but alpha will get discarded
-        PF_X8R8G8B8 = 9,
-        // 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red.
-        // Like PF_A8B8G8R8, but alpha will get discarded.
-        PF_X8B8G8R8 = 10,
-		// 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue.
-		// Like PF_R8G8B8A8, but alpha will get discarded.
-		PF_R8G8B8X8 = 11,
-		// 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red.
-		// Like PF_B8G8R8A8, but alpha will get discarded.
-		PF_B8G8R8X8 = 12,
-		// 24-bit pixel format, 8 bits for red, green and blue.
-		PF_BYTE_RGB = PF_R8G8B8,
-		// 24-bit pixel format, 8 bits for blue, green and red.
-		PF_BYTE_BGR = PF_B8G8R8,
-		// 32-bit pixel format, 8 bits for blue, green, red and alpha.
-		PF_BYTE_BGRA = PF_B8G8R8A8,
-		// 32-bit pixel format, 8 bits for red, green, blue and alpha.
-		PF_BYTE_RGBA = PF_R8G8B8A8,      
-        // DXT1/BC1 format containing opaque RGB or 1-bit alpha RGB. 4 bits per pixel.
-        PF_BC1 = 13,
-		// DXT3/BC2 format containing RGB with premultiplied alpha. 4 bits per pixel.
-		PF_BC1a = 14,
-        // DXT3/BC2 format containing RGB with explicit alpha. 8 bits per pixel.
-        PF_BC2 = 15,
-        // DXT5/BC2 format containing RGB with explicit alpha. 8 bits per pixel. Better alpha gradients than BC2.
-        PF_BC3 = 16,
-		// One channel compressed format. 4 bits per pixel.
-		PF_BC4 = 17,
-		// Two channel compressed format. 8 bits per pixel.
-		PF_BC5 = 18,
-		// Format storing RGB in half (16-bit) floating point format usable for HDR. 8 bits per pixel.
-		PF_BC6H = 19,
-		// Format storing RGB with optional alpha channel. Similar to BC1/BC2/BC3 formats but with higher quality and higher decompress overhead. 8 bits per pixel.
-		PF_BC7 = 20,
-		// 16-bit pixel format, 16 bits (float) for red
-        PF_FLOAT16_R = 21,
-		// 32-bit, 2-channel s10e5 floating point pixel format, 16-bit red, 16-bit green
-		PF_FLOAT16_RG = 22,
-        // 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue
-        PF_FLOAT16_RGB = 23,
-        // 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits (float) for alpha
-        PF_FLOAT16_RGBA = 24,
-		// 32-bit pixel format, 32 bits (float) for red
-        PF_FLOAT32_R = 25,
-		// 64-bit, 2-channel floating point pixel format, 32-bit red, 32-bit green
-		PF_FLOAT32_RG = 26,
-        // 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue
-        PF_FLOAT32_RGB = 27,
-        // 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits (float) for alpha
-        PF_FLOAT32_RGBA = 28,
-		// Depth stencil format, 32bit depth, 8bit stencil + 24 unused
-		PF_D32_S8X24 = 29,
-		// Depth stencil fomrat, 24bit depth + 8bit stencil
-		PF_D24S8 = 30,
-		// Depth format, 32bits
-		PF_D32 = 31,
-		// Depth format, 16bits
-		PF_D16 = 32,
-		// Number of pixel formats currently defined
-        PF_COUNT = 33
-    };
-	typedef Vector<PixelFormat> PixelFormatList;
-
-	/**
-	 * @brief	Flags defining some properties of pixel formats.
-	 */
-    enum PixelFormatFlags {
-        // This format has an alpha channel
-        PFF_HASALPHA = 0x00000001,      
-        // This format is compressed. This invalidates the values in elemBytes,
-        // elemBits and the bit counts as these might not be fixed in a compressed format.
-        PFF_COMPRESSED = 0x00000002,
-        // This is a floating point format
-        PFF_FLOAT = 0x00000004,         
-        // This is a depth format (for depth textures)
-        PFF_DEPTH = 0x00000008,
-        // Format is in native endian. Generally true for the 16, 24 and 32 bits
-        // formats which can be represented as machine integers.
-        PFF_NATIVEENDIAN = 0x00000010
-    };
-    
-	/**
-	 * @brief	Types of pixel components
-	 */
-    enum PixelComponentType
-    {
-        PCT_BYTE = 0,    /**< Byte per component */
-        PCT_SHORT = 1,   /**< Short per component */
-        PCT_FLOAT16 = 2, /**< 16 bit float per component */
-        PCT_FLOAT32 = 3, /**< 32 bit float per component */
-        PCT_COUNT = 4    /**< Number of pixel types */
-    };
-    
-	/**
-	 * @brief	A buffer describing a volume (3D), image (2D) or line (1D) of pixels in memory.
-	 *			Pixels are stored as a succession of "depth" slices, each containing "height" rows of
-	 *			"width" pixels.
-	 *
-	 *			As any GpuResourceData this is used primarily for reading and writing from/to a GPU resource,
-	 *			and is normally constructed by the resource itself. However you may still construct it manually
-	 *			and use it for other purposes if needed.
-	 *
-	 * @note	You must call allocateInternalBuffer or set the buffer in some other way before reading/writing
-	 *			from this object.
-	 *
-	 * @see		GpuResourceData
-	 */
-    class BS_CORE_EXPORT PixelData : public GpuResourceData
-	{
-    public:
-    	PixelData() {}
-		~PixelData() {}
-
-		/**
-		 * @brief	Constructs a new object with an internal buffer capable of holding "extents" volume of pixels, 
-		 *			where each pixel is of the specified pixel format. Extent offsets are also stored, but are not used
-		 *			internally.
-		 */
-		PixelData(const PixelVolume &extents, PixelFormat pixelFormat)
-			:mExtents(extents), mFormat(pixelFormat)
-		{
-			setConsecutive();
-		}
-
-		/**
-		 * @brief	Constructs a new object with an internal buffer capable of holding volume of pixels described by
-		 *			provided width, height and depth, where each pixel is of the specified pixel format.
-		 */
-    	PixelData(UINT32 width, UINT32 height, UINT32 depth, PixelFormat pixelFormat)
-			: mExtents(0, 0, 0, width, height, depth), mFormat(pixelFormat)
-    	{
-    		setConsecutive();
-    	}
-
-		PixelData(const PixelData& copy);
-		PixelData& operator=(const PixelData& rhs);
-
-		/**
-		 * @brief	Returns the number of pixels that offsets one row from another. This can be
-		 *			"width", but doesn't have to be as some buffers require padding.
-		 */
-		UINT32 getRowPitch() const { return mRowPitch; }
-
-		/**
-		 * @brief	Returns the number of pixels that offsets one depth slice from another. This can be
-		 *			"width * height", but doesn't have to be as some buffers require padding.
-		 */
-		UINT32 getSlicePitch() const { return mSlicePitch; }
-
-		/**
-		 * @brief	Sets the pitch (in pixels) that determines offset between rows of the pixel buffer.
-		 *			Call this before allocating the buffer.
-		 */
-		void setRowPitch(UINT32 rowPitch) { mRowPitch = rowPitch; }
-
-		/**
-		 * @brief	Sets the pitch (in pixels) that determines offset between depth slices of the pixel buffer.
-		 *			Call this before allocating the buffer.
-		 */
-        void setSlicePitch(UINT32 slicePitch) { mSlicePitch = slicePitch; }
-
-		/**
-		 * @brief	Returns the number of extra pixels in a row (non-zero only if rows are not
-		 *			consecutive (row pitch is larger than width)).
-		 */
-        UINT32 getRowSkip() const { return mRowPitch - getWidth(); }
-
-		/**
-		 * @brief	Returns the number of extra pixels in a depth slice (non-zero only if
-		 *			slices aren't consecutive (slice pitch is larger than width*height).
-		 */
-        UINT32 getSliceSkip() const { return mSlicePitch - (getHeight() * mRowPitch); }
-
-		/**
-		 * @brief	Returns the pixel format used by the internal buffer for storing the pixels.
-		 */
-		PixelFormat getFormat() const { return mFormat; }
-
-		/**
-		 * @brief	Returns width of the buffer in pixels.
-		 */
-		UINT32 getWidth() const { return mExtents.getWidth(); }
-
-		/**
-		 * @brief	Returns height of the buffer in pixels.
-		 */
-		UINT32 getHeight() const { return mExtents.getHeight(); }
-
-		/**
-		 * @brief	Returns depth of the buffer in pixels.
-		 */
-		UINT32 getDepth() const { return mExtents.getDepth(); }
-
-		/**
-		 * @brief	Returns left-most start of the pixel volume. This value is not used internally in any way.
-		 *			It is just passed through from the constructor.
-		 */
-		UINT32 getLeft() const { return mExtents.left; }
-
-		/**
-		 * @brief	Returns right-most end of the pixel volume. This value is not used internally in any way.
-		 *			It is just passed through from the constructor.
-		 */
-		UINT32 getRight() const { return mExtents.right; }
-
-		/**
-		 * @brief	Returns top-most start of the pixel volume. This value is not used internally in any way.
-		 *			It is just passed through from the constructor.
-		 */
-		UINT32 getTop() const { return mExtents.top; }
-
-		/**
-		 * @brief	Returns bottom-most end of the pixel volume. This value is not used internally in any way.
-		 *			It is just passed through from the constructor.
-		 */
-		UINT32 getBottom() const { return mExtents.bottom; }
-
-		/**
-		 * @brief	Returns front-most start of the pixel volume. This value is not used internally in any way.
-		 *			It is just passed through from the constructor.
-		 */
-		UINT32 getFront() const { return mExtents.front; }
-
-		/**
-		 * @brief	Returns back-most end of the pixel volume. This value is not used internally in any way.
-		 *			It is just passed through from the constructor.
-		 */
-		UINT32 getBack() const { return mExtents.back; }
-
-		/**
-		 * @brief	Returns extents of the pixel volume this object is capable of holding.
-		 */
-		PixelVolume getExtents() const { return mExtents; }
-
-		/**
-		 * @brief	Return whether this buffer is laid out consecutive in memory 
-		 *			(i.e. the pitches are equal to the dimensions).
-		 */
-        bool isConsecutive() const 
-		{ 
-			return mRowPitch == getWidth() && mSlicePitch == getWidth()*getHeight(); 
-		}
-
-		/**
-		 * @brief	Return the size (in bytes) this image would take if it was
-		 *			laid out consecutive in memory.
-		 */
-      	UINT32 getConsecutiveSize() const;
-
-		/**
-		 * @brief	Return the size (in bytes) of the buffer this image requires.
-		 */
-      	UINT32 getSize() const;
-
-		/**
-		 * @brief	Returns pixel data containing a sub-volume of this object. Returned
-		 *			data will not have its own buffer, but will instead point to this one.
-		 *			It is up to the caller to ensure this object outlives any sub-volume objects.
-		 */
-      	PixelData getSubVolume(const PixelVolume &def) const;
-        
-		/**
-		 * @brief	Returns pixel color at the specified coordinates.
-		 */
-        Color getColorAt(UINT32 x, UINT32 y, UINT32 z = 0);
-
-		/**
-		 * @brief	Sets the pixel color at the specified coordinates.
-		 */
-        void setColorAt(Color const &cv, UINT32 x, UINT32 y, UINT32 z = 0);
-
-	private:
-		/**
-		 * @brief	Set the rowPitch and slicePitch so that the buffer is laid out consecutive
-		 *			in memory. Does not actually modify the buffer itself.
-		 */
-		void setConsecutive()
-		{
-			mRowPitch = getWidth();
-			mSlicePitch = getWidth()*getHeight();
-		}
-
-		/**
-		 * @brief	Returns the needed size of the internal buffer, in bytes.
-		 */
-		UINT32 getInternalBufferSize();
-
-	private:
-		PixelVolume mExtents;
-        PixelFormat mFormat;
-        UINT32 mRowPitch;
-        UINT32 mSlicePitch;
-
-		/************************************************************************/
-		/* 								SERIALIZATION                      		*/
-		/************************************************************************/
-	public:
-		friend class PixelDataRTTI;
-		static RTTITypeBase* getRTTIStatic();
-		virtual RTTITypeBase* getRTTI() const;
-    };
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsPixelVolume.h"
+#include "BsGpuResourceData.h"
+#include "BsIReflectable.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Resources
+	 *  @{
+	 */
+
+	/** Pixel formats usable by images, textures and render surfaces. */
+    enum PixelFormat
+    {
+        /** Unknown pixel format. */
+        PF_UNKNOWN = 0,
+        /** 8-bit pixel format, all bits red. */
+        PF_R8 = 1,
+		/** 2 byte pixel format, 1 byte red, 1 byte green. */
+		PF_R8G8 = 2,
+        /** 24-bit pixel format, 8 bits for red, green and blue. */
+        PF_R8G8B8 = 3,
+        /** 24-bit pixel format, 8 bits for blue, green and red. */
+        PF_B8G8R8 = 4,
+        /** 32-bit pixel format, 8 bits for alpha, red, green and blue. */
+        PF_A8R8G8B8 = 5,
+        /** 32-bit pixel format, 8 bits for blue, green, red and alpha. */
+        PF_A8B8G8R8 = 6,
+        /** 32-bit pixel format, 8 bits for blue, green, red and alpha. */
+        PF_B8G8R8A8 = 7,
+		/** 32-bit pixel format, 8 bits for red, green, blue and alpha. */
+		PF_R8G8B8A8 = 8,
+        /** 
+		 * 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue. Like PF_A8R8G8B8, but alpha will get 
+		 * discarded.
+		 */
+        PF_X8R8G8B8 = 9,
+        /** 
+		 * 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red. Like PF_A8B8G8R8, but alpha will get 
+		 * discarded.
+		 */
+        PF_X8B8G8R8 = 10,
+		/** 
+		 * 32-bit pixel format, 8 bits for red, 8 bits for green, 8 bits for blue. Like PF_R8G8B8A8, but alpha will get 
+		 * discarded. 
+		 */
+		PF_R8G8B8X8 = 11,
+		/** 32-bit pixel format, 8 bits for blue, 8 bits for green, 8 bits for red. */
+		/** Like PF_B8G8R8A8, but alpha will get discarded. */
+		PF_B8G8R8X8 = 12,
+		/** 24-bit pixel format, 8 bits for red, green and blue. */
+		PF_BYTE_RGB = PF_R8G8B8,
+		/** 24-bit pixel format, 8 bits for blue, green and red. */
+		PF_BYTE_BGR = PF_B8G8R8,
+		/** 32-bit pixel format, 8 bits for blue, green, red and alpha. */
+		PF_BYTE_BGRA = PF_B8G8R8A8,
+		/** 32-bit pixel format, 8 bits for red, green, blue and alpha. */
+		PF_BYTE_RGBA = PF_R8G8B8A8,      
+        /** DXT1/BC1 format containing opaque RGB or 1-bit alpha RGB. 4 bits per pixel. */
+        PF_BC1 = 13,
+		/** DXT3/BC2 format containing RGB with premultiplied alpha. 4 bits per pixel. */
+		PF_BC1a = 14,
+        /** DXT3/BC2 format containing RGB with explicit alpha. 8 bits per pixel. */
+        PF_BC2 = 15,
+        /** DXT5/BC2 format containing RGB with explicit alpha. 8 bits per pixel. Better alpha gradients than BC2. */
+        PF_BC3 = 16,
+		/** One channel compressed format. 4 bits per pixel. */
+		PF_BC4 = 17,
+		/** Two channel compressed format. 8 bits per pixel. */
+		PF_BC5 = 18,
+		/** Format storing RGB in half (16-bit) floating point format usable for HDR. 8 bits per pixel. */
+		PF_BC6H = 19,
+		/** 
+		 * Format storing RGB with optional alpha channel. Similar to BC1/BC2/BC3 formats but with higher quality and 
+		 * higher decompress overhead. 8 bits per pixel. 
+		 */
+		PF_BC7 = 20,
+		/** 16-bit pixel format, 16 bits (float) for red. */
+        PF_FLOAT16_R = 21,
+		/** 32-bit, 2-channel s10e5 floating point pixel format, 16-bit red, 16-bit green. */
+		PF_FLOAT16_RG = 22,
+        /** 48-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue. */
+        PF_FLOAT16_RGB = 23,
+        /** 
+		 * 64-bit pixel format, 16 bits (float) for red, 16 bits (float) for green, 16 bits (float) for blue, 16 bits 
+		 * (float) for alpha. 
+		 */
+        PF_FLOAT16_RGBA = 24,
+		/** 32-bit pixel format, 32 bits (float) for red. */
+        PF_FLOAT32_R = 25,
+		/** 64-bit, 2-channel floating point pixel format, 32-bit red, 32-bit green. */
+		PF_FLOAT32_RG = 26,
+        /** 96-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue. */
+        PF_FLOAT32_RGB = 27,
+        /** 
+		 * 128-bit pixel format, 32 bits (float) for red, 32 bits (float) for green, 32 bits (float) for blue, 32 bits 
+		 * (float) for alpha. 
+		 */
+        PF_FLOAT32_RGBA = 28,
+		/** Depth stencil format, 32bit depth, 8bit stencil + 24 unused. */
+		PF_D32_S8X24 = 29,
+		/** Depth stencil fomrat, 24bit depth + 8bit stencil. */
+		PF_D24S8 = 30,
+		/** Depth format, 32bits. */
+		PF_D32 = 31,
+		/** Depth format, 16bits. */
+		PF_D16 = 32,
+		/** 
+		 * 32-bit float format, 11 bits (float) for red, 11 bits (float) for green, 10 bits (float) for blue. Framebuffer 
+		 * only format, not for CPU use. 
+		 */
+		PF_FLOAT_R11G11B10 = 33,
+		/** 
+		 * 32-bit unsigned normalized format, 10 bits (float) for red, 10 bits (float) for green, 10 bits (float) for blue, 
+		 * and two bits for alpha. Framebuffer only format, not for CPU use.
+		 */
+		PF_UNORM_R10G10B10A2 = 34,
+		/** Number of pixel formats currently defined. */
+        PF_COUNT = 35
+    };
+	typedef Vector<PixelFormat> PixelFormatList;
+
+	/**	Flags defining some properties of pixel formats. */
+    enum PixelFormatFlags {
+        /** This format has an alpha channel. */
+        PFF_HASALPHA = 0x00000001,      
+        /**
+		 * This format is compressed. This invalidates the values in elemBytes, elemBits and the bit counts as these might
+		 * not be fixed in a compressed format.
+		 */
+        PFF_COMPRESSED = 0x00000002,
+        /** This is a floating point format. */
+        PFF_FLOAT = 0x00000004,         
+        /** This is a depth format (for depth textures). */
+        PFF_DEPTH = 0x00000008,
+        /** 
+		 * Format is in native endian. Generally true for the 16, 24 and 32 bits formats which can be represented as 
+		 * machine integers.
+		 */
+        PFF_NATIVEENDIAN = 0x00000010
+    };
+    
+	/**	Types used for individual components of a pixel. */
+    enum PixelComponentType
+    {
+        PCT_BYTE = 0,    /**< Byte per component */
+        PCT_SHORT = 1,   /**< Short per component */
+        PCT_FLOAT16 = 2, /**< 16 bit float per component */
+        PCT_FLOAT32 = 3, /**< 32 bit float per component */
+		PCT_PACKED_R11G11B10 = 4, /**< 11 bits for first two components, 10 for third component. */
+		PCT_PACKED_R10G10B10A2 = 5, /**< 10 bits for first three components, 2 bits for last component */
+        PCT_COUNT = 4    /**< Number of pixel types */
+    };
+    
+	/**
+	 * A buffer describing a volume (3D), image (2D) or line (1D) of pixels in memory. Pixels are stored as a succession 
+	 * of "depth" slices, each containing "height" rows of "width" pixels.
+	 *
+	 * As any GpuResourceData this is used primarily for reading and writing from/to a GPU resource, and is normally 
+	 * constructed by the resource itself. However you may still construct it manually and use it for other purposes if 
+	 * needed.
+	 *
+	 * @note	
+	 * You must call allocateInternalBuffer or set the buffer in some other way before reading/writing from this object.
+	 *
+	 * @see		GpuResourceData
+	 */
+    class BS_CORE_EXPORT PixelData : public GpuResourceData
+	{
+    public:
+    	PixelData() {}
+		~PixelData() {}
+
+		/**
+		 * Constructs a new object with an internal buffer capable of holding "extents" volume of pixels, where each pixel 
+		 * is of the specified pixel format. Extent offsets are also stored, but are not used internally.
+		 */
+		PixelData(const PixelVolume& extents, PixelFormat pixelFormat)
+			:mExtents(extents), mFormat(pixelFormat)
+		{
+			setConsecutive();
+		}
+
+		/**
+		 * Constructs a new object with an internal buffer capable of holding volume of pixels described by	provided width, 
+		 * height and depth, where each pixel is of the specified pixel format.
+		 */
+    	PixelData(UINT32 width, UINT32 height, UINT32 depth, PixelFormat pixelFormat)
+			: mExtents(0, 0, 0, width, height, depth), mFormat(pixelFormat)
+    	{
+    		setConsecutive();
+    	}
+
+		PixelData(const PixelData& copy);
+		PixelData& operator=(const PixelData& rhs);
+
+		/**
+		 * Returns the number of pixels that offsets one row from another. This can be "width", but doesn't have to be as
+		 * some buffers require padding.
+		 */
+		UINT32 getRowPitch() const { return mRowPitch; }
+
+		/**
+		 * Returns the number of pixels that offsets one depth slice from another. This can be "width * height", but 
+		 * doesn't have to be as some buffers require padding.
+		 */
+		UINT32 getSlicePitch() const { return mSlicePitch; }
+
+		/**
+		 * Sets the pitch (in pixels) that determines offset between rows of the pixel buffer. Call this before allocating
+		 * the buffer.
+		 */
+		void setRowPitch(UINT32 rowPitch) { mRowPitch = rowPitch; }
+
+		/**
+		 * Sets the pitch (in pixels) that determines offset between depth slices of the pixel buffer. Call this before 
+		 * allocating the buffer.
+		 */
+        void setSlicePitch(UINT32 slicePitch) { mSlicePitch = slicePitch; }
+
+		/**
+		 * Returns the number of extra pixels in a row (non-zero only if rows are not consecutive (row pitch is larger 
+		 * than width)).
+		 */
+        UINT32 getRowSkip() const { return mRowPitch - getWidth(); }
+
+		/**
+		 * Returns the number of extra pixels in a depth slice (non-zero only if slices aren't consecutive (slice pitch is 
+		 * larger than width*height).
+		 */
+        UINT32 getSliceSkip() const { return mSlicePitch - (getHeight() * mRowPitch); }
+
+		/** Returns the pixel format used by the internal buffer for storing the pixels. */
+		PixelFormat getFormat() const { return mFormat; }
+
+		/**	Returns width of the buffer in pixels. */
+		UINT32 getWidth() const { return mExtents.getWidth(); }
+
+		/**	Returns height of the buffer in pixels. */
+		UINT32 getHeight() const { return mExtents.getHeight(); }
+
+		/**	Returns depth of the buffer in pixels. */
+		UINT32 getDepth() const { return mExtents.getDepth(); }
+
+		/**
+		 * Returns left-most start of the pixel volume. This value is not used internally in any way. It is just passed 
+		 * through from the constructor.
+		 */
+		UINT32 getLeft() const { return mExtents.left; }
+
+		/**
+		 * Returns right-most end of the pixel volume. This value is not used internally in any way. It is just passed 
+		 * through from the constructor.
+		 */
+		UINT32 getRight() const { return mExtents.right; }
+
+		/**
+		 * Returns top-most start of the pixel volume. This value is not used internally in any way. It is just passed 
+		 * through from the constructor.
+		 */
+		UINT32 getTop() const { return mExtents.top; }
+
+		/**
+		 * Returns bottom-most end of the pixel volume. This value is not used internally in any way. It is just passed 
+		 * through from the constructor.
+		 */
+		UINT32 getBottom() const { return mExtents.bottom; }
+
+		/**
+		 * Returns front-most start of the pixel volume. This value is not used internally in any way. It is just passed 
+		 * through from the constructor.
+		 */
+		UINT32 getFront() const { return mExtents.front; }
+
+		/**
+		 * Returns back-most end of the pixel volume. This value is not used internally in any way. It is just passed 
+		 * through from the constructor.
+		 */
+		UINT32 getBack() const { return mExtents.back; }
+
+		/** Returns extents of the pixel volume this object is capable of holding. */
+		PixelVolume getExtents() const { return mExtents; }
+
+		/** Return whether this buffer is laid out consecutive in memory (i.e. the pitches are equal to the dimensions). */
+        bool isConsecutive() const 
+		{ 
+			return mRowPitch == getWidth() && mSlicePitch == getWidth()*getHeight(); 
+		}
+
+		/** Return the size (in bytes) this image would take if it was laid out consecutive in memory. */
+      	UINT32 getConsecutiveSize() const;
+
+		/**	Return the size (in bytes) of the buffer this image requires. */
+      	UINT32 getSize() const;
+
+		/**
+		 * Returns pixel data containing a sub-volume of this object. Returned data will not have its own buffer, but will
+		 * instead point to this one. It is up to the caller to ensure this object outlives any sub-volume objects.
+		 */
+      	PixelData getSubVolume(const PixelVolume &def) const;
+        
+		/**	Returns pixel color at the specified coordinates. */
+		Color getColorAt(UINT32 x, UINT32 y, UINT32 z = 0) const;
+
+		/**	Sets the pixel color at the specified coordinates. */
+        void setColorAt(Color const &cv, UINT32 x, UINT32 y, UINT32 z = 0);
+
+		/**
+		 * Converts all the internal data into an array of colors. Array is mapped as such: 
+		 * arrayIdx = x + y * width + z * width * height.
+		 */
+		Vector<Color> getColors() const;
+
+		/**
+		 * Initializes the internal buffer with the provided set of colors. The array should be of width * height * depth 
+		 * size and mapped as such: arrayIdx = x + y * width + z * width * height.
+		 */
+		void setColors(const Vector<Color>& colors);
+
+		/**
+		 * Initializes the internal buffer with the provided set of colors. The array should be of 
+		 * width * height * depth size and mapped as such: arrayIdx = x + y * width + z * width * height.
+		 */
+		void setColors(Color* colors, UINT32 numElements);
+
+		/**
+		 * Constructs a new object with an internal buffer capable of holding "extents" volume of pixels, where each pixel
+		 * is of the specified pixel format. Extent offsets are also stored, but are not used internally.
+		 */
+		static PixelDataPtr create(const PixelVolume &extents, PixelFormat pixelFormat);
+
+		/**
+		 * Constructs a new object with an internal buffer capable of holding volume of pixels described by provided width,
+		 * height and depth, where each pixel is of the specified pixel format.
+		 */
+		static PixelDataPtr create(UINT32 width, UINT32 height, UINT32 depth, PixelFormat pixelFormat);
+
+	private:
+		/**
+		 * Set the rowPitch and slicePitch so that the buffer is laid out consecutive in memory. Does not actually modify
+		 * the buffer itself.
+		 */
+		void setConsecutive()
+		{
+			mRowPitch = getWidth();
+			mSlicePitch = getWidth()*getHeight();
+		}
+
+		/**
+		 * Initializes the internal buffer with the provided set of colors. The array should be of width * height * depth 
+		 * size and mapped as such: arrayIdx = x + y * width + z * width * height.
+		 *
+		 * @note	A generic method that is reused in other more specific setColors() calls.
+		 */
+		template<class T>
+		void setColorsInternal(const T& colors, UINT32 numElements);
+
+		/**	Returns the needed size of the internal buffer, in bytes. */
+		UINT32 getInternalBufferSize() const override;
+
+	private:
+		PixelVolume mExtents;
+        PixelFormat mFormat;
+        UINT32 mRowPitch;
+        UINT32 mSlicePitch;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class PixelDataRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+    };
+
+	/** @} */
 }

+ 101 - 91
BansheeCore/Include/BsPixelDataRTTI.h

@@ -1,92 +1,102 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsPixelData.h"
-#include "BsRTTIType.h"
-#include "BsManagedDataBlock.h"
-
-namespace BansheeEngine
-{
-	class BS_CORE_EXPORT PixelDataRTTI : public RTTIType<PixelData, GpuResourceData, PixelDataRTTI>
-	{
-		UINT32& getLeft(PixelData* obj) { return obj->mExtents.left; }
-		void setLeft(PixelData* obj, UINT32& val) { obj->mExtents.left = val; }
-
-		UINT32& getTop(PixelData* obj) { return obj->mExtents.top; }
-		void setTop(PixelData* obj, UINT32& val) { obj->mExtents.top = val; }
-
-		UINT32& getRight(PixelData* obj) { return obj->mExtents.right; }
-		void setRight(PixelData* obj, UINT32& val) { obj->mExtents.right = val; }
-
-		UINT32& getBottom(PixelData* obj) { return obj->mExtents.bottom; }
-		void setBottom(PixelData* obj, UINT32& val) { obj->mExtents.bottom = val; }
-
-		UINT32& getFront(PixelData* obj) { return obj->mExtents.front; }
-		void setFront(PixelData* obj, UINT32& val) { obj->mExtents.front = val; }
-
-		UINT32& getBack(PixelData* obj) { return obj->mExtents.back; }
-		void setBack(PixelData* obj, UINT32& val) { obj->mExtents.back = val; }
-
-		UINT32& getRowPitch(PixelData* obj) { return obj->mRowPitch; }
-		void setRowPitch(PixelData* obj, UINT32& val) { obj->mRowPitch = val; }
-
-		UINT32& getSlicePitch(PixelData* obj) { return obj->mSlicePitch; }
-		void setSlicePitch(PixelData* obj, UINT32& val) { obj->mSlicePitch = val; }
-
-		PixelFormat& getFormat(PixelData* obj) { return obj->mFormat; }
-		void setFormat(PixelData* obj, PixelFormat& val) { obj->mFormat = val; }
-
-		ManagedDataBlock getData(PixelData* obj) 
-		{ 
-			ManagedDataBlock dataBlock((UINT8*)obj->getData(), obj->getConsecutiveSize());
-			return dataBlock; 
-		}
-
-		void setData(PixelData* obj, ManagedDataBlock val) 
-		{ 
-			// Nothing to do here, the pointer we provided already belongs to PixelData
-			// so the data is already written
-		}
-
-		static UINT8* allocateData(PixelData* obj, UINT32 numBytes)
-		{
-			obj->allocateInternalBuffer(numBytes);
-
-			return obj->getData();
-		}
-
-	public:
-		PixelDataRTTI()
-		{
-			addPlainField("left", 0, &PixelDataRTTI::getLeft, &PixelDataRTTI::setLeft);
-			addPlainField("top", 1, &PixelDataRTTI::getTop, &PixelDataRTTI::setTop);
-			addPlainField("right", 2, &PixelDataRTTI::getRight, &PixelDataRTTI::setRight);
-			addPlainField("bottom", 3, &PixelDataRTTI::getBottom, &PixelDataRTTI::setBottom);
-			addPlainField("front", 4, &PixelDataRTTI::getFront, &PixelDataRTTI::setFront);
-			addPlainField("back", 5, &PixelDataRTTI::getBack, &PixelDataRTTI::setBack);
-			addPlainField("rowPitch", 6, &PixelDataRTTI::getRowPitch, &PixelDataRTTI::setRowPitch);
-			addPlainField("slicePitch", 7, &PixelDataRTTI::getSlicePitch, &PixelDataRTTI::setSlicePitch);
-			addPlainField("format", 8, &PixelDataRTTI::getFormat, &PixelDataRTTI::setFormat);
-
-			addDataBlockField("data", 9, &PixelDataRTTI::getData, &PixelDataRTTI::setData, 0, &PixelDataRTTI::allocateData);
-		}
-
-		virtual const String& getRTTIName()
-		{
-			static String name = "PixelData";
-			return name;
-		}
-
-		virtual UINT32 getRTTIId()
-		{
-			return TID_PixelData;
-		}
-
-		virtual std::shared_ptr<IReflectable> newRTTIObject()
-		{
-			PixelDataPtr newPixelData = bs_shared_ptr<PixelData, PoolAlloc>();
-
-			return newPixelData;
-		}
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsPixelData.h"
+#include "BsRTTIType.h"
+#include "BsManagedDataBlock.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT PixelDataRTTI : public RTTIType<PixelData, GpuResourceData, PixelDataRTTI>
+	{
+		UINT32& getLeft(PixelData* obj) { return obj->mExtents.left; }
+		void setLeft(PixelData* obj, UINT32& val) { obj->mExtents.left = val; }
+
+		UINT32& getTop(PixelData* obj) { return obj->mExtents.top; }
+		void setTop(PixelData* obj, UINT32& val) { obj->mExtents.top = val; }
+
+		UINT32& getRight(PixelData* obj) { return obj->mExtents.right; }
+		void setRight(PixelData* obj, UINT32& val) { obj->mExtents.right = val; }
+
+		UINT32& getBottom(PixelData* obj) { return obj->mExtents.bottom; }
+		void setBottom(PixelData* obj, UINT32& val) { obj->mExtents.bottom = val; }
+
+		UINT32& getFront(PixelData* obj) { return obj->mExtents.front; }
+		void setFront(PixelData* obj, UINT32& val) { obj->mExtents.front = val; }
+
+		UINT32& getBack(PixelData* obj) { return obj->mExtents.back; }
+		void setBack(PixelData* obj, UINT32& val) { obj->mExtents.back = val; }
+
+		UINT32& getRowPitch(PixelData* obj) { return obj->mRowPitch; }
+		void setRowPitch(PixelData* obj, UINT32& val) { obj->mRowPitch = val; }
+
+		UINT32& getSlicePitch(PixelData* obj) { return obj->mSlicePitch; }
+		void setSlicePitch(PixelData* obj, UINT32& val) { obj->mSlicePitch = val; }
+
+		PixelFormat& getFormat(PixelData* obj) { return obj->mFormat; }
+		void setFormat(PixelData* obj, PixelFormat& val) { obj->mFormat = val; }
+
+		ManagedDataBlock getData(PixelData* obj) 
+		{ 
+			ManagedDataBlock dataBlock((UINT8*)obj->getData(), obj->getConsecutiveSize());
+			return dataBlock; 
+		}
+
+		void setData(PixelData* obj, ManagedDataBlock val) 
+		{ 
+			// Nothing to do here, the pointer we provided already belongs to PixelData
+			// so the data is already written
+		}
+
+		static UINT8* allocateData(PixelData* obj, UINT32 numBytes)
+		{
+			obj->allocateInternalBuffer(numBytes);
+
+			return obj->getData();
+		}
+
+	public:
+		PixelDataRTTI()
+		{
+			addPlainField("left", 0, &PixelDataRTTI::getLeft, &PixelDataRTTI::setLeft);
+			addPlainField("top", 1, &PixelDataRTTI::getTop, &PixelDataRTTI::setTop);
+			addPlainField("right", 2, &PixelDataRTTI::getRight, &PixelDataRTTI::setRight);
+			addPlainField("bottom", 3, &PixelDataRTTI::getBottom, &PixelDataRTTI::setBottom);
+			addPlainField("front", 4, &PixelDataRTTI::getFront, &PixelDataRTTI::setFront);
+			addPlainField("back", 5, &PixelDataRTTI::getBack, &PixelDataRTTI::setBack);
+			addPlainField("rowPitch", 6, &PixelDataRTTI::getRowPitch, &PixelDataRTTI::setRowPitch);
+			addPlainField("slicePitch", 7, &PixelDataRTTI::getSlicePitch, &PixelDataRTTI::setSlicePitch);
+			addPlainField("format", 8, &PixelDataRTTI::getFormat, &PixelDataRTTI::setFormat);
+
+			addDataBlockField("data", 9, &PixelDataRTTI::getData, &PixelDataRTTI::setData, 0, &PixelDataRTTI::allocateData);
+		}
+
+		virtual const String& getRTTIName() override
+		{
+			static String name = "PixelData";
+			return name;
+		}
+
+		virtual UINT32 getRTTIId() override
+		{
+			return TID_PixelData;
+		}
+
+		virtual std::shared_ptr<IReflectable> newRTTIObject() override
+		{
+			PixelDataPtr newPixelData = bs_shared_ptr_new<PixelData>();
+
+			return newPixelData;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
 }

+ 229 - 268
BansheeCore/Include/BsPixelUtil.h

@@ -1,269 +1,230 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsPixelData.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Available types of texture compression quality.
-	 */
-	enum class CompressionQuality
-	{
-		Fastest,
-		Normal,
-		Production,
-		Highest
-	};
-
-	/**
-	 * @brief	Specifies what is alpha channel used for in the texture.
-	 */
-	enum class AlphaMode
-	{
-		None,
-		Transparency,
-		Premultiplied
-	};
-
-	/**
-	 * @brief	Wrap mode to use when generating mip maps.
-	 */
-	enum class MipMapWrapMode
-	{
-		Mirror,
-		Repeat,
-		Clamp
-	};
-
-	/**
-	 * @brief	Filter to use when generating mip maps.
-	 */
-	enum class MipMapFilter
-	{
-		Box,
-		Triangle,
-		Kaiser
-	};
-
-	/**
-	 * @brief	Options used to control texture compression.
-	 */
-	struct CompressionOptions
-	{
-		PixelFormat format = PF_BC1;
-		AlphaMode alphaMode = AlphaMode::None;
-		bool isNormalMap = false;
-		bool isSRGB = false;
-		CompressionQuality quality = CompressionQuality::Normal;
-	};
-
-	/**
-	 * @brief	Options used to control texture mip map generation.
-	 */
-	struct MipMapGenOptions
-	{
-		MipMapFilter filter = MipMapFilter::Box;
-		MipMapWrapMode wrapMode = MipMapWrapMode::Mirror;
-		bool isNormalMap = false;
-		bool normalizeMipmaps = false;
-	};
-
-	/**
-	 * @brief	Utility methods for converting and managing pixel data and formats.
-	 */
-    class BS_CORE_EXPORT PixelUtil 
-	{
-    public:
-		/**
-		 * @brief	A list of filtering types to use when scaling images.
-		 */
-		enum Filter
-		{
-			FILTER_NEAREST,
-			FILTER_LINEAR
-		};
-
-		/**
-		 * @brief	Returns the size of a single pixel of the provided pixel format,
-		 *			in bytes.
-		 */
-        static UINT32 getNumElemBytes(PixelFormat format);
-
-		/**
-		 * @brief	Returns the size of a single pixel of the provided pixel format,
-		 *			in bits.
-		 */
-        static UINT32 getNumElemBits( PixelFormat format );
-
-		/**
-		 * @brief	Returns the size of the memory region of the provided size and the pixel format.
-		 */
-		static UINT32 getMemorySize(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
-		
-		/**
-		 * @brief	Returns property flags for this pixel format.
-		 *
-		 * @see		PixelFormatFlags
-		 */
-        static UINT32 getFlags(PixelFormat format);
-
-		/**
-		 * @brief	Checks if the provided pixel format has an alpha channel.
-		 */
-        static bool hasAlpha(PixelFormat format);
-
-		/**
-		 * @brief	Checks is the provided pixel format a floating point format.
-		 */
-        static bool isFloatingPoint(PixelFormat format);
-
-		/**
-		 * @brief	Checks is the provided pixel format compressed.
-		 */
-        static bool isCompressed(PixelFormat format);
-
-		/**
-		 * @brief	Checks is the provided pixel format a depth/stencil buffer format.
-		 */
-        static bool isDepth(PixelFormat format);
-
-		/**
-		 * @brief	Checks is the provided format in native endian format.
-		 */
-        static bool isNativeEndian(PixelFormat format);
-		
-		/**
-		 * @brief	Checks are the provided dimensions valid for the specified pixel format.
-		 *			Some formats (like DXT) require width/height to be multiples of four and some
-		 *			formats dont allow depth larger than 1.
-		 */
-		static bool isValidExtent(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
-
-		/**
-		 * @brief	Returns the number of bits per each element in the provided pixel format.
-		 *			This will return all zero for compressed and depth/stencil formats.
-		 */
-        static void getBitDepths(PixelFormat format, int rgba[4]);
-
-		/**
-		 * @brief	Returns bit masks that determine in what bit range is each channel stored.
-		 *
-		 * @note	e.g. if your color is stored in an UINT32 and you want to extract the red channel
-		 *			you should AND the color UINT32 with the bit-mask for the red channel and then
-		 *			right shift it by the red channel bit shift amount.
-		 */
-        static void getBitMasks(PixelFormat format, UINT32 rgba[4]);
-
-		/**
-		 * @brief	Returns number of bits you need to shift a pixel element in order
-		 *			to move it to the start of the data type.
-		 *
-		 * @note	e.g. if your color is stored in an UINT32 and you want to extract the red channel
-		 *			you should AND the color UINT32 with the bit-mask for the red channel and then
-		 *			right shift it by the red channel bit shift amount.
-		 */
-		static void getBitShifts(PixelFormat format, UINT8 rgba[4]);
-
-		/**
-		 * @brief	Returns the name of the pixel format.
-		 */
-        static String getFormatName(PixelFormat srcformat);
-
-		/**
-		 * @brief	Returns true if the pixel data in the format can be directly accessed and read.
-		 *			This is generally not true for compressed formats.
-		 */
-        static bool isAccessible(PixelFormat srcformat);
-        
-		/**
-		 * @brief	Returns the type of an individual pixel element in the provided format.
-		 */
-        static PixelComponentType getElementType(PixelFormat format);
-        
-		/**
-		 * @brief	Returns the number of pixel elements in the provided format.
-		 */
-		static UINT32 getNumElements(PixelFormat format);
-
-		/**
-		 * @brief	Returns the maximum number of mip maps that can be generated until we reach
-		 *			the minimum size possible. This does not count the base level.
-		 */
-		static UINT32 getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
-
-		/**
-		 * @brief	Writes the color to the provided memory location.
-		 */
-        static void packColor(const Color& color, PixelFormat format, void* dest);
-
-		/**
-		 * @brief	Writes the color to the provided memory location. If the destination
-		 *			format is floating point, the byte values will be converted into [0.0, 1.0] range.
-		 */
-		static void packColor(UINT8 r, UINT8 g, UINT8 b, UINT8 a, PixelFormat format, void* dest);
-
-		/**
-		 * @brief	Writes the color to the provided memory location. If the destination format
-		 *			in non-floating point, the float values will be assumed to be in [0.0, 1.0] which
-		 *			will be converted to integer range. ([0, 255] in the case of bytes)
-		 */
-		static void packColor(float r, float g, float b, float a, const PixelFormat format, void* dest);
-
-		/**
-		 * @brief	Reads the color from the provided memory location and stores it 
-		 *			into the provided color object.
-		 */
-		static void unpackColor(Color* color, PixelFormat format, const void* src);
-
-		/**
-		 * @brief	Reads the color from the provided memory location and stores it 
-		 *			into the provided color elements, as bytes clamped to [0, 255] range.
-		 */
-		static void unpackColor(UINT8* r, UINT8* g, UINT8* b, UINT8* a, PixelFormat format, const void* src);
-
-		/**
-		 * @brief	Reads the color from the provided memory location and stores it 
-		 *			into the provided color elements. If the format is not natively floating
-		 *			point a conversion is done in such a way that returned values range [0.0, 1.0].
-		 */
-        static void unpackColor(float* r, float* g, float* b, float* a, PixelFormat format, const void* src); 
-        
-		/**
-		 * @brief	Converts pixels from one format to another. Provided pixel data objects
-		 *			must have previously allocated buffers of adequate size and their sizes must match.
-		 */
-        static void bulkPixelConversion(const PixelData& src, PixelData& dst);
-
-		/**
-		 * @brief	Compresses the provided data using the specified compression options. 
-		 */
-		static void compress(const PixelData& src, PixelData& dst, const CompressionOptions& options);
-
-		/**
-		 * @brief	Generates mip-maps from the provided source data using the specified compression options.
-		 *			Returned list includes the base level.
-		 *
-		 * @returns	A list of calculated mip-map data. First entry is the largest mip and other follow in
-		 *			order from largest to smallest.
-		 */
-		static Vector<PixelDataPtr> genMipmaps(const PixelData& src, const MipMapGenOptions& options);
-
-		/**
-		 * @brief	Scales pixel data in the source buffer and stores the scaled data in the destination buffer.
-		 *			Provided pixel data objects must have previously allocated buffers of adequate size. You may
-		 *			also provided a filtering method to use when scaling.
-		 */
-		static void scale(const PixelData& src, PixelData& dst, Filter filter = FILTER_LINEAR);
-
-		/**
-		 * @brief	Applies gamma correction to the pixels in the provided buffer.
-		 *
-		 * @param	buffer	Pointer to the buffer containing the pixels.
-		 * @param	gamma	Gamma value to apply.
-		 * @param	size	Size of the buffer in bytes.
-		 * @param	bpp		Number of bits per pixel of the pixels in the buffer.
-		 */
-        static void applyGamma(UINT8* buffer, float gamma, UINT32 size, UINT8 bpp);
-    };
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsPixelData.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Utility-Core
+	 *  @{
+	 */
+
+	/**	Types of texture compression quality. */
+	enum class CompressionQuality
+	{
+		Fastest,
+		Normal,
+		Production,
+		Highest
+	};
+
+	/**	Mode of the alpha channel in a texture. */
+	enum class AlphaMode
+	{
+		None, /*< Texture has no alpha values. */
+		Transparency, /*< Alpha is in the separate transparency channel. */
+		Premultiplied /*< Alpha values have been pre-multiplied with the color values. */
+	};
+
+	/**	Wrap mode to use when generating mip maps. */
+	enum class MipMapWrapMode
+	{
+		Mirror,
+		Repeat,
+		Clamp
+	};
+
+	/**	Filter to use when generating mip maps. */
+	enum class MipMapFilter
+	{
+		Box,
+		Triangle,
+		Kaiser
+	};
+
+	/**	Options used to control texture compression. */
+	struct CompressionOptions
+	{
+		PixelFormat format = PF_BC1; /*< Format to compress to. Must be a format containing compressed data. */
+		AlphaMode alphaMode = AlphaMode::None; /*< Controls how to (and if) to compress the alpha channel. */
+		bool isNormalMap = false; /*< Determines does the input data represent a normal map. */
+		bool isSRGB = false; /*< Determines has the input data been gamma corrected. */
+		CompressionQuality quality = CompressionQuality::Normal; /*< Compressed image quality. Better compression might take longer to execute but will generate better results. */
+	};
+
+	/**	Options used to control texture mip map generation. */
+	struct MipMapGenOptions
+	{
+		MipMapFilter filter = MipMapFilter::Box; /*< Filter to use when downsamping input data. */
+		MipMapWrapMode wrapMode = MipMapWrapMode::Mirror; /*< Determines how to downsample pixels on borders. */
+		bool isNormalMap = false; /*< Determines does the input data represent a normal map. */
+		bool normalizeMipmaps = false; /*< Should the downsampled values be re-normalized. Only relevant for mip-maps representing normal maps. */
+	};
+
+	/**	Utility methods for converting and managing pixel data and formats. */
+    class BS_CORE_EXPORT PixelUtil 
+	{
+    public:
+		/**	Filtering types to use when scaling images. */
+		enum Filter
+		{
+			FILTER_NEAREST, /*< No filtering is performed and nearest existing value is used. */
+			FILTER_LINEAR /*< Box filter is applied, averaging nearby pixels. */
+		};
+
+		/**	Returns the size of a single pixel of the provided pixel format, in bytes. */
+        static UINT32 getNumElemBytes(PixelFormat format);
+
+		/**	Returns the size of a single pixel of the provided pixel format, in bits. */
+        static UINT32 getNumElemBits( PixelFormat format );
+
+		/**	Returns the size of the memory region required to hold pixels of the provided size ana format. */
+		static UINT32 getMemorySize(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
+		
+		/**	Calculates the size of a mip level of a texture with the provided size. */
+		static void getSizeForMipLevel(UINT32 width, UINT32 height, UINT32 depth, UINT32 mipLevel, 
+			UINT32& mipWidth, UINT32& mipHeight, UINT32& mipDepth);
+
+		/**
+		 * Returns property flags for this pixel format.
+		 *
+		 * @see		PixelFormatFlags
+		 */
+        static UINT32 getFlags(PixelFormat format);
+
+		/**	Checks if the provided pixel format has an alpha channel. */
+        static bool hasAlpha(PixelFormat format);
+
+		/**	Checks is the provided pixel format a floating point format. */
+        static bool isFloatingPoint(PixelFormat format);
+
+		/**	Checks is the provided pixel format compressed. */
+        static bool isCompressed(PixelFormat format);
+
+		/**	Checks is the provided pixel format a depth/stencil buffer format. */
+        static bool isDepth(PixelFormat format);
+
+		/**	Checks is the provided format in native endian format. */
+        static bool isNativeEndian(PixelFormat format);
+		
+		/**
+		 * Checks are the provided dimensions valid for the specified pixel format. Some formats (like DXT) require 
+		 * width/height to be multiples of four and some formats dont allow depth larger than 1.
+		 */
+		static bool isValidExtent(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
+
+		/**
+		 * Returns the number of bits per each element in the provided pixel format. This will return all zero for 
+		 * compressed and depth/stencil formats.
+		 */
+        static void getBitDepths(PixelFormat format, int rgba[4]);
+
+		/**
+		 * Returns bit masks that determine in what bit range is each channel stored.
+		 *
+		 * @note	
+		 * e.g. if your color is stored in an UINT32 and you want to extract the red channel you should AND the color
+		 * UINT32 with the bit-mask for the red channel and then right shift it by the red channel bit shift amount.
+		 */
+        static void getBitMasks(PixelFormat format, UINT32 rgba[4]);
+
+		/**
+		 * Returns number of bits you need to shift a pixel element in order to move it to the start of the data type.
+		 *
+		 * @note	
+		 * e.g. if your color is stored in an UINT32 and you want to extract the red channel you should AND the color 
+		 * UINT32 with the bit-mask for the red channel and then right shift it by the red channel bit shift amount.
+		 */
+		static void getBitShifts(PixelFormat format, UINT8 rgba[4]);
+
+		/**	Returns the name of the pixel format. */
+        static String getFormatName(PixelFormat srcformat);
+
+		/**
+		 * Returns true if the pixel data in the format can be directly accessed and read. This is generally not true 
+		 * for compressed formats.
+		 */
+        static bool isAccessible(PixelFormat srcformat);
+        
+		/**	Returns the type of an individual pixel element in the provided format. */
+        static PixelComponentType getElementType(PixelFormat format);
+        
+		/**	Returns the number of pixel elements in the provided format. */
+		static UINT32 getNumElements(PixelFormat format);
+
+		/**
+		 * Returns the maximum number of mip maps that can be generated until we reach the minimum size possible. This 
+		 * does not count the base level.
+		 */
+		static UINT32 getMaxMipmaps(UINT32 width, UINT32 height, UINT32 depth, PixelFormat format);
+
+		/**	Writes the color to the provided memory location. */
+        static void packColor(const Color& color, PixelFormat format, void* dest);
+
+		/**
+		 * Writes the color to the provided memory location. If the destination	format is floating point, the byte values
+		 * will be converted into [0.0, 1.0] range.
+		 */
+		static void packColor(UINT8 r, UINT8 g, UINT8 b, UINT8 a, PixelFormat format, void* dest);
+
+		/**
+		 * Writes the color to the provided memory location. If the destination format in non-floating point, the float
+		 * values will be assumed to be in [0.0, 1.0] which	will be converted to integer range. ([0, 255] in the case of bytes)
+		 */
+		static void packColor(float r, float g, float b, float a, const PixelFormat format, void* dest);
+
+		/** Reads the color from the provided memory location and stores it into the provided color object. */
+		static void unpackColor(Color* color, PixelFormat format, const void* src);
+
+		/**
+		 * Reads the color from the provided memory location and stores it into the provided color elements, as bytes 
+		 * clamped to [0, 255] range.
+		 */
+		static void unpackColor(UINT8* r, UINT8* g, UINT8* b, UINT8* a, PixelFormat format, const void* src);
+
+		/**
+		 * Reads the color from the provided memory location and stores it into the provided color elements. If the format 
+		 * is not natively floating point a conversion is done in such a way that returned values range [0.0, 1.0].
+		 */
+        static void unpackColor(float* r, float* g, float* b, float* a, PixelFormat format, const void* src); 
+        
+		/**
+		 * Converts pixels from one format to another. Provided pixel data objects must have previously allocated buffers
+		 * of adequate size and their sizes must match.
+		 */
+        static void bulkPixelConversion(const PixelData& src, PixelData& dst);
+
+		/** Compresses the provided data using the specified compression options.  */
+		static void compress(const PixelData& src, PixelData& dst, const CompressionOptions& options);
+
+		/**
+		 * Generates mip-maps from the provided source data using the specified compression options. Returned list includes
+		 * the base level.
+		 *
+		 * @return	A list of calculated mip-map data. First entry is the largest mip and other follow in order from 
+		 *			largest to smallest.
+		 */
+		static Vector<PixelDataPtr> genMipmaps(const PixelData& src, const MipMapGenOptions& options);
+
+		/**
+		 * Scales pixel data in the source buffer and stores the scaled data in the destination buffer. Provided pixel data
+		 * objects must have previously allocated buffers of adequate size. You may also provided a filtering method to use
+		 * when scaling.
+		 */
+		static void scale(const PixelData& src, PixelData& dst, Filter filter = FILTER_LINEAR);
+
+		/**
+		 * Applies gamma correction to the pixels in the provided buffer.
+		 *
+		 * @param[in]	buffer	Pointer to the buffer containing the pixels.
+		 * @param[in]	gamma	Gamma value to apply.
+		 * @param[in]	size	Size of the buffer in bytes.
+		 * @param[in]	bpp		Number of bits per pixel of the pixels in the buffer.
+		 */
+        static void applyGamma(UINT8* buffer, float gamma, UINT32 size, UINT8 bpp);
+    };
+
+	/** @} */
 }

+ 48 - 43
BansheeCore/Include/BsPixelVolume.h

@@ -1,44 +1,49 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Volume of pixels used for referencing a part of
-	 * 			a texture.
-	 */
-	struct BS_CORE_EXPORT PixelVolume
-	{
-		UINT32 left, top, right, bottom, front, back;
-
-		PixelVolume()
-			: left(0), top(0), right(1), bottom(1), front(0), back(1)
-		{ }
-
-		PixelVolume(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom):
-			left(left), top(top), right(right), bottom(bottom), front(0), back(1)
-		{
-			assert(right >= left && bottom >= top && back >= front);
-		}
-
-		PixelVolume(UINT32 left, UINT32 top, UINT32 front, UINT32 right, UINT32 bottom, UINT32 back):
-			left(left), top(top), right(right), bottom(bottom), front(front), back(back)
-		{
-			assert(right >= left && bottom >= top && back >= front);
-		}
-            
-		/**
-		 * @brief	Return true if the other box is a part of this one.
-		 */
-		bool contains(const PixelVolume &volume) const
-		{
-			return (volume.left >= left && volume.top >= top && volume.front >= front &&
-				volume.right <= right && volume.bottom <= bottom && volume.back <= back);
-		}
-            
-		UINT32 getWidth() const { return right-left; }
-		UINT32 getHeight() const { return bottom-top; }
-		UINT32 getDepth() const { return back-front; }
-	};
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Utility-Core
+	 *  @{
+	 */
+
+	/**	Represents a 3D region of pixels used for referencing pixel data. */
+	struct BS_CORE_EXPORT PixelVolume
+	{
+		UINT32 left, top, right, bottom, front, back;
+
+		PixelVolume()
+			: left(0), top(0), right(1), bottom(1), front(0), back(1)
+		{ }
+
+		PixelVolume(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom):
+			left(left), top(top), right(right), bottom(bottom), front(0), back(1)
+		{
+			assert(right >= left && bottom >= top && back >= front);
+		}
+
+		PixelVolume(UINT32 left, UINT32 top, UINT32 front, UINT32 right, UINT32 bottom, UINT32 back):
+			left(left), top(top), right(right), bottom(bottom), front(front), back(back)
+		{
+			assert(right >= left && bottom >= top && back >= front);
+		}
+            
+		/**
+		 * @brief	Return true if the other box is a part of this one.
+		 */
+		bool contains(const PixelVolume &volume) const
+		{
+			return (volume.left >= left && volume.top >= top && volume.front >= front &&
+				volume.right <= right && volume.bottom <= bottom && volume.back <= back);
+		}
+            
+		UINT32 getWidth() const { return right-left; }
+		UINT32 getHeight() const { return bottom-top; }
+		UINT32 getDepth() const { return back-front; }
+	};
+
+	/** @} */
 }

+ 450 - 189
BansheeCore/Include/BsPlatform.h

@@ -1,189 +1,450 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains values representing default
-	 *			mouse cursor types.
-	 */
-	enum class PlatformCursorType
-	{
-		Arrow,
-		Wait,
-		IBeam,
-		Help,
-		Hand,
-		SizeAll,
-		SizeNESW,
-		SizeNS,
-		SizeNWSE,
-		SizeWE
-	};
-
-	/**
-	 * @brief	Contains values reprenting window non client areas.
-	 *
-	 * @note	These are used for things like resize/move and tell the OS
-	 *			where each of those areas are on our window.
-	 */
-	enum class NonClientAreaBorderType
-	{
-		TopLeft,
-		Top,
-		TopRight,
-		Left,
-		Right,
-		BottomLeft,
-		Bottom,
-		BottomRight	
-	};
-
-	/**
-	 * @brief	Types of mouse buttons provided by the OS.
-	 */
-	enum class OSMouseButton
-	{
-		Left, Middle, Right, Count
-	};
-
-	/**
-	 * @brief	Describes pointer (mouse, touch) states as reported
-	 *			by the OS.
-	 */
-	struct BS_CORE_EXPORT OSPointerButtonStates
-	{
-		OSPointerButtonStates()
-		{
-			mouseButtons[0] = false;
-			mouseButtons[1] = false;
-			mouseButtons[2] = false;
-
-			shift = false;
-			ctrl = false;
-		}
-
-		bool mouseButtons[OSMouseButton::Count];
-		bool shift, ctrl;
-	};
-
-	/**
-	 * @brief	Type of drop event type. This is used
-	 *			when dragging items over drop targets.
-	 */
-	enum class OSDropType
-	{
-		FileList,
-		None
-	};
-
-	/**
-	 * @brief	Drop targets allow you to register a certain portion of a window as a drop target that
-	 *			accepts certain drop types. Accepted drop types are provided by the OS and include things
-	 *			like file and item dragging.
-	 *
-	 *			You will receive events with the specified drop area as long as it is active.
-	 */
-	class BS_CORE_EXPORT OSDropTarget
-	{
-	public:
-		/**
-		 * @brief	Triggered when a pointer is being dragged over the drop area.
-		 *			Provides window coordinates of the pointer position.
-		 */
-		Event<void(INT32 x, INT32 y)> onDragOver;
-
-		/**
-		 * @brief	Triggered when the user completes a drop while pointer is over
-		 *			the drop area.
-		 *			Provides window coordinates of the pointer position.
-		 */
-		Event<void(INT32 x, INT32 y)> onDrop;
-
-		/**
-		 * @brief	Triggered when a pointer enters the drop area.
-		 *			Provides window coordinates of the pointer position.
-		 */
-		Event<void(INT32 x, INT32 y)> onEnter;
-
-		/**
-		 * @brief	Triggered when a pointer leaves the drop area.
-		 */
-		Event<void()> onLeave;
-
-		/**
-		 * @brief	Sets the drop target area, in local window coordinates.
-		 */
-		void setArea(INT32 x, INT32 y, UINT32 width, UINT32 height);
-
-		/**
-		 * @brief	Gets the type of drop that this drop target is looking for. Only
-		 *			valid after a drop has been triggered.
-		 */
-		OSDropType getDropType() const { return mDropType; }
-
-		/**
-		 * @brief	Returns a list of files received by the drop target. Only valid
-		 *			after a drop of FileList type has been triggered.
-		 */
-		const Vector<WString>& getFileList() const { return *mFileList; }
-
-		/**
-		 * @brief	Internal method. Clears all internal values.
-		 */
-		void _clear();
-
-		/**
-		 * @brief	Internal method. Sets the file list and marks the drop event as FileList.
-		 */
-		void _setFileList(const Vector<WString>& fileList);
-
-		/**
-		 * @brief	Marks the drop area as inactive or active.
-		 */
-		void _setActive(bool active) { mActive = active; }
-
-		/**
-		 * @brief	Checks is the specified position within the current drop area.
-		 *			Position should be in window local coordinates.
-		 */
-		bool _isInside(const Vector2I& pos) const;
-
-		/**
-		 * @brief	Returns true if the drop target is active.
-		 */
-		bool _isActive() const { return mActive; }
-	private:
-		friend class Platform;
-
-		OSDropTarget(const RenderWindow* ownerWindow, INT32 x, INT32 y, UINT32 width, UINT32 height);
-		~OSDropTarget();
-
-		/**
-		 * @brief	Returns a render window this drop target is attached to.
-		 */
-		const RenderWindow* getOwnerWindow() const { return mOwnerWindow; }
-	private:
-		INT32 mX, mY;
-		UINT32 mWidth, mHeight;
-		bool mActive;
-		const RenderWindow* mOwnerWindow;
-
-		OSDropType mDropType;
-
-		union 
-		{
-			Vector<WString>* mFileList;
-		};
-	};
-}
-
-// Bring in the specific platform's header file
-#if BS_PLATFORM == BS_PLATFORM_WIN32
-# include "Win32/BsPlatformImpl.h"
-#elif (BS_PLATFORM == BS_PLATFORM_LINUX)
-# include "GLX/BsPlatformImpl.h"
-#elif BS_PLATFORM == BS_PLATFORM_APPLE
-# include "OSX/BsPlatformImpl.h"
-#endif
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsInputFwd.h"
+#include "BsVector2I.h"
+#include "BsRect2I.h"
+#include "BsEvent.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Platform
+	 *  @{
+	 */
+
+	/** Contains values representing default mouse cursor types. */
+	enum class PlatformCursorType
+	{
+		Arrow,
+		Wait,
+		IBeam,
+		Help,
+		Hand,
+		SizeAll,
+		SizeNESW,
+		SizeNS,
+		SizeNWSE,
+		SizeWE
+	};
+
+	/**
+	 * Contains values reprenting window non client areas.
+	 *
+	 * @note	These are used for things like resize/move and tell the OS where each of those areas are on our window.
+	 */
+	enum class NonClientAreaBorderType
+	{
+		TopLeft,
+		Top,
+		TopRight,
+		Left,
+		Right,
+		BottomLeft,
+		Bottom,
+		BottomRight
+	};
+
+	/** Types of mouse buttons provided by the OS. */
+	enum class OSMouseButton
+	{
+		Left, Middle, Right, Count
+	};
+
+	/** Describes pointer (mouse, touch) states as reported by the OS. */
+	struct BS_CORE_EXPORT OSPointerButtonStates
+	{
+		OSPointerButtonStates()
+		{
+			mouseButtons[0] = false;
+			mouseButtons[1] = false;
+			mouseButtons[2] = false;
+
+			shift = false;
+			ctrl = false;
+		}
+
+		bool mouseButtons[OSMouseButton::Count];
+		bool shift, ctrl;
+	};
+
+	/** Type of drop event type. This is used when dragging items over drop targets. */
+	enum class OSDropType
+	{
+		FileList,
+		None
+	};
+
+	/**
+	 * Drop targets allow you to register a certain portion of a window as a drop target that accepts certain drop types 
+	 * from the OS (platform) specific drag and drop system. Accepted drop types are provided by the OS and include things
+	 * like file and item dragging.
+	 *
+	 * You will receive events with the specified drop area as long as it is active.
+	 */
+	class BS_CORE_EXPORT OSDropTarget
+	{
+	public:
+		/**
+		 * Triggered when a pointer is being dragged over the drop area. Provides window coordinates of the pointer position.
+		 */
+		Event<void(INT32 x, INT32 y)> onDragOver;
+
+		/**
+		 * Triggered when the user completes a drop while pointer is over the drop area. Provides window coordinates of the 
+		 * pointer position.
+		 */
+		Event<void(INT32 x, INT32 y)> onDrop;
+
+		/**
+		 * Triggered when a pointer enters the drop area. Provides window coordinates of the pointer position.
+		 */
+		Event<void(INT32 x, INT32 y)> onEnter;
+
+		/** Triggered when a pointer leaves the drop area. */
+		Event<void()> onLeave;
+
+		/**	Sets the drop target area, in local window coordinates. */
+		void setArea(INT32 x, INT32 y, UINT32 width, UINT32 height);
+
+		/**	Gets the type of drop that this drop target is looking for. Only valid after a drop has been triggered. */
+		OSDropType getDropType() const { return mDropType; }
+
+		/**	
+		 * Returns a list of files received by the drop target. Only valid after a drop of FileList type has been triggered.
+		 */
+		const Vector<WString>& getFileList() const { return *mFileList; }
+
+		/** Clears all internal values. */
+		void _clear();
+
+		/** Sets the file list and marks the drop event as FileList. */
+		void _setFileList(const Vector<WString>& fileList);
+
+		/** Marks the drop area as inactive or active. */
+		void _setActive(bool active) { mActive = active; }
+
+		/**	Checks is the specified position within the current drop area. Position should be in window local coordinates. */
+		bool _isInside(const Vector2I& pos) const;
+
+		/** Returns true if the drop target is active. */
+		bool _isActive() const { return mActive; }
+	private:
+		friend class Platform;
+
+		OSDropTarget(const RenderWindow* ownerWindow, INT32 x, INT32 y, UINT32 width, UINT32 height);
+		~OSDropTarget();
+
+		/**	Returns a render window this drop target is attached to. */
+		const RenderWindow* getOwnerWindow() const { return mOwnerWindow; }
+	private:
+		INT32 mX, mY;
+		UINT32 mWidth, mHeight;
+		bool mActive;
+		const RenderWindow* mOwnerWindow;
+
+		OSDropType mDropType;
+
+		union
+		{
+			Vector<WString>* mFileList;
+		};
+	};
+
+	/**	Represents a specific non client area used for window resizing. */
+	struct BS_CORE_EXPORT NonClientResizeArea
+	{
+		NonClientAreaBorderType type;
+		Rect2I area;
+	};
+
+	/** Contains a list of window move and resize non client areas. */
+	struct BS_CORE_EXPORT WindowNonClientAreaData
+	{
+		Vector<NonClientResizeArea> resizeAreas;
+		Vector<Rect2I> moveAreas;
+	};
+
+	/**	Provides access to various operating system functions, including the main message pump. */
+	class BS_CORE_EXPORT Platform
+	{
+	public:
+		struct Pimpl;
+
+		Platform() { }
+		virtual ~Platform();
+
+		/**
+		 * Retrieves the cursor position in screen coordinates.
+		 *
+		 * @note	Thread safe.
+		 */
+		static Vector2I getCursorPosition();
+
+		/**
+		 * Moves the cursor to the specified screen position.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void setCursorPosition(const Vector2I& screenPos);
+
+		/**
+		 * Capture mouse to this window so that we get mouse input even if the mouse leaves the window area.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void captureMouse(const RenderWindow& window);
+
+		/**
+		 * Releases the mouse capture set by captureMouse().
+		 *
+		 * @note	Thread safe.
+		 */
+		static void releaseMouseCapture();
+
+		/**
+		 * Checks if provided over screen position is over the specified window.
+		 */
+		static bool isPointOverWindow(const RenderWindow& window, const Vector2I& screenPos);
+
+		/**
+		 * Limit cursor movement to the specified window.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void clipCursorToWindow(const RenderWindow& window);
+
+		/**
+		 * Clip cursor to specific area on the screen.
+		 *
+		 * @note	Thread safe.
+		 */
+
+		static void clipCursorToRect(const Rect2I& screenRect);
+
+		/**
+		 * Disables cursor clipping.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void clipCursorDisable();
+
+		/**
+		 * Hides the cursor.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void hideCursor();
+
+		/**
+		 * Shows the cursor.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void showCursor();
+
+		/**
+		 * Query if the cursor is hidden.
+		 *
+		 * @note	Thread safe.
+		 */
+		static bool isCursorHidden();
+
+		/**
+		 * Sets a cursor using a custom image.
+		 *
+		 * @param[in] 	pixelData	Cursor image data.
+		 * @param[in]	hotSpot		Offset on the cursor image to where the actual input happens (e.g. tip of the Arrow 
+		 *							cursor).
+		 *
+		 * @note	Thread safe.
+		 */
+		static void setCursor(PixelData& pixelData, const Vector2I& hotSpot);
+
+		/**
+		 * Sets an icon for the main application window.
+		 *
+		 * @param[in] 	pixelData	Icon image data. This will be resized to the required icon size, depending on platform
+		 * 							implementation.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void setIcon(const PixelData& pixelData);
+
+		/**
+		 * Sets custom caption non client areas for the specified window. Using custom client areas will override window 
+		 * move/drag operation and trigger when user interacts with the custom area.
+		 *
+		 * @note	
+		 * Thread safe.
+		 * @note
+		 * All provided areas are relative to the specified window. Mostly useful for frameless windows that don't have 
+		 * typical caption bar.
+		 */
+		static void setCaptionNonClientAreas(const RenderWindowCore& window, const Vector<Rect2I>& nonClientAreas);
+
+		/**
+		 * Sets custom non client areas for the specified window. Using custom client areas will override window resize 
+		 * operation and trigger when user interacts with the custom area.
+		 *
+		 * @note	
+		 * Thread safe.
+		 * @note
+		 * All provided areas are relative to the specified window. Mostly useful for frameless windows that don't have 
+		 * typical border.
+		 */
+		static void setResizeNonClientAreas(const RenderWindowCore& window, const Vector<NonClientResizeArea>& nonClientAreas);
+
+		/**
+		 * Resets the non client areas for the specified windows and allows the platform to use the default values.
+		 *
+		 * @note	Thread safe.
+		 */
+		static void resetNonClientAreas(const RenderWindowCore& window);
+
+		/** 
+		 * Causes the current thread to pause execution for the specified amount of time.
+		 *
+		 * @param[in]	duration	Duration in milliseconds. Providing zero will give up the current time-slice.
+		 *
+		 * @note	This method relies on timer granularity being set to 1 millisecond. If it is not, you can expect
+		 *			this method to potentially take significantly longer if you are providing it with low ms values (<10).
+		 */
+		static void sleep(UINT32 duration);
+
+		/**
+		 * Creates a drop target that you can use for tracking OS drag and drop operations performed over a certain area 
+		 * on the specified window.
+		 *
+		 * @param[in]	window	The window on which to track drop operations.
+		 * @param[in]	x	  	The x coordinate of the area to track, relative to window.
+		 * @param[in]	y	  	The y coordinate of the area to track, relative to window.
+		 * @param[in]	width 	The width of the area to track.
+		 * @param[in]	height	The height of the area to track.
+		 * @return				OSDropTarget that you will use to receive all drop data. When no longer needed make sure 
+		 *						to destroy it with destroyDropTarget().
+		 */
+		static OSDropTarget& createDropTarget(const RenderWindow* window, int x, int y, unsigned int width, unsigned int height);
+
+		/** Destroys a drop target previously created with createDropTarget. */
+		static void destroyDropTarget(OSDropTarget& target);
+
+		/**
+		 * Displays a platform specific file/folder open/save dialog.
+		 *
+		 * @param[in]	type		Type of dialog to open.
+		 * @param[in]	defaultPath	Initial path the dialog will be set to once opened.
+		 * @param[in]	filterList	Semi-colon separated list of file names or types to display in the dialog, 
+		 *							e.g. "exe;txt;png". Ignored if dialog is to display folders instead of files.
+		 * @param[out]	paths		Output list of selected file or folder paths (if any).
+		 * @return					True if file was selected and false if selection was canceled.
+		 */
+		static bool openBrowseDialog(FileDialogType type, const Path& defaultPath, const WString& filterList,
+			Vector<Path>& paths);
+
+		/**
+		 * Message pump. Processes OS messages and returns when it's free.
+		 *
+		 * @note	Core thread only.
+		 */
+		static void _messagePump();
+
+		/**
+		 * Called during application start up from the sim thread. Must be called before any other operations are done.
+		 *
+		 * @note	Internal method.
+		 */
+		static void _startUp();
+
+		/**
+		 * Called once per frame from the sim thread.
+		 *
+		 * @note	Sim thread only.
+		 */
+		static void _update();
+
+		/**
+		 * Called once per frame from the core thread.
+		 *
+		 * @note	Core thread only.
+		 */
+		static void _coreUpdate();
+
+		/**
+		 * Called during application shut down from the sim thread.
+		 *
+		 * @note	Sim thread only.
+		 */
+		static void _shutDown();
+
+		/**
+		 * Triggered when a pointer leaves the provided window.
+		 *
+		 * @note	Sim thread only.
+		 */
+		static Event<void(RenderWindowCore*)> onMouseLeftWindow;
+
+		/**
+		 * Triggered whenever the pointer moves.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(const Vector2I&, OSPointerButtonStates)> onCursorMoved;
+
+		/**
+		 * Triggered whenever a pointer button is pressed.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(const Vector2I&, OSMouseButton button, OSPointerButtonStates)> onCursorButtonPressed;
+
+		/**
+		 * Triggered whenever pointer button is released.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(const Vector2I&, OSMouseButton button, OSPointerButtonStates)> onCursorButtonReleased;
+
+		/**
+		 * Triggered whenever a pointer button is double clicked.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(const Vector2I&, OSPointerButtonStates)> onCursorDoubleClick;
+
+		/**
+		 * Triggered whenever an input command is entered.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(InputCommandType)> onInputCommand;
+
+		/**
+		 * Triggered whenever the mouse wheel is scolled.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(float)> onMouseWheelScrolled;
+
+		/**
+		 * Triggered whenever a character is entered.
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void(UINT32)> onCharInput;
+
+		/**
+		 * Triggered whenever mouse capture state for the window is changed (it receives or loses it).
+		 *
+		 * @note	Core thread only.
+		 */
+		static Event<void()> onMouseCaptureChanged;
+	protected:
+		static Pimpl* mData;
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 94 - 0
BansheeCore/Include/BsPrefab.h

@@ -0,0 +1,94 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsGameObject.h"
+#include "BsResource.h"
+
+namespace BansheeEngine
+{
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/**
+	 * Prefab is a saveable hierarchy of scene objects. In general it can serve as any grouping of scene objects 
+	 * (e.g. a level) or be used as a form of a template instantiated and reused throughout the scene.
+	 */
+	class BS_CORE_EXPORT Prefab : public Resource
+	{
+	public:
+		Prefab();
+		~Prefab();
+
+		/**
+		 * Creates a new prefab from the provided scene object. If the scene object has an existing prefab link it will 
+		 * be broken. After the prefab is created the scene object will be automatically linked to it.
+		 */
+		static HPrefab create(const HSceneObject& sceneObject);
+
+		/**
+		 * Instantiates a prefab by creating an instance of the prefab's scene object hierarchy. The returned hierarchy 
+		 * will be parented to world root by default.
+		 *			
+		 * @return	Instantiated clone of the prefab's scene object hierarchy.
+		 */
+		HSceneObject instantiate();
+
+		/**
+		 * Replaces the contents of this prefab with new contents from the provided object. Object will be automatically
+		 * linked to this prefab, and its previous prefab link (if any) will be broken.
+		 */
+		void update(const HSceneObject& sceneObject);
+
+		/**
+		 * Returns a hash value that can be used for determining if a prefab changed by comparing it to a previously saved
+		 * hash.
+		 */
+		UINT32 getHash() const { return mHash; }
+
+		/** @cond INTERNAL */
+
+		/** Updates any prefab child instances by loading their prefabs and making sure they are up to date. */
+		void _updateChildInstances();
+
+		/**
+		 * Returns a reference to the internal prefab hierarchy. Returned hierarchy is not instantiated and cannot be 
+		 * interacted with in a manner you would with normal scene objects.
+		 */
+		HSceneObject _getRoot() const { return mRoot; }
+
+		/**
+		 * Creates the clone of the prefab's current hierarchy but doesn't instantiate it.
+		 *			
+		 * @return	Clone of the prefab's scene object hierarchy.
+		 */
+		HSceneObject _clone();
+
+		/** @endcond */
+
+	private:
+		/**	Initializes the internal prefab hierarchy. Must be called druing creation. */
+		void initialize(const HSceneObject& sceneObject);
+
+		/**	Creates an empty and uninitialized prefab. */
+		static PrefabPtr createEmpty();
+
+		HSceneObject mRoot;
+		UINT32 mHash;
+		String mUUID;
+		UINT32 mNextLinkId;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class PrefabRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
+}

+ 158 - 0
BansheeCore/Include/BsPrefabDiff.h

@@ -0,0 +1,158 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
+#include "BsGameObject.h"
+#include "BsVector3.h"
+#include "BsQuaternion.h"
+
+namespace BansheeEngine
+{
+	/** @cond INTERNAL */
+	/** @addtogroup Scene
+	 *  @{
+	 */
+
+	/**
+	 * Contains differences between two components of the same type.
+	 *
+	 * @see		PrefabDiff
+	 */
+	struct BS_CORE_EXPORT PrefabComponentDiff : public IReflectable
+	{
+		INT32 id;
+		SPtr<SerializedObject> data;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class PrefabComponentDiffRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** Flags that mark which portion of a scene-object is modified. */
+	enum class SceneObjectDiffFlags
+	{
+		Name = 0x01,
+		Position = 0x02,
+		Rotation = 0x04,
+		Scale = 0x08,
+		Active = 0x10
+	};
+
+	/**
+	 * Contains a set of prefab differences for a single scene object.
+	 *
+	 * @see		PrefabDiff
+	 */
+	struct BS_CORE_EXPORT PrefabObjectDiff : public IReflectable
+	{
+		UINT32 id = 0;
+
+		String name;
+		Vector3 position;
+		Quaternion rotation;
+		Vector3 scale;
+		bool isActive = false;
+		UINT32 soFlags = 0;
+
+		Vector<SPtr<PrefabComponentDiff>> componentDiffs;
+		Vector<UINT32> removedComponents;
+		Vector<SPtr<SerializedObject>> addedComponents;
+
+		Vector<SPtr<PrefabObjectDiff>> childDiffs;
+		Vector<UINT32> removedChildren;
+		Vector<SPtr<SerializedObject>> addedChildren;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class PrefabObjectDiffRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/**
+	 * Contains modifications between an prefab and its instance. The modifications are a set of added/removed children or
+	 * components and per-field "diffs" of their components.
+	 */
+	class BS_CORE_EXPORT PrefabDiff : public IReflectable
+	{
+	public:
+		/**
+		 * Creates a new prefab diff by comparing the provided instanced scene object hierarchy with the prefab scene 
+		 * object hierarchy.
+		 */
+		static SPtr<PrefabDiff> create(const HSceneObject& prefab, const HSceneObject& instance);
+
+		/**
+		 * Applies the internal prefab diff to the provided object. The object should have similar hierarchy as the prefab
+		 * the diff was created for, otherwise the results are undefined.
+		 */
+		void apply(const HSceneObject& object);
+
+	private:
+		/** A reference to a renamed game object instance data, and its original ID so it may be restored later. */
+		struct RenamedGameObject
+		{
+			GameObjectInstanceDataPtr instanceData;
+			UINT64 originalId;
+		};
+
+		/**
+		 * Recurses over every scene object in the prefab a generates differences between itself and the instanced version.
+		 *
+		 * @see		create
+		 */
+		static SPtr<PrefabObjectDiff> generateDiff(const HSceneObject& prefab, const HSceneObject& instance);
+
+		/**
+		 * Recursively applies a per-object set of prefab differences to a specific object.
+		 *
+		 * @see		apply			
+		 */
+		static void applyDiff(const SPtr<PrefabObjectDiff>& diff, const HSceneObject& object);
+
+		/**
+		 * Renames all game objects in the provided instance so that IDs of the objects will match the IDs of their 
+		 * counterparts in the prefab. 
+		 *
+		 * @note	
+		 * This is a temporary action and should be undone by calling restoreInstanceIds() and providing  it with the 
+		 * output of this method. 
+		 * @note
+		 * By doing this before calling generateDiff() we ensure that any game object handles pointing to objects within 
+		 * the prefab instance hierarchy aren't recorded by the diff system, since we want those to remain as they are 
+		 * after applying the diff.
+		 */
+		static void renameInstanceIds(const HSceneObject& prefab, const HSceneObject& instance, Vector<RenamedGameObject>& output);
+
+		/**
+		 * Restores any instance IDs that were modified by the renameInstanceIds() method.
+		 *
+		 * @see		renameInstanceIds
+		 */
+		static void restoreInstanceIds(const Vector<RenamedGameObject>& renamedObjects);
+
+		SPtr<PrefabObjectDiff> mRoot;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+
+	public:
+		friend class PrefabDiffRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		virtual RTTITypeBase* getRTTI() const override;
+	};
+
+	/** @} */
+	/** @endcond */
+}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików