Browse Source

A lot more renderer and proxy refactoring

Marko Pintera 11 years ago
parent
commit
97744d0baf
37 changed files with 534 additions and 524 deletions
  1. 2 5
      BansheeCore/BansheeCore.vcxproj
  2. 5 14
      BansheeCore/BansheeCore.vcxproj.filters
  3. 5 2
      BansheeCore/Include/BsCorePrerequisites.h
  4. 0 17
      BansheeCore/Include/BsDefaultRenderQueue.h
  5. 7 0
      BansheeCore/Include/BsGpuResource.h
  6. 4 39
      BansheeCore/Include/BsMaterial.h
  7. 44 0
      BansheeCore/Include/BsMaterialProxy.h
  8. 23 7
      BansheeCore/Include/BsMesh.h
  9. 36 4
      BansheeCore/Include/BsMeshBase.h
  10. 18 0
      BansheeCore/Include/BsMeshProxy.h
  11. 0 99
      BansheeCore/Include/BsMeshRenderData.h
  12. 0 23
      BansheeCore/Include/BsRenderOperation.h
  13. 15 13
      BansheeCore/Include/BsRenderQueue.h
  14. 4 6
      BansheeCore/Include/BsRenderableProxy.h
  15. 6 5
      BansheeCore/Include/BsSceneObject.h
  16. 2 2
      BansheeCore/Include/BsShader.h
  17. 6 11
      BansheeCore/Include/BsTransientMesh.h
  18. 1 0
      BansheeCore/Source/BsCoreThreadAccessor.cpp
  19. 0 26
      BansheeCore/Source/BsDefaultRenderQueue.cpp
  20. 4 4
      BansheeCore/Source/BsMaterial.cpp
  21. 45 28
      BansheeCore/Source/BsMesh.cpp
  22. 2 2
      BansheeCore/Source/BsMeshBase.cpp
  23. 0 14
      BansheeCore/Source/BsMeshHeap.cpp
  24. 0 55
      BansheeCore/Source/BsMeshRenderData.cpp
  25. 30 10
      BansheeCore/Source/BsRenderQueue.cpp
  26. 1 2
      BansheeCore/Source/BsRenderableProxy.cpp
  27. 2 2
      BansheeCore/Source/BsSceneObject.cpp
  28. 12 7
      BansheeCore/Source/BsTransientMesh.cpp
  29. 41 6
      BansheeEngine/Include/BsCamera.h
  30. 2 2
      BansheeEngine/Include/BsRenderable.h
  31. 5 0
      BansheeEngine/Include/BsSceneManager.h
  32. 26 9
      BansheeEngine/Source/BsCamera.cpp
  33. 9 3
      BansheeEngine/Source/BsRenderable.cpp
  34. 18 12
      BansheeRenderer/Include/BsBansheeRenderer.h
  35. 134 73
      BansheeRenderer/Source/BsBansheeRenderer.cpp
  36. 2 0
      BansheeSceneManager/Source/BsBansheeSceneManager.cpp
  37. 23 22
      Renderer.txt

+ 2 - 5
BansheeCore/BansheeCore.vcxproj

@@ -274,7 +274,8 @@
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="Include\BsCameraProxy.h" />
     <ClInclude Include="Include\BsCameraProxy.h" />
     <ClInclude Include="Include\BsDrawList.h" />
     <ClInclude Include="Include\BsDrawList.h" />
-    <ClInclude Include="Include\BsMeshRenderData.h" />
+    <ClInclude Include="Include\BsMaterialProxy.h" />
+    <ClInclude Include="Include\BsMeshProxy.h" />
     <ClInclude Include="Include\BsRenderableProxy.h" />
     <ClInclude Include="Include\BsRenderableProxy.h" />
     <ClInclude Include="Include\BsRendererParams.h" />
     <ClInclude Include="Include\BsRendererParams.h" />
     <ClInclude Include="Include\BsRenderStats.h" />
     <ClInclude Include="Include\BsRenderStats.h" />
@@ -282,7 +283,6 @@
     <ClInclude Include="Include\BsBindableGpuParams.h" />
     <ClInclude Include="Include\BsBindableGpuParams.h" />
     <ClInclude Include="Include\BsCoreThread.h" />
     <ClInclude Include="Include\BsCoreThread.h" />
     <ClInclude Include="Include\BsProfilerCPU.h" />
     <ClInclude Include="Include\BsProfilerCPU.h" />
-    <ClInclude Include="Include\BsDefaultRenderQueue.h" />
     <ClInclude Include="Include\BsDeferredCallManager.h" />
     <ClInclude Include="Include\BsDeferredCallManager.h" />
     <ClInclude Include="Include\BsDrawOps.h" />
     <ClInclude Include="Include\BsDrawOps.h" />
     <ClInclude Include="Include\BsEventQuery.h" />
     <ClInclude Include="Include\BsEventQuery.h" />
@@ -311,7 +311,6 @@
     <ClInclude Include="Include\BsPlatform.h" />
     <ClInclude Include="Include\BsPlatform.h" />
     <ClInclude Include="Include\BsProfilingManager.h" />
     <ClInclude Include="Include\BsProfilingManager.h" />
     <ClInclude Include="Include\BsQueryManager.h" />
     <ClInclude Include="Include\BsQueryManager.h" />
-    <ClInclude Include="Include\BsRenderOperation.h" />
     <ClInclude Include="Include\BsRenderQueue.h" />
     <ClInclude Include="Include\BsRenderQueue.h" />
     <ClInclude Include="Include\BsResourceManifest.h" />
     <ClInclude Include="Include\BsResourceManifest.h" />
     <ClInclude Include="Include\BsResourceManifestRTTI.h" />
     <ClInclude Include="Include\BsResourceManifestRTTI.h" />
@@ -426,9 +425,7 @@
     <ClCompile Include="Source\BsCameraProxy.cpp" />
     <ClCompile Include="Source\BsCameraProxy.cpp" />
     <ClCompile Include="Source\BsCoreThread.cpp" />
     <ClCompile Include="Source\BsCoreThread.cpp" />
     <ClCompile Include="Source\BsDrawList.cpp" />
     <ClCompile Include="Source\BsDrawList.cpp" />
-    <ClCompile Include="Source\BsMeshRenderData.cpp" />
     <ClCompile Include="Source\BsProfilerCPU.cpp" />
     <ClCompile Include="Source\BsProfilerCPU.cpp" />
-    <ClCompile Include="Source\BsDefaultRenderQueue.cpp" />
     <ClCompile Include="Source\BsDeferredCallManager.cpp" />
     <ClCompile Include="Source\BsDeferredCallManager.cpp" />
     <ClCompile Include="Source\BsDrawOps.cpp" />
     <ClCompile Include="Source\BsDrawOps.cpp" />
     <ClCompile Include="Source\BsEventQuery.cpp" />
     <ClCompile Include="Source\BsEventQuery.cpp" />

+ 5 - 14
BansheeCore/BansheeCore.vcxproj.filters

@@ -414,9 +414,6 @@
     <ClInclude Include="Include\BsRenderQueue.h">
     <ClInclude Include="Include\BsRenderQueue.h">
       <Filter>Header Files\Renderer</Filter>
       <Filter>Header Files\Renderer</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsRenderOperation.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
     <ClInclude Include="Include\BsRendererManager.h">
     <ClInclude Include="Include\BsRendererManager.h">
       <Filter>Header Files\Renderer</Filter>
       <Filter>Header Files\Renderer</Filter>
     </ClInclude>
     </ClInclude>
@@ -426,9 +423,6 @@
     <ClInclude Include="Include\BsRenderer.h">
     <ClInclude Include="Include\BsRenderer.h">
       <Filter>Header Files\Renderer</Filter>
       <Filter>Header Files\Renderer</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsDefaultRenderQueue.h">
-      <Filter>Header Files\Renderer</Filter>
-    </ClInclude>
     <ClInclude Include="Include\Win32\BsWin32FolderMonitor.h">
     <ClInclude Include="Include\Win32\BsWin32FolderMonitor.h">
       <Filter>Header Files\Platform</Filter>
       <Filter>Header Files\Platform</Filter>
     </ClInclude>
     </ClInclude>
@@ -525,10 +519,13 @@
     <ClInclude Include="Include\BsDrawList.h">
     <ClInclude Include="Include\BsDrawList.h">
       <Filter>Header Files\Renderer</Filter>
       <Filter>Header Files\Renderer</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsMeshRenderData.h">
+    <ClInclude Include="Include\BsRendererParams.h">
       <Filter>Header Files\Renderer</Filter>
       <Filter>Header Files\Renderer</Filter>
     </ClInclude>
     </ClInclude>
-    <ClInclude Include="Include\BsRendererParams.h">
+    <ClInclude Include="Include\BsMeshProxy.h">
+      <Filter>Header Files\Renderer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsMaterialProxy.h">
       <Filter>Header Files\Renderer</Filter>
       <Filter>Header Files\Renderer</Filter>
     </ClInclude>
     </ClInclude>
   </ItemGroup>
   </ItemGroup>
@@ -749,9 +746,6 @@
     <ClCompile Include="Source\BsVideoModeInfo.cpp">
     <ClCompile Include="Source\BsVideoModeInfo.cpp">
       <Filter>Source Files\RenderSystem</Filter>
       <Filter>Source Files\RenderSystem</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\BsDefaultRenderQueue.cpp">
-      <Filter>Source Files\Renderer</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsRenderer.cpp">
     <ClCompile Include="Source\BsRenderer.cpp">
       <Filter>Source Files\Renderer</Filter>
       <Filter>Source Files\Renderer</Filter>
     </ClCompile>
     </ClCompile>
@@ -839,9 +833,6 @@
     <ClCompile Include="Source\BsCameraProxy.cpp">
     <ClCompile Include="Source\BsCameraProxy.cpp">
       <Filter>Source Files\Renderer</Filter>
       <Filter>Source Files\Renderer</Filter>
     </ClCompile>
     </ClCompile>
-    <ClCompile Include="Source\BsMeshRenderData.cpp">
-      <Filter>Source Files\Renderer</Filter>
-    </ClCompile>
     <ClCompile Include="Source\BsRendererParams.cpp">
     <ClCompile Include="Source\BsRendererParams.cpp">
       <Filter>Source Files\Renderer</Filter>
       <Filter>Source Files\Renderer</Filter>
     </ClCompile>
     </ClCompile>

+ 5 - 2
BansheeCore/Include/BsCorePrerequisites.h

@@ -132,9 +132,10 @@ namespace BansheeEngine
 	class VideoModeInfo;
 	class VideoModeInfo;
 	class RenderableProxy;
 	class RenderableProxy;
 	class RenderableElement;
 	class RenderableElement;
-	class MeshRenderData;
 	class CameraProxy;
 	class CameraProxy;
 	class MaterialProxy;
 	class MaterialProxy;
+	class MaterialProxyPass;
+	class MeshProxy;
 	class DrawList;
 	class DrawList;
 	// Asset import
 	// Asset import
 	class SpecificImporter;
 	class SpecificImporter;
@@ -231,7 +232,9 @@ namespace BansheeEngine
 	typedef std::shared_ptr<VideoModeInfo> VideoModeInfoPtr;
 	typedef std::shared_ptr<VideoModeInfo> VideoModeInfoPtr;
 	typedef std::shared_ptr<DrawList> DrawListPtr;
 	typedef std::shared_ptr<DrawList> DrawListPtr;
 	typedef std::shared_ptr<RenderQueue> RenderQueuePtr;
 	typedef std::shared_ptr<RenderQueue> RenderQueuePtr;
-	typedef std::shared_ptr<MeshRenderData> MeshRenderDataPtr;
+	typedef std::shared_ptr<CameraProxy> CameraProxyPtr;
+	typedef std::shared_ptr<MaterialProxy> MaterialProxyPtr;
+	typedef std::shared_ptr<MeshProxy> MeshProxyPtr;
 }
 }
 
 
 /************************************************************************/
 /************************************************************************/

+ 0 - 17
BansheeCore/Include/BsDefaultRenderQueue.h

@@ -1,17 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRenderQueue.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	Default implementation of a render queue. Just passes
-	 * 			through elements unmodified as they were queued in.
-	 */
-	class BS_CORE_EXPORT DefaultRenderQueue : public RenderQueue
-	{
-	public:
-		void sort();
-	};
-}

+ 7 - 0
BansheeCore/Include/BsGpuResource.h

@@ -14,6 +14,13 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GpuResource : public Resource
 	class BS_CORE_EXPORT GpuResource : public Resource
 	{
 	{
 	public:
 	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
 		 * @brief	Updates a part of the current resource with the provided data. Specific resource
 		 * 			implementations provide a way to retrieve a subresource index.
 		 * 			implementations provide a way to retrieve a subresource index.

+ 4 - 39
BansheeCore/Include/BsMaterial.h

@@ -3,6 +3,7 @@
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "BsResource.h"
 #include "BsResource.h"
 #include "BsGpuParam.h"
 #include "BsGpuParam.h"
+#include "BsMaterialProxy.h"
 #include "BsVector2.h"
 #include "BsVector2.h"
 #include "BsVector3.h"
 #include "BsVector3.h"
 #include "BsVector4.h"
 #include "BsVector4.h"
@@ -378,45 +379,9 @@ namespace BansheeEngine
 		/* 								CORE PROXY                      		*/
 		/* 								CORE PROXY                      		*/
 		/************************************************************************/
 		/************************************************************************/
 
 
-		/**
-		 * @brief	Contains material information as seen by the core thread.
-		 *			(Used for rendering and such.)
-		 */
-		struct BS_CORE_EXPORT CoreProxy
-		{
-			struct BS_CORE_EXPORT PassData
-			{
-				HGpuProgram vertexProg;
-				HGpuProgram fragmentProg;
-				HGpuProgram geometryProg;
-				HGpuProgram hullProg;
-				HGpuProgram domainProg;
-				HGpuProgram computeProg;
-
-				GpuParamsPtr vertexProgParams;
-				GpuParamsPtr fragmentProgParams;
-				GpuParamsPtr geometryProgParams;
-				GpuParamsPtr hullProgParams;
-				GpuParamsPtr domainProgParams;
-				GpuParamsPtr computeProgParams;
-
-				HBlendState blendState;
-				HRasterizerState rasterizerState;
-				HDepthStencilState depthStencilState;
-				UINT32 stencilRefValue;
-			};
-
-			Vector<PassData> passes;
-			bool separablePasses;
-			UINT32 queuePriority;
-			QueueSortType queueSortType;
-		};
-
-		typedef std::shared_ptr<CoreProxy> CoreProxyPtr;
-
 		/**
 		/**
 		 * @brief	Checks is the core dirty flag set. This is used by external systems 
 		 * @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.
+		 *			to know when internal data has changed and core thread potentially needs to be notified.
 		 *
 		 *
 		 * @note	Sim thread only.
 		 * @note	Sim thread only.
 		 */
 		 */
@@ -438,7 +403,7 @@ namespace BansheeEngine
 		 *			You generally need to update the core thread with a new proxy whenever core 
 		 *			You generally need to update the core thread with a new proxy whenever core 
 		 *			dirty flag is set.
 		 *			dirty flag is set.
 		 */
 		 */
-		CoreProxyPtr _createProxy();
+		MaterialProxyPtr _createProxy();
 	protected:
 	protected:
 		/**
 		/**
 		 * @copydoc	Resource::destroy_internal
 		 * @copydoc	Resource::destroy_internal
@@ -493,7 +458,7 @@ namespace BansheeEngine
 		void throwIfNotInitialized() const;
 		void throwIfNotInitialized() const;
 
 
 		/**
 		/**
-		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
+		 * @brief	Marks the core data as dirty.
 		 */
 		 */
 		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
 		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
 
 

+ 44 - 0
BansheeCore/Include/BsMaterialProxy.h

@@ -0,0 +1,44 @@
+#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;
+
+		GpuParamsPtr vertexProgParams;
+		GpuParamsPtr fragmentProgParams;
+		GpuParamsPtr geometryProgParams;
+		GpuParamsPtr hullProgParams;
+		GpuParamsPtr domainProgParams;
+		GpuParamsPtr computeProgParams;
+
+		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
+	{
+		Vector<MaterialProxyPass> passes;
+		bool separablePasses;
+		UINT32 queuePriority;
+		QueueSortType queueSortType;
+	};
+}

+ 23 - 7
BansheeCore/Include/BsMesh.h

@@ -2,7 +2,6 @@
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "BsMeshBase.h"
 #include "BsMeshBase.h"
-#include "BsMeshRenderData.h"
 #include "BsMeshData.h"
 #include "BsMeshData.h"
 #include "BsVertexData.h"
 #include "BsVertexData.h"
 #include "BsDrawOps.h"
 #include "BsDrawOps.h"
@@ -21,6 +20,16 @@ namespace BansheeEngine
 	public:
 	public:
 		virtual ~Mesh();
 		virtual ~Mesh();
 
 
+		/**
+		 * @copydoc	MeshBase::initialize
+		 */
+		virtual void initialize();
+
+		/**
+		 * @copydoc GpuResource::_writeSubresourceSim
+		 */
+		virtual void _writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer);
+
 		/**
 		/**
 		 * @copydoc GpuResource::writeSubresource
 		 * @copydoc GpuResource::writeSubresource
 		 */
 		 */
@@ -57,14 +66,18 @@ namespace BansheeEngine
 		virtual IndexBufferPtr _getIndexBuffer() const;
 		virtual IndexBufferPtr _getIndexBuffer() const;
 
 
 		/**
 		/**
-		 * @copydoc	MeshBase::_getRenderData
+		 * @brief	Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh.
 		 */
 		 */
-		MeshRenderDataPtr _getRenderData(UINT32 subMeshIdx) { return mRenderData[subMeshIdx]; }
+		static HMesh dummy();
+
+		/************************************************************************/
+		/* 								CORE PROXY                      		*/
+		/************************************************************************/
 
 
 		/**
 		/**
-		 * @brief	Returns a dummy mesh, containing just one triangle. Don't modify the returned mesh.
+		 * @copydoc	MeshBase::_createProxy
 		 */
 		 */
-		static HMesh dummy();
+		MeshProxyPtr _createProxy(UINT32 subMeshIdx);
 
 
 	protected:
 	protected:
 		friend class MeshManager;
 		friend class MeshManager;
@@ -86,8 +99,6 @@ namespace BansheeEngine
 		IndexBufferPtr mIndexBuffer; // Core thread
 		IndexBufferPtr mIndexBuffer; // Core thread
 
 
 		Bounds mBounds; // Core thread
 		Bounds mBounds; // Core thread
-		Vector<MeshRenderDataPtr> mRenderData; // Core thread
-
 		VertexDataDescPtr mVertexDesc; // Immutable
 		VertexDataDescPtr mVertexDesc; // Immutable
 		MeshBufferType mBufferType; // Immutable
 		MeshBufferType mBufferType; // Immutable
 		IndexBuffer::IndexType mIndexType; // Immutable
 		IndexBuffer::IndexType mIndexType; // Immutable
@@ -104,6 +115,11 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void 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.
 		 * @brief	Calculates bounds surrounding the vertices in the provided buffer.
 		 *
 		 *

+ 36 - 4
BansheeCore/Include/BsMeshBase.h

@@ -2,8 +2,10 @@
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "BsGpuResource.h"
 #include "BsGpuResource.h"
+#include "BsBounds.h"
 #include "BsDrawOps.h"
 #include "BsDrawOps.h"
 #include "BsSubMesh.h"
 #include "BsSubMesh.h"
+#include "BsMeshProxy.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -126,18 +128,48 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void _notifyUsedOnGPU() { }
 		virtual void _notifyUsedOnGPU() { }
 
 
+		/************************************************************************/
+		/* 								CORE PROXY                      		*/
+		/************************************************************************/
+
 		/**
 		/**
-		 * @brief	Gets sub-mesh render data. Render data provides a link between a mesh and
-		 *			the renderer and it will be modified by both. It may be modified as mesh 
-		 *			changes occur and as renderer uses the mesh.
+		 * @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.
 		 */
 		 */
-		virtual MeshRenderDataPtr _getRenderData(UINT32 subMeshIdx) = 0;
+		bool _isCoreDirty() const { mCoreDirtyFlags != 0; }
+
+		/**
+		 * @brief	Marks the core dirty flag as clean.
+		 *
+		 * @note	Sim thread only.
+		 */
+		void _markCoreClean() { mCoreDirtyFlags = 0; }
+
+		/**
+		 * @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:
 	protected:
 		Vector<SubMesh> mSubMeshes; // Immutable
 		Vector<SubMesh> mSubMeshes; // Immutable
 		UINT32 mNumVertices; // Immutable
 		UINT32 mNumVertices; // Immutable
 		UINT32 mNumIndices; // Immutable
 		UINT32 mNumIndices; // Immutable
 
 
+		UINT32 mCoreDirtyFlags;
+
 		/************************************************************************/
 		/************************************************************************/
 		/* 								SERIALIZATION                      		*/
 		/* 								SERIALIZATION                      		*/
 		/************************************************************************/
 		/************************************************************************/

+ 18 - 0
BansheeCore/Include/BsMeshProxy.h

@@ -0,0 +1,18 @@
+#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
+	{
+		MeshPtr mesh;
+		SubMesh subMesh;
+		Bounds bounds;
+	};
+}

+ 0 - 99
BansheeCore/Include/BsMeshRenderData.h

@@ -1,99 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsRenderableProxy.h"
-#include "BsBounds.h"
-#include "BsSubMesh.h"
-
-namespace BansheeEngine
-{
-	/**
-	* Mesh render data provides a link between a Mesh and a Renderer. It may be modified
-	* by both as changes occur and as the mesh is used in the renderer. Essentially it allows
-	* the two to communicate without knowing about each other.
-	*/
-	class BS_CORE_EXPORT MeshRenderData
-	{
-	public:
-		/**
-		 * Creates a new empty render data.
-		 */
-		MeshRenderData() {}
-
-		/**
-		 * Creates render render data pointing to the specified vertex and index buffer, referencing
-		 * the provided sub-mesh index range.
-		 */
-		MeshRenderData(const std::shared_ptr<VertexData>& vertexData, const IndexBufferPtr& indexBuffer, 
-			const SubMesh& subMesh, UINT32 vertexOffset, std::function<void()> usedOnGPUcallback);
-
-		/**
-		 * Registers a new renderable proxy that references this mesh.
-		 */
-		void addRenderableProxy(RenderableElement* proxy);
-
-		/**
-		 * Unregisters a renderable proxy that references this mesh.
-		 */
-		void removeRenderableProxy(RenderableElement* proxy);
-
-		/**
-		 * Update mesh local bounds with the new provided bounds.
-		 */
-		void updateBounds(const Bounds& bounds);
-
-		/**
-		 * Get mesh local bounds.
-		 */
-		Bounds getBounds() const { return mBounds; }
-
-		/**
-		 * Set new internal buffers and a sub-mesh range.
-		 */
-		void updateData(const std::shared_ptr<VertexData>& vertexData, const IndexBufferPtr& indexBuffer, 
-			const SubMesh& subMesh, UINT32 vertexOffset);
-
-		/**
-		 * Get vertex buffers.
-		 */
-		std::shared_ptr<VertexData> getVertexData() const { return mVertexData; }
-
-		/**
-		 * Get index buffer.
-		 */
-		IndexBufferPtr getIndexBuffer() const { return mIndexBuffer; }
-
-		/**
-		 * Get sub-mesh range to render.
-		 */
-		SubMesh getSubMesh() const { return mSubMesh; }
-
-		/**
-		 * Get vertex offset;
-		 */
-		UINT32 getVertexOffset() const { return mVertexOffset; }
-
-		/**
-		 * Should be called by the renderer whenever the buffers get queued for use on the GPU.
-		 */
-		void notifyUsedOnGPU() const;
-
-		/**
-		 * Marks the render data as invalid, usually when the parent mesh was destroyed.
-		 */
-		void _markAsInvalid();
-
-	private:
-		friend class Mesh;
-
-		std::shared_ptr<VertexData> mVertexData;
-		IndexBufferPtr mIndexBuffer;
-		SubMesh mSubMesh;
-		UINT32 mVertexOffset;
-
-		Vector<RenderableElement*> mRenderableProxies;
-		Bounds mBounds;
-		std::function<void()> mUsedOnGPUCallback;
-		bool mIsMeshValid;
-	};
-}

+ 0 - 23
BansheeCore/Include/BsRenderOperation.h

