Browse Source

Merge branch 'master' into preview

BearishSun 10 years ago
parent
commit
4ce5c9b932
100 changed files with 15202 additions and 12320 deletions
  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 */
+}

Some files were not shown because too many files changed in this diff