2
0
Эх сурвалжийг харах

Various fixes to Renderer

Marko Pintera 11 жил өмнө
parent
commit
d1881075fa

+ 2 - 2
BansheeCore/Include/BsCoreObject.h

@@ -193,12 +193,12 @@ namespace BansheeEngine
 		/**
 		 * @brief	Helper wrapper method used for queuing commands with no return value on the core thread.
 		 */
-		static void executeGpuCommand(std::shared_ptr<CoreObject>& obj, std::function<void()> func);
+		static void executeGpuCommand(std::shared_ptr<CoreObject> obj, std::function<void()> func);
 
 		/**
 		 * @brief	Helper wrapper method used for queuing commands with a return value on the core thread.
 		 */
-		static void executeReturnGpuCommand(std::shared_ptr<CoreObject>& obj, std::function<void(AsyncOp&)> func, AsyncOp& op); 
+		static void executeReturnGpuCommand(std::shared_ptr<CoreObject> obj, std::function<void(AsyncOp&)> func, AsyncOp& op); 
 	};
 
 	/**

+ 2 - 0
BansheeCore/Include/BsGpuParamBlockBuffer.h

@@ -82,6 +82,8 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT GenericGpuParamBlockBuffer : public GpuParamBlockBuffer
 	{
 	public:
+		GenericGpuParamBlockBuffer();
+
 		/**
 		 * @copydoc	GpuParamBlockBuffer::writeData
 		 */

+ 3 - 3
BansheeCore/Include/BsGpuParamDesc.h

@@ -10,9 +10,9 @@ namespace BansheeEngine
 	struct GpuParamDataDesc
 	{
 		String name;
-		UINT32 elementSize; // Multiple of 4 bytes
+		UINT32 elementSize; /**< In multiples of 4 bytes. */
 		UINT32 arraySize;
-		UINT32 arrayElementStride; // Multiple of 4 bytes
+		UINT32 arrayElementStride; /**< In multiples of 4 bytes. */
 		GpuParamDataType type;
 
 		UINT32 paramBlockSlot;
@@ -38,7 +38,7 @@ namespace BansheeEngine
 	{
 		String name;
 		UINT32 slot;
-		UINT32 blockSize;
+		UINT32 blockSize; /**< In multiples of 4 bytes. */
 		bool isShareable;
 	};
 

+ 9 - 4
BansheeCore/Include/BsGpuParams.h

@@ -39,6 +39,11 @@ namespace BansheeEngine
 
 		~GpuParams();
 
+		// Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
+		// all the internal buffers too). Trivial to implement but not needed at this time. Un-delete and implement if necessary.
+		GpuParams(const GpuParams& other) = delete;
+		GpuParams& operator=(const GpuParams& rhs) = delete;
+
 		/**
 		 * @brief	Binds a new parameter buffer to the specified slot. Any following parameter reads or
 		 *			writes that are referencing that buffer slot will use the new buffer.
@@ -264,11 +269,11 @@ namespace BansheeEngine
 		GpuParamDataDesc* getParamDesc(const String& name) const;
 
 		/**
-		 * @brief	Calculates size and offsets used when splitting a large memory chunk into separate buffers.
-		 *			Parameter counts must have been previously assigned.
+		 * @brief	Allocates and constructs internal buffers. Parameter counts must have been previously assigned.
+		 *			If provided, internal data will be allocated using the frame allocator, otherwise using
+		 *			the normal allocator.
 		 */
-		void getInternalBufferData(UINT32& bufferSize, UINT32& paramBlockOffset, UINT32& paramBlockBufferOffset,
-			UINT32& textureOffset, UINT32& samplerStateOffset) const;
+		void constructInternalBuffers(FrameAlloc* frameAlloc = nullptr);
 
 		/**
 		 * @brief	Marks the core data as dirty, signifying the core thread it should update it.

+ 23 - 7
BansheeCore/Include/BsRenderer.h

@@ -12,10 +12,11 @@ namespace BansheeEngine
 	 */
 	enum RendererBlockSemantic
 	{
-		RBS_Static,
-		RBS_PerCamera,
-		RBS_PerFrame,
-		RBS_PerObject
+		// 0 - Reserved
+		RBS_Static = 1,
+		RBS_PerCamera = 2,
+		RBS_PerFrame = 3,
+		RBS_PerObject = 4
 	};
 
 	/**
@@ -24,9 +25,10 @@ namespace BansheeEngine
 	 */
 	enum RendererParamSemantic
 	{
-		RPS_WorldViewProjTfrm,
-		RPS_ViewProjTfrm,
-		RPS_WorldTfrm
+		// 0 - Reserved
+		RPS_WorldViewProjTfrm = 1,
+		RPS_ViewProjTfrm = 2,
+		RPS_WorldTfrm = 3
 	};
 
 	/**
@@ -39,6 +41,20 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT Renderer
 	{
 	public:
+		/**
+		 * @brief	Called after the renderer has been activated.
+		 *
+		 * @note	Internal method.
+		 */
+		virtual void _onActivated() { }
+
+		/**
+		 * @brief	Called just before the renderer is deactivated.
+		 *
+		 * @note	Internal method.
+		 */
+		virtual void _onDeactivated() { }
+
 		/**
 		 * @brief	Name of the renderer. Used by materials to find 
 		 * 			an appropriate technique for this renderer.

+ 5 - 5
BansheeCore/Include/BsShader.h

@@ -154,16 +154,16 @@ namespace BansheeEngine
 		 * @param	name		   	 The name of the parameter. Name must be unique between all data and object parameters.
 		 * @param	gpuVariableName	 Name of the GPU variable in the GpuProgram that the parameter corresponds with.
 		 * @param	type		   	 The type of the parameter, must be the same as the type in GpuProgram.
-		 * @param	arraySize	   	 (optional) If the parameter is an array, the number of elements in the array. Size of 1 means its not an array.
-		 * @param	elementSize	   	 (optional) Size of an individual element in the array, in bytes. You only need to set this if you are setting variable
-		 * 							 length parameters, like structs.
 		 * @param	rendererSemantic (optional) Semantic that allows you to specify the use of this parameter in the renderer. The actual value of the semantic
 		 *							 depends on the current Renderer and its supported list of semantics. Elements with renderer semantics should not be updated
 		 *							 by the user, and will be updated by the renderer. These semantics will also be used to determine if a shader is compatible
 		 *							 with a specific renderer or not. Value of 0 signifies the parameter is not used by the renderer.
+		 * @param	arraySize	   	 (optional) If the parameter is an array, the number of elements in the array. Size of 1 means its not an array.
+		 * @param	elementSize	   	 (optional) Size of an individual element in the array, in bytes. You only need to set this if you are setting variable
+		 * 							 length parameters, like structs.
 		 */
-		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 arraySize = 1, 
-			UINT32 elementSize = 0, UINT32 rendererSemantic = 0);
+		void addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 rendererSemantic = 0,
+			UINT32 arraySize = 1, UINT32 elementSize = 0);
 
 		/**
 		 * @brief	Registers a new object (texture, sampler state, etc.) parameter you that you may then use 

+ 2 - 2
BansheeCore/Source/BsCoreObject.cpp

@@ -189,14 +189,14 @@ namespace BansheeEngine
 		gCoreAccessor().queueCommand(std::bind(&CoreObject::executeGpuCommand, obj, func));
 	}
 
-	void CoreObject::executeGpuCommand(std::shared_ptr<CoreObject>& obj, std::function<void()> func)
+	void CoreObject::executeGpuCommand(std::shared_ptr<CoreObject> obj, std::function<void()> func)
 	{
 		volatile std::shared_ptr<CoreObject> objParam = obj; // Makes sure obj isn't optimized out?
 
 		func();
 	}
 
-	void CoreObject::executeReturnGpuCommand(std::shared_ptr<CoreObject>& obj, std::function<void(AsyncOp&)> func, AsyncOp& op)
+	void CoreObject::executeReturnGpuCommand(std::shared_ptr<CoreObject> obj, std::function<void(AsyncOp&)> func, AsyncOp& op)
 	{
 		volatile std::shared_ptr<CoreObject> objParam = obj; // Makes sure obj isn't optimized out?
 

+ 1 - 1
BansheeCore/Source/BsGpuParam.cpp

@@ -151,7 +151,7 @@ namespace BansheeEngine
 	{ }
 
 	GpuParamSampState::GpuParamSampState(GpuParamObjectDesc* paramDesc, const std::shared_ptr<GpuParamsInternalData>& internalData)
-		: mParamDesc(nullptr), mInternalData(internalData)
+		: mParamDesc(paramDesc), mInternalData(internalData)
 	{ }
 
 	void GpuParamSampState::set(const HSamplerState& samplerState)

+ 9 - 2
BansheeCore/Source/BsGpuParamBlock.cpp

@@ -9,14 +9,21 @@ namespace BansheeEngine
 	GpuParamBlock::GpuParamBlock(UINT32 size)
 		:mDirty(true), mData(nullptr), mSize(size)
 	{
-		mData = (UINT8*)bs_alloc<ScratchAlloc>(mSize);
+		if (mSize > 0)
+			mData = (UINT8*)bs_alloc<ScratchAlloc>(mSize);
+
 		memset(mData, 0, mSize);
 	}
 
 	GpuParamBlock::GpuParamBlock(GpuParamBlock* otherBlock)
 	{
 		mSize = otherBlock->mSize;
-		mData = (UINT8*)bs_alloc<ScratchAlloc>(mSize);
+
+		if (mSize > 0)
+			mData = (UINT8*)bs_alloc<ScratchAlloc>(mSize);
+		else
+			mData = nullptr;
+
 		write(0, otherBlock->getData(), otherBlock->getSize());
 		mDirty = otherBlock->mDirty;
 	}

+ 9 - 1
BansheeCore/Source/BsGpuParamBlockBuffer.cpp

@@ -24,6 +24,10 @@ namespace BansheeEngine
 		CoreObject::initialize();
 	}
 
+	GenericGpuParamBlockBuffer::GenericGpuParamBlockBuffer()
+		:mData(nullptr)
+	{ }
+
 	void GenericGpuParamBlockBuffer::writeData(const UINT8* data)
 	{
 		memcpy(mData, data, mSize);
@@ -36,7 +40,11 @@ namespace BansheeEngine
 
 	void GenericGpuParamBlockBuffer::initialize_internal()
 	{
-		mData = (UINT8*)bs_alloc<ScratchAlloc>(mSize);
+		if (mSize > 0)
+			mData = (UINT8*)bs_alloc<ScratchAlloc>(mSize);
+		else
+			mData = nullptr;
+
 		memset(mData, 0, mSize);
 
 		GpuParamBlockBuffer::initialize_internal();

+ 55 - 59
BansheeCore/Source/BsGpuParams.cpp

@@ -11,7 +11,8 @@ namespace BansheeEngine
 {
 	GpuParamsInternalData::GpuParamsInternalData()
 		:mTransposeMatrices(false), mData(nullptr), mNumParamBlocks(0), mNumTextures(0), mNumSamplerStates(0), mFrameAlloc(nullptr),
-		mParamBlocks(nullptr), mParamBlockBuffers(nullptr), mTextures(nullptr), mSamplerStates(nullptr), mCoreDirtyFlags(0xFFFFFFFF)
+		mParamBlocks(nullptr), mParamBlockBuffers(nullptr), mTextures(nullptr), mSamplerStates(nullptr), mCoreDirtyFlags(0xFFFFFFFF),
+		mIsDestroyed(false)
 	{ }
 
 	GpuParams::GpuParams(GpuParamDesc& paramDesc, bool transposeMatrices)
@@ -38,46 +39,7 @@ namespace BansheeEngine
 				mInternalData->mNumSamplerStates = sampler.second.slot + 1;
 		}
 
-		// Allocate everything in a single block of memory to get rid of extra memory allocations
-		UINT32 bufferSize = 0;
-		UINT32 paramBlockOffset = 0;
-		UINT32 paramBlockBufferOffset = 0;
-		UINT32 textureOffset = 0;
-		UINT32 samplerStateOffset = 0;
-
-		getInternalBufferData(bufferSize, paramBlockOffset, paramBlockBufferOffset, textureOffset, samplerStateOffset);
-
-		mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
-		mInternalData->mParamBlocks = (GpuParamBlockPtr*)(mInternalData->mData + paramBlockOffset);
-		mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)(mInternalData->mData + paramBlockBufferOffset);
-		mInternalData->mTextures = (HTexture*)(mInternalData->mData + textureOffset);
-		mInternalData->mSamplerStates = (HSamplerState*)(mInternalData->mData + samplerStateOffset);
-
-		// Ensure everything is constructed
-		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
-		{
-			{
-				GpuParamBlockPtr* ptrToIdx = (&mInternalData->mParamBlocks[i]);
-				ptrToIdx = new (&mInternalData->mParamBlocks[i]) GpuParamBlockPtr(nullptr);
-			}
-
-			{
-				GpuParamBlockBufferPtr* ptrToIdx = (&mInternalData->mParamBlockBuffers[i]);
-				ptrToIdx = new (&mInternalData->mParamBlockBuffers[i]) GpuParamBlockBufferPtr(nullptr);
-			}
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
-		{
-			HTexture* ptrToIdx = (&mInternalData->mTextures[i]);
-			ptrToIdx = new (&mInternalData->mTextures[i]) HTexture();
-		}
-
-		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
-		{
-			HSamplerState* ptrToIdx = (&mInternalData->mSamplerStates[i]);
-			ptrToIdx = new (&mInternalData->mSamplerStates[i]) HSamplerState();
-		}
+		constructInternalBuffers();
 	}
 
 	GpuParams::GpuParams(GpuParamDesc& paramDesc, PrivatelyConstruct& dummy)
@@ -266,14 +228,6 @@ namespace BansheeEngine
 
 	GpuParamsPtr GpuParams::_cloneForCore(FrameAlloc* frameAlloc) const
 	{
-		UINT32 bufferSize = 0;
-		UINT32 paramBlockOffset = 0;
-		UINT32 paramBlockBufferOffset = 0;
-		UINT32 textureOffset = 0;
-		UINT32 samplerStateOffset = 0;
-
-		getInternalBufferData(bufferSize, paramBlockOffset, paramBlockBufferOffset, textureOffset, samplerStateOffset);
-
 		GpuParamsPtr myClone = nullptr;
 		
 		if (frameAlloc != nullptr)
@@ -281,14 +235,11 @@ namespace BansheeEngine
 			StdFrameAlloc<GpuParams> myAlloc(frameAlloc);
 			myClone = std::allocate_shared<GpuParams>(myAlloc, mParamDesc, PrivatelyConstruct());
 			myClone->mInternalData = std::allocate_shared<GpuParamsInternalData>(myAlloc);
-			myClone->mInternalData->mData = frameAlloc->alloc(bufferSize);
-			myClone->mInternalData->mFrameAlloc = frameAlloc;
 		}
 		else
 		{
 			myClone = bs_shared_ptr<GpuParams>(mParamDesc, PrivatelyConstruct());;
 			myClone->mInternalData = bs_shared_ptr<GpuParamsInternalData>();
-			myClone->mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
 		}
 		
 		myClone->mInternalData->mIsDestroyed = mInternalData->mIsDestroyed;
@@ -297,10 +248,7 @@ namespace BansheeEngine
 		myClone->mInternalData->mNumTextures = mInternalData->mNumTextures;
 		myClone->mInternalData->mNumSamplerStates = mInternalData->mNumSamplerStates;
 
-		myClone->mInternalData->mParamBlocks = (GpuParamBlockPtr*)(myClone->mInternalData->mData + paramBlockOffset);
-		myClone->mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)(myClone->mInternalData->mData + paramBlockBufferOffset);
-		myClone->mInternalData->mTextures = (HTexture*)(myClone->mInternalData->mData + textureOffset);
-		myClone->mInternalData->mSamplerStates = (HSamplerState*)(myClone->mInternalData->mData + samplerStateOffset);
+		myClone->constructInternalBuffers(frameAlloc);
 
 		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
 		{
@@ -336,10 +284,16 @@ namespace BansheeEngine
 		return myClone;
 	}
 
-	void GpuParams::getInternalBufferData(UINT32& bufferSize, UINT32& paramBlockOffset, UINT32& paramBlockBufferOffset,
-		UINT32& textureOffset, UINT32& samplerStateOffset) const
+	void GpuParams::constructInternalBuffers(FrameAlloc* frameAlloc)
 	{
-		UINT32 paramBlockBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlock*);
+		// Allocate everything in a single block of memory to get rid of extra memory allocations
+		UINT32 bufferSize = 0;
+		UINT32 paramBlockOffset = 0;
+		UINT32 paramBlockBufferOffset = 0;
+		UINT32 textureOffset = 0;
+		UINT32 samplerStateOffset = 0;
+
+		UINT32 paramBlockBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlockPtr);
 		UINT32 paramBlockBuffersBufferSize = mInternalData->mNumParamBlocks * sizeof(GpuParamBlockBufferPtr);
 		UINT32 textureBufferSize = mInternalData->mNumTextures * sizeof(HTexture);
 		UINT32 samplerStateBufferSize = mInternalData->mNumSamplerStates * sizeof(HSamplerState);
@@ -349,6 +303,48 @@ namespace BansheeEngine
 		paramBlockBufferOffset = paramBlockOffset + paramBlockBufferSize;
 		textureOffset = paramBlockBufferOffset + paramBlockBuffersBufferSize;
 		samplerStateOffset = textureOffset + textureBufferSize;
+
+		if (frameAlloc != nullptr)
+		{
+			mInternalData->mData = frameAlloc->alloc(bufferSize);
+			mInternalData->mFrameAlloc = frameAlloc;
+		}
+		else
+		{
+			mInternalData->mData = (UINT8*)bs_alloc(bufferSize);
+			mInternalData->mFrameAlloc = nullptr;
+		}
+
+		mInternalData->mParamBlocks = (GpuParamBlockPtr*)(mInternalData->mData + paramBlockOffset);
+		mInternalData->mParamBlockBuffers = (GpuParamBlockBufferPtr*)(mInternalData->mData + paramBlockBufferOffset);
+		mInternalData->mTextures = (HTexture*)(mInternalData->mData + textureOffset);
+		mInternalData->mSamplerStates = (HSamplerState*)(mInternalData->mData + samplerStateOffset);
+
+		// Ensure everything is constructed
+		for (UINT32 i = 0; i < mInternalData->mNumParamBlocks; i++)
+		{
+			{
+				GpuParamBlockPtr* ptrToIdx = (&mInternalData->mParamBlocks[i]);
+				ptrToIdx = new (&mInternalData->mParamBlocks[i]) GpuParamBlockPtr(nullptr);
+			}
+
+			{
+			GpuParamBlockBufferPtr* ptrToIdx = (&mInternalData->mParamBlockBuffers[i]);
+			ptrToIdx = new (&mInternalData->mParamBlockBuffers[i]) GpuParamBlockBufferPtr(nullptr);
+		}
+		}
+
+		for (UINT32 i = 0; i < mInternalData->mNumTextures; i++)
+		{
+			HTexture* ptrToIdx = (&mInternalData->mTextures[i]);
+			ptrToIdx = new (&mInternalData->mTextures[i]) HTexture();
+		}
+
+		for (UINT32 i = 0; i < mInternalData->mNumSamplerStates; i++)
+		{
+			HSamplerState* ptrToIdx = (&mInternalData->mSamplerStates[i]);
+			ptrToIdx = new (&mInternalData->mSamplerStates[i]) HSamplerState();
+		}
 	}
 
 	bool GpuParams::_isCoreDirty() const 

+ 4 - 2
BansheeCore/Source/BsMesh.cpp

@@ -276,6 +276,8 @@ namespace BansheeEngine
 		{
 			updateBounds(*mTempInitialMeshData);
 		}
+
+		MeshBase::initialize();
 	}
 
 	void Mesh::initialize_internal()
@@ -311,14 +313,14 @@ namespace BansheeEngine
 			mTempInitialMeshData = nullptr;
 		}
 
-		Resource::initialize_internal();
+		MeshBase::initialize_internal();
 	}
 
 	void Mesh::destroy_internal()
 	{
 		THROW_IF_NOT_CORE_THREAD;
 
-		Resource::destroy_internal();
+		MeshBase::destroy_internal();
 	}
 
 	void Mesh::updateBounds(const MeshData& meshData)

+ 4 - 0
BansheeCore/Source/BsRendererManager.cpp

@@ -13,7 +13,11 @@ namespace BansheeEngine
 				RendererPtr newRenderer = (*iter)->create();
 				if(newRenderer != nullptr)
 				{
+					if (mActiveRenderer != nullptr)
+						mActiveRenderer->_onDeactivated();
+
 					mActiveRenderer = newRenderer;
+					mActiveRenderer->_onActivated();
 				}				
 			}
 		}

+ 1 - 1
BansheeCore/Source/BsShader.cpp

@@ -84,7 +84,7 @@ namespace BansheeEngine
 		markCoreDirty();
 	}
 
-	void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 arraySize, UINT32 elementSize, UINT32 rendererSemantic)
+	void Shader::addParameter(const String& name, const String& gpuVariableName, GpuParamDataType type, UINT32 rendererSemantic, UINT32 arraySize, UINT32 elementSize)
 	{
 		if(type == GPDT_STRUCT && elementSize <= 0)
 			BS_EXCEPT(InvalidParametersException, "You need to provide a non-zero element size for a struct parameter.")

+ 10 - 0
BansheeRenderer/Include/BsBansheeRenderer.h

@@ -41,6 +41,16 @@ namespace BansheeEngine
 		 */
 		virtual void renderAll();
 
+		/**
+		 * @copydoc	Renderer::_onActivated
+		 */
+		virtual void _onActivated();
+
+		/**
+		 * @copydoc	Renderer::_onDeactivated
+		 */
+		virtual void _onDeactivated();
+
 	private:
 		void addRenderableProxy(RenderableProxyPtr proxy);
 		void removeRenderableProxy(RenderableProxyPtr proxy);

+ 37 - 21
BansheeRenderer/Source/BsBansheeLitTexRenderableHandler.cpp

@@ -19,7 +19,7 @@ namespace BansheeEngine
 		TechniquePtr defaultTechnique = defaultShader->getBestTechnique();
 		PassPtr defaultPass = defaultTechnique->getPass(0);
 
-		bool matrixTranspose = defaultPass->getVertexProgram()->requiresMatrixTranspose(); // This is a static setting across all GPU programs
+		bool matrixTranspose = defaultPass->getVertexProgram()->requiresMatrixTranspose(); // Only need this from first vertex program as this is a static setting across all GPU programs
 		const GpuParamDesc& vertParamDesc = defaultPass->getVertexProgram()->getParamDesc();
 		const GpuParamDesc& fragParamDesc = defaultPass->getFragmentProgram()->getParamDesc();
 
@@ -27,82 +27,98 @@ namespace BansheeEngine
 		GpuParamDesc perFrameParamsDesc;
 		GpuParamDesc perObjectParamsDesc;
 
+		bool foundLightDir = false;
+		bool foundTime = false;
+		bool foundWVP = false;
+		bool foundStatic = false;
+		bool foundPerFrame = false;
+		bool foundPerObject = false;
+
 		const Map<String, SHADER_DATA_PARAM_DESC>& dataParams = defaultShader->_getDataParams();
 		for (auto& param : dataParams)
 		{
-			if (param.second.rendererSemantic == RPS_LightDir)
+			if (!foundLightDir && param.second.rendererSemantic == RPS_LightDir)
 			{
 				auto iterFind = fragParamDesc.params.find(param.second.gpuVariableName);
 				if (iterFind == fragParamDesc.params.end())
-					BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+					continue;
 
 				lightDirParamDesc = iterFind->second;
 				staticParamsDesc.params[iterFind->first] = iterFind->second;
+				foundLightDir = true;
 			}
-			else if (param.second.rendererSemantic == RPS_Time)
+			else if (!foundTime && param.second.rendererSemantic == RPS_Time)
 			{
 				auto iterFind = vertParamDesc.params.find(param.second.gpuVariableName);
 				if (iterFind == vertParamDesc.params.end())
-					BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+					continue;
 
 				timeParamDesc = iterFind->second;
 				perFrameParamsDesc.params[iterFind->first] = iterFind->second;
+				foundTime = true;
 			}
-			else if (param.second.rendererSemantic == RPS_WorldViewProjTfrm)
+			else if (!foundWVP && param.second.rendererSemantic == RPS_WorldViewProjTfrm)
 			{
 				auto iterFind = vertParamDesc.params.find(param.second.gpuVariableName);
 				if (iterFind == vertParamDesc.params.end())
-					BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+					continue;
 
 				wvpParamDesc = iterFind->second;
 				perObjectParamsDesc.params[iterFind->first] = iterFind->second;
+				foundWVP = true;
 			}
 		}
 
 		const Map<String, SHADER_PARAM_BLOCK_DESC>& paramBlocks = defaultShader->_getParamBlocks();
 		for (auto& block : paramBlocks)
 		{
-			if (block.second.rendererSemantic == RBS_Static)
+			if (!foundStatic && block.second.rendererSemantic == RBS_Static)
 			{
-				auto iterFind = vertParamDesc.paramBlocks.find(block.second.name);
-				if (iterFind == vertParamDesc.paramBlocks.end())
-					BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+				auto iterFind = fragParamDesc.paramBlocks.find(block.second.name);
+				if (iterFind == fragParamDesc.paramBlocks.end())
+					continue;
 
 				staticParamBlockDesc = iterFind->second;
 				staticParamsDesc.paramBlocks[iterFind->first] = iterFind->second;
+				foundStatic = true;
 			}
-			else if (block.second.rendererSemantic == RBS_PerFrame)
+			else if (!foundPerFrame && block.second.rendererSemantic == RBS_PerFrame)
 			{
-				auto iterFind = fragParamDesc.paramBlocks.find(block.second.name);
-				if (iterFind == fragParamDesc.paramBlocks.end())
-					BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+				auto iterFind = vertParamDesc.paramBlocks.find(block.second.name);
+				if (iterFind == vertParamDesc.paramBlocks.end())
+					continue;
 
 				perFrameParamBlockDesc = iterFind->second;
 				perFrameParamsDesc.paramBlocks[iterFind->first] = iterFind->second;
+				foundPerFrame = true;
 			}
-			else if (block.second.rendererSemantic == RBS_PerObject)
+			else if (!foundPerObject && block.second.rendererSemantic == RBS_PerObject)
 			{
 				auto iterFind = vertParamDesc.paramBlocks.find(block.second.name);
 				if (iterFind == vertParamDesc.paramBlocks.end())
-					BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+					continue;
 
 				perObjectParamBlockDesc = iterFind->second;
 				perObjectParamsDesc.paramBlocks[iterFind->first] = iterFind->second;
+				foundPerObject = true;
 			}
 		}
 
+		if (!foundLightDir || !foundLightDir || !foundWVP || !foundStatic || !foundPerFrame || !foundPerObject)
+			BS_EXCEPT(InternalErrorException, "Invalid default shader.");
+
 		// Create global GPU param buffers and get parameter handles
 		staticParams = bs_shared_ptr<GpuParams>(staticParamsDesc, matrixTranspose);
 		perFrameParams = bs_shared_ptr<GpuParams>(perFrameParamsDesc, matrixTranspose);
 
-		staticParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(staticParamBlockDesc.blockSize);
-		perFrameParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(perFrameParamBlockDesc.blockSize);
+		staticParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(staticParamBlockDesc.blockSize * sizeof(UINT32));
+		perFrameParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(perFrameParamBlockDesc.blockSize * sizeof(UINT32));
 
 		staticParams->setParamBlockBuffer(staticParamBlockDesc.slot, staticParamBuffer);
 		perFrameParams->setParamBlockBuffer(perFrameParamBlockDesc.slot, perFrameParamBuffer);
 
 		staticParams->getParam(lightDirParamDesc.name, lightDirParam);
-		staticParams->getParam(timeParamDesc.name, timeParam);
+		perFrameParams->getParam(timeParamDesc.name, timeParam);
 
 		lightDirParam.set(Vector4(0.707f, 0.707f, 0.707f, 0.0f));
 	}
@@ -193,7 +209,7 @@ namespace BansheeEngine
 						if (findIter->second.blockSize == perObjectParamBlockDesc.blockSize)
 						{
 							if (rendererData->perObjectParamBuffer == nullptr)
-								rendererData->perObjectParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(perObjectParamBlockDesc.blockSize);
+								rendererData->perObjectParamBuffer = HardwareBufferManager::instance().createGpuParamBlockBuffer(perObjectParamBlockDesc.blockSize * sizeof(UINT32));
 
 							rendererData->perObjectBuffers.push_back(MaterialProxy::BufferBindInfo(idx, findIter->second.slot, rendererData->perObjectParamBuffer));
 

+ 19 - 10
BansheeRenderer/Source/BsBansheeRenderer.cpp

@@ -38,14 +38,10 @@ namespace BansheeEngine
 	{
 		mRenderableRemovedConn = gBsSceneManager().onRenderableRemoved.connect(std::bind(&BansheeRenderer::renderableRemoved, this, _1));
 		mCameraRemovedConn = gBsSceneManager().onCameraRemoved.connect(std::bind(&BansheeRenderer::cameraRemoved, this, _1));
-
-		mLitTexHandler = bs_new<LitTexRenderableHandler>();
 	}
 
 	BansheeRenderer::~BansheeRenderer()
 	{
-		bs_delete(mLitTexHandler);
-
 		mRenderableRemovedConn.disconnect();
 		mCameraRemovedConn.disconnect();
 	}
@@ -56,6 +52,22 @@ namespace BansheeEngine
 		return name;
 	}
 
+	void BansheeRenderer::_onActivated()
+	{
+		Renderer::_onActivated();
+
+		mLitTexHandler = bs_new<LitTexRenderableHandler>();
+		mLitTexHandler = nullptr;
+	}
+
+	void BansheeRenderer::_onDeactivated()
+	{
+		Renderer::_onDeactivated();
+
+		if (mLitTexHandler != nullptr)
+			bs_delete(mLitTexHandler);
+	}
+
 	void BansheeRenderer::addRenderableProxy(RenderableProxyPtr proxy)
 	{
 		for (auto& element : proxy->renderableElements)
@@ -204,12 +216,10 @@ namespace BansheeEngine
 		for (auto& renderable : allRenderables)
 		{
 			bool addedNewProxy = false;
-			RenderableProxyPtr proxy;
+			RenderableProxyPtr proxy = renderable->_getActiveProxy();
 
-			if (!renderable->_isCoreDirty())
+			if (renderable->_isCoreDirty())
 			{
-				proxy = renderable->_getActiveProxy();
-
 				if (proxy != nullptr)
 					gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::removeRenderableProxy, this, proxy));
 
@@ -222,9 +232,8 @@ namespace BansheeEngine
 				dirtySceneObjects.push_back(renderable->SO());
 				addedNewProxy = true;
 			}
-			else if (!renderable->SO()->_isCoreDirty())
+			else if (renderable->SO()->_isCoreDirty())
 			{
-				proxy = renderable->_getActiveProxy();
 				assert(proxy != nullptr);
 
 				gCoreAccessor().queueCommand(std::bind(&BansheeRenderer::updateRenderableProxy, this, proxy, renderable->SO()->getWorldTfrm()));