@@ -1,23 +0,0 @@
-#pragma once
-
-#include "BsCorePrerequisites.h"
-#include "BsMaterial.h"
-#include "BsDrawOps.h"
-#include "BsVector3.h"
-
-namespace BansheeEngine 
-{
-	/**
-	 * @brief	A render operation describing everything we need for rendering
-	 * 			a single object.
-	 */
-	struct BS_CORE_EXPORT RenderOperation
-	{
-		RenderOperation()
-		{ }
-
-		Material::CoreProxyPtr material;
-		MeshRenderDataPtr mesh;
-		Vector3 worldPosition;
-	};
-}

+ 15 - 13
BansheeCore/Include/BsRenderQueue.h

@@ -1,21 +1,23 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
-#include "BsMaterial.h"
+#include "BsMaterialProxy.h"
+#include "BsMeshProxy.h"
 
 
 namespace BansheeEngine 
 namespace BansheeEngine 
 {
 {
 	/**
 	/**
-	 * @brief	Slightly more fine grained version of RenderOperation, as each pass
-	 * 			is specified as an individual operation. Used for sorting within the RenderQueue.
+	 * @brief	Contains data needed for performing a single rendering pass.
 	 */
 	 */
-	struct BS_CORE_EXPORT SortedRenderOp
+	struct BS_CORE_EXPORT RenderQueueElement
 	{
 	{
-		SortedRenderOp()
-			:baseOperation(nullptr), passIdx(0)
+		RenderQueueElement()
+			:passIdx(0)
 		{ }
 		{ }
 
 
-		const RenderOperation* baseOperation;
+		MaterialProxyPtr material;
+		MeshProxyPtr mesh;
+		Vector3 worldPosition;
 		UINT32 passIdx;
 		UINT32 passIdx;
 	};
 	};
 
 
@@ -33,7 +35,7 @@ namespace BansheeEngine
 	public:
 	public:
 		RenderQueue();
 		RenderQueue();
 
 
-		void add(const Material::CoreProxyPtr& material, const MeshRenderDataPtr& mesh, const Vector3& worldPosForSort);
+		void add(const MaterialProxyPtr& material, const MeshProxyPtr& mesh, const Vector3& worldPosForSort);
 
 
 		/**
 		/**
 		 * @brief	Clears all render operations from the queue.
 		 * @brief	Clears all render operations from the queue.
@@ -43,16 +45,16 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Sorts all the render operations using user-defined rules.
 		 * @brief	Sorts all the render operations using user-defined rules.
 		 */
 		 */
-		virtual void sort() = 0;
+		virtual void sort();
 
 
 		/**
 		/**
-		 * @brief	Returns a list of sorted render operations. Caller must ensure
+		 * @brief	Returns a list of sorted render elements. Caller must ensure
 		 * 			"sort" is called before this method.
 		 * 			"sort" is called before this method.
 		 */
 		 */
-		const Vector<SortedRenderOp>& getSortedRenderOps() const;
+		const Vector<RenderQueueElement>& getSortedElements() const;
 
 
 	protected:
 	protected:
-		Vector<RenderOperation> mRenderOperations;
-		Vector<SortedRenderOp> mSortedRenderOps;
+		Vector<RenderQueueElement> mRenderElements;
+		Vector<RenderQueueElement> mSortedRenderElements;
 	};
 	};
 }
 }

+ 4 - 6
BansheeCore/Include/BsRenderableProxy.h

@@ -1,7 +1,8 @@
 #pragma once
 #pragma once
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
-#include "BsMaterial.h"
+#include "BsMaterialProxy.h"
+#include "BsMeshProxy.h"
 #include "BsBounds.h"
 #include "BsBounds.h"
 #include "BsMatrix4.h"
 #include "BsMatrix4.h"
 
 
@@ -13,16 +14,13 @@ namespace BansheeEngine
 	public:
 	public:
 		RenderableElement();
 		RenderableElement();
 
 
-		void markBoundsDirty() { mBoundsDirty = true; }
-		void markBoundsClean() { mBoundsDirty = false; }
-		bool getBoundsDirty() const { return mBoundsDirty; }
 		Bounds calculateWorldBounds();
 		Bounds calculateWorldBounds();
 
 
 		UINT32 id;
 		UINT32 id;
 		Matrix4 worldTransform;
 		Matrix4 worldTransform;
 
 
-		MeshRenderDataPtr mesh;
-		Material::CoreProxyPtr material;
+		MeshProxyPtr mesh;
+		MaterialProxyPtr material;
 
 
 		UINT64 layer;
 		UINT64 layer;
 
 

+ 6 - 5
BansheeCore/Include/BsSceneObject.h

@@ -196,14 +196,15 @@ namespace BansheeEngine
 		void updateTransformsIfDirty();
 		void updateTransformsIfDirty();
 
 
 		/**
 		/**
-		 * @brief	Called by the renderer to check if the transform changed in any way.
+		 * @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 _isRenderDataUpToDate() const { return mIsRenderDataUpToDate; }
+		bool _isCoreDirty() const { mIsCoreDirtyFlags != 0; }
 
 
 		/**
 		/**
-		 * @brief	Called by the renderer to notify the scene object that render data has been updated.
+		 * @brief	Marks the core dirty flag as clean.
 		 */
 		 */
-		void _markRenderDataUpToDate() { mIsRenderDataUpToDate = true; }
+		void _markCoreClean() { mIsCoreDirtyFlags = 0; }
 
 
 	private:
 	private:
 		Vector3 mPosition;
 		Vector3 mPosition;
@@ -220,7 +221,7 @@ namespace BansheeEngine
 		mutable Matrix4 mCachedWorldTfrm;
 		mutable Matrix4 mCachedWorldTfrm;
 		mutable bool mIsCachedWorldTfrmUpToDate;
 		mutable bool mIsCachedWorldTfrmUpToDate;
 
 
-		mutable bool mIsRenderDataUpToDate;
+		mutable UINT32 mIsCoreDirtyFlags;
 
 
 		/**
 		/**
 		 * @brief	Marks the transform as dirty so that we know to update
 		 * @brief	Marks the transform as dirty so that we know to update

+ 2 - 2
BansheeCore/Include/BsShader.h

@@ -243,7 +243,7 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * @brief	Checks is the core dirty flag set. This is used by external systems 
 		 * @brief	Checks is the core dirty flag set. This is used by external systems 
-		 *			to know  when internal data has changed;
+		 *			to know when internal data has changed and core thread potentially needs to be notified.
 		 */
 		 */
 		bool _isCoreDirty() const { return mCoreDirtyFlags != 0; }
 		bool _isCoreDirty() const { return mCoreDirtyFlags != 0; }
 
 
@@ -266,7 +266,7 @@ namespace BansheeEngine
 		Shader(const String& name);
 		Shader(const String& name);
 
 
 		/**
 		/**
-		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
+		 * @brief	Marks the core data as dirty.
 		 */
 		 */
 		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
 		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
 
 

+ 6 - 11
BansheeCore/Include/BsTransientMesh.h

@@ -2,7 +2,6 @@
 
 
 #include "BsCorePrerequisites.h"
 #include "BsCorePrerequisites.h"
 #include "BsMeshBase.h"
 #include "BsMeshBase.h"
-#include "BsMeshRenderData.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -41,11 +40,6 @@ namespace BansheeEngine
 		 */
 		 */
 		IndexBufferPtr _getIndexBuffer() const;
 		IndexBufferPtr _getIndexBuffer() const;
 
 
-		/**
-		 * @copydoc	MeshBase::_getRenderData
-		 */
-		MeshRenderDataPtr _getRenderData(UINT32 subMeshIdx) { return mRenderData; }
-
 		/**
 		/**
 		 * @brief	Returns the ID that uniquely identifies this mesh in the parent heap.
 		 * @brief	Returns the ID that uniquely identifies this mesh in the parent heap.
 		 */
 		 */
@@ -66,11 +60,14 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void _notifyUsedOnGPU();
 		virtual void _notifyUsedOnGPU();
 
 
+		/************************************************************************/
+		/* 								CORE PROXY                      		*/
+		/************************************************************************/
+
 		/**
 		/**
-		 * @brief	Called by parent MeshHeap when notable changes that invalidate
-		 *			the render data happen.
+		 * @copydoc	MeshBase::_createProxy
 		 */
 		 */
-		void _updateRenderData();
+		MeshProxyPtr _createProxy(UINT32 subMeshIdx);
 
 
 	protected:
 	protected:
 		friend class MeshHeap;
 		friend class MeshHeap;
@@ -92,7 +89,5 @@ namespace BansheeEngine
 		bool mIsDestroyed;
 		bool mIsDestroyed;
 		MeshHeapPtr mParentHeap;
 		MeshHeapPtr mParentHeap;
 		UINT32 mId;
 		UINT32 mId;
-
-		MeshRenderDataPtr mRenderData;
 	};
 	};
 }
 }

+ 1 - 0
BansheeCore/Source/BsCoreThreadAccessor.cpp

@@ -148,6 +148,7 @@ namespace BansheeEngine
 	{
 	{
 		data->_lock();
 		data->_lock();
 
 
+		resource->_writeSubresourceSim(subresourceIdx, *data, discardEntireBuffer);
 		return mCommandQueue->queueReturn(std::bind(&RenderSystem::writeSubresource, RenderSystem::instancePtr(), resource, 
 		return mCommandQueue->queueReturn(std::bind(&RenderSystem::writeSubresource, RenderSystem::instancePtr(), resource, 
 			subresourceIdx, data, discardEntireBuffer, std::placeholders::_1));
 			subresourceIdx, data, discardEntireBuffer, std::placeholders::_1));
 	}
 	}

+ 0 - 26
BansheeCore/Source/BsDefaultRenderQueue.cpp

@@ -1,26 +0,0 @@
-#include "BsDefaultRenderQueue.h"
-#include "BsRenderOperation.h"
-#include "BsMaterial.h"
-
-namespace BansheeEngine
-{
-	void DefaultRenderQueue::sort()
-	{
-		// Just pass-through for now
-		for(auto& renderOp : mRenderOperations)
-		{
-			UINT32 numPasses = (UINT32)renderOp.material->passes.size();
-			for(UINT32 i = 0; i < numPasses; i++)
-			{
-				mSortedRenderOps.push_back(SortedRenderOp());
-
-				SortedRenderOp& sortedOp = mSortedRenderOps.back();
-				sortedOp.baseOperation = &renderOp;
-				sortedOp.passIdx = i;
-			}
-		}
-
-		// TODO - Actually do some sorting. Use material options to sort (isTransparent, isOverlay(need to add this), etc.)
-		// Note: When sorting make sure not to change order of unsorted elements. Some outside managers (like overlay and GUI) will provide render ops which are already sorted
-	}
-}

+ 4 - 4
BansheeCore/Source/BsMaterial.cpp

@@ -713,11 +713,11 @@ namespace BansheeEngine
 			mShader->_markCoreClean();
 			mShader->_markCoreClean();
 	}
 	}
 
 
-	Material::CoreProxyPtr Material::_createProxy()
+	MaterialProxyPtr Material::_createProxy()
 	{
 	{
 		throwIfNotInitialized();
 		throwIfNotInitialized();
 
 
-		CoreProxyPtr proxy = bs_shared_ptr<CoreProxy>();
+		MaterialProxyPtr proxy = bs_shared_ptr<MaterialProxy>();
 
 
 		UINT32 numPasses = mShader->getBestTechnique()->getNumPasses();
 		UINT32 numPasses = mShader->getBestTechnique()->getNumPasses();
 		for (UINT32 i = 0; i < numPasses; i++)
 		for (UINT32 i = 0; i < numPasses; i++)
@@ -725,8 +725,8 @@ namespace BansheeEngine
 			PassParametersPtr params = mParametersPerPass[i];
 			PassParametersPtr params = mParametersPerPass[i];
 			PassPtr pass = mShader->getBestTechnique()->getPass(i);
 			PassPtr pass = mShader->getBestTechnique()->getPass(i);
 
 
-			proxy->passes.push_back(CoreProxy::PassData());
-			CoreProxy::PassData& passData = proxy->passes.back();
+			proxy->passes.push_back(MaterialProxyPass());
+			MaterialProxyPass& passData = proxy->passes.back();
 
 
 			if (pass->hasVertexProgram())
 			if (pass->hasVertexProgram())
 			{
 			{

+ 45 - 28
BansheeCore/Source/BsMesh.cpp

@@ -55,8 +55,13 @@ namespace BansheeEngine
 
 
 	Mesh::~Mesh()
 	Mesh::~Mesh()
 	{
 	{
-		for (auto& renderData : mRenderData)
-			renderData->_markAsInvalid();
+
+	}
+
+	void Mesh::_writeSubresourceSim(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
+	{
+		const MeshData& meshData = static_cast<const MeshData&>(data);
+		updateBounds(meshData);
 	}
 	}
 
 
 	void Mesh::writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
 	void Mesh::writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
@@ -157,26 +162,6 @@ namespace BansheeEngine
 				vertexBuffer->writeData(0, bufferSize, srcVertBufferData, discardEntireBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
 				vertexBuffer->writeData(0, bufferSize, srcVertBufferData, discardEntireBuffer ? BufferWriteType::Discard : BufferWriteType::Normal);
 			}
 			}
 		}
 		}
-
-		// Update bounds
-		VertexDataDescPtr vertexDesc = meshData.getVertexDesc();
-		for (UINT32 i = 0; i < vertexDesc->getNumElements(); i++)
-		{
-			const VertexElement& curElement = vertexDesc->getElement(i);
-
-			if (curElement.getSemantic() != VES_POSITION || (curElement.getType() != VET_FLOAT3 && curElement.getType() != VET_FLOAT4))
-				continue;
-
-			UINT8* data = meshData.getElementData(curElement.getSemantic(), curElement.getSemanticIdx(), curElement.getStreamIdx());
-			UINT32 stride = vertexDesc->getVertexStride(curElement.getStreamIdx());
-
-			mBounds = calculateBounds((UINT8*)data, mTempInitialMeshData->getNumVertices(), stride);
-
-			for (auto& renderData : mRenderData)
-				renderData->updateBounds(mBounds);
-
-			break;
-		}
 	}
 	}
 
 
 	void Mesh::readSubresource(UINT32 subresourceIdx, GpuResourceData& data)
 	void Mesh::readSubresource(UINT32 subresourceIdx, GpuResourceData& data)
@@ -285,6 +270,14 @@ namespace BansheeEngine
 		return mIndexBuffer;
 		return mIndexBuffer;
 	}
 	}
 
 
+	void Mesh::initialize()
+	{
+		if (mTempInitialMeshData != nullptr)
+		{
+			updateBounds(*mTempInitialMeshData);
+		}
+	}
+
 	void Mesh::initialize_internal()
 	void Mesh::initialize_internal()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
@@ -318,12 +311,6 @@ namespace BansheeEngine
 			mTempInitialMeshData = nullptr;
 			mTempInitialMeshData = nullptr;
 		}
 		}
 
 
-		for (auto& subMesh : mSubMeshes)
-		{
-			mRenderData.push_back(bs_shared_ptr<MeshRenderData>(mVertexData, mIndexBuffer, subMesh, 0, nullptr));
-
-		}
-
 		Resource::initialize_internal();
 		Resource::initialize_internal();
 	}
 	}
 
 
@@ -334,6 +321,26 @@ namespace BansheeEngine
 		Resource::destroy_internal();
 		Resource::destroy_internal();
 	}
 	}
 
 
+	void Mesh::updateBounds(const MeshData& meshData)
+	{
+		VertexDataDescPtr vertexDesc = meshData.getVertexDesc();
+		for (UINT32 i = 0; i < vertexDesc->getNumElements(); i++)
+		{
+			const VertexElement& curElement = vertexDesc->getElement(i);
+
+			if (curElement.getSemantic() != VES_POSITION || (curElement.getType() != VET_FLOAT3 && curElement.getType() != VET_FLOAT4))
+				continue;
+
+			UINT8* data = meshData.getElementData(curElement.getSemantic(), curElement.getSemanticIdx(), curElement.getStreamIdx());
+			UINT32 stride = vertexDesc->getVertexStride(curElement.getStreamIdx());
+
+			mBounds = calculateBounds((UINT8*)data, mTempInitialMeshData->getNumVertices(), stride);
+			markCoreDirty();
+
+			break;
+		}
+	}
+
 	Bounds Mesh::calculateBounds(UINT8* verticesPtr, UINT32 numVertices, UINT32 stride) const
 	Bounds Mesh::calculateBounds(UINT8* verticesPtr, UINT32 numVertices, UINT32 stride) const
 	{
 	{
 		Bounds bounds;
 		Bounds bounds;
@@ -355,6 +362,16 @@ namespace BansheeEngine
 		return bounds;
 		return bounds;
 	}
 	}
 
 
+	MeshProxyPtr Mesh::_createProxy(UINT32 subMeshIdx)
+	{
+		MeshProxyPtr coreProxy = bs_shared_ptr<MeshProxy>();
+		coreProxy->mesh = getThisPtr();
+		coreProxy->bounds = mBounds;
+		coreProxy->subMesh = getSubMesh(subMeshIdx);
+
+		return coreProxy;
+	}
+
 	HMesh Mesh::dummy()
 	HMesh Mesh::dummy()
 	{
 	{
 		return MeshManager::instance().getDummyMesh();
 		return MeshManager::instance().getDummyMesh();

+ 2 - 2
BansheeCore/Source/BsMeshBase.cpp

@@ -6,13 +6,13 @@
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
 	MeshBase::MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp)
 	MeshBase::MeshBase(UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp)
-		:mNumIndices(numIndices), mNumVertices(numVertices)
+		:mNumIndices(numIndices), mNumVertices(numVertices), mCoreDirtyFlags(0xFFFFFF)
 	{
 	{
 		mSubMeshes.push_back(SubMesh(0, numIndices, drawOp));
 		mSubMeshes.push_back(SubMesh(0, numIndices, drawOp));
 	}
 	}
 
 
 	MeshBase::MeshBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes)
 	MeshBase::MeshBase(UINT32 numVertices, UINT32 numIndices, const Vector<SubMesh>& subMeshes)
-		: mNumIndices(numIndices), mNumVertices(numVertices)
+		: mNumIndices(numIndices), mNumVertices(numVertices), mCoreDirtyFlags(0xFFFFFF)
 	{
 	{
 		mSubMeshes = subMeshes;
 		mSubMeshes = subMeshes;
 	}
 	}

+ 0 - 14
BansheeCore/Source/BsMeshHeap.cpp

@@ -98,7 +98,6 @@ namespace BansheeEngine
 		UINT32 smallestVertFit = 0;
 		UINT32 smallestVertFit = 0;
 		UINT32 smallestVertFitIdx = 0;
 		UINT32 smallestVertFitIdx = 0;
 
 
-		bool buffersModified = false;
 		while(smallestVertFit == 0)
 		while(smallestVertFit == 0)
 		{
 		{
 			UINT32 curIdx = 0;
 			UINT32 curIdx = 0;
@@ -125,7 +124,6 @@ namespace BansheeEngine
 			}
 			}
 
 
 			growVertexBuffer(newNumVertices);
 			growVertexBuffer(newNumVertices);
-			buffersModified = true;
 		}
 		}
 
 
 		// Find free index chunk and grow if needed
 		// Find free index chunk and grow if needed
@@ -158,16 +156,6 @@ namespace BansheeEngine
 			}
 			}
 
 
 			growIndexBuffer(newNumIndices);
 			growIndexBuffer(newNumIndices);
-			buffersModified = true;
-		}
-
-		if (buffersModified)
-		{
-			for (auto& allocData : mMeshAllocData)
-			{
-				if (allocData.second.useFlags != UseFlags::CPUFree && allocData.second.useFlags != UseFlags::Free)
-					allocData.second.mesh->_updateRenderData();
-			}
 		}
 		}
 
 
 		UINT32 freeVertChunkIdx = 0;
 		UINT32 freeVertChunkIdx = 0;
@@ -316,8 +304,6 @@ namespace BansheeEngine
 		UINT8* idxDest = mCPUIndexData + idxChunkStart * idxSize;
 		UINT8* idxDest = mCPUIndexData + idxChunkStart * idxSize;
 		memcpy(idxDest, meshData->getIndexData(), meshData->getNumIndices() * idxSize);
 		memcpy(idxDest, meshData->getIndexData(), meshData->getNumIndices() * idxSize);
 		mIndexBuffer->writeData(idxChunkStart * idxSize, meshData->getNumIndices() * idxSize, idxDest, BufferWriteType::NoOverwrite);
 		mIndexBuffer->writeData(idxChunkStart * idxSize, meshData->getNumIndices() * idxSize, idxDest, BufferWriteType::NoOverwrite);
-
-		mesh->_updateRenderData();
 	}
 	}
 
 
 	void MeshHeap::deallocInternal(TransientMeshPtr mesh)
 	void MeshHeap::deallocInternal(TransientMeshPtr mesh)

+ 0 - 55
BansheeCore/Source/BsMeshRenderData.cpp

@@ -1,55 +0,0 @@
-#include "BsMeshRenderData.h"
-#include "BsRenderableProxy.h"
-
-namespace BansheeEngine
-{
-	MeshRenderData::MeshRenderData(const std::shared_ptr<VertexData>& vertexData, 
-		const IndexBufferPtr& indexBuffer, const SubMesh& subMesh, UINT32 vertexOffset, std::function<void()> usedOnGPUcallback)
-		:mVertexData(vertexData), mIndexBuffer(indexBuffer), mSubMesh(subMesh), 
-		mUsedOnGPUCallback(usedOnGPUcallback), mVertexOffset(vertexOffset), mIsMeshValid(true)
-	{
-
-	}
-
-	void MeshRenderData::addRenderableProxy(RenderableElement* proxy)
-	{
-		mRenderableProxies.push_back(proxy);
-	}
-
-	void MeshRenderData::removeRenderableProxy(RenderableElement* proxy)
-	{
-		auto iterFind = std::find(mRenderableProxies.begin(), mRenderableProxies.end(), proxy);
-
-		if (iterFind != mRenderableProxies.end())
-			mRenderableProxies.erase(iterFind);
-	}
-
-	void MeshRenderData::updateBounds(const Bounds& bounds)
-	{
-		mBounds = bounds;
-
-		for (auto& renderableProxy : mRenderableProxies)
-		{
-			renderableProxy->markBoundsDirty();
-		}
-	}
-
-	void MeshRenderData::updateData(const std::shared_ptr<VertexData>& vertexData, const IndexBufferPtr& indexBuffer, 
-		const SubMesh& subMesh, UINT32 vertexOffset)
-	{
-		mVertexData = vertexData;
-		mIndexBuffer = indexBuffer;
-		mSubMesh = subMesh;
-	}
-
-	void MeshRenderData::notifyUsedOnGPU() const
-	{
-		if (mIsMeshValid && mUsedOnGPUCallback != nullptr)
-			mUsedOnGPUCallback();
-	}
-
-	void MeshRenderData::_markAsInvalid()
-	{
-		mIsMeshValid = false;
-	}
-}

+ 30 - 10
BansheeCore/Source/BsRenderQueue.cpp

@@ -1,6 +1,4 @@
 #include "BsRenderQueue.h"
 #include "BsRenderQueue.h"
-#include "BsRenderOperation.h"
-#include "BsMeshRenderData.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -11,23 +9,45 @@ namespace BansheeEngine
 
 
 	void RenderQueue::clear()
 	void RenderQueue::clear()
 	{
 	{
-		mRenderOperations.clear();
-		mSortedRenderOps.clear();
+		mRenderElements.clear();
+		mSortedRenderElements.clear();
 	}
 	}
 
 
-	void RenderQueue::add(const Material::CoreProxyPtr& material, const MeshRenderDataPtr& mesh, const Vector3& worldPosForSort)
+	void RenderQueue::add(const MaterialProxyPtr& material, const MeshProxyPtr& mesh, const Vector3& worldPosForSort)
 	{
 	{
-		// TODO - Make sure RenderOperations are cached so we dont allocate memory for them every frame
-		mRenderOperations.push_back(RenderOperation());
+		// TODO - Make sure RenderQueueElements are cached so we dont allocate memory for them every frame
+		mRenderElements.push_back(RenderQueueElement());
 
 
-		RenderOperation& renderOp = mRenderOperations.back();
+		RenderQueueElement& renderOp = mRenderElements.back();
 		renderOp.material = material;
 		renderOp.material = material;
 		renderOp.mesh = mesh;
 		renderOp.mesh = mesh;
 		renderOp.worldPosition = worldPosForSort;
 		renderOp.worldPosition = worldPosForSort;
 	}
 	}
 
 
-	const Vector<SortedRenderOp>& RenderQueue::getSortedRenderOps() const
+	void RenderQueue::sort()
 	{
 	{
-		return mSortedRenderOps;
+		// Just pass-through for now
+		for (auto& renderElem : mRenderElements)
+		{
+			UINT32 numPasses = (UINT32)renderElem.material->passes.size();
+			for (UINT32 i = 0; i < numPasses; i++)
+			{
+				mSortedRenderElements.push_back(RenderQueueElement());
+
+				RenderQueueElement& sortedElem = mSortedRenderElements.back();
+				sortedElem.material = renderElem.material;
+				sortedElem.mesh = renderElem.mesh;
+				sortedElem.worldPosition = renderElem.worldPosition;
+				sortedElem.passIdx = i;
+			}
+		}
+
+		// TODO - Actually do some sorting. Use material options to sort (isTransparent, isOverlay(need to add this), etc.)
+		// Note: When sorting make sure not to change order of unsorted elements. Some outside managers (like overlay and GUI) will provide render ops which are already sorted
+	}
+
+	const Vector<RenderQueueElement>& RenderQueue::getSortedElements() const
+	{
+		return mSortedRenderElements;
 	}
 	}
 }
 }

+ 1 - 2
BansheeCore/Source/BsRenderableProxy.cpp

@@ -1,5 +1,4 @@
 #include "BsRenderableProxy.h"
 #include "BsRenderableProxy.h"
-#include "BsMeshRenderData.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -12,7 +11,7 @@ namespace BansheeEngine
 		if (mesh == nullptr)
 		if (mesh == nullptr)
 			return Bounds();
 			return Bounds();
 
 
-		Bounds worldBounds = mesh->getBounds();
+		Bounds worldBounds = mesh->bounds;
 		worldBounds.transformAffine(worldTransform);
 		worldBounds.transformAffine(worldTransform);
 
 
 		return worldBounds;
 		return worldBounds;

+ 2 - 2
BansheeCore/Source/BsSceneObject.cpp

@@ -13,7 +13,7 @@ namespace BansheeEngine
 		:GameObject(), mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::ONE),
 		:GameObject(), mPosition(Vector3::ZERO), mRotation(Quaternion::IDENTITY), mScale(Vector3::ONE),
 		mWorldPosition(Vector3::ZERO), mWorldRotation(Quaternion::IDENTITY), mWorldScale(Vector3::ONE),
 		mWorldPosition(Vector3::ZERO), mWorldRotation(Quaternion::IDENTITY), mWorldScale(Vector3::ONE),
 		mCachedLocalTfrm(Matrix4::IDENTITY), mIsCachedLocalTfrmUpToDate(false),
 		mCachedLocalTfrm(Matrix4::IDENTITY), mIsCachedLocalTfrmUpToDate(false),
-		mCachedWorldTfrm(Matrix4::IDENTITY), mIsCachedWorldTfrmUpToDate(false), mIsRenderDataUpToDate(false)
+		mCachedWorldTfrm(Matrix4::IDENTITY), mIsCachedWorldTfrmUpToDate(false), mIsCoreDirtyFlags(0xFFFFFFFF)
 	{
 	{
 		setName(name);
 		setName(name);
 	}
 	}
@@ -242,7 +242,7 @@ namespace BansheeEngine
 	{
 	{
 		mIsCachedLocalTfrmUpToDate = false;
 		mIsCachedLocalTfrmUpToDate = false;
 		mIsCachedWorldTfrmUpToDate = false;
 		mIsCachedWorldTfrmUpToDate = false;
-		mIsRenderDataUpToDate = false;
+		mIsCoreDirtyFlags = 0xFFFFFFFF;
 
 
 		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
 		for(auto iter = mChildren.begin(); iter != mChildren.end(); ++iter)
 		{
 		{

+ 12 - 7
BansheeCore/Source/BsTransientMesh.cpp

@@ -1,5 +1,6 @@
 #include "BsTransientMesh.h"
 #include "BsTransientMesh.h"
 #include "BsVertexData.h"
 #include "BsVertexData.h"
+#include "BsBounds.h"
 #include "BsMeshHeap.h"
 #include "BsMeshHeap.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
@@ -7,7 +8,7 @@ namespace BansheeEngine
 	TransientMesh::TransientMesh(const MeshHeapPtr& parentHeap, UINT32 id, UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp)
 	TransientMesh::TransientMesh(const MeshHeapPtr& parentHeap, UINT32 id, UINT32 numVertices, UINT32 numIndices, DrawOperationType drawOp)
 		:MeshBase(numVertices, numIndices, drawOp), mParentHeap(parentHeap), mId(id), mIsDestroyed(false)
 		:MeshBase(numVertices, numIndices, drawOp), mParentHeap(parentHeap), mId(id), mIsDestroyed(false)
 	{
 	{
-		mRenderData = bs_shared_ptr<MeshRenderData>(nullptr, nullptr, SubMesh(), 0, std::bind(&TransientMesh::_notifyUsedOnGPU, this));
+
 	}
 	}
 
 
 	TransientMesh::~TransientMesh()
 	TransientMesh::~TransientMesh()
@@ -17,8 +18,6 @@ namespace BansheeEngine
 			TransientMeshPtr meshPtr = std::static_pointer_cast<TransientMesh>(getThisPtr());
 			TransientMeshPtr meshPtr = std::static_pointer_cast<TransientMesh>(getThisPtr());
 			mParentHeap->dealloc(meshPtr);
 			mParentHeap->dealloc(meshPtr);
 		}
 		}
-
-		mRenderData->_markAsInvalid();
 	}
 	}
 
 
 	void TransientMesh::writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
 	void TransientMesh::writeSubresource(UINT32 subresourceIdx, const GpuResourceData& data, bool discardEntireBuffer)
@@ -56,10 +55,16 @@ namespace BansheeEngine
 		mParentHeap->notifyUsedOnGPU(mId);
 		mParentHeap->notifyUsedOnGPU(mId);
 	}
 	}
 
 
-	void TransientMesh::_updateRenderData()
+	MeshProxyPtr TransientMesh::_createProxy(UINT32 subMeshIdx)
 	{
 	{
-		mRenderData->updateData(mParentHeap->_getVertexData(), mParentHeap->_getIndexBuffer(),
-			SubMesh(mParentHeap->getIndexOffset(mId), getNumIndices(), getSubMesh(0).drawOp),
-			mParentHeap->getVertexOffset(mId));
+		MeshProxyPtr coreProxy = bs_shared_ptr<MeshProxy>();
+		coreProxy->mesh = getThisPtr();
+		coreProxy->subMesh = mSubMeshes[0];
+
+		// Note: Not calculating bounds for transient meshes yet
+		// (No particular reason, I just didn't bother)
+		coreProxy->bounds = Bounds(); 
+
+		return coreProxy;
 	}
 	}
 }
 }

+ 41 - 6
BansheeEngine/Include/BsCamera.h

@@ -276,7 +276,7 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	This option tells the renderer that this camera should ignore any renderable components.
 		 * @brief	This option tells the renderer that this camera should ignore any renderable components.
 		 */
 		 */
-		void setIgnoreSceneRenderables(bool value) { mIgnoreSceneRenderables = true; }
+		void setIgnoreSceneRenderables(bool value) { mIgnoreSceneRenderables = true; markCoreDirty(); }
 
 
 		/**
 		/**
 		 * @brief	This option tells the renderer that this camera should ignore any renderable components.
 		 * @brief	This option tells the renderer that this camera should ignore any renderable components.
@@ -295,7 +295,7 @@ namespace BansheeEngine
 		 *
 		 *
 		 * @param	priority	The priority. Higher value means the camera will be rendered sooner.
 		 * @param	priority	The priority. Higher value means the camera will be rendered sooner.
 		 */
 		 */
-		void setPriority(INT32 priority) { mPriority = priority; }
+		void setPriority(INT32 priority) { mPriority = priority; markCoreDirty(); }
 
 
 		/**
 		/**
 		 * @brief	Retrieves layer bitfield that is used when determining which object should the camera render.
 		 * @brief	Retrieves layer bitfield that is used when determining which object should the camera render.
@@ -305,13 +305,40 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Sets layer bitfield that is used when determining which object should the camera render.
 		 * @brief	Sets layer bitfield that is used when determining which object should the camera render.
 		 */
 		 */
-		void setLayers(UINT64 layers) { mLayers = layers; }
-
-		// TODO UNDOCUMENTED
-		CameraProxy _createProxy() const;
+		void setLayers(UINT64 layers) { mLayers = layers; markCoreDirty(); }
 
 
         static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
         static const float INFINITE_FAR_PLANE_ADJUST; /**< Small constant used to reduce far plane projection to avoid inaccuracies. */
 
 
+		/************************************************************************/
+		/* 								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.
+		 */
+		bool _isCoreDirty() const { return mCoreDirtyFlags != 0; }
+
+		/**
+		 * @brief	Marks the core dirty flag as clean.
+		 */
+		void _markCoreClean() { mCoreDirtyFlags = 0; }
+
+		/**
+		 * @brief	Creates a new core proxy from the currently set options. Core proxies ensure
+		 *			that the core thread has all the necessary data, while avoiding the need
+		 *			to manage Camera 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.
+		 */
+		CameraProxyPtr _createProxy() const;
+
+		// TODO UNDOCUMENTED
+		CameraProxyPtr _getActiveProxy() const { return mActiveProxy; }
+		void _setActiveProxy(const CameraProxyPtr& proxy) { mActiveProxy = proxy; }
+
 	protected:
 	protected:
 		/**
 		/**
 		 * @brief	Calculate projection parameters that are used when constructing the projection matrix.
 		 * @brief	Calculate projection parameters that are used when constructing the projection matrix.
@@ -345,6 +372,11 @@ namespace BansheeEngine
 		 */
 		 */
 		virtual void invalidateFrustum() const;
 		virtual void invalidateFrustum() const;
 
 
+		/**
+		 * @brief	Marks the core data as dirty.
+		 */
+		void markCoreDirty() { mCoreDirtyFlags = 0xFFFFFFFF; }
+
     protected:
     protected:
 		ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
 		ViewportPtr mViewport; /**< Viewport that describes 2D rendering surface. */
 		UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
 		UINT64 mLayers; /**< Bitfield that can be used for filtering what objects the camera sees. */
@@ -363,6 +395,9 @@ namespace BansheeEngine
 		bool mFrustumExtentsManuallySet; /**< Are frustum extents manually set. */
 		bool mFrustumExtentsManuallySet; /**< Are frustum extents manually set. */
 		bool mIgnoreSceneRenderables; /**< Should the camera ignore renderable components. */
 		bool mIgnoreSceneRenderables; /**< Should the camera ignore renderable components. */
 
 
+		UINT32 mCoreDirtyFlags; /**< True when internal data has changed and core thread wasn't yet informed. */
+		CameraProxyPtr mActiveProxy; /**< Active core proxy if any. */
+
 		mutable Matrix4 mProjMatrixRS; /**< Cached render-system specific projection matrix. */
 		mutable Matrix4 mProjMatrixRS; /**< Cached render-system specific projection matrix. */
 		mutable Matrix4 mProjMatrix; /**< Cached projection matrix that determines how are 3D points projected to a 2D viewport. */
 		mutable Matrix4 mProjMatrix; /**< Cached projection matrix that determines how are 3D points projected to a 2D viewport. */
 		mutable Matrix4 mViewMatrix; /**< Cached view matrix that determines camera position/orientation. */
 		mutable Matrix4 mViewMatrix; /**< Cached view matrix that determines camera position/orientation. */

+ 2 - 2
BansheeEngine/Include/BsRenderable.h

@@ -87,7 +87,7 @@ namespace BansheeEngine
 
 
 		/**
 		/**
 		 * @brief	Checks is the core dirty flag set. This is used by external systems 
 		 * @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.
+		 *			to know when internal data has changed and core thread potentially needs to be notified.
 		 */
 		 */
 		bool _isCoreDirty() const;
 		bool _isCoreDirty() const;
 
 
@@ -109,7 +109,7 @@ namespace BansheeEngine
 		void updateResourceLoadStates() const;
 		void updateResourceLoadStates() const;
 
 
 		/**
 		/**
-		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.
+		 * @brief	Marks the core data as dirty.
 		 */
 		 */
 		void markCoreDirty() const { mCoreDirtyFlags = 0xFFFFFFFF; }
 		void markCoreDirty() const { mCoreDirtyFlags = 0xFFFFFFFF; }
 	private:
 	private:

+ 5 - 0
BansheeEngine/Include/BsSceneManager.h

@@ -30,6 +30,11 @@ namespace BansheeEngine
 		 * @brief	Triggered whenever a renderable is removed from a SceneObject.
 		 * @brief	Triggered whenever a renderable is removed from a SceneObject.
 		 */
 		 */
 		Event<void(const HRenderable&)> onRenderableRemoved;
 		Event<void(const HRenderable&)> onRenderableRemoved;
+
+		/**
+		 * @brief	Triggered whenever a camera is removed from a SceneObject.
+		 */
+		Event<void(const HCamera&)> onCameraRemoved;
 	};
 	};
 
 
 	BS_EXPORT SceneManager& gBsSceneManager();
 	BS_EXPORT SceneManager& gBsSceneManager();

+ 26 - 9
BansheeEngine/Source/BsCamera.cpp

@@ -20,7 +20,7 @@ namespace BansheeEngine
         : Component(parent), mProjType(PT_PERSPECTIVE), mHorzFOV(Radian(Math::PI/4.0f)), mFarDist(100000.0f), 
         : Component(parent), mProjType(PT_PERSPECTIVE), mHorzFOV(Radian(Math::PI/4.0f)), mFarDist(100000.0f), 
 		mNearDist(100.0f), mAspect(1.33333333333333f), mOrthoHeight(1000), mRecalcFrustum(true), mRecalcFrustumPlanes(true), 
 		mNearDist(100.0f), mAspect(1.33333333333333f), mOrthoHeight(1000), mRecalcFrustum(true), mRecalcFrustumPlanes(true), 
 		mCustomViewMatrix(false), mCustomProjMatrix(false), mFrustumExtentsManuallySet(false), mIgnoreSceneRenderables(false), 
 		mCustomViewMatrix(false), mCustomProjMatrix(false), mFrustumExtentsManuallySet(false), mIgnoreSceneRenderables(false), 
-		mPriority(0), mLayers(0xFFFFFFFFFFFFFFFF)
+		mPriority(0), mLayers(0xFFFFFFFFFFFFFFFF), mCoreDirtyFlags(0xFFFFFFFF)
     {
     {
 		setName("Camera");
 		setName("Camera");
 
 
@@ -43,6 +43,7 @@ namespace BansheeEngine
 	{
 	{
 		mHorzFOV = fov;
 		mHorzFOV = fov;
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	const Radian& Camera::getHorzFOV() const
 	const Radian& Camera::getHorzFOV() const
@@ -54,6 +55,7 @@ namespace BansheeEngine
 	{
 	{
 		mFarDist = farPlane;
 		mFarDist = farPlane;
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	float Camera::getFarClipDistance() const
 	float Camera::getFarClipDistance() const
@@ -70,6 +72,7 @@ namespace BansheeEngine
 
 
 		mNearDist = nearPlane;
 		mNearDist = nearPlane;
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	float Camera::getNearClipDistance() const
 	float Camera::getNearClipDistance() const
@@ -444,6 +447,7 @@ namespace BansheeEngine
 	{
 	{
 		mAspect = r;
 		mAspect = r;
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	const AABox& Camera::getBoundingBox() const
 	const AABox& Camera::getBoundingBox() const
@@ -457,6 +461,7 @@ namespace BansheeEngine
 	{
 	{
 		mProjType = pt;
 		mProjType = pt;
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	ProjectionType Camera::getProjectionType() const
 	ProjectionType Camera::getProjectionType() const
@@ -472,6 +477,8 @@ namespace BansheeEngine
 			assert(viewMatrix.isAffine());
 			assert(viewMatrix.isAffine());
 			mViewMatrix = viewMatrix;
 			mViewMatrix = viewMatrix;
 		}
 		}
+
+		markCoreDirty();
 	}
 	}
 
 
 	void Camera::setCustomProjectionMatrix(bool enable, const Matrix4& projMatrix)
 	void Camera::setCustomProjectionMatrix(bool enable, const Matrix4& projMatrix)
@@ -482,25 +489,32 @@ namespace BansheeEngine
 			mProjMatrix = projMatrix;
 			mProjMatrix = projMatrix;
 
 
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	void Camera::setOrthoWindow(float w, float h)
 	void Camera::setOrthoWindow(float w, float h)
 	{
 	{
 		mOrthoHeight = h;
 		mOrthoHeight = h;
 		mAspect = w / h;
 		mAspect = w / h;
+
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	void Camera::setOrthoWindowHeight(float h)
 	void Camera::setOrthoWindowHeight(float h)
 	{
 	{
 		mOrthoHeight = h;
 		mOrthoHeight = h;
+
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	void Camera::setOrthoWindowWidth(float w)
 	void Camera::setOrthoWindowWidth(float w)
 	{
 	{
 		mOrthoHeight = w / mAspect;
 		mOrthoHeight = w / mAspect;
+
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	float Camera::getOrthoWindowHeight() const
 	float Camera::getOrthoWindowHeight() const
@@ -522,12 +536,15 @@ namespace BansheeEngine
 		mBottom = bottom;
 		mBottom = bottom;
 
 
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	void Camera::resetFrustumExtents()
 	void Camera::resetFrustumExtents()
 	{
 	{
 		mFrustumExtentsManuallySet = false;
 		mFrustumExtentsManuallySet = false;
+
 		invalidateFrustum();
 		invalidateFrustum();
+		markCoreDirty();
 	}
 	}
 
 
 	void Camera::getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const
 	void Camera::getFrustumExtents(float& outleft, float& outright, float& outtop, float& outbottom) const
@@ -545,15 +562,15 @@ namespace BansheeEngine
 		mRecalcFrustumPlanes = true;
 		mRecalcFrustumPlanes = true;
     }
     }
 
 
-	CameraProxy Camera::_createProxy() const
+	CameraProxyPtr Camera::_createProxy() const
 	{
 	{
-		CameraProxy proxy;
-		proxy.layer = mLayers;
-		proxy.priority = mPriority;
-		proxy.projMatrix = getProjectionMatrixRS();
-		proxy.viewMatrix = getViewMatrix();
-		proxy.viewport = mViewport->clone();
-		proxy.ignoreSceneRenderables = mIgnoreSceneRenderables;
+		CameraProxyPtr proxy = bs_shared_ptr<CameraProxy>();
+		proxy->layer = mLayers;
+		proxy->priority = mPriority;
+		proxy->projMatrix = getProjectionMatrixRS();
+		proxy->viewMatrix = getViewMatrix();
+		proxy->viewport = mViewport->clone();
+		proxy->ignoreSceneRenderables = mIgnoreSceneRenderables;
 
 
 		return proxy;
 		return proxy;
 	}
 	}

+ 9 - 3
BansheeEngine/Source/BsRenderable.cpp

@@ -74,10 +74,13 @@ namespace BansheeEngine
 
 
 		for (auto& materialData : mMaterialData)
 		for (auto& materialData : mMaterialData)
 		{
 		{
-			if (materialData.material.isLoaded() && materialData.material->_isCoreDirty())
+			if (materialData.material != nullptr && materialData.material.isLoaded() && materialData.material->_isCoreDirty())
 				return true;
 				return true;
 		}
 		}
 
 
+		if (mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded() && mMeshData.mesh->_isCoreDirty())
+			return true;
+
 		return mCoreDirtyFlags; 
 		return mCoreDirtyFlags; 
 	}
 	}
 
 
@@ -85,10 +88,13 @@ namespace BansheeEngine
 	{
 	{
 		for (auto& materialData : mMaterialData)
 		for (auto& materialData : mMaterialData)
 		{
 		{
-			if (materialData.material.isLoaded())
+			if (materialData.material != nullptr && materialData.material.isLoaded())
 				materialData.material->_markCoreClean();
 				materialData.material->_markCoreClean();
 		}
 		}
 
 
+		if (mMeshData.mesh != nullptr && mMeshData.mesh.isLoaded())
+			mMeshData.mesh->_markCoreClean();
+
 		mCoreDirtyFlags = 0;
 		mCoreDirtyFlags = 0;
 	}
 	}
 
 
@@ -124,7 +130,7 @@ namespace BansheeEngine
 			RenderableElement* renElement = bs_new<RenderableElement>();
 			RenderableElement* renElement = bs_new<RenderableElement>();
 			renElement->layer = mLayer;
 			renElement->layer = mLayer;
 			renElement->worldTransform = SO()->getWorldTfrm();
 			renElement->worldTransform = SO()->getWorldTfrm();
-			renElement->mesh = mMeshData.mesh->_getRenderData(i);
+			renElement->mesh = mMeshData.mesh->_createProxy(i);
 
 
 			HMaterial material;
 			HMaterial material;
 			if (i < mMaterialData.size())
 			if (i < mMaterialData.size())

+ 18 - 12
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -4,7 +4,6 @@
 #include "BsRenderer.h"
 #include "BsRenderer.h"
 #include "BsBounds.h"
 #include "BsBounds.h"
 #include "BsCameraProxy.h"
 #include "BsCameraProxy.h"
-#include "BsMaterialProxy.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -18,7 +17,7 @@ namespace BansheeEngine
 	{
 	{
 		struct CameraData
 		struct CameraData
 		{
 		{
-			CameraProxy cameraProxy;
+			CameraProxyPtr cameraProxy;
 			RenderQueuePtr renderQueue;
 			RenderQueuePtr renderQueue;
 		};
 		};
 
 
@@ -28,11 +27,6 @@ namespace BansheeEngine
 			Vector<CameraData> cameras;
 			Vector<CameraData> cameras;
 		};
 		};
 
 
-		struct FrameData
-		{
-			Vector<RenderTargetData> renderTargets;
-		};
-
 	public:
 	public:
 		BansheeRenderer();
 		BansheeRenderer();
 		~BansheeRenderer();
 		~BansheeRenderer();
@@ -52,24 +46,36 @@ namespace BansheeEngine
 		void removeRenderableProxy(RenderableProxyPtr proxy);
 		void removeRenderableProxy(RenderableProxyPtr proxy);
 		void updateRenderableProxy(RenderableProxyPtr proxy, Matrix4 localToWorld);
 		void updateRenderableProxy(RenderableProxyPtr proxy, Matrix4 localToWorld);
 
 
-		void renderAllCore(std::shared_ptr<FrameData> frameData);
+		void addCameraProxy(CameraProxyPtr proxy);
+		void removeCameraProxy(CameraProxyPtr proxy);
+		void updateCameraProxy(CameraProxyPtr proxy, Matrix4 viewMatrix);
+
+		void renderAllCore();
 
 
 		/**
 		/**
 		 * @brief	Renders all objects visible by the provided camera.
 		 * @brief	Renders all objects visible by the provided camera.
 		 */
 		 */
 		virtual void render(const CameraProxy& cameraProxy, const RenderQueuePtr& renderQueue);
 		virtual void render(const CameraProxy& cameraProxy, const RenderQueuePtr& renderQueue);
 
 
-		void setPass(const Material::CoreProxy::PassData& pass);
-		void draw(const MeshRenderData& mesh);
+		void setPass(const MaterialProxyPass& pass);
+		void draw(const MeshProxy& mesh);
 
 
 		void renderableRemoved(const HRenderable& renderable);
 		void renderableRemoved(const HRenderable& renderable);
+		void cameraRemoved(const HCamera& camera);
+
+		Vector<RenderableProxyPtr> mDeletedRenderableProxies;
+		Vector<CameraProxyPtr> mDeletedCameraProxies;
+
+		UnorderedMap<UINT64, RenderableProxyPtr> mRenderableProxies;
+		UnorderedMap<UINT64, CameraProxyPtr> mCameraProxies;
 
 
-		Vector<RenderableProxyPtr> mDeletedProxies;
+		Vector<RenderTargetData> mRenderTargets;
 
 
-		Vector<RenderableElement*> mRenderableProxies;
+		Vector<RenderableElement*> mRenderableElements;
 		Vector<Matrix4> mWorldTransforms;
 		Vector<Matrix4> mWorldTransforms;
 		Vector<Bounds> mWorldBounds;
 		Vector<Bounds> mWorldBounds;
 
 
 		HEvent mRenderableRemovedConn;
 		HEvent mRenderableRemovedConn;
+		HEvent mCameraRemovedConn;
 	};
 	};
 }
 }

+ 134 - 73
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -12,8 +12,7 @@
 #include "BsCoreApplication.h"
 #include "BsCoreApplication.h"
 #include "BsViewport.h"
 #include "BsViewport.h"
 #include "BsRenderTarget.h"
 #include "BsRenderTarget.h"
-#include "BsRenderOperation.h"
-#include "BsDefaultRenderQueue.h"
+#include "BsRenderQueue.h"
 #include "BsOverlayManager.h"
 #include "BsOverlayManager.h"
 #include "BsDrawHelper2D.h"
 #include "BsDrawHelper2D.h"
 #include "BsDrawHelper3D.h"
 #include "BsDrawHelper3D.h"
@@ -29,6 +28,7 @@ namespace BansheeEngine
 	BansheeRenderer::BansheeRenderer()
 	BansheeRenderer::BansheeRenderer()
 	{
 	{
 		mRenderableRemovedConn = gBsSceneManager().onRenderableRemoved.connect(std::bind(&BansheeRenderer::renderableRemoved, this, _1));
 		mRenderableRemovedConn = gBsSceneManager().onRenderableRemoved.connect(std::bind(&BansheeRenderer::renderableRemoved, this, _1));
+		mCameraRemovedConn = gBsSceneManager().onCameraRemoved.connect(std::bind(&BansheeRenderer::cameraRemoved, this, _1));
 
 
 		// Init compatibile material params
 		// Init compatibile material params
 		RendererMaterialParams dx9params("BansheeD3D9RenderSystem", RenType_UnlitUntextured);
 		RendererMaterialParams dx9params("BansheeD3D9RenderSystem", RenType_UnlitUntextured);
@@ -43,6 +43,7 @@ namespace BansheeEngine
 	BansheeRenderer::~BansheeRenderer()
 	BansheeRenderer::~BansheeRenderer()
 	{
 	{
 		mRenderableRemovedConn.disconnect();
 		mRenderableRemovedConn.disconnect();
+		mCameraRemovedConn.disconnect();
 	}
 	}
 
 
 	const String& BansheeRenderer::getName() const
 	const String& BansheeRenderer::getName() const
@@ -55,13 +56,11 @@ namespace BansheeEngine
 	{
 	{
 		for (auto& element : proxy->renderableElements)
 		for (auto& element : proxy->renderableElements)
 		{
 		{
-			mRenderableProxies.push_back(element);
+			mRenderableElements.push_back(element);
 			mWorldTransforms.push_back(element->worldTransform);
 			mWorldTransforms.push_back(element->worldTransform);
 			mWorldBounds.push_back(element->calculateWorldBounds());
 			mWorldBounds.push_back(element->calculateWorldBounds());
-			element->markBoundsClean();
 
 
-			element->id = (UINT32)(mRenderableProxies.size() - 1);
-			element->mesh->addRenderableProxy(element);
+			element->id = (UINT32)(mRenderableElements.size() - 1);
 		}
 		}
 	}
 	}
 
 
@@ -69,19 +68,17 @@ namespace BansheeEngine
 	{
 	{
 		for (auto& element : proxy->renderableElements)
 		for (auto& element : proxy->renderableElements)
 		{
 		{
-			assert(mRenderableProxies.size() > element->id && element->id >= 0);
+			assert(mRenderableElements.size() > element->id && element->id >= 0);
 
 
-			if (mRenderableProxies.size() == 0)
-				mRenderableProxies.erase(mRenderableProxies.begin());
+			if (mRenderableElements.size() == 0)
+				mRenderableElements.erase(mRenderableElements.begin());
 			else
 			else
 			{
 			{
-				std::swap(mRenderableProxies[element->id], mRenderableProxies.back());
-				mRenderableProxies.erase(mRenderableProxies.end() - 1);
+				std::swap(mRenderableElements[element->id], mRenderableElements.back());
+				mRenderableElements.erase(mRenderableElements.end() - 1);
 
 
-				mRenderableProxies[element->id]->id = element->id;
+				mRenderableElements[element->id]->id = element->id;
 			}
 			}
-
-			element->mesh->removeRenderableProxy(element);
 		}
 		}
 	}
 	}
 
 
@@ -93,15 +90,84 @@ namespace BansheeEngine
 
 
 			mWorldTransforms[element->id] = localToWorld;
 			mWorldTransforms[element->id] = localToWorld;
 			mWorldBounds[element->id] = element->calculateWorldBounds();
 			mWorldBounds[element->id] = element->calculateWorldBounds();
-			element->markBoundsClean();
 		}
 		}
 	}
 	}
 
 
+	void BansheeRenderer::addCameraProxy(CameraProxyPtr proxy)
+	{
+		RenderTargetPtr renderTarget = proxy->viewport.getTarget();
+		auto findIter = std::find(mRenderTargets.begin(), mRenderTargets.end(), renderTarget);
+
+		if (findIter != mRenderTargets.end())
+		{
+			findIter->cameras.push_back(CameraData());
+			CameraData& camData = findIter->cameras.back();
+
+			camData.cameraProxy = proxy;
+			camData.renderQueue = bs_shared_ptr<RenderQueue>();
+		}
+		else
+		{
+			mRenderTargets.push_back(RenderTargetData());
+			RenderTargetData& renderTargetData = mRenderTargets.back();
+
+			renderTargetData.cameras.push_back(CameraData());
+			CameraData& camData = renderTargetData.cameras.back();
+
+			camData.cameraProxy = proxy;
+			camData.renderQueue = bs_shared_ptr<RenderQueue>();
+		}
+
+		// Sort everything based on priority
+		auto cameraComparer = [&](const CameraData& a, const CameraData& b) { return a.cameraProxy->priority > b.cameraProxy->priority; };
+		auto renderTargetInfoComparer = [&](const RenderTargetData& a, const RenderTargetData& b) { return a.target->getPriority() > b.target->getPriority(); };
+		std::sort(begin(mRenderTargets), end(mRenderTargets), renderTargetInfoComparer);
+
+		for (auto& camerasPerTarget : mRenderTargets)
+		{
+			Vector<CameraData>& cameras = camerasPerTarget.cameras;
+
+			std::sort(begin(cameras), end(cameras), cameraComparer);
+		}
+	}
+
+	void BansheeRenderer::removeCameraProxy(CameraProxyPtr proxy)
+	{
+		RenderTargetPtr renderTarget = proxy->viewport.getTarget();
+		auto findIter = std::find(mRenderTargets.begin(), mRenderTargets.end(), renderTarget);
+
+		if (findIter != mRenderTargets.end())
+		{
+			auto findIter2 = std::find(findIter->cameras.begin(), findIter->cameras.end(), proxy);
+
+			if (findIter2 != findIter->cameras.end())
+			{
+				findIter->cameras.erase(findIter2);
+			}
+
+			if (findIter->cameras.size() == 0)
+				mRenderTargets.erase(findIter);
+		}
+	}
+
+	void BansheeRenderer::updateCameraProxy(CameraProxyPtr proxy, Matrix4 viewMatrix)
+	{
+		proxy->viewMatrix = viewMatrix;
+	}
+
 	void BansheeRenderer::renderableRemoved(const HRenderable& renderable)
 	void BansheeRenderer::renderableRemoved(const HRenderable& renderable)
 	{
 	{
 		if (renderable->_getActiveProxy() != nullptr)
 		if (renderable->_getActiveProxy() != nullptr)
 		{
 		{
-			mDeletedProxies.push_back(renderable->_getActiveProxy());
+			mDeletedRenderableProxies.push_back(renderable->_getActiveProxy());
+		}
+	}
+
+	void BansheeRenderer::cameraRemoved(const HCamera& camera)
+	{
+		if (camera->_getActiveProxy() != nullptr)
+		{
+			mDeletedCameraProxies.push_back(camera->_getActiveProxy());
 		}
 		}
 	}
 	}
 
 
@@ -111,8 +177,8 @@ namespace BansheeEngine
 
 
 		gBsSceneManager().updateRenderableTransforms();
 		gBsSceneManager().updateRenderableTransforms();
 
 
-		// Remove proxies from deleted Renderable
-		for (auto& proxy : mDeletedProxies)
+		// Remove proxies from deleted Renderables
+		for (auto& proxy : mDeletedRenderableProxies)
 		{
 		{
 			if (proxy != nullptr)
 			if (proxy != nullptr)
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, proxy));
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, proxy));
@@ -120,6 +186,7 @@ namespace BansheeEngine
 
 
 		// Add or update Renderable proxies
 		// Add or update Renderable proxies
 		const Vector<HRenderable>& allRenderables = gBsSceneManager().getAllRenderables();
 		const Vector<HRenderable>& allRenderables = gBsSceneManager().getAllRenderables();
+		Vector<HSceneObject> dirtySceneObjects;
 		for (auto& renderable : allRenderables)
 		for (auto& renderable : allRenderables)
 		{
 		{
 			if (!renderable->_isCoreDirty())
 			if (!renderable->_isCoreDirty())
@@ -135,67 +202,61 @@ namespace BansheeEngine
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addRenderableProxy, this, proxy));
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addRenderableProxy, this, proxy));
 
 
 				renderable->_markCoreClean();
 				renderable->_markCoreClean();
-				renderable->SO()->_markRenderDataUpToDate();
+
+				dirtySceneObjects.push_back(renderable->SO());
 			}
 			}
-			else if (!renderable->SO()->_isRenderDataUpToDate())
+			else if (!renderable->SO()->_isCoreDirty())
 			{
 			{
 				RenderableProxyPtr proxy = renderable->_getActiveProxy();
 				RenderableProxyPtr proxy = renderable->_getActiveProxy();
 				assert(proxy != nullptr);
 				assert(proxy != nullptr);
 
 
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateRenderableProxy, this, proxy, renderable->SO()->getWorldTfrm()));
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateRenderableProxy, this, proxy, renderable->SO()->getWorldTfrm()));
 
 
-				renderable->SO()->_markRenderDataUpToDate();
+				dirtySceneObjects.push_back(renderable->SO());
 			}
 			}
 		}
 		}
 
 
-		// Create frame data
-		const Vector<HCamera>& allCameras = gBsSceneManager().getAllCameras();
-		Vector<RenderQueuePtr> renderQueues;
-
-		std::shared_ptr<FrameData> frameData = bs_shared_ptr<FrameData>();
+		// Remove proxies from deleted Cameras
+		for (auto& proxy : mDeletedCameraProxies)
+		{
+			if (proxy != nullptr)
+				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeCameraProxy, this, proxy));
+		}
 
 
+		// Add or update Camera proxies
+		const Vector<HCamera>& allCameras = gBsSceneManager().getAllCameras();
 		for (auto& camera : allCameras)
 		for (auto& camera : allCameras)
 		{
 		{
-			RenderTargetPtr target = camera->getViewport()->getTarget();
-			auto findIter = std::find_if(begin(frameData->renderTargets), end(frameData->renderTargets), 
-				[&target](const RenderTargetData& x) { return x.target == target; });
-
-			if (findIter == frameData->renderTargets.end())
+			if (!camera->_isCoreDirty())
 			{
 			{
-				frameData->renderTargets.push_back(RenderTargetData());
-				RenderTargetData& renderTargetData = frameData->renderTargets.back();
+				CameraProxyPtr proxy = camera->_getActiveProxy();
 
 
-				renderTargetData.target = target;
-				renderTargetData.cameras.push_back(CameraData());
+				if (proxy != nullptr)
+					gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeCameraProxy, this, proxy));
+
+				proxy = camera->_createProxy();
+				camera->_setActiveProxy(proxy);
 
 
-				CameraData& camData = renderTargetData.cameras.back();
-				camData.cameraProxy = camera->_createProxy();
-				camData.renderQueue = bs_shared_ptr<DefaultRenderQueue>();
+				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::addCameraProxy, this, proxy));
 
 
-				renderQueues.push_back(camData.renderQueue);
+				camera->_markCoreClean();
+				dirtySceneObjects.push_back(camera->SO());
 			}
 			}
-			else
+			else if (!camera->SO()->_isCoreDirty())
 			{
 			{
-				findIter->cameras.push_back(CameraData());
+				CameraProxyPtr proxy = camera->_getActiveProxy();
+				assert(proxy != nullptr);
 
 
-				CameraData& camData = findIter->cameras.back();
-				camData.cameraProxy = camera->_createProxy();
-				camData.renderQueue = bs_shared_ptr<DefaultRenderQueue>();
+				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateCameraProxy, this, proxy, camera->getViewMatrix()));
 
 
-				renderQueues.push_back(camData.renderQueue);
+				dirtySceneObjects.push_back(camera->SO());
 			}
 			}
 		}
 		}
 
 
-		// Sort everything based on priority
-		auto cameraComparer = [&](const CameraData& a, const CameraData& b) { return a.cameraProxy.priority > b.cameraProxy.priority; };
-		auto renderTargetInfoComparer = [&](const RenderTargetData& a, const RenderTargetData& b) { return a.target->getPriority() > b.target->getPriority(); };
-		std::sort(begin(frameData->renderTargets), end(frameData->renderTargets), renderTargetInfoComparer);
-
-		for (auto& camerasPerTarget : frameData->renderTargets)
+		// Mark everything clean
+		for (auto& dirtySO : dirtySceneObjects)
 		{
 		{
-			Vector<CameraData>& cameras = camerasPerTarget.cameras;
-
-			std::sort(begin(cameras), end(cameras), cameraComparer);
+			dirtySO->_markCoreClean();
 		}
 		}
 
 
 		// Populate direct draw lists
 		// Populate direct draw lists
@@ -229,21 +290,21 @@ namespace BansheeEngine
 				// TODO - Will I need to check if materials match renderer?
 				// TODO - Will I need to check if materials match renderer?
 
 
 				renderQueue->add(drawOp.material->_createProxy(),
 				renderQueue->add(drawOp.material->_createProxy(),
-					drawOp.mesh->_getRenderData(drawOp.submeshIdx), drawOp.worldPosition);
+					drawOp.mesh->_createProxy(drawOp.submeshIdx), drawOp.worldPosition);
 			}
 			}
 
 
 			idx++;
 			idx++;
 		}
 		}
 
 
-		gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::renderAllCore, this, frameData));
+		gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::renderAllCore, this));
 	}
 	}
 
 
-	void BansheeRenderer::renderAllCore(std::shared_ptr<FrameData> frameData)
+	void BansheeRenderer::renderAllCore()
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		// Render everything, target by target
 		// Render everything, target by target
-		for (auto& renderTargetData : frameData->renderTargets)
+		for (auto& renderTargetData : mRenderTargets)
 		{
 		{
 			RenderTargetPtr target = renderTargetData.target;
 			RenderTargetPtr target = renderTargetData.target;
 			Vector<CameraData>& cameraData = renderTargetData.cameras;
 			Vector<CameraData>& cameraData = renderTargetData.cameras;
@@ -252,7 +313,7 @@ namespace BansheeEngine
 
 
 			for(auto& data : cameraData)
 			for(auto& data : cameraData)
 			{
 			{
-				Viewport& viewport = data.cameraProxy.viewport;
+				Viewport& viewport = data.cameraProxy->viewport;
 				RenderSystem::instance().setViewport(viewport);
 				RenderSystem::instance().setViewport(viewport);
 
 
 				UINT32 clearBuffers = 0;
 				UINT32 clearBuffers = 0;
@@ -268,7 +329,7 @@ namespace BansheeEngine
 				if(clearBuffers != 0)
 				if(clearBuffers != 0)
 					RenderSystem::instance().clearViewport(clearBuffers, viewport.getClearColor(), viewport.getClearDepthValue(), viewport.getClearStencilValue());
 					RenderSystem::instance().clearViewport(clearBuffers, viewport.getClearColor(), viewport.getClearDepthValue(), viewport.getClearStencilValue());
 
 
-				render(data.cameraProxy, data.renderQueue);
+				render(*data.cameraProxy, data.renderQueue);
 			}
 			}
 
 
 			RenderSystem::instance().endFrame();
 			RenderSystem::instance().endFrame();
@@ -285,7 +346,7 @@ namespace BansheeEngine
 		if (!cameraProxy.ignoreSceneRenderables)
 		if (!cameraProxy.ignoreSceneRenderables)
 		{
 		{
 			// TODO - Do frustum culling
 			// TODO - Do frustum culling
-			for (auto& renderableProxy : mRenderableProxies)
+			for (auto& renderableProxy : mRenderableElements)
 			{
 			{
 				// TODO - Apply world-view-proj matrix
 				// TODO - Apply world-view-proj matrix
 
 
@@ -300,19 +361,18 @@ namespace BansheeEngine
 		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
 		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
 
 
 		renderQueue->sort();
 		renderQueue->sort();
-		const Vector<SortedRenderOp>& sortedROps = renderQueue->getSortedRenderOps();
+		const Vector<RenderQueueElement>& sortedRenderElements = renderQueue->getSortedElements();
 
 
-		for(auto iter = sortedROps.begin(); iter != sortedROps.end(); ++iter)
+		for(auto iter = sortedRenderElements.begin(); iter != sortedRenderElements.end(); ++iter)
 		{
 		{
-			const RenderOperation& renderOp = *iter->baseOperation;
-			Material::CoreProxyPtr materialProxy = renderOp.material;
+			MaterialProxyPtr materialProxy = iter->material;
 
 
 			setPass(materialProxy->passes[iter->passIdx]);
 			setPass(materialProxy->passes[iter->passIdx]);
-			draw(*renderOp.mesh);
+			draw(*iter->mesh);
 		}
 		}
 	}
 	}
 
 
-	void BansheeRenderer::setPass(const Material::CoreProxy::PassData& pass)
+	void BansheeRenderer::setPass(const MaterialProxyPass& pass)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
@@ -385,12 +445,13 @@ namespace BansheeEngine
 			rs.setRasterizerState(RasterizerState::getDefault());
 			rs.setRasterizerState(RasterizerState::getDefault());
 	}
 	}
 
 
-	void BansheeRenderer::draw(const MeshRenderData& mesh)
+	void BansheeRenderer::draw(const MeshProxy& meshProxy)
 	{
 	{
 		THROW_IF_NOT_CORE_THREAD;
 		THROW_IF_NOT_CORE_THREAD;
 
 
 		RenderSystem& rs = RenderSystem::instance();
 		RenderSystem& rs = RenderSystem::instance();
-		std::shared_ptr<VertexData> vertexData = mesh.getVertexData();
+		MeshPtr mesh = meshProxy.mesh;
+		std::shared_ptr<VertexData> vertexData = mesh->_getVertexData();
 
 
 		rs.setVertexDeclaration(vertexData->vertexDeclaration);
 		rs.setVertexDeclaration(vertexData->vertexDeclaration);
 		auto vertexBuffers = vertexData->getBuffers();
 		auto vertexBuffers = vertexData->getBuffers();
@@ -418,18 +479,18 @@ namespace BansheeEngine
 			rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
 			rs.setVertexBuffers(startSlot, buffers, endSlot - startSlot + 1);
 		}
 		}
 
 
-		SubMesh subMesh = mesh.getSubMesh();
+		SubMesh subMesh = meshProxy.subMesh;
 		rs.setDrawOperation(subMesh.drawOp);
 		rs.setDrawOperation(subMesh.drawOp);
 
 
-		IndexBufferPtr indexBuffer = mesh.getIndexBuffer();
+		IndexBufferPtr indexBuffer = mesh->_getIndexBuffer();
 
 
 		UINT32 indexCount = subMesh.indexCount;
 		UINT32 indexCount = subMesh.indexCount;
 		if (indexCount == 0)
 		if (indexCount == 0)
 			indexCount = indexBuffer->getNumIndices();
 			indexCount = indexBuffer->getNumIndices();
 
 
 		rs.setIndexBuffer(indexBuffer);
 		rs.setIndexBuffer(indexBuffer);
-		rs.drawIndexed(subMesh.indexOffset, indexCount, mesh.getVertexOffset(), vertexData->vertexCount);
+		rs.drawIndexed(subMesh.indexOffset, indexCount, mesh->_getVertexOffset(), vertexData->vertexCount);
 
 
-		mesh.notifyUsedOnGPU();
+		mesh->_notifyUsedOnGPU();
 	}
 	}
 }
 }

+ 2 - 0
BansheeSceneManager/Source/BsBansheeSceneManager.cpp

@@ -55,6 +55,8 @@ namespace BansheeEngine
 			}
 			}
 
 
 			mCachedCameras.erase(findIter);
 			mCachedCameras.erase(findIter);
+
+			onCameraRemoved(camera);
 		}
 		}
 		else if(component->getTypeId() == TID_Renderable)
 		else if(component->getTypeId() == TID_Renderable)
 		{
 		{

+ 23 - 22
Renderer.txt

@@ -1,23 +1,28 @@
-Make MeshProxy also be CPU based?
- - Signal when bounds change from CoreThreadAccessor
-    - add preWriteCallback that's called on CPU to GpuResource
- - Remove a list of RenderableProxies from MeshRenderData
- - Renderable can check if it is dirty
+1. Refactor proxies
 
 
-Make RenderableProxy -> CoreProxy, move it to Renderable and make it a shared pointer (maybe an unique pointer?)
- - This solves the issue with not knowing when to delete RenderableProxies
+Finish refactoring draw lists
 
 
-Need a way to update existing material proxies when params change
- - Create bindable GPu params, pass them to core and update GpuParams
+2. Gpu params update 
+   - Way to update sim -> core gpu params (send BindableGpuParams and update core buffers using it)
+   - Add a way to bind gpu params by using GpuParams directly
+   - And a way to update hardware buffers without using BindableGpuParams
 
 
-Apply world view proj matrix in renderer
+3. Renderer parameters and buffers
+   - Will likely need to finalize material <-> renderer interface matching first
+   - Add a way to create renderer gpu buffers
+   - Add a way to create handles to renderer gpu parameters (and store them in RenderableProxy)
+   - Update renderable parameters each frame
+      - Apply world view proj matrix in renderer
 
 
-Stage 2:
-Add material <-> renderer interface matching
- - Ensure renderer creates and updates parameters and parameter blocks it owns
- - Actually add frustum culling
- - Implement RenderQueue sorting with support for sort type, priority and separable pass
-   - Use a hash list(containing type, queue, layer, etc.) for faster sorting
+-----------------------------------------------------------
+NON TRIVIAL BUT SIMPLE
+
+Actually add frustum culling
+Implement RenderQueue sorting with support for sort type, priority and separable pass
+ - Use a hash list(containing type, queue, layer, etc.) for faster sorting
+
+-----------------------------------------------------------
+REFACTORING, NOTES AND OTHER TRIVIAL STUFF
 
 
 Finally
 Finally
  - Document elements marked with TODO UNDOCUMENTED
  - Document elements marked with TODO UNDOCUMENTED
@@ -27,15 +32,11 @@ Finally
 
 
 Semantic/design issues:
 Semantic/design issues:
  - DrawList is too similar to RenderQueue - Their names need to be more distinct
  - DrawList is too similar to RenderQueue - Their names need to be more distinct
- - MeshProxy is very different that material/camera/renderable proxy. Rename it to something else?
- - Material and camera proxy is returned by value while renderable by pointer. Also material proxy seems a bit heavy weight to be passed by value.
  - Consider removing SceneManager from Core? I two scene manager base classes.
  - Consider removing SceneManager from Core? I two scene manager base classes.
- - Consider moving RenderOperation in RenderQueue and removing its header/source. Maybe also renaming it to something more render queue specific. 
- - Remove DefaultRenderQueue. Instead make RenderQueue non-abstract and have it provide default implementation.
-
 
 
 -------------------------------------------------------
 -------------------------------------------------------
-ENSURING MATERIAL COMPATIBILITY:
+
+Material compatibility:
 
 
 When renderer is first created we create a list of default materials, each corresponding to a single valid renderable type.
 When renderer is first created we create a list of default materials, each corresponding to a single valid renderable type.
 When checking for material compatibility we compare parameter and param block descriptions between example
 When checking for material compatibility we compare parameter and param block descriptions between example