Selaa lähdekoodia

Finished Renderable refactor, mostly (still got an exception on shutdown)

Marko Pintera 11 vuotta sitten
vanhempi
sitoutus
acf6121ee6
54 muutettua tiedostoa jossa 878 lisäystä ja 629 poistoa
  1. 2 2
      BansheeCore/BansheeCore.vcxproj
  2. 6 6
      BansheeCore/BansheeCore.vcxproj.filters
  3. 7 1
      BansheeCore/Include/BsCoreObject.h
  4. 1 1
      BansheeCore/Include/BsCoreObjectCore.h
  5. 2 2
      BansheeCore/Include/BsCorePrerequisites.h
  6. 3 1
      BansheeCore/Include/BsCoreRenderer.h
  7. 5 0
      BansheeCore/Include/BsMaterial.h
  8. 1 1
      BansheeCore/Include/BsRendererFactory.h
  9. 2 2
      BansheeCore/Include/BsRendererManager.h
  10. 0 13
      BansheeCore/Include/BsSceneObject.h
  11. 1 1
      BansheeCore/Source/BsCoreApplication.cpp
  12. 3 3
      BansheeCore/Source/BsCoreRenderer.cpp
  13. 10 0
      BansheeCore/Source/BsMaterial.cpp
  14. 2 2
      BansheeCore/Source/BsRendererManager.cpp
  15. 1 4
      BansheeCore/Source/BsSceneObject.cpp
  16. 1 1
      BansheeCore/Source/BsTechnique.cpp
  17. 1 1
      BansheeEditor/Source/BsDockManager.cpp
  18. 1 1
      BansheeEditor/Source/BsEditorApplication.cpp
  19. 8 8
      BansheeEditor/Source/BsGizmoManager.cpp
  20. 7 7
      BansheeEditor/Source/BsHandleDrawManager.cpp
  21. 1 1
      BansheeEditor/Source/BsHandleSliderManager.cpp
  22. 1 1
      BansheeEditor/Source/BsSceneEditorWidget.cpp
  23. 5 5
      BansheeEditor/Source/BsScenePicking.cpp
  24. 3 2
      BansheeEngine/BansheeEngine.vcxproj
  25. 9 6
      BansheeEngine/BansheeEngine.vcxproj.filters
  26. 5 0
      BansheeEngine/Include/BsCameraHandler.h
  27. 7 1
      BansheeEngine/Include/BsCameraHandlerRTTI.h
  28. 2 2
      BansheeEngine/Include/BsPrerequisites.h
  29. 7 34
      BansheeEngine/Include/BsRenderable.h
  30. 3 3
      BansheeEngine/Include/BsRenderableController.h
  31. 55 0
      BansheeEngine/Include/BsRenderableElement.h
  32. 143 57
      BansheeEngine/Include/BsRenderableHandler.h
  33. 12 6
      BansheeEngine/Include/BsRenderableHandlerRTTI.h
  34. 0 108
      BansheeEngine/Include/BsRenderableProxy.h
  35. 45 0
      BansheeEngine/Include/BsRenderer.h
  36. 0 5
      BansheeEngine/Include/BsSceneManager.h
  37. 10 1
      BansheeEngine/Source/BsCameraHandler.cpp
  38. 1 1
      BansheeEngine/Source/BsRenderQueue.cpp
  39. 19 18
      BansheeEngine/Source/BsRenderable.cpp
  40. 4 4
      BansheeEngine/Source/BsRenderableController.cpp
  41. 201 66
      BansheeEngine/Source/BsRenderableHandler.cpp
  42. 0 26
      BansheeEngine/Source/BsRenderableProxy.cpp
  43. 10 0
      BansheeEngine/Source/BsRenderer.cpp
  44. 4 4
      BansheeRenderer/Include/BsBansheeLitTexRenderableController.h
  45. 31 34
      BansheeRenderer/Include/BsBansheeRenderer.h
  46. 1 1
      BansheeRenderer/Include/BsBansheeRendererFactory.h
  47. 13 14
      BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp
  48. 188 142
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  49. 1 1
      BansheeRenderer/Source/BsBansheeRendererFactory.cpp
  50. 0 5
      BansheeSceneManager/Include/BsBansheeSceneManager.h
  51. 0 14
      BansheeSceneManager/Source/BsBansheeSceneManager.cpp
  52. 2 0
      BansheeUtility/Include/BsAABox.h
  53. 1 1
      ExampleProject/Main/Main.cpp
  54. 30 9
      TODO.txt

+ 2 - 2
BansheeCore/BansheeCore.vcxproj

@@ -375,7 +375,7 @@
     <ClInclude Include="Include\BsCorePrerequisites.h" />
     <ClInclude Include="Include\BsRasterizerState.h" />
     <ClInclude Include="Include\BsRasterizerStateRTTI.h" />
-    <ClInclude Include="Include\BsRenderer.h" />
+    <ClInclude Include="Include\BsCoreRenderer.h" />
     <ClInclude Include="Include\BsRendererFactory.h" />
     <ClInclude Include="Include\BsRendererManager.h" />
     <ClInclude Include="Include\BsRenderStateManager.h" />
@@ -471,7 +471,7 @@
     <ClCompile Include="Source\BsPlatform.cpp" />
     <ClCompile Include="Source\BsProfilingManager.cpp" />
     <ClCompile Include="Source\BsQueryManager.cpp" />
-    <ClCompile Include="Source\BsRenderer.cpp" />
+    <ClCompile Include="Source\BsCoreRenderer.cpp" />
     <ClCompile Include="Source\BsResourceManifest.cpp" />
     <ClCompile Include="Source\BsResourceMetaData.cpp" />
     <ClCompile Include="Source\BsTextureImportOptions.cpp" />

+ 6 - 6
BansheeCore/BansheeCore.vcxproj.filters

@@ -402,9 +402,6 @@
     <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>
@@ -516,6 +513,9 @@
     <ClInclude Include="Include\BsCoreObjectCore.h">
       <Filter>Header Files\Core</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsCoreRenderer.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
@@ -722,9 +722,6 @@
     <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>
@@ -812,5 +809,8 @@
     <ClCompile Include="Source\BsCoreObjectCore.cpp">
       <Filter>Source Files\Core</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsCoreRenderer.cpp">
+      <Filter>Source Files\Renderer</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 7 - 1
BansheeCore/Include/BsCoreObject.h

@@ -237,7 +237,7 @@ namespace BansheeEngine
 		 *					internal data is dirty. syncFromCore() will be called regardless
 		 *					and it's up to the implementation to read the flags value if needed.
 		 */
-		void markCoreDirty(UINT32 flags = 0xFFFFFFFF) { mCoreDirtyFlags = flags; }
+		void markCoreDirty(UINT32 flags = 0xFFFFFFFF) { mCoreDirtyFlags |= flags; }
 
 		/**
 		 * @brief	Marks the core data as clean. Normally called right after syncToCore()
@@ -251,6 +251,12 @@ namespace BansheeEngine
 		 */
 		bool isCoreDirty() const { return mCoreDirtyFlags != 0; }
 
+		/**
+		 * @brief	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; }
+
 		/**
 		 * @brief	Copy internal dirty data to a memory buffer that will be used
 		 *			for updating core thread version of that data.

+ 1 - 1
BansheeCore/Include/BsCoreObjectCore.h

@@ -67,7 +67,7 @@ namespace BansheeEngine
 		 *					internal data is dirty. syncFromCore() will be called regardless
 		 *					and it's up to the implementation to read the flags value if needed.
 		 */
-		void markCoreDirty(UINT32 flags = 0xFFFFFFFF) { mCoreDirtyFlags = flags; }
+		void markCoreDirty(UINT32 flags = 0xFFFFFFFF) { mCoreDirtyFlags |= flags; }
 
 		/**
 		 * @brief	Marks the core data as clean. Normally called right after syncFromCore()

+ 2 - 2
BansheeCore/Include/BsCorePrerequisites.h

@@ -99,7 +99,7 @@ namespace BansheeEngine
 	class Input;
 	struct PointerEvent;
 	class RawInputHandler;
-	class Renderer;
+	class CoreRenderer;
 	class RendererFactory;
 	class AsyncOp;
 	class HardwareBufferManager;
@@ -217,7 +217,7 @@ namespace BansheeEngine
 	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<CoreRenderer> CoreRendererPtr;
 	typedef std::shared_ptr<RendererFactory> RendererFactoryPtr;
 	typedef std::shared_ptr<Component> ComponentPtr;
 	typedef std::shared_ptr<GameObject> GameObjectPtr;

+ 3 - 1
BansheeCore/Include/BsRenderer.h → BansheeCore/Include/BsCoreRenderer.h

@@ -39,9 +39,11 @@ namespace BansheeEngine
 	 * @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 Renderer
+	class BS_CORE_EXPORT CoreRenderer
 	{
 	public:
+		virtual ~CoreRenderer() { }
+
 		/**
 		 * @brief	Called after the renderer has been activated.
 		 *

+ 5 - 0
BansheeCore/Include/BsMaterial.h

@@ -575,6 +575,11 @@ namespace BansheeEngine
 	public:
 		~MaterialCore() { }
 
+		/**
+		 * @brief	Creates a new material with the specified shader.
+		 */
+		static SPtr<MaterialCore> create(const SPtr<ShaderCore>& shader);
+
 	private:
 		friend class Material;
 

+ 1 - 1
BansheeCore/Include/BsRendererFactory.h

@@ -19,7 +19,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Creates a new instance of the renderer.
 		 */
-		virtual RendererPtr create() = 0;
+		virtual CoreRendererPtr create() = 0;
 
 		/**
 		 * @brief	Returns the name of the renderer this factory creates.

+ 2 - 2
BansheeCore/Include/BsRendererManager.h

@@ -26,7 +26,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Returns the currently active renderer. Null if no renderer is active.
 		 */
-		RendererPtr getActive() { return mActiveRenderer; }
+		CoreRendererPtr getActive() { return mActiveRenderer; }
 
 		/**
 		 * @brief	Core renderer represents a set of shared features within all renderers.
@@ -51,7 +51,7 @@ namespace BansheeEngine
 	private:
 		Vector<RendererFactoryPtr> mAvailableFactories;
 
-		RendererPtr mActiveRenderer;
+		CoreRendererPtr mActiveRenderer;
 	};
 }
 

+ 0 - 13
BansheeCore/Include/BsSceneObject.h

@@ -237,17 +237,6 @@ namespace BansheeEngine
 		 */
 		void updateTransformsIfDirty();
 
-		/**
-		 * @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.
-		 */
-		bool _isCoreDirty() const { return mIsCoreDirtyFlags != 0; }
-
-		/**
-		 * @brief	Marks the core dirty flag as clean.
-		 */
-		void _markCoreClean() { mIsCoreDirtyFlags = 0; }
-
 		/**
 		 * @brief	Returns a hash value that changes whenever a scene objects
 		 *			transform gets updated. It allows you to detect changes with
@@ -269,8 +258,6 @@ namespace BansheeEngine
 		mutable Matrix4 mCachedWorldTfrm;
 
 		mutable UINT32 mDirtyFlags;
-		mutable UINT32 mIsCoreDirtyFlags;
-
 		mutable UINT32 mDirtyHash;
 
 		/**

+ 1 - 1
BansheeCore/Source/BsCoreApplication.cpp

@@ -26,7 +26,7 @@
 #include "BsMaterialManager.h"
 #include "BsFontManager.h"
 #include "BsRenderWindowManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsDeferredCallManager.h"
 #include "BsCoreThread.h"
 #include "BsStringTable.h"

+ 3 - 3
BansheeCore/Source/BsRenderer.cpp → BansheeCore/Source/BsCoreRenderer.cpp

@@ -1,4 +1,4 @@
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsCoreThread.h"
 #include "BsRenderSystem.h"
 #include "BsMesh.h"
@@ -10,7 +10,7 @@
 
 namespace BansheeEngine
 {
-	void Renderer::setPass(const SPtr<MaterialCore>& material, UINT32 passIdx)
+	void CoreRenderer::setPass(const SPtr<MaterialCore>& material, UINT32 passIdx)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
@@ -86,7 +86,7 @@ namespace BansheeEngine
 			rs.setRasterizerState(RasterizerState::getDefault()->getCore());
 	}
 
-	void Renderer::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh)
+	void CoreRenderer::draw(const SPtr<MeshCoreBase>& mesh, const SubMesh& subMesh)
 	{
 		THROW_IF_NOT_CORE_THREAD;
 

+ 10 - 0
BansheeCore/Source/BsMaterial.cpp

@@ -859,6 +859,16 @@ namespace BansheeEngine
 		dataPtr += sizeof(SPtr<TechniqueCore>);
 	}
 
+	SPtr<MaterialCore> MaterialCore::create(const SPtr<ShaderCore>& shader)
+	{
+		MaterialCore* material = new (bs_alloc<MaterialCore>()) MaterialCore(shader);
+		SPtr<MaterialCore> materialPtr = bs_shared_ptr<MaterialCore, GenAlloc>(material);
+		materialPtr->_setThisPtr(materialPtr);
+		materialPtr->initialize();
+
+		return materialPtr;
+	}
+
 	Material::Material(const ShaderPtr& shader)
 	{
 		setShader(shader);

+ 2 - 2
BansheeCore/Source/BsRendererManager.cpp

@@ -1,5 +1,5 @@
 #include "BsRendererManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsException.h"
 
 namespace BansheeEngine
@@ -16,7 +16,7 @@ namespace BansheeEngine
 		{
 			if((*iter)->name() == name)
 			{
-				RendererPtr newRenderer = (*iter)->create();
+				CoreRendererPtr newRenderer = (*iter)->create();
 				if(newRenderer != nullptr)
 				{
 					if (mActiveRenderer != nullptr)

+ 1 - 4
BansheeCore/Source/BsSceneObject.cpp

@@ -13,7 +13,7 @@ namespace BansheeEngine
 		:GameObject(), mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::ONE),
 		mWorldPosition(Vector3::ZERO), mWorldRotation(Quaternion::IDENTITY), mWorldScale(Vector3::ONE),
 		mCachedLocalTfrm(Matrix4::IDENTITY), mDirtyFlags(0xFFFFFFFF), mCachedWorldTfrm(Matrix4::IDENTITY), 
-		mIsCoreDirtyFlags(0xFFFFFFFF), mActiveSelf(true), mActiveHierarchy(true), mDirtyHash(0)
+		mActiveSelf(true), mActiveHierarchy(true), mDirtyHash(0)
 	{
 		setName(name);
 	}
@@ -294,7 +294,6 @@ namespace BansheeEngine
 	void SceneObject::markTfrmDirty() const
 	{
 		mDirtyFlags |= DirtyFlags::LocalTfrmDirty | DirtyFlags::WorldTfrmDirty;
-		mIsCoreDirtyFlags = 0xFFFFFFFF;
 		mDirtyHash++;
 
 		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
@@ -422,8 +421,6 @@ namespace BansheeEngine
 		{
 			child->setActiveHierarchy(mActiveHierarchy);
 		}
-
-		mIsCoreDirtyFlags = 0xFFFFFFFF;
 	}
 
 	bool SceneObject::getActive(bool self)

+ 1 - 1
BansheeCore/Source/BsTechnique.cpp

@@ -3,7 +3,7 @@
 #include "BsRenderSystem.h"
 #include "BsRendererManager.h"
 #include "BsPass.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsFrameAlloc.h"
 #include "BsTechniqueRTTI.h"
 

+ 1 - 1
BansheeEditor/Source/BsDockManager.cpp

@@ -10,7 +10,7 @@
 #include "BsDrawList.h"
 #include "BsCoreApplication.h"
 #include "BsRendererManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsSceneObject.h"
 #include "BsGUIManager.h"
 #include "BsBuiltinEditorResources.h"

+ 1 - 1
BansheeEditor/Source/BsEditorApplication.cpp

@@ -39,7 +39,7 @@
 #include "BsGUIButton.h"
 #include "BsGUILayout.h"
 #include "BsEvent.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsProjectSettings.h"
 
 namespace BansheeEngine

+ 8 - 8
BansheeEditor/Source/BsGizmoManager.cpp

@@ -12,7 +12,7 @@
 #include "BsMaterial.h"
 #include "BsGpuParams.h"
 #include "BsRenderSystem.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsTransientMesh.h"
 #include "BsRendererManager.h"
 #include "BsDrawHelper.h"
@@ -700,7 +700,7 @@ namespace BansheeEngine
 			alphaCutoffParam.set(PICKING_ALPHA_CUTOFF);
 		}
 
-		RendererPtr activeRenderer = RendererManager::instance().getActive();
+		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
 		activeRenderer->onCorePostRenderViewport.connect(std::bind(&GizmoManagerCore::render, this, _1));
 	}
 
@@ -752,19 +752,19 @@ namespace BansheeEngine
 		{
 		case GizmoManager::GizmoMaterial::Solid:
 			mSolidMaterial.mViewProj.set(viewProjMat);
-			Renderer::setPass(mSolidMaterial.mat, 0);
+			CoreRenderer::setPass(mSolidMaterial.mat, 0);
 			break;
 		case GizmoManager::GizmoMaterial::Wire:
 			mWireMaterial.mViewProj.set(viewProjMat);
-			Renderer::setPass(mWireMaterial.mat, 0);
+			CoreRenderer::setPass(mWireMaterial.mat, 0);
 			break;
 		case GizmoManager::GizmoMaterial::Picking:
 			mPickingMaterial.mViewProj.set(viewProjMat);
-			Renderer::setPass(mPickingMaterial.mat, 0);
+			CoreRenderer::setPass(mPickingMaterial.mat, 0);
 			break;
 		}
 		
-		Renderer::draw(mesh, mesh->getProperties().getSubMesh(0));
+		CoreRenderer::draw(mesh, mesh->getProperties().getSubMesh(0));
 	}
 
 	void GizmoManagerCore::renderIconGizmos(Rect2I screenArea, SPtr<MeshCoreBase> mesh, GizmoManager::IconRenderDataVecPtr renderData, bool usePickingMaterial)
@@ -808,7 +808,7 @@ namespace BansheeEngine
 
 			for (UINT32 passIdx = 0; passIdx < 2; passIdx++)
 			{
-				Renderer::setPass(mIconMaterial.mat, passIdx);
+				CoreRenderer::setPass(mIconMaterial.mat, passIdx);
 
 				UINT32 curIndexOffset = mesh->getIndexOffset();
 				for (auto curRenderData : *renderData)
@@ -825,7 +825,7 @@ namespace BansheeEngine
 		{
 			mAlphaPickingMaterial.mViewProj.set(projMat);
 
-			Renderer::setPass(mAlphaPickingMaterial.mat, 0);
+			CoreRenderer::setPass(mAlphaPickingMaterial.mat, 0);
 
 			UINT32 curIndexOffset = 0;
 			for (auto curRenderData : *renderData)

+ 7 - 7
BansheeEditor/Source/BsHandleDrawManager.cpp

@@ -4,7 +4,7 @@
 #include "BsBuiltinEditorResources.h"
 #include "BsCoreThread.h"
 #include "BsRendererManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsTransientMesh.h"
 #include "BsCameraHandler.h"
 #include "BsSceneObject.h"
@@ -200,7 +200,7 @@ namespace BansheeEngine
 			vertParams->getParam("matViewProj", mSolidMaterial.mViewProj);
 		}
 
-		RendererPtr activeRenderer = RendererManager::instance().getActive();
+		CoreRendererPtr activeRenderer = RendererManager::instance().getActive();
 		activeRenderer->onCorePostRenderViewport.connect(std::bind(&HandleDrawManagerCore::render, this, _1));
 	}
 
@@ -239,9 +239,9 @@ namespace BansheeEngine
 			currentType = mMeshes[0].type;
 
 			if (currentType == MeshType::Solid)
-				Renderer::setPass(mSolidMaterial.mat, 0);
+				CoreRenderer::setPass(mSolidMaterial.mat, 0);
 			else
-				Renderer::setPass(mWireMaterial.mat, 0);
+				CoreRenderer::setPass(mWireMaterial.mat, 0);
 		}
 
 		for (auto& meshData : mMeshes)
@@ -249,14 +249,14 @@ namespace BansheeEngine
 			if (currentType != meshData.type)
 			{
 				if (meshData.type == MeshType::Solid)
-					Renderer::setPass(mSolidMaterial.mat, 0);
+					CoreRenderer::setPass(mSolidMaterial.mat, 0);
 				else
-					Renderer::setPass(mWireMaterial.mat, 0);
+					CoreRenderer::setPass(mWireMaterial.mat, 0);
 
 				currentType = meshData.type;
 			}
 
-			Renderer::draw(meshData.mesh, meshData.mesh->getProperties().getSubMesh(0));
+			CoreRenderer::draw(meshData.mesh, meshData.mesh->getProperties().getSubMesh(0));
 		}
 	}
 }

+ 1 - 1
BansheeEditor/Source/BsHandleSliderManager.cpp

@@ -4,7 +4,7 @@
 #include "BsBuiltinEditorResources.h"
 #include "BsCoreThread.h"
 #include "BsRendererManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsTransientMesh.h"
 #include "BsCamera.h"
 #include "BsHandleSlider.h"

+ 1 - 1
BansheeEditor/Source/BsSceneEditorWidget.cpp

@@ -15,7 +15,7 @@
 #include "BsCoreThread.h"
 #include "BsEditorWidgetContainer.h"
 #include "BsRendererManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsGUIWidget.h"
 #include "BsSceneGrid.h"
 #include "BsInput.h"

+ 5 - 5
BansheeEditor/Source/BsScenePicking.cpp

@@ -21,7 +21,7 @@
 #include "BsGpuParams.h"
 #include "BsBuiltinEditorResources.h"
 #include "BsShader.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsGizmoManager.h"
 
 using namespace std::placeholders;
@@ -264,7 +264,7 @@ namespace BansheeEngine
 		rs.clearRenderTarget(FBT_COLOR | FBT_DEPTH | FBT_STENCIL, Color::White);
 		rs.setScissorRect(position.x, position.y, position.x + area.x, position.y + area.y);
 
-		Renderer::setPass(mMaterialData[0].mMatPickingCore, 0);
+		CoreRenderer::setPass(mMaterialData[0].mMatPickingCore, 0);
 		bool activeMaterialIsAlpha = false;
 		CullingMode activeMaterialCull = (CullingMode)0;
 
@@ -276,9 +276,9 @@ namespace BansheeEngine
 				activeMaterialCull = renderable.cullMode;
 
 				if (activeMaterialIsAlpha)
-					Renderer::setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingAlphaCore, 0);
+					CoreRenderer::setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingAlphaCore, 0);
 				else
-					Renderer::setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingCore, 0);
+					CoreRenderer::setPass(mMaterialData[(UINT32)activeMaterialCull].mMatPickingCore, 0);
 			}
 
 			Color color = ScenePicking::encodeIndex(renderable.index);
@@ -302,7 +302,7 @@ namespace BansheeEngine
 				rs.bindGpuParams(GPT_FRAGMENT_PROGRAM, md.mParamPickingFragParams);
 			}
 
-			Renderer::draw(renderable.mesh, renderable.mesh->getProperties().getSubMesh(0));
+			CoreRenderer::draw(renderable.mesh, renderable.mesh->getProperties().getSubMesh(0));
 		}
 	}
 

+ 3 - 2
BansheeEngine/BansheeEngine.vcxproj

@@ -239,7 +239,7 @@
     <ClCompile Include="Source\BsInputConfiguration.cpp" />
     <ClCompile Include="Source\BsRenderableController.cpp" />
     <ClCompile Include="Source\BsRenderableHandler.cpp" />
-    <ClCompile Include="Source\BsRenderableProxy.cpp" />
+    <ClCompile Include="Source\BsRenderer.cpp" />
     <ClCompile Include="Source\BsRenderQueue.cpp" />
     <ClCompile Include="Source\BsVirtualInput.cpp" />
     <ClInclude Include="Include\BsApplication.h" />
@@ -247,8 +247,10 @@
     <ClInclude Include="Include\BsCameraHandlerRTTI.h" />
     <ClInclude Include="Include\BsCursor.h" />
     <ClInclude Include="Include\BsDrawHelper.h" />
+    <ClInclude Include="Include\BsRenderableElement.h" />
     <ClInclude Include="Include\BsRenderableHandler.h" />
     <ClInclude Include="Include\BsRenderableHandlerRTTI.h" />
+    <ClInclude Include="Include\BsRenderer.h" />
     <ClInclude Include="Include\BsShapeMeshes3D.h" />
     <ClInclude Include="Include\BsDragAndDropManager.h" />
     <ClInclude Include="Include\BsShapeMeshes2D.h" />
@@ -306,7 +308,6 @@
     <ClInclude Include="Include\BsProfilerOverlay.h" />
     <ClInclude Include="Include\BsRectOffset.h" />
     <ClInclude Include="Include\BsRenderableController.h" />
-    <ClInclude Include="Include\BsRenderableProxy.h" />
     <ClInclude Include="Include\BsRenderQueue.h" />
     <ClInclude Include="Include\BsSceneManager.h" />
     <ClInclude Include="Include\BsGUIScrollArea.h" />

+ 9 - 6
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -249,9 +249,6 @@
     <ClInclude Include="Include\BsRectOffset.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Include\BsRenderableProxy.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsRenderQueue.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -285,6 +282,12 @@
     <ClInclude Include="Include\BsRenderableHandlerRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsRenderableElement.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsRenderer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -461,9 +464,6 @@
     <ClCompile Include="Source\BsBuiltinResources.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Source\BsRenderableProxy.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsRenderQueue.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -488,5 +488,8 @@
     <ClCompile Include="Source\BsRenderableHandler.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsRenderer.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 5 - 0
BansheeEngine/Include/BsCameraHandler.h

@@ -576,6 +576,11 @@ namespace BansheeEngine
 		 */
 		CoreSyncData syncToCore(FrameAlloc* allocator);
 
+		/**
+		 * @brief	Creates a new camera without initializing it.
+		 */
+		static CameraHandlerPtr createEmpty();
+
 		ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
 
 		/************************************************************************/

+ 7 - 1
BansheeEngine/Include/BsCameraHandlerRTTI.h

@@ -102,6 +102,12 @@ namespace BansheeEngine
 			addPlainField("mBottom", 21, &CameraHandlerRTTI::getBottom, &CameraHandlerRTTI::setBottom);
 		}
 
+		virtual void onDeserializationEnded(IReflectable* obj)
+		{
+			CameraHandler* cameraHandler = static_cast<CameraHandler*>(obj);
+			cameraHandler->initialize();
+		}
+
 		virtual const String& getRTTIName()
 		{
 			static String name = "CameraHandler";
@@ -115,7 +121,7 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject()
 		{
-			return CameraHandler::create();
+			return CameraHandler::createEmpty();
 		}
 	};
 }

+ 2 - 2
BansheeEngine/Include/BsPrerequisites.h

@@ -75,14 +75,15 @@ namespace BansheeEngine
 	class GUIContent;
 	class GUIContextMenu;
 	class GUIDropDownHitBox;
+	class RenderableElement;
 
-	class RenderableProxy;
 	class RenderableController;
 	class ProfilerOverlay;
 	class DrawHelper;
 	class CameraHandler;
 	class RenderableHandler;
 	class CameraHandlerCore;
+	class RenderableHandlerCore;
 
 	// 2D
 	class TextSprite;
@@ -101,7 +102,6 @@ namespace BansheeEngine
 	typedef std::shared_ptr<Camera> CameraPtr;
 	typedef std::shared_ptr<Renderable> RenderablePtr;
 	typedef std::shared_ptr<GUIToggleGroup> GUIToggleGroupPtr;
-	typedef std::shared_ptr<RenderableProxy> RenderableProxyPtr;
 	typedef std::shared_ptr<CameraHandler> CameraHandlerPtr;
 	typedef std::shared_ptr<RenderableHandler> RenderableHandlerPtr;
 	typedef std::shared_ptr<InputConfiguration> InputConfigurationPtr;

+ 7 - 34
BansheeEngine/Include/BsRenderable.h

@@ -2,6 +2,7 @@
 
 #include "BsPrerequisites.h"
 #include "BsRenderableHandler.h"
+#include "BsBounds.h"
 #include "BsComponent.h"
 
 namespace BansheeEngine
@@ -58,42 +59,14 @@ namespace BansheeEngine
 		 */
 		RenderableHandlerPtr _getHandler() const { return mInternal; }
 
-		/************************************************************************/
-		/* 								CORE PROXY                      		*/
-		/************************************************************************/
-
-		/**
-		 * @copydoc	RenderableHandler::_isCoreDirty
-		 */
-		bool _isCoreDirty() const { return mInternal->_isCoreDirty(); }
-
-		/**
-		 * @copydoc	RenderableHandler::_markCoreClean
-		 */
-		void _markCoreClean() { mInternal->_markCoreClean(); }
-
-		/**
-		 * @copydoc	RenderableHandler::_markCoreDirty
-		 */
-		void _markCoreDirty() const { mInternal->_markCoreDirty(); }
-
-		/**
-		 * @copydoc	RenderableHandler::_createProxy
-		 */
-		RenderableProxyPtr _createProxy() const;
-
-		/**
-		 * @copydoc	RenderableHandler::_getActiveProxy
-		 */
-		RenderableProxyPtr _getActiveProxy() const { return mInternal->_getActiveProxy();; }
-
+	private:
 		/**
-		 * @copydoc	RenderableHandler::_setActiveProxy
+		 * @brief	Updates the world transform if the SceneObject transform changed.
 		 */
-		void _setActiveProxy(const RenderableProxyPtr& proxy) { mInternal->_setActiveProxy(proxy); }
+		void updateTransform() const;
 
-	private:
-		RenderableHandlerPtr mInternal;
+		mutable RenderableHandlerPtr mInternal;
+		mutable UINT32 mLastUpdateHash;
 
 		/************************************************************************/
 		/* 							COMPONENT OVERRIDES                    		*/
@@ -108,7 +81,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	Component::update
 		 */
-		virtual void update() {}
+		virtual void update();
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/

+ 3 - 3
BansheeEngine/Include/BsRenderableController.h

@@ -26,17 +26,17 @@ namespace BansheeEngine
 		 *			to be used. Caller must ensure the renderable element actually
 		 *			supports this handler.
 		 */
-		virtual void initializeRenderElem(RenderableElement* element) = 0;
+		virtual void initializeRenderElem(RenderableElement& element) = 0;
 
 		/**
 		 * @brief	Binds per object GPU parameter buffers to the provided element.
 		 */
-		virtual void bindPerObjectBuffers(const RenderableElement* element) = 0;
+		virtual void bindPerObjectBuffers(const RenderableElement& element) = 0;
 
 		/**
 		 * @brief	Binds global GPU parameter buffers used for this Renderable 
 		 *			type to the provided element.
 		 */
-		virtual void bindGlobalBuffers(const RenderableElement* element);
+		virtual void bindGlobalBuffers(const RenderableElement& element);
 	};
 }

+ 55 - 0
BansheeEngine/Include/BsRenderableElement.h

@@ -0,0 +1,55 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsBounds.h"
+#include "BsMatrix4.h"
+#include "BsSubMesh.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @brief	Contains all information needed for rendering a single
+	 *			sub-mesh. Closely tied with Renderer.
+	 */
+	class BS_EXPORT RenderableElement
+	{
+	public:
+		/**
+		 * @brief	Contains a hardware GPU parameter buffer and index of the parameters and the slot
+		 *			it binds to in a material.
+		 */
+		struct BS_EXPORT BufferBindInfo
+		{
+			BufferBindInfo(UINT32 passIdx, UINT32 paramsIdx, UINT32 slotIdx, const SPtr<GpuParamBlockBufferCore>& buffer)
+				:passIdx(passIdx), paramsIdx(paramsIdx), slotIdx(slotIdx), buffer(buffer)
+			{ }
+
+			UINT32 passIdx;
+			UINT32 paramsIdx;
+			UINT32 slotIdx;
+			SPtr<GpuParamBlockBufferCore> buffer;
+		};
+
+		/**
+		 * @brief	Reference to the mesh to render.
+		 */
+		SPtr<MeshCore> mesh;
+
+		/**
+		 * @brief	Portion of the mesh to render.
+		 */
+		SubMesh subMesh;
+
+		/**
+		 * @brief	Proxy of the material to render the mesh with.
+		 */
+		SPtr<MaterialCore> material;
+
+		/**
+		 * @brief	Custom data that may optionally be set by the RenderableHanbdler.
+		 */
+		Any rendererData;
+
+		Vector<BufferBindInfo> rendererBuffers;
+	};
+}

+ 143 - 57
BansheeEngine/Include/BsRenderableHandler.h

@@ -2,60 +2,64 @@
 
 #include "BsPrerequisites.h"
 #include "BsIReflectable.h"
-#include "BsRenderableProxy.h"
+#include "BsCoreObject.h"
+#include "BsBounds.h"
 #include "BsAABox.h"
-#include "BsGpuParam.h"
 
 namespace BansheeEngine
 {
+	/**
+	 * @brief	Signals which portion of a RenderableHandler is dirty.
+	 */
+	enum class RenderableDirtyFlag
+	{
+		Transform = 0x01,
+		Everything = 0x02
+	};
+
 	/**
 	 * @brief	Renderable represents any visible object in the scene. It has a mesh,
 	 *			bounds and a set of materials. Renderer will render any Renderable objects
 	 *			visible by the camera.
 	 */
-	class BS_EXPORT RenderableHandler : public IReflectable
+	template<bool Core>
+	class BS_EXPORT TRenderableHandler
 	{
-		struct MeshData
-		{
-			MeshData() {}
-			MeshData(const HMesh& mesh);
+		template<bool Core> struct TMeshType {};
+		template<> struct TMeshType < false > { typedef HMesh Type; };
+		template<> struct TMeshType < true > { typedef SPtr<MeshCore> Type; };
 
-			HMesh mesh;
-			mutable bool isLoaded;
-		};
+		template<bool Core> struct TMaterialType {};
+		template<> struct TMaterialType < false > { typedef HMaterial Type; };
+		template<> struct TMaterialType < true > { typedef SPtr<MaterialCore> Type; };
 
-		struct MaterialData
-		{
-			MaterialData() {}
-			MaterialData(const HMaterial& material);
-
-			HMaterial material;
-			mutable bool isLoaded;
-		};
+		typedef typename TMeshType<Core>::Type MeshType;
+		typedef typename TMaterialType<Core>::Type MaterialType;
 
 	public:
-		RenderableHandler();
+		TRenderableHandler();
+		virtual ~TRenderableHandler() { }
 
 		/**
 		 * @brief	Sets the mesh to render. All sub-meshes of the mesh will be rendered,
 		 *			and you may set individual materials for each sub-mesh.
 		 */
-		void setMesh(HMesh mesh);
+		void setMesh(const MeshType& mesh);
 
 		/**
 		 * @brief	Sets a material that will be used for rendering a sub-mesh with
 		 *			the specified index. If a sub-mesh doesn't have a specific material set
 		 *			then the primary material will be used.
 		 */
-		void setMaterial(UINT32 idx, HMaterial material);
+		void setMaterial(UINT32 idx, const MaterialType& material);
 
 		/**
-		 * @brief	Sets the primary material to use for rendering. Any sub-mesh that 
+		 * @brief	Sets the primary material to use for rendering. Any sub-mesh that
 		 *			doesn't have an explicit material set will use this material.
 		 *
 		 * @note	This is equivalent to calling setMaterial(0, material).
 		 */
-		void setMaterial(HMaterial material);
+		void setMaterial(const MaterialType& material);
 
 		/**
 		 * @brief	Sets the layer bitfield. Renderable layer must match camera layer
@@ -63,6 +67,22 @@ namespace BansheeEngine
 		 */
 		void setLayer(UINT64 layer);
 
+		/**
+		 * @brief	Sets the transform matrix that is applied to the object
+		 *			when its being rendered.
+		 */
+		void setTransform(const Matrix4& transform);
+
+		/**
+		 * @brief	Sets the world position of the renderable.
+		 */
+		void setPosition(const Vector3& position);
+
+		/**
+		 * @brief	Sets whether the object should be rendered or not.
+		 */
+		void setIsActive(bool active);
+
 		/**
 		 * @brief	Gets the layer bitfield. Renderable layer must match camera layer
 		 *			in order for the camera to render the component.
@@ -72,69 +92,135 @@ namespace BansheeEngine
 		/**
 		 * @brief	Returns the mesh used for rendering.
 		 */
-		HMesh getMesh() const { return mMeshData.mesh; }
+		MeshType getMesh() const { return mMesh; }
 
 		/**
 		 * @brief	Returns the material used for rendering a sub-mesh with
 		 *			the specified index.
 		 */
-		HMaterial getMaterial(UINT32 idx) const;
+		MaterialType getMaterial(UINT32 idx) const { return mMaterials[idx]; }
 
-		/************************************************************************/
-		/* 								CORE PROXY                      		*/
-		/************************************************************************/
+		/**
+		 * @brief	Returns the transform matrix that is applied to the object
+		 *			when its being rendered.
+		 */
+		Matrix4 getTransform() const { return mTransform; }
 
 		/**
-		 * @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.
+		 * @brief	Gets whether the object should be rendered or not.
 		 */
-		bool _isCoreDirty() const;
+		bool getIsActive() const { return mIsActive; }
 
 		/**
-		 * @brief	Marks the core dirty flag as clean.
+		 * @brief	Retrieves the world position of the renderable.
 		 */
-		void _markCoreClean();
+		Vector3 getPosition() const { return mPosition; }
 
+	protected:
 		/**
-		 * @brief	Marks the core data as dirty.
+		 * @copydoc	CoreObject::markCoreDirty
 		 */
-		void _markCoreDirty() const { mCoreDirtyFlags = 0xFFFFFFFF; }
+		virtual void _markCoreDirty(RenderableDirtyFlag flag = RenderableDirtyFlag::Everything) { }
+
+		MeshType mMesh;
+		Vector<MaterialType> mMaterials;
+		UINT64 mLayer;
+		Vector<AABox> mWorldBounds;
+		Vector3 mPosition;
+		Matrix4 mTransform;
+		bool mIsActive;
+	};
+
+	/**
+	 * @copydoc	TRenderableHandler
+	 */
+	class BS_EXPORT RenderableHandlerCore : public CoreObjectCore, public TRenderableHandler<true>
+	{
+	public:
+		~RenderableHandlerCore();
 
 		/**
-		 * @brief	Creates a new core proxy from the currently set Renderable data. Core proxies ensure
-		 *			that the core thread has all the necessary Renderable data, while avoiding the need
-		 *			to manage Renderable itself on the core thread.
-		 *
-		 * @note	You generally need to update the core thread with a new proxy whenever core 
-		 *			dirty flag is set.
+		 * @brief	Gets world bounds of the mesh rendered by this object.
 		 */
-		RenderableProxyPtr _createProxy(const Matrix4& worldTransform) const;
+		Bounds getBounds() const;
 
 		/**
-		 * @brief	Returns the currently active proxy object, if any.
+		 * @brief	Returns the type that controls how is this object rendered.
 		 */
-		RenderableProxyPtr _getActiveProxy() const { return mActiveProxy; }
+		RenderableType getRenderableType() const { return RenType_LitTextured; }
 
 		/**
-		 * @brief	Changes the currently active proxy object. 
+		 * @brief	Sets an ID that can be used for uniquely identifying this handler by the renderer.
 		 */
-		void _setActiveProxy(const RenderableProxyPtr& proxy) { mActiveProxy = proxy; }
+		void setRendererId(UINT32 id) { mRendererId = id; }
 
-	private:
 		/**
-		 * @brief	Checks if any resources were loaded since last time. Marks the core data as dirty
-		 *			if they have (does nothing if all resources are already loaded).
+		 * @brief	Retrieves an ID that can be used for uniquely identifying this handler by the renderer.
 		 */
-		void updateResourceLoadStates() const;
+		UINT32 getRendererId() const { return mRendererId; }
 
-	private:
-		MeshData mMeshData;
-		Vector<MaterialData> mMaterialData;
-		UINT64 mLayer;
-		Vector<AABox> mWorldBounds;
+	protected:
+		friend class RenderableHandler;
 
-		RenderableProxyPtr mActiveProxy;
-		mutable UINT32 mCoreDirtyFlags;
+		RenderableHandlerCore();
+
+		/**
+		 * @copydoc	RenderableHandlerCore::initialize
+		 */
+		void initialize();
+
+		/**
+		 * @copydoc	CoreObject::syncToCore
+		 */
+		void syncToCore(const CoreSyncData& data);
+
+		UINT32 mRendererId;
+	};
+
+	/**
+	 * @copydoc	TRenderableHandler
+	 */
+	class BS_EXPORT RenderableHandler : public IReflectable, public CoreObject, public TRenderableHandler<false>
+	{
+	public:
+		/**
+		 * @brief	Gets world bounds of the mesh rendered by this object.
+		 */
+		Bounds getBounds() const;
+
+		/**
+		 * @brief	Retrieves an implementation of a renderable handler usable only from the
+		 *			core thread.
+		 */
+		SPtr<RenderableHandlerCore> getCore() const;
+
+		/**
+		 * @brief	Creates a new renderable handler instance.
+		 */
+		static RenderableHandlerPtr create();
+
+	protected:
+		RenderableHandler() { }
+
+		/**
+		 * @copydoc	CoreObject::createCore
+		 */
+		SPtr<CoreObjectCore> createCore() const;
+
+		/**
+		 * @copydoc	CoreObject::markCoreDirty
+		 */
+		void _markCoreDirty(RenderableDirtyFlag flag = RenderableDirtyFlag::Everything);
+
+		/**
+		 * @copydoc	CoreObject::syncToCore
+		 */
+		CoreSyncData syncToCore(FrameAlloc* allocator);
+
+		/**
+		 * @brief	Creates a new renderable handler instance without initializing it.
+		 */
+		static RenderableHandlerPtr createEmpty();
 
 		/************************************************************************/
 		/* 								RTTI		                     		*/

+ 12 - 6
BansheeEngine/Include/BsRenderableHandlerRTTI.h

@@ -9,16 +9,16 @@ namespace BansheeEngine
 	class BS_EXPORT RenderableHandlerRTTI : public RTTIType<RenderableHandler, IReflectable, RenderableHandlerRTTI>
 	{
 	private:
-		HMesh& getMesh(RenderableHandler* obj) { return obj->mMeshData.mesh; }
-		void setMesh(RenderableHandler* obj, HMesh& val) { obj->mMeshData.mesh = val; }
+		HMesh& getMesh(RenderableHandler* obj) { return obj->mMesh; }
+		void setMesh(RenderableHandler* obj, HMesh& val) { obj->mMesh = val; }
 
 		UINT64& getLayer(RenderableHandler* obj) { return obj->mLayer; }
 		void setLayer(RenderableHandler* obj, UINT64& val) { obj->mLayer = val; }
 
-		HMaterial& getMaterial(RenderableHandler* obj, UINT32 idx) { return obj->mMaterialData[idx].material; }
+		HMaterial& getMaterial(RenderableHandler* obj, UINT32 idx) { return obj->mMaterials[idx]; }
 		void setMaterial(RenderableHandler* obj, UINT32 idx, HMaterial& val) { obj->setMaterial(idx, val); }
-		UINT32 getNumMaterials(RenderableHandler* obj) { return (UINT32)obj->mMaterialData.size(); }
-		void setNumMaterials(RenderableHandler* obj, UINT32 num) { obj->mMaterialData.resize(num); }
+		UINT32 getNumMaterials(RenderableHandler* obj) { return (UINT32)obj->mMaterials.size(); }
+		void setNumMaterials(RenderableHandler* obj, UINT32 num) { obj->mMaterials.resize(num); }
 
 	public:
 		RenderableHandlerRTTI()
@@ -29,6 +29,12 @@ namespace BansheeEngine
 				&RenderableHandlerRTTI::getNumMaterials, &RenderableHandlerRTTI::setMaterial, &RenderableHandlerRTTI::setNumMaterials);
 		}
 
+		virtual void onDeserializationEnded(IReflectable* obj)
+		{
+			RenderableHandler* renderable = static_cast<RenderableHandler*>(obj);
+			renderable->initialize();
+		}
+
 		virtual const String& getRTTIName()
 		{
 			static String name = "RenderableHandler";
@@ -42,7 +48,7 @@ namespace BansheeEngine
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject()
 		{
-			return bs_shared_ptr<RenderableHandler>();
+			return RenderableHandler::createEmpty();
 		}
 	};
 }

+ 0 - 108
BansheeEngine/Include/BsRenderableProxy.h

@@ -1,108 +0,0 @@
-#pragma once
-
-#include "BsPrerequisites.h"
-#include "BsBounds.h"
-#include "BsMatrix4.h"
-#include "BsSubMesh.h"
-
-namespace BansheeEngine
-{
-	/**
-	 * @brief	Contains all information needed for rendering a single
-	 *			sub-mesh. Closely tied with Renderer.
-	 */
-	class BS_EXPORT RenderableElement
-	{
-	public:
-		/**
-		 * @brief	Contains a hardware GPU parameter buffer and index of the parameters and the slot
-		 *			it binds to in a material proxy.
-		 */
-		struct BS_EXPORT BufferBindInfo
-		{
-			BufferBindInfo(UINT32 passIdx, UINT32 paramsIdx, UINT32 slotIdx, const SPtr<GpuParamBlockBufferCore>& buffer)
-				:passIdx(passIdx), paramsIdx(paramsIdx), slotIdx(slotIdx), buffer(buffer)
-			{ }
-
-			UINT32 passIdx;
-			UINT32 paramsIdx;
-			UINT32 slotIdx;
-			SPtr<GpuParamBlockBufferCore> buffer;
-		};
-
-		RenderableElement();
-
-		/**
-		 * @brief	Calculate mesh world bounds.
-		 */
-		Bounds calculateWorldBounds();
-
-		/**
-		 * @brief	Index of the renderable element in the global array
-		 *			managed by the Renderer.
-		 */
-		UINT32 id;
-
-		/**
-		 * @brief	World transform matrix of the element.
-		 */
-		Matrix4 worldTransform;
-
-		/**
-		 * @brief	Reference to the mesh to render.
-		 */
-		SPtr<MeshCore> mesh;
-
-		/**
-		 * @brief	Portion of the mesh to render.
-		 */
-		SubMesh subMesh;
-
-		/**
-		 * @brief	Proxy of the material to render the mesh with.
-		 */
-		SPtr<MaterialCore> material;
-
-		/**
-		 * @brief	Optional layer that may be used for the camera for culling
-		 *			certain elements.
-		 */
-		UINT64 layer;
-
-		/**
-		 * @brief	Custom data that may optionally be set by the RenderableHanbdler.
-		 */
-		Any rendererData;
-
-		/**
-		 * @brief	Handler responsible for initializing and updating this element.
-		 */
-		RenderableController* handler;
-
-		/**
-		 * @brief	Type that determines which type of RenderableHandler to use for this element.
-		 */
-		RenderableType renderableType;
-
-		Vector<BufferBindInfo> rendererBuffers;
-	private:
-		bool mBoundsDirty;
-	};
-
-	/**
-	 * @brief	Proxy contains data about a single Renderable object, to
-	 *			be used for rendering by the Renderer on the core thread.
-	 *
-	 * @note	Essentially it is a snapshot of Renderable (We cannot use
-	 *			Renderable itself because this is meant for the core thread).
-	 */
-	class BS_EXPORT RenderableProxy
-	{
-	public:
-		~RenderableProxy();
-
-		Vector<RenderableElement*> renderableElements;
-
-		RenderableType renderableType;
-	};
-}

+ 45 - 0
BansheeEngine/Include/BsRenderer.h

@@ -0,0 +1,45 @@
+#pragma once
+
+#include "BsPrerequisites.h"
+#include "BsCoreRenderer.h"
+
+namespace BansheeEngine
+{
+	/**
+	 * @copydoc	CoreRenderer
+	 */
+	class BS_EXPORT Renderer : public CoreRenderer
+	{
+	public:
+		virtual ~Renderer() { }
+
+		/**
+		 * @brief	Called whenever a new renderable is created.
+		 *
+		 * @note	Core thread.
+		 *			Internal method.
+		 */
+		virtual void _notifyRenderableAdded(RenderableHandlerCore* renderable) { }
+
+		/**
+		 * @brief	Called whenever a renderable is updated.
+		 *
+		 * @note	Core thread.
+		 *			Internal method.
+		 */
+		virtual void _notifyRenderableUpdated(RenderableHandlerCore* renderable) { }
+
+		/**
+		 * @brief	Called whenever a renderable is destroyed.
+		 *
+		 * @note	Core thread.
+		 *			Internal method.
+		 */
+		virtual void _notifyRenderableRemoved(RenderableHandlerCore* renderable) { }
+	};
+
+	/**
+	 * @brief	Retrieves the currently active renderer.
+	 */
+	SPtr<Renderer> BS_EXPORT gRenderer();
+}

+ 0 - 5
BansheeEngine/Include/BsSceneManager.h

@@ -51,11 +51,6 @@ namespace BansheeEngine
 		 */
 		virtual const Vector<SceneRenderableData>& getAllRenderables() const = 0;
 
-		/**
-		 * @brief	Updates dirty transforms on any scene objects with a Renderable component.
-		 */
-		virtual void updateRenderableTransforms() = 0;
-
 		/**
 		 * @copydoc	CoreSceneManager::instance
 		 */

+ 10 - 1
BansheeEngine/Source/BsCameraHandler.cpp

@@ -10,7 +10,7 @@
 #include "BsSceneObject.h"
 #include "BsDebug.h"
 #include "BsRendererManager.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsFrameAlloc.h"
 
 namespace BansheeEngine
@@ -748,6 +748,15 @@ namespace BansheeEngine
 		return handlerPtr;
 	}
 
+	CameraHandlerPtr CameraHandler::createEmpty()
+	{
+		CameraHandler* handler = new (bs_alloc<CameraHandler>()) CameraHandler();
+		CameraHandlerPtr handlerPtr = bs_core_ptr<CameraHandler, GenAlloc>(handler);
+		handlerPtr->_setThisPtr(handlerPtr);
+
+		return handlerPtr;
+	}
+
 	SPtr<CoreObjectCore> CameraHandler::createCore() const
 	{
 		Rect2 normArea = mViewport->getNormArea();

+ 1 - 1
BansheeEngine/Source/BsRenderQueue.cpp

@@ -1,9 +1,9 @@
 #include "BsRenderQueue.h"
-#include "BsRenderableProxy.h"
 #include "BsSubMesh.h"
 #include "BsShader.h"
 #include "BsMesh.h"
 #include "BsMaterial.h"
+#include "BsRenderableElement.h"
 
 namespace BansheeEngine
 {

+ 19 - 18
BansheeEngine/Source/BsRenderable.cpp

@@ -10,38 +10,39 @@
 namespace BansheeEngine
 {
 	Renderable::Renderable(const HSceneObject& parent)
-		:Component(parent)
+		:Component(parent), mLastUpdateHash(0)
 	{
 		setName("Renderable");
 
-		mInternal = bs_shared_ptr<RenderableHandler>();
+		mInternal = RenderableHandler::create();
 	}
 
 	Bounds Renderable::getBounds() const
 	{
-		HMesh mesh = mInternal->getMesh();
+		updateTransform();
 
-		if (mesh == nullptr || !mesh.isLoaded())
-		{
-			Vector3 pos = SO()->getWorldPosition();
-
-			AABox box(pos, pos);
-			Sphere sphere(pos, 0.0f);
+		return mInternal->getBounds();
+	}
 
-			return Bounds(box, sphere);
-		}
-		else
+	void Renderable::updateTransform() const
+	{
+		UINT32 curHash = SO()->getTransformHash();
+		if (curHash != mLastUpdateHash)
 		{
-			Bounds bounds = mesh->getProperties().getBounds();
-			bounds.transformAffine(SO()->getWorldTfrm());
+			mInternal->setTransform(SO()->getWorldTfrm());
 
-			return bounds;
+			mLastUpdateHash = curHash;
 		}
 	}
 
-	RenderableProxyPtr Renderable::_createProxy() const 
-	{ 
-		return mInternal->_createProxy(SO()->getWorldTfrm()); 
+	void Renderable::update()
+	{
+		updateTransform();
+
+		if (SO()->getActive() != mInternal->getIsActive())
+		{
+			mInternal->setIsActive(SO()->getActive());
+		}
 	}
 
 	RTTITypeBase* Renderable::getRTTIStatic()

+ 4 - 4
BansheeEngine/Source/BsRenderableController.cpp

@@ -1,15 +1,15 @@
 #include "BsRenderableController.h"
-#include "BsRenderableProxy.h"
 #include "BsGpuParams.h"
 #include "BsMaterial.h"
+#include "BsRenderableElement.h"
 
 namespace BansheeEngine
 {
-	void RenderableController::bindGlobalBuffers(const RenderableElement* element)
+	void RenderableController::bindGlobalBuffers(const RenderableElement& element)
 	{
-		for (auto& rendererBuffer : element->rendererBuffers)
+		for (auto& rendererBuffer : element.rendererBuffers)
 		{
-			SPtr<PassParametersCore> passParams = element->material->getPassParameters(rendererBuffer.passIdx);
+			SPtr<PassParametersCore> passParams = element.material->getPassParameters(rendererBuffer.passIdx);
 			passParams->getParamByIdx(rendererBuffer.paramsIdx)->setParamBlockBuffer(rendererBuffer.slotIdx, rendererBuffer.buffer);
 		}
 	}

+ 201 - 66
BansheeEngine/Source/BsRenderableHandler.cpp

@@ -6,56 +6,43 @@
 #include "BsMaterial.h"
 #include "BsRenderQueue.h"
 #include "BsBounds.h"
+#include "BsRenderer.h"
+#include "BsFrameAlloc.h"
 
 namespace BansheeEngine
 {
-	RenderableHandler::MeshData::MeshData(const HMesh& mesh)
+	template<bool Core>
+	TRenderableHandler<Core>::TRenderableHandler()
+		:mLayer(1), mTransform(Matrix4::IDENTITY), mIsActive(true)
 	{
-		this->mesh = mesh;
-		isLoaded = mesh.isLoaded();
+		mMaterials.resize(1);
 	}
 
-	RenderableHandler::MaterialData::MaterialData(const HMaterial& material)
+	template<bool Core>
+	void TRenderableHandler<Core>::setMesh(const MeshType& mesh)
 	{
-		this->material = material;
-		isLoaded = material.isLoaded();
-	}
-
-	RenderableHandler::RenderableHandler()
-		:mLayer(1), mCoreDirtyFlags(0xFFFFFFFF), mActiveProxy(nullptr)
-	{
-		mMaterialData.resize(1);
-	}
-
-	void RenderableHandler::setMesh(HMesh mesh)
-	{
-		mMeshData = mesh;
-		mMaterialData.resize(mesh->getProperties().getNumSubMeshes());
+		mMesh = mesh;
+		mMaterials.resize(mesh->getProperties().getNumSubMeshes());
 
 		_markCoreDirty();
 	}
 
-	void RenderableHandler::setMaterial(UINT32 idx, HMaterial material)
+	template<bool Core>
+	void TRenderableHandler<Core>::setMaterial(UINT32 idx, const MaterialType& material)
 	{
-		mMaterialData[idx] = material;
+		mMaterials[idx] = material;
 
 		_markCoreDirty();
 	}
 
-	void RenderableHandler::setMaterial(HMaterial material)
+	template<bool Core>
+	void TRenderableHandler<Core>::setMaterial(const MaterialType& material)
 	{
 		setMaterial(0, material);
 	}
 
-	HMaterial RenderableHandler::getMaterial(UINT32 idx) const
-	{
-		if (mMaterialData[idx].material != nullptr)
-			return mMaterialData[idx].material;
-		else
-			return mMaterialData[0].material;
-	}
-
-	void RenderableHandler::setLayer(UINT64 layer)
+	template<bool Core>
+	void TRenderableHandler<Core>::setLayer(UINT64 layer)
 	{
 		bool isPow2 = layer && !((layer - 1) & layer);
 
@@ -66,70 +53,218 @@ namespace BansheeEngine
 		_markCoreDirty();
 	}
 
-	bool RenderableHandler::_isCoreDirty() const
+	template<bool Core>
+	void TRenderableHandler<Core>::setTransform(const Matrix4& transform)
+	{
+		mTransform = transform;
+		_markCoreDirty(RenderableDirtyFlag::Transform);
+	}
+
+	template<bool Core>
+	void TRenderableHandler<Core>::setPosition(const Vector3& position)
+	{
+		mPosition = position;
+		_markCoreDirty(RenderableDirtyFlag::Transform);
+	}
+
+	template<bool Core>
+	void TRenderableHandler<Core>::setIsActive(bool active)
+	{
+		mIsActive = active;
+		_markCoreDirty();
+	}
+
+	template class TRenderableHandler < false >;
+	template class TRenderableHandler < true >;
+
+	RenderableHandlerCore::RenderableHandlerCore() 
+		:mRendererId(0)
 	{
-		updateResourceLoadStates();
+	}
 
-		return mCoreDirtyFlags != 0;
+	RenderableHandlerCore::~RenderableHandlerCore()
+	{
+		if (mIsActive)
+			gRenderer()->_notifyRenderableRemoved(this);
 	}
 
-	void RenderableHandler::_markCoreClean()
+	void RenderableHandlerCore::initialize()
 	{
-		mCoreDirtyFlags = 0;
+		gRenderer()->_notifyRenderableAdded(this);
+
+		CoreObjectCore::initialize();
 	}
 
-	void RenderableHandler::updateResourceLoadStates() const
+	Bounds RenderableHandlerCore::getBounds() const
 	{
-		if (!mMeshData.isLoaded && mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
+		SPtr<MeshCore> mesh = getMesh();
+
+		if (mesh == nullptr)
 		{
-			mMeshData.isLoaded = true;
+			AABox box(mPosition, mPosition);
+			Sphere sphere(mPosition, 0.0f);
 
-			_markCoreDirty();
+			return Bounds(box, sphere);
 		}
+		else
+		{
+			Bounds bounds = mesh->getProperties().getBounds();
+			bounds.transformAffine(mTransform);
 
-		for (auto& materialData : mMaterialData)
+			return bounds;
+		}
+	}
+
+	void RenderableHandlerCore::syncToCore(const CoreSyncData& data)
+	{
+		char* dataPtr = (char*)data.getBuffer();
+
+		mWorldBounds.clear();
+		mMaterials.clear();
+
+		UINT32 numMaterials = 0;
+		UINT32 dirtyFlags = 0;
+		bool oldIsActive = mIsActive;
+
+		dataPtr = rttiReadElem(mLayer, dataPtr);
+		dataPtr = rttiReadElem(mWorldBounds, dataPtr);
+		dataPtr = rttiReadElem(numMaterials, dataPtr);
+		dataPtr = rttiReadElem(mTransform, dataPtr);
+		dataPtr = rttiReadElem(mPosition, dataPtr);
+		dataPtr = rttiReadElem(mIsActive, dataPtr);
+		dataPtr = rttiReadElem(dirtyFlags, dataPtr);
+
+		SPtr<MeshCore>* mesh = (SPtr<MeshCore>*)dataPtr;
+		mMesh = *mesh;
+		mesh->~SPtr<MeshCore>();
+		dataPtr += sizeof(SPtr<MeshCore>);
+
+		for (UINT32 i = 0; i < numMaterials; i++)
 		{
-			if (!materialData.isLoaded && materialData.material != nullptr && materialData.material.isLoaded())
-			{
-				materialData.isLoaded = true;
+			SPtr<MaterialCore>* material = (SPtr<MaterialCore>*)dataPtr;
+			mMaterials.push_back(*material);
+			material->~SPtr<MaterialCore>();
+			dataPtr += sizeof(SPtr<MaterialCore>);
+		}
 
-				_markCoreDirty();
+		if (dirtyFlags == (UINT32)RenderableDirtyFlag::Transform)
+		{
+			if (mIsActive)
+				gRenderer()->_notifyRenderableUpdated(this);
+		}
+		else
+		{
+			if (oldIsActive != mIsActive)
+			{
+				if (mIsActive)
+					gRenderer()->_notifyRenderableAdded(this);
+				else
+					gRenderer()->_notifyRenderableRemoved(this);
+			}
+			else
+			{
+				gRenderer()->_notifyRenderableRemoved(this);
+				gRenderer()->_notifyRenderableAdded(this);
 			}
 		}
 	}
 
-	RenderableProxyPtr RenderableHandler::_createProxy(const Matrix4& worldTransform) const
+	Bounds RenderableHandler::getBounds() const
 	{
-		if (mMeshData.mesh == nullptr || !mMeshData.mesh.isLoaded())
-			return nullptr;
+		HMesh mesh = getMesh();
 
-		RenderableProxyPtr proxy = bs_shared_ptr<RenderableProxy>();
+		if (!mesh.isLoaded())
+		{
+			AABox box(mPosition, mPosition);
+			Sphere sphere(mPosition, 0.0f);
 
-		for (UINT32 i = 0; i < mMeshData.mesh->getProperties().getNumSubMeshes(); i++)
+			return Bounds(box, sphere);
+		}
+		else
 		{
-			RenderableElement* renElement = bs_new<RenderableElement>();
-			renElement->layer = mLayer;
-			renElement->worldTransform = worldTransform;
-			renElement->mesh = mMeshData.mesh->getCore();
-			renElement->subMesh = mMeshData.mesh->getProperties().getSubMesh(i);
-
-			HMaterial material;
-			if (mMaterialData[i].material != nullptr)
-				material = mMaterialData[i].material;
-			else
-				material = mMaterialData[0].material;
+			Bounds bounds = mesh->getProperties().getBounds();
+			bounds.transformAffine(mTransform);
+
+			return bounds;
+		}
+	}
+
+	SPtr<RenderableHandlerCore> RenderableHandler::getCore() const
+	{
+		return std::static_pointer_cast<RenderableHandlerCore>(mCoreSpecific);
+	}
+
+	SPtr<CoreObjectCore> RenderableHandler::createCore() const
+	{
+		RenderableHandlerCore* handler = new (bs_alloc<RenderableHandlerCore>()) RenderableHandlerCore();
+		SPtr<RenderableHandlerCore> handlerPtr = bs_shared_ptr<RenderableHandlerCore, GenAlloc>(handler);
+		handlerPtr->_setThisPtr(handlerPtr);
+
+		return handlerPtr;
+	}
+
+	void RenderableHandler::_markCoreDirty(RenderableDirtyFlag flag)
+	{
+		markCoreDirty((UINT32)flag);
+	}
+
+	CoreSyncData RenderableHandler::syncToCore(FrameAlloc* allocator)
+	{
+		UINT32 numMaterials = (UINT32)mMaterials.size();
+
+		UINT32 size = rttiGetElemSize(mLayer) + 
+			rttiGetElemSize(mWorldBounds) + 
+			rttiGetElemSize(numMaterials) + 
+			rttiGetElemSize(mTransform) +
+			rttiGetElemSize(mPosition) +
+			rttiGetElemSize(mIsActive) +
+			rttiGetElemSize(getCoreDirtyFlags()) +
+			sizeof(SPtr<MeshCore>) + 
+			numMaterials * sizeof(SPtr<MaterialCore>);
+
+		UINT8* data = allocator->alloc(size);
+		char* dataPtr = (char*)data;
+		dataPtr = rttiWriteElem(mLayer, dataPtr);
+		dataPtr = rttiWriteElem(mWorldBounds, dataPtr);
+		dataPtr = rttiWriteElem(numMaterials, dataPtr);
+		dataPtr = rttiWriteElem(mTransform, dataPtr);
+		dataPtr = rttiWriteElem(mPosition, dataPtr);
+		dataPtr = rttiWriteElem(mIsActive, dataPtr);
+		dataPtr = rttiWriteElem(getCoreDirtyFlags(), dataPtr);
 
-			if (material == nullptr || !material.isLoaded())
-				material = BuiltinResources::instance().createDummyMaterial();
+		SPtr<MeshCore>* mesh = new (dataPtr) SPtr<MeshCore>();
+		if (mMesh.isLoaded())
+			*mesh = mMesh->getCore();
 
-			renElement->material = material->getCore();
+		dataPtr += sizeof(SPtr<MeshCore>);
 
-			proxy->renderableElements.push_back(renElement);
+		for (UINT32 i = 0; i < numMaterials; i++)
+		{
+			SPtr<MaterialCore>* material = new (dataPtr)SPtr<MaterialCore>();
+			if (mMaterials[i].isLoaded())
+				*material = mMaterials[i]->getCore();
+
+			dataPtr += sizeof(SPtr<MaterialCore>);
 		}
 
-		proxy->renderableType = RenType_LitTextured;
+		return CoreSyncData(data, size);
+	}
+
+	RenderableHandlerPtr RenderableHandler::create()
+	{
+		RenderableHandlerPtr handlerPtr = createEmpty();
+		handlerPtr->initialize();
+
+		return handlerPtr;
+	}
+
+	RenderableHandlerPtr RenderableHandler::createEmpty()
+	{
+		RenderableHandler* handler = new (bs_alloc<RenderableHandler>()) RenderableHandler();
+		RenderableHandlerPtr handlerPtr = bs_core_ptr<RenderableHandler, GenAlloc>(handler);
+		handlerPtr->_setThisPtr(handlerPtr);
 
-		return proxy;
+		return handlerPtr;
 	}
 
 	RTTITypeBase* RenderableHandler::getRTTIStatic()

+ 0 - 26
BansheeEngine/Source/BsRenderableProxy.cpp

@@ -1,26 +0,0 @@
-#include "BsRenderableProxy.h"
-#include "BsMesh.h"
-
-namespace BansheeEngine
-{
-	RenderableElement::RenderableElement()
-		:mBoundsDirty(false), id(0), mesh(nullptr)
-	{ }
-
-	Bounds RenderableElement::calculateWorldBounds()
-	{
-		if (mesh == nullptr)
-			return Bounds();
-
-		Bounds worldBounds = mesh->getProperties().getBounds();
-		worldBounds.transformAffine(worldTransform);
-
-		return worldBounds;
-	}
-
-	RenderableProxy::~RenderableProxy()
-	{
-		for (auto& renderableElement : renderableElements)
-			bs_delete(renderableElement);
-	}
-}

+ 10 - 0
BansheeEngine/Source/BsRenderer.cpp

@@ -0,0 +1,10 @@
+#include "BsRenderer.h"
+#include "BsRendererManager.h"
+
+namespace BansheeEngine
+{
+	SPtr<Renderer> gRenderer()
+	{
+		return std::static_pointer_cast<Renderer>(RendererManager::instance().getActive());
+	}
+}

+ 4 - 4
BansheeRenderer/Include/BsBansheeLitTexRenderableController.h

@@ -4,7 +4,7 @@
 #include "BsRenderableController.h"
 #include "BsGpuParamDesc.h"
 #include "BsGpuParam.h"
-#include "BsRenderableProxy.h"
+#include "BsRenderableElement.h"
 
 namespace BansheeEngine
 {
@@ -36,12 +36,12 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	RenderableHandler::initializeRenderElem
 		 */
-		void initializeRenderElem(RenderableElement* element);
+		void initializeRenderElem(RenderableElement& element);
 
 		/**
 		 * @copydoc	RenderableHandler::bindPerObjectBuffers
 		 */
-		void bindPerObjectBuffers(const RenderableElement* element);
+		void bindPerObjectBuffers(const RenderableElement& element);
 
 		/**
 		 * @brief	Updates global parameter buffers with new values. 
@@ -53,7 +53,7 @@ namespace BansheeEngine
 		 * @brief	Updates object specific parameter buffers with new values.
 		 *			To be called whenever object specific values change.
 		 */
-		void updatePerObjectBuffers(RenderableElement* element, const Matrix4& wvpMatrix);
+		void updatePerObjectBuffers(RenderableElement& element, const Matrix4& wvpMatrix);
 
 	protected:
 		/**

+ 31 - 34
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -3,6 +3,7 @@
 #include "BsBansheeRendererPrerequisites.h"
 #include "BsRenderer.h"
 #include "BsBounds.h"
+#include "BsRenderableElement.h"
 
 namespace BansheeEngine
 {
@@ -34,16 +35,26 @@ namespace BansheeEngine
 		};
 
 		/**
-		 * @brief	Various data used by a single camera.
+		 * @brief	Data used by the renderer for a camera.
 		 */
 		struct CameraData
 		{
 			RenderQueuePtr renderQueue;
 		};
 
+		/**
+		 * @brief	Data used by the renderer when rendering renderable handlers.
+		 */
+		struct RenderableData
+		{
+			RenderableHandlerCore* renderable;
+			Vector<RenderableElement> elements;
+			RenderableController* controller;
+		};
+
 	public:
-		BansheeRenderer();
-		~BansheeRenderer();
+		BansheeRenderer() { }
+		~BansheeRenderer() { }
 
 		/**
 		 * @copydoc	Renderer::getName
@@ -69,38 +80,27 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	Renderer::_notifyCameraAdded
 		 */
-		virtual void _notifyCameraAdded(const CameraHandlerCore* camera);
+		void _notifyCameraAdded(const CameraHandlerCore* camera);
 
 		/**
 		 * @copydoc	Renderer::_notifyCameraRemoved
 		 */
-		virtual void _notifyCameraRemoved(const CameraHandlerCore* camera);
+		void _notifyCameraRemoved(const CameraHandlerCore* camera);
 
 		/**
-		 * @brief	Adds a new renderable proxy which will be considered for rendering next frame.
-		 *
-		 * @note	Core thread only.
+		 * @copydoc	Renderer::_notifyRenderableAdded
 		 */
-		void addRenderableProxy(RenderableProxyPtr proxy);
+		void _notifyRenderableAdded(RenderableHandlerCore* renderable);
 
 		/**
-		 * @brief	Removes a previously existing renderable proxy so it will no longer be considered
-		 *			for rendering.
-		 *
-		 * @note	Core thread only.
+		 * @copydoc	Renderer::_notifyRenderableUpdated
 		 */
-		void removeRenderableProxy(RenderableProxyPtr proxy);
+		void _notifyRenderableUpdated(RenderableHandlerCore* renderable);
 
 		/**
-		 * @brief	Updates an existing renderable proxy with new data. This includes data that changes
-		 *			often. For other data it is best to remove old proxy and add new one.
-		 *
-		 * @param	proxy			Proxy to update.
-		 * @param	localToWorld	Local to world transform of the parent Renderable.
-		 *
-		 * @note	Core thread only.
+		 * @copydoc	Renderer::_notifyRenderableRemoved
 		 */
-		void updateRenderableProxy(RenderableProxyPtr proxy, Matrix4 localToWorld);
+		void _notifyRenderableRemoved(RenderableHandlerCore* renderable);
 
 		/**
 		 * @brief	Adds a new set of objects to the cameras render queue.
@@ -131,12 +131,6 @@ namespace BansheeEngine
 		 */
 		virtual void render(const CameraHandlerCore& camera, const RenderQueuePtr& renderQueue);
 
-		/**
-		 * @brief	Called by the scene manager whenever a Renderable component has been
-		 *			removed from the scene.
-		 */
-		void renderableRemoved(const RenderableHandlerPtr& renderable);
-
 		/**
 		 * @brief	Creates data used by the renderer on the core thread.
 		 */
@@ -147,17 +141,20 @@ namespace BansheeEngine
 		 */
 		void destroyCore();
 
-		Vector<RenderableProxyPtr> mDeletedRenderableProxies;
+		/**
+		 * @brief	Creates a dummy shader to be used when no other is available.
+		 */
+		SPtr<ShaderCore> createDefaultShader();
 
 		Vector<RenderTargetData> mRenderTargets; // Core thread
 		UnorderedMap<const CameraHandlerCore*, CameraData> mCameraData; // Core thread
 
-		Vector<RenderableElement*> mRenderableElements;
-		Vector<Matrix4> mWorldTransforms;
-		Vector<Bounds> mWorldBounds;
+		SPtr<MaterialCore> mDummyMaterial; // Core thread
 
-		LitTexRenderableController* mLitTexHandler;
+		Vector<RenderableData> mRenderables; // Core thread
+		Vector<Matrix4> mWorldTransforms; // Core thread
+		Vector<Bounds> mWorldBounds; // Core thread
 
-		HEvent mRenderableRemovedConn;
+		LitTexRenderableController* mLitTexHandler;
 	};
 }

+ 1 - 1
BansheeRenderer/Include/BsBansheeRendererFactory.h

@@ -17,7 +17,7 @@ namespace BansheeEngine
 		/**
 		 * @copydoc	RendererFactory::create
 		 */
-		virtual RendererPtr create();
+		virtual CoreRendererPtr create();
 
 		/**
 		 * @copydoc	RendererFactory::name

+ 13 - 14
BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp

@@ -1,5 +1,4 @@
 #include "BsBansheeLitTexRenderableController.h"
-#include "BsRenderableProxy.h"
 #include "BsShader.h"
 #include "BsGpuParams.h"
 #include "BsBansheeRenderer.h"
@@ -122,7 +121,7 @@ namespace BansheeEngine
 		lightDirParam.set(Vector4(0.707f, 0.707f, 0.707f, 0.0f));
 	}
 
-	void LitTexRenderableController::initializeRenderElem(RenderableElement* element)
+	void LitTexRenderableController::initializeRenderElem(RenderableElement& element)
 	{
 		static auto paramsMatch = [](const GpuParamDataDesc& a, const GpuParamDataDesc& b)
 		{
@@ -130,10 +129,10 @@ namespace BansheeEngine
 				a.arraySize == b.arraySize && a.arrayElementStride == b.arrayElementStride;
 		};
 
-		element->rendererData = PerObjectData();
-		PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element->rendererData);
+		element.rendererData = PerObjectData();
+		PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element.rendererData);
 
-		SPtr<ShaderCore> shader = element->material->getShader();
+		SPtr<ShaderCore> shader = element.material->getShader();
 
 		const Map<String, SHADER_PARAM_BLOCK_DESC>& paramBlockDescs = shader->getParamBlocks();
 		const Map<String, SHADER_DATA_PARAM_DESC>& dataParamDescs = shader->getDataParams();
@@ -165,10 +164,10 @@ namespace BansheeEngine
 				wvpParamName = paramDesc.second.gpuVariableName;
 		}
 
-		UINT32 numPasses = element->material->getNumPasses();
+		UINT32 numPasses = element.material->getNumPasses();
 		for (UINT32 i = 0; i < numPasses; i++)
 		{
-			SPtr<PassParametersCore> passParams = element->material->getPassParameters(i);
+			SPtr<PassParametersCore> passParams = element.material->getPassParameters(i);
 
 			for (UINT32 j = 0; j < passParams->getNumParams(); j++)
 			{
@@ -188,7 +187,7 @@ namespace BansheeEngine
 						if (findIter->second.blockSize == staticParamBlockDesc.blockSize)
 						{
 							UINT32 slotIdx = findIter->second.slot;
-							element->rendererBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, staticParamBuffer));
+							element.rendererBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, staticParamBuffer));
 						}
 					}
 				}
@@ -201,7 +200,7 @@ namespace BansheeEngine
 						if (findIter->second.blockSize == perFrameParamBlockDesc.blockSize)
 						{
 							UINT32 slotIdx = findIter->second.slot;
-							element->rendererBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, perFrameParamBuffer));
+							element.rendererBuffers.push_back(RenderableElement::BufferBindInfo(i, j, slotIdx, perFrameParamBuffer));
 						}
 					}
 				}
@@ -239,12 +238,12 @@ namespace BansheeEngine
 		bindGlobalBuffers(element);
 	}
 
-	void LitTexRenderableController::bindPerObjectBuffers(const RenderableElement* element)
+	void LitTexRenderableController::bindPerObjectBuffers(const RenderableElement& element)
 	{
-		const PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element->rendererData);
+		const PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element.rendererData);
 		for (auto& perObjectBuffer : rendererData->perObjectBuffers)
 		{
-			SPtr<GpuParamsCore> params = element->material->getPassParameters(perObjectBuffer.passIdx)->getParamByIdx(perObjectBuffer.paramsIdx);
+			SPtr<GpuParamsCore> params = element.material->getPassParameters(perObjectBuffer.passIdx)->getParamByIdx(perObjectBuffer.paramsIdx);
 
 			params->setParamBlockBuffer(perObjectBuffer.slotIdx, rendererData->perObjectParamBuffer);
 		}
@@ -258,9 +257,9 @@ namespace BansheeEngine
 		perFrameParams->updateHardwareBuffers();
 	}
 
-	void LitTexRenderableController::updatePerObjectBuffers(RenderableElement* element, const Matrix4& wvpMatrix)
+	void LitTexRenderableController::updatePerObjectBuffers(RenderableElement& element, const Matrix4& wvpMatrix)
 	{
-		PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element->rendererData);
+		PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element.rendererData);
 
 		if (rendererData->hasWVPParam)
 			rendererData->wvpParam.set(wvpMatrix);

+ 188 - 142
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -26,22 +26,13 @@
 #include "BsShader.h"
 #include "BsBansheeLitTexRenderableController.h"
 #include "BsTime.h"
+#include "BsRenderableElement.h"
 #include "BsFrameAlloc.h"
 
 using namespace std::placeholders;
 
 namespace BansheeEngine
 {
-	BansheeRenderer::BansheeRenderer()
-	{
-		mRenderableRemovedConn = gSceneManager().onRenderableRemoved.connect(std::bind(&BansheeRenderer::renderableRemoved, this, _1));
-	}
-
-	BansheeRenderer::~BansheeRenderer()
-	{
-		mRenderableRemovedConn.disconnect();
-	}
-
 	const String& BansheeRenderer::getName() const
 	{
 		static String name = "BansheeRenderer";
@@ -50,14 +41,14 @@ namespace BansheeEngine
 
 	void BansheeRenderer::_onActivated()
 	{
-		Renderer::_onActivated();
+		CoreRenderer::_onActivated();
 
 		gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::initializeCore, this));
 	}
 
 	void BansheeRenderer::_onDeactivated()
 	{
-		Renderer::_onDeactivated();
+		CoreRenderer::_onDeactivated();
 
 		gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::destroyCore, this));
 		gCoreAccessor().submitToCoreThread(true);
@@ -66,6 +57,9 @@ namespace BansheeEngine
 	void BansheeRenderer::initializeCore()
 	{
 		mLitTexHandler = bs_new<LitTexRenderableController>();
+
+		SPtr<ShaderCore> shader = createDefaultShader();
+		mDummyMaterial = MaterialCore::create(shader);
 	}
 
 	void BansheeRenderer::destroyCore()
@@ -75,56 +69,82 @@ namespace BansheeEngine
 
 		mRenderTargets.clear();
 		mCameraData.clear();
+		mRenderables.clear();
+
+		mDummyMaterial = nullptr;
 	}
 
-	void BansheeRenderer::addRenderableProxy(RenderableProxyPtr proxy)
+	void BansheeRenderer::_notifyRenderableAdded(RenderableHandlerCore* renderable)
 	{
-		for (auto& element : proxy->renderableElements)
-		{
-			mRenderableElements.push_back(element);
-			mWorldTransforms.push_back(element->worldTransform);
-			mWorldBounds.push_back(element->calculateWorldBounds());
+		UINT32 renderableId = (UINT32)mRenderables.size();
 
-			element->renderableType = proxy->renderableType;
-			if (proxy->renderableType == RenType_LitTextured)
-				element->handler = mLitTexHandler;
-			else
-				element->handler = nullptr;
+		renderable->setRendererId(renderableId);
 
-			if (element->handler != nullptr)
-				element->handler->initializeRenderElem(element);
+		mRenderables.push_back(RenderableData());
+		mWorldTransforms.push_back(renderable->getTransform());
+		mWorldBounds.push_back(renderable->getBounds());
 
-			element->id = (UINT32)(mRenderableElements.size() - 1);
-		}
-	}
+		RenderableData& renderableData = mRenderables.back();
+		renderableData.renderable = renderable;
 
-	void BansheeRenderer::removeRenderableProxy(RenderableProxyPtr proxy)
-	{
-		for (auto& element : proxy->renderableElements)
-		{
-			assert(mRenderableElements.size() > element->id && element->id >= 0);
+		if (renderable->getRenderableType() == RenType_LitTextured)
+			renderableData.controller = mLitTexHandler;
+		else
+			renderableData.controller = nullptr;
 
-			if (mRenderableElements.size() == 0)
-				mRenderableElements.erase(mRenderableElements.begin());
-			else
+		SPtr<MeshCore> mesh = renderable->getMesh();
+		if (mesh != nullptr)
+		{
+			const MeshProperties& meshProps = mesh->getProperties();
+			for (UINT32 i = 0; i < meshProps.getNumSubMeshes(); i++)
 			{
-				std::swap(mRenderableElements[element->id], mRenderableElements.back());
-				mRenderableElements.erase(mRenderableElements.end() - 1);
+				renderableData.elements.push_back(RenderableElement());
+				RenderableElement& renElement = renderableData.elements.back();
+
+				renElement.mesh = mesh;
+				renElement.subMesh = meshProps.getSubMesh(i);
+
+				renElement.material = renderable->getMaterial(i);
+				if (renElement.material == nullptr)
+					renElement.material = renderable->getMaterial(0);
+
+				if (renElement.material == nullptr)
+					renElement.material = mDummyMaterial;
 
-				mRenderableElements[element->id]->id = element->id;
+				if (renderableData.controller != nullptr)
+					renderableData.controller->initializeRenderElem(renElement);
 			}
 		}
 	}
 
-	void BansheeRenderer::updateRenderableProxy(RenderableProxyPtr proxy, Matrix4 localToWorld)
+	void BansheeRenderer::_notifyRenderableRemoved(RenderableHandlerCore* renderable)
 	{
-		for (auto& element : proxy->renderableElements)
+		UINT32 renderableId = renderable->getRendererId();
+		RenderableHandlerCore* lastRenerable = mRenderables.back().renderable;
+		UINT32 lastRenderableId = lastRenerable->getRendererId();
+
+		if (renderableId != lastRenderableId)
 		{
-			element->worldTransform = localToWorld;
+			// Swap current last element with the one we want to erase
+			std::swap(mRenderables[renderableId], mRenderables[lastRenderableId]);
+			std::swap(mWorldBounds[renderableId], mWorldBounds[lastRenderableId]);
+			std::swap(mWorldTransforms[renderableId], mWorldTransforms[lastRenderableId]);
 
-			mWorldTransforms[element->id] = localToWorld;
-			mWorldBounds[element->id] = element->calculateWorldBounds();
+			lastRenerable->setRendererId(renderableId);
 		}
+
+		// Last element is the one we want to erase
+		mRenderables.erase(mRenderables.end() - 1);
+		mWorldBounds.erase(mWorldBounds.end() - 1);
+		mWorldTransforms.erase(mWorldTransforms.end() - 1);
+	}
+
+	void BansheeRenderer::_notifyRenderableUpdated(RenderableHandlerCore* renderable)
+	{
+		UINT32 renderableId = renderable->getRendererId();
+
+		mWorldTransforms[renderableId] = renderable->getTransform();
+		mWorldBounds[renderableId] = renderable->getBounds();
 	}
 
 	void BansheeRenderer::_notifyCameraAdded(const CameraHandlerCore* camera)
@@ -138,88 +158,8 @@ namespace BansheeEngine
 		mCameraData.erase(camera);
 	}
 
-	void BansheeRenderer::renderableRemoved(const RenderableHandlerPtr& renderable)
-	{
-		if (renderable->_getActiveProxy() != nullptr)
-		{
-			mDeletedRenderableProxies.push_back(renderable->_getActiveProxy());
-		}
-	}
-
 	void BansheeRenderer::renderAll() 
 	{
-		gSceneManager().updateRenderableTransforms();
-
-		// Remove proxies from deleted Renderables
-		for (auto& camera : mDeletedRenderableProxies)
-		{
-			if (camera != nullptr)
-				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, camera));
-		}
-
-		// Add or update Renderable proxies
-		const Vector<SceneRenderableData>& allRenderables = gSceneManager().getAllRenderables();
-		Vector<HSceneObject> dirtySceneObjects;
-		Vector<RenderableHandlerPtr> dirtyRenderables;
-
-		for (auto& renderableData : allRenderables)
-		{
-			RenderableHandlerPtr renderable = renderableData.renderable;
-			HSceneObject renderableSO = renderableData.sceneObject;
-
-			bool addedNewProxy = false;
-			RenderableProxyPtr proxy = renderable->_getActiveProxy();
-
-			if (renderableSO->getActive())
-			{
-				if (renderable->_isCoreDirty())
-				{
-					if (proxy != nullptr)
-						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, proxy));
-
-					proxy = renderable->_createProxy(renderableSO->getWorldTfrm());
-					renderable->_setActiveProxy(proxy);
-
-					if (proxy != nullptr)
-						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addRenderableProxy, this, proxy));
-
-					dirtyRenderables.push_back(renderable);
-					dirtySceneObjects.push_back(renderableSO);
-					addedNewProxy = true;
-				}
-				else if (renderableSO->_isCoreDirty())
-				{
-					if (proxy != nullptr)
-						gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateRenderableProxy, this, proxy, renderableSO->getWorldTfrm()));
-
-					dirtySceneObjects.push_back(renderableSO);
-				}
-			}
-			else // If inactive we remove the proxy until re-activated
-			{
-				if (proxy != nullptr)
-				{
-					gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, proxy));
-					renderable->_setActiveProxy(nullptr);
-					renderable->_markCoreDirty();
-				}
-			}
-		}
-
-		// Mark all renderables as clean (needs to be done after all proxies are updated as
-		// this will also clean materials & meshes which may be shared, so we don't want to clean them
-		// too early.
-		for (auto& renderable : dirtyRenderables)
-		{
-			renderable->_markCoreClean();
-		}
-
-		// Mark scene objects clean
-		for (auto& dirtySO : dirtySceneObjects)
-		{
-			dirtySO->_markCoreClean();
-		}
-
 		// Populate direct draw lists
 		const Vector<SceneCameraData>& allCameras = gSceneManager().getAllCameras();
 		for (auto& cameraData : allCameras)
@@ -360,44 +300,54 @@ namespace BansheeEngine
 			ConvexVolume worldFrustum = camera.getWorldFrustum();
 
 			// Update per-object param buffers and queue render elements
-			for (auto& renderElem : mRenderableElements)
+			for (auto& renderableData : mRenderables)
 			{
-				if (renderElem->handler != nullptr)
-					renderElem->handler->bindPerObjectBuffers(renderElem);
+				RenderableHandlerCore* renderable = renderableData.renderable;
+				RenderableController* controller = renderableData.controller;
+				UINT32 renderableType = renderable->getRenderableType();
+				UINT32 rendererId = renderable->getRendererId();
 
-				if (renderElem->renderableType == RenType_LitTextured)
+				// Update buffers
+				for (auto& renderElem : renderableData.elements)
 				{
-					Matrix4 worldViewProjMatrix = viewProjMatrix * mWorldTransforms[renderElem->id];;
-					mLitTexHandler->updatePerObjectBuffers(renderElem, worldViewProjMatrix);
-				}
+					if (controller != nullptr)
+						controller->bindPerObjectBuffers(renderElem);
 
-				UINT32 numPasses = renderElem->material->getNumPasses();
-				for (UINT32 i = 0; i < numPasses; i++)
-				{
-					SPtr<PassParametersCore> passParams = renderElem->material->getPassParameters(i);
+					if (renderableType == RenType_LitTextured)
+					{
+						Matrix4 worldViewProjMatrix = viewProjMatrix * mWorldTransforms[rendererId];
+						mLitTexHandler->updatePerObjectBuffers(renderElem, worldViewProjMatrix);
+					}
 
-					for (UINT32 j = 0; j < passParams->getNumParams(); j++)
+					UINT32 numPasses = renderElem.material->getNumPasses();
+					for (UINT32 i = 0; i < numPasses; i++)
 					{
-						SPtr<GpuParamsCore> params = passParams->getParamByIdx(j);
-						if (params != nullptr)
-							params->updateHardwareBuffers();
+						SPtr<PassParametersCore> passParams = renderElem.material->getPassParameters(i);
+
+						for (UINT32 j = 0; j < passParams->getNumParams(); j++)
+						{
+							SPtr<GpuParamsCore> params = passParams->getParamByIdx(j);
+							if (params != nullptr)
+								params->updateHardwareBuffers();
+						}
 					}
 				}
 
 				// Do frustum culling
 				// TODO - This is bound to be a bottleneck at some point. When it is ensure that intersect
 				// methods use vector operations, as it is trivial to update them.
-				const Sphere& boundingSphere = mWorldBounds[renderElem->id].getSphere();
+				const Sphere& boundingSphere = mWorldBounds[rendererId].getSphere();
 				if (worldFrustum.intersects(boundingSphere))
 				{
 					// More precise with the box
-					const AABox& boundingBox = mWorldBounds[renderElem->id].getBox();
+					const AABox& boundingBox = mWorldBounds[rendererId].getBox();
 
 					if (worldFrustum.intersects(boundingBox))
 					{
 						float distanceToCamera = (camera.getPosition() - boundingBox.getCenter()).length();
 
-						renderQueue->add(renderElem, distanceToCamera);
+						for (auto& renderElem : renderableData.elements)
+							renderQueue->add(&renderElem, distanceToCamera);
 					}
 				}
 			}
@@ -418,4 +368,100 @@ namespace BansheeEngine
 
 		onCorePostRenderViewport(camera);
 	}
+
+	SPtr<ShaderCore> BansheeRenderer::createDefaultShader()
+	{
+		String rsName = RenderSystem::instance().getName();
+
+		SPtr<GpuProgramCore> vsProgram;
+		SPtr<GpuProgramCore> psProgram;
+
+		if (rsName == RenderSystemDX11)
+		{
+			String vsCode = R"(
+				cbuffer PerObject
+				{
+					float4x4 matWorldViewProj;
+				}
+
+				void vs_main(
+				in float3 inPos : POSITION,
+				out float4 oPosition : SV_Position)
+				{
+					oPosition = mul(matWorldViewProj, float4(inPos.xyz, 1));
+				})";
+
+			String psCode = R"(
+				float4 ps_main() : SV_Target
+				{
+					return float4(0.3f, 0.9f, 0.3f, 1.0f);
+				})";
+
+			vsProgram = GpuProgramCore::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+			psProgram = GpuProgramCore::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_FS_4_0);
+		}
+		else if (rsName == RenderSystemDX9)
+		{
+			String vsCode = R"(
+				 BS_PARAM_BLOCK PerObject { matWorldViewProj }
+				 float4x4 matWorldViewProj;
+
+				 void vs_main(
+				 in float3 inPos : POSITION,
+				 out float4 oPosition : POSITION)
+				 {
+					 oPosition = mul(matWorldViewProj, float4(inPos.xyz, 1));
+				 })";
+
+			String psCode = R"(
+				float4 ps_main() : COLOR0
+				{
+					return float4(0.3f, 0.9f, 0.3f, 1.0f);
+				})";
+
+			vsProgram = GpuProgramCore::create(vsCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+			psProgram = GpuProgramCore::create(psCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_FS_2_0);
+		}
+		else if (rsName == RenderSystemOpenGL)
+		{
+			String vsCode = R"(#version 400
+				uniform PerObject
+				{
+					mat4 matWorldViewProj;
+				};
+
+				in vec3 bs_position;
+
+				void main()
+				{
+					gl_Position = matWorldViewProj * vec4(bs_position.xyz, 1);
+				})";
+
+			String psCode = R"(#version 400
+				out vec4 fragColor;
+
+				void main()
+				{
+					fragColor = vec4(0.3f, 0.9f, 0.3f, 1.0f);
+				})";
+
+			vsProgram = GpuProgramCore::create(vsCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_4_0);
+			psProgram = GpuProgramCore::create(psCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_FS_4_0);
+		}
+
+		PASS_DESC_CORE passDesc;
+		passDesc.vertexProgram = vsProgram;
+		passDesc.fragmentProgram = psProgram;
+
+		SPtr<PassCore> newPass = PassCore::create(passDesc);
+		SPtr<TechniqueCore> newTechnique = TechniqueCore::create(rsName, RendererDefault, { newPass });
+
+		SHADER_DESC shaderDesc;
+		shaderDesc.setParamBlockAttribs("PerObject", true, GPBU_DYNAMIC, RBS_PerObject);
+		shaderDesc.addParameter("matWorldViewProj", "matWorldViewProj", GPDT_MATRIX_4X4, RPS_WorldViewProjTfrm);
+
+		SPtr<ShaderCore> defaultShader = ShaderCore::create("DummyShader", shaderDesc, { newTechnique });
+
+		return defaultShader;
+	}
 }

+ 1 - 1
BansheeRenderer/Source/BsBansheeRendererFactory.cpp

@@ -4,7 +4,7 @@
 
 namespace BansheeEngine
 {
-	RendererPtr BansheeRendererFactory::create()
+	CoreRendererPtr BansheeRendererFactory::create()
 	{
 		return bs_shared_ptr<BansheeRenderer>();
 	}

+ 0 - 5
BansheeSceneManager/Include/BsBansheeSceneManager.h

@@ -27,11 +27,6 @@ namespace BansheeEngine
 		 */
 		const Vector<SceneRenderableData>& getAllRenderables() const { return mRenderables; }
 
-		/**
-		 * @copydoc	SceneManager
-		 */
-		void updateRenderableTransforms();
-
 	private:
 		/**
 		 * @brief	Called by scene objects whenever a new component is added to the scene.

+ 0 - 14
BansheeSceneManager/Source/BsBansheeSceneManager.cpp

@@ -7,20 +7,6 @@
 
 namespace BansheeEngine
 {
-	void BansheeSceneManager::updateRenderableTransforms()
-	{
-		// TODO - Consider a way to make the update faster. Either do it concurrently or
-		// consider organizing renderable matrices in an array for quicker updates
-		//   - I could keep everything in a sequential array but deal with dynamic elements
-		//     but putting them in a slow, normal array. Once the number of dynamic elements
-		//	   goes over some number the hierarchy is re-optimized.
-
-		for(auto& iter : mRenderables)
-		{
-			iter.sceneObject->updateTransformsIfDirty();
-		}
-	}
-
 	void BansheeSceneManager::notifyComponentAdded(const HComponent& component)
 	{
 		if(component->getTypeId() == TID_Camera)

+ 2 - 0
BansheeUtility/Include/BsAABox.h

@@ -136,4 +136,6 @@ namespace BansheeEngine
 		Vector3 mMinimum;
 		Vector3 mMaximum;
 	};
+
+	BS_ALLOW_MEMCPY_SERIALIZATION(AABox);
 }

+ 1 - 1
ExampleProject/Main/Main.cpp

@@ -28,7 +28,7 @@
 #include "BsSceneObject.h"
 #include "BsCoreThread.h"
 #include "BsProfilerOverlay.h"
-#include "BsRenderer.h"
+#include "BsCoreRenderer.h"
 #include "BsResources.h"
 
 #include "CameraFlyer.h"

+ 30 - 9
TODO.txt

@@ -1,15 +1,14 @@
 --------- ALL LONG TERM TASKS / FIXES BELONG TO GOOGLE DOCS: ImplementationTODO OR PossibleImprovements ----------
 
- - Make RenderableHandler a CoreObject and remove RenderableProxy
-   - BansheeRenderer::mDeletedRenderableProxies is holding references to core objects
+Renderable TODO:
 
-GpuParams refactor:
-
-I need to ensure renderer buffers get set properly after GpuParams are synced
- - This used to up in updateMaterialProxy along with updating dirty params but since syncing
-   is now internal to GpuParams I need to figure out a better way of doing it.
-   (In case user overrides Renderer buffers)
-    - Likely just an extra field on GPuParamsCore
+ - Restore RenderableElement (it was in RenderableProxy files)
+ - I need to update Renderable with world transform
+   - I've removed SceneObject dirty flags so that is no longer done anywhere
+   - RenderableHandler should keep track of world transform
+     - Also I should keep track of SceneObject active state to hide/show the object as needed
+   - Make sure to call gSceneManager().updateRenderableTransforms(); BEFORE syncing
+     and not like now when it's called in renderAll after sync
 
 Disallow CoreObject creation from core thread
  - Add asserts in CoreObject::destroy and CoreObject::initialize
@@ -20,6 +19,28 @@ Refactor RenderSystem and CoreThreadAccessor methods (move them to RenderSystem
  New issues:
   - Since Mesh refactor when I select/deselect a gizmo the entire render texture flashes white for one frame (might be related to RT refactor instead)
 
+HANDLE RESOURCE LOADING AND CORE OBJECT SYNC:
+How to handle RenderableHandler (and other types) that reference resource handles? What if the handle is invalid and in the process 
+of being loaded? The core thread needs to be notified when loading is complete so it retrieves the proper Core object.
+ - Add getResourceDependencies() and markDependenciesDirty() to CoreObject
+   - CoreObjectManager then keeps track of all resource handles and receives notifications from 
+     Resources when a resource finishes loading or gets modified due to reimport
+   - When such notification is issued CoreObjectManager performs a lookup among its resource handles to find 
+     CoreObject (store CoreObject as a raw pointer or an ID, but make sure to handle deletion of CoreObject properly in either case)
+   - That object then receives notifyResourceUpdated(const HResource& resource) which by default makes the object dirty
+ - This can then be used for resource hot-swap functionality as well
+
+BETTER SYNC IN GENERAL:
+ - Extend CoreObject with getDependencies() that returns all child CoreObjects
+ - Then when performing syncToCore I can iterate through all dependencies and sync them all
+   - e.g. Material references GpuParams which reference GpuParamBlockBuffer, all of which require syncing
+ - Add a method similar to syncToCore that just appends CoreSyncData to a larger object, so many objects
+   can be synced at once.
+ - Get rid of syncUpload/syncDownload methods and replace them with:
+   - Custom sync in BansheeRenderer that iterates over all Renderable and Camera objects and syncs the dirty ones
+     - Will likely want to remove core->sim sync with mesh bounds and other similar core->sync transfers
+   - Custom sync for RenderTargets that happens both ways, likely handled by RenderableTargetManager
+
 -----------------
 
 Port SceneCameraController to C#