Browse Source

Shaders are now referenced via resource handle instead directly

Marko Pintera 11 years ago
parent
commit
05ad4ecf2d

+ 1 - 0
BansheeCore/Include/BsCorePrerequisites.h

@@ -341,6 +341,7 @@ namespace BansheeEngine
 	typedef ResourceHandle<BlendState> HBlendState;
 	typedef ResourceHandle<GpuProgInclude> HGpuProgInclude;
 	typedef ResourceHandle<Font> HFont;
+	typedef ResourceHandle<Shader> HShader;
 }
 
 namespace BansheeEngine

+ 3 - 3
BansheeCore/Include/BsMaterial.h

@@ -146,7 +146,7 @@ namespace BansheeEngine
 		template<> struct TTechniqueType < true > { typedef SPtr<TechniqueCore> Type; };
 
 		template<bool Core> struct TShaderType {};
-		template<> struct TShaderType < false > { typedef SPtr<Shader> Type; };
+		template<> struct TShaderType < false > { typedef HShader Type; };
 		template<> struct TShaderType < true > { typedef SPtr<ShaderCore> Type; };
 
 		template<bool Core> struct TGpuParamBlockBufferType {};
@@ -619,13 +619,13 @@ namespace BansheeEngine
 		/**
 		 * @brief	Creates a new material with the specified shader.
 		 */
-		static HMaterial create(ShaderPtr shader);
+		static HMaterial create(const HShader& shader);
 
 	private:
 		friend class MaterialManager;
 
 		Material() { }
-		Material(const ShaderPtr& shader);
+		Material(const HShader& shader);
 
 		/**
 		 * @copydoc	CoreObject::createCore

+ 1 - 1
BansheeCore/Include/BsMaterialManager.h

@@ -21,7 +21,7 @@ namespace BansheeEngine
 		/**
 		 * @brief	Creates a new material with the specified shader.
 		 */
-		MaterialPtr create(ShaderPtr shader) const;
+		MaterialPtr create(const HShader& shader) const;
 
 		/**
 		 * @brief	Creates a new empty material without initializing it.

+ 3 - 3
BansheeCore/Include/BsMaterialRTTI.h

@@ -540,12 +540,12 @@ namespace BansheeEngine
 	class BS_CORE_EXPORT MaterialRTTI : public RTTIType<Material, Resource, MaterialRTTI>
 	{
 	private:
-		ShaderPtr getShader(Material* obj)
+		HShader& getShader(Material* obj)
 		{
 			return obj->mShader;
 		}
 
-		void setShader(Material* obj, ShaderPtr val)
+		void setShader(Material* obj, HShader& val)
 		{
 			obj->mShader = val;
 		}
@@ -566,7 +566,7 @@ namespace BansheeEngine
 	public:
 		MaterialRTTI()
 		{
-			addReflectablePtrField("mShader", 0, &MaterialRTTI::getShader, &MaterialRTTI::setShader);
+			addReflectableField("mShader", 0, &MaterialRTTI::getShader, &MaterialRTTI::setShader);
 			addReflectablePtrField("mMaterialParams", 1, &MaterialRTTI::getMaterialParams, &MaterialRTTI::setMaterialParams);
 		}
 

+ 1 - 1
BansheeCore/Include/BsShader.h

@@ -299,7 +299,7 @@ namespace BansheeEngine
 		 * @brief	Returns an empty shader object with the specified name. Caller must register
 		 *			techniques with the shader before using it in a Material.
 		 */
-		static ShaderPtr create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
+		static HShader create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques);
 
 		/**
 		 * @brief	Returns a shader object but doesn't initialize it.

+ 25 - 4
BansheeCore/Source/BsMaterial.cpp

@@ -441,16 +441,37 @@ namespace BansheeEngine
 		return allParamDescs;
 	}
 
-	template<bool Core>
-	void TMaterial<Core>::setShader(ShaderType shader)
+	template<>
+	void TMaterial<true>::setShader(ShaderType shader)
+	{
+		mShader = shader;
+
+		initBestTechnique();
+
+		_markCoreDirty();
+	}
+
+	template<>
+	void TMaterial<false>::setShader(ShaderType shader)
 	{
 		mShader = shader;
+		if (mShader)
+		{
+			if (!mShader.isLoaded())
+			{
+				LOGWRN("Initializing a material with shader that is not yet loaded. Waiting until load is complete. This will result in a performance hit.");
+				mShader.blockUntilLoaded();
+
+				return; // Return because we rely on the resource listener to trigger initialization after load, so we don't do it twice
+			}
+		}
 
 		initBestTechnique();
 
 		_markCoreDirty();
 	}
 
+
 	template<bool Core>
 	UINT32 TMaterial<Core>::getNumPasses() const
 	{
@@ -876,7 +897,7 @@ namespace BansheeEngine
 		return materialPtr;
 	}
 
-	Material::Material(const ShaderPtr& shader)
+	Material::Material(const HShader& shader)
 	{
 		setShader(shader);
 	}
@@ -969,7 +990,7 @@ namespace BansheeEngine
 		return static_resource_cast<Material>(gResources()._createResourceHandle(materialPtr));
 	}
 
-	HMaterial Material::create(ShaderPtr shader)
+	HMaterial Material::create(const HShader& shader)
 	{
 		MaterialPtr materialPtr = MaterialManager::instance().create(shader);
 

+ 1 - 1
BansheeCore/Source/BsMaterialManager.cpp

@@ -12,7 +12,7 @@ namespace BansheeEngine
 		return newMat;
 	}
 
-	MaterialPtr MaterialManager::create(ShaderPtr shader) const
+	MaterialPtr MaterialManager::create(const HShader& shader) const
 	{
 		MaterialPtr newMat = bs_core_ptr<Material, PoolAlloc>(new (bs_alloc<Material, PoolAlloc>()) Material(shader));
 		newMat->_setThisPtr(newMat);

+ 2 - 2
BansheeCore/Source/BsMaterialRTTI.cpp

@@ -39,7 +39,7 @@ namespace BansheeEngine
 		Material* material = static_cast<Material*>(obj);
 		std::shared_ptr<MaterialParams> params = bs_shared_ptr<MaterialParams, ScratchAlloc>();
 
-		ShaderPtr shader = material->getShader();
+		HShader shader = material->getShader();
 		if(shader != nullptr)
 		{
 			const Map<String, String>& validParamNames = material->getValidParamNames();
@@ -212,7 +212,7 @@ namespace BansheeEngine
 
 		std::shared_ptr<MaterialParams> params = any_cast<std::shared_ptr<MaterialParams>>(material->mRTTIData);
 
-		ShaderPtr shader = material->getShader();
+		HShader shader = material->getShader();
 		if(shader != nullptr)
 		{
 			for(auto iter = params->floatParams.begin(); iter != params->floatParams.end(); ++iter)

+ 3 - 2
BansheeCore/Source/BsShader.cpp

@@ -3,6 +3,7 @@
 #include "BsException.h"
 #include "BsDebug.h"
 #include "BsShaderRTTI.h"
+#include "BsResources.h"
 #include "BsFrameAlloc.h"
 
 namespace BansheeEngine
@@ -245,13 +246,13 @@ namespace BansheeEngine
 		return false;
 	}
 
-	ShaderPtr Shader::create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques)
+	HShader Shader::create(const String& name, const SHADER_DESC& desc, const Vector<SPtr<Technique>>& techniques)
 	{
 		ShaderPtr newShader = bs_core_ptr<Shader, PoolAlloc>(new (bs_alloc<Shader, PoolAlloc>()) Shader(name, desc, techniques));
 		newShader->_setThisPtr(newShader);
 		newShader->initialize();
 
-		return newShader;
+		return static_resource_cast<Shader>(gResources()._createResourceHandle(newShader));
 	}
 
 	ShaderPtr Shader::createEmpty()

+ 11 - 11
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -160,17 +160,17 @@ namespace BansheeEngine
 		WString mActiveShaderSubFolder;
 		String mActiveRenderSystem;
 
-		ShaderPtr mShaderDockOverlay;
-		ShaderPtr mShaderSceneGrid;
-		ShaderPtr mShaderPicking[3];
-		ShaderPtr mShaderPickingAlpha[3];
-		ShaderPtr mShaderGizmoSolid;
-		ShaderPtr mShaderGizmoWire;
-		ShaderPtr mShaderGizmoIcon;
-		ShaderPtr mShaderGizmoPicking;
-		ShaderPtr mShaderGizmoAlphaPicking;
-		ShaderPtr mShaderHandleSolid;
-		ShaderPtr mShaderHandleWire;
+		HShader mShaderDockOverlay;
+		HShader mShaderSceneGrid;
+		HShader mShaderPicking[3];
+		HShader mShaderPickingAlpha[3];
+		HShader mShaderGizmoSolid;
+		HShader mShaderGizmoWire;
+		HShader mShaderGizmoIcon;
+		HShader mShaderGizmoPicking;
+		HShader mShaderGizmoAlphaPicking;
+		HShader mShaderHandleSolid;
+		HShader mShaderHandleWire;
 
 		GUISkin mSkin;
 

+ 1 - 1
BansheeEditor/Include/BsEditorApplication.h

@@ -43,7 +43,7 @@ namespace BansheeEngine
 		HGpuProgram mFragProgRef;
 		HGpuProgram mVertProgRef;
 
-		ShaderPtr mTestShader;
+		HShader mTestShader;
 		TechniquePtr mNewTechniqueGL;
 		PassPtr mNewPassGL;
 		TechniquePtr mNewTechniqueDX;

+ 3 - 0
BansheeEditor/Source/BsEditorApplication.cpp

@@ -293,10 +293,13 @@ namespace BansheeEngine
 		mTestTexRef->blockUntilCoreInitialized();
 
 		mTestMaterial->setTexture("tex", mTestTexRef);
+		gResources().save(mTestShader, L"C:\\ExportShader.asset", true);
 		gResources().save(mTestMaterial, L"C:\\ExportMaterial.mat", true);
 
 		gResources().unload(mTestMaterial);
+		gResources().unload(mTestShader);
 
+		mTestShader = gResources().load<Shader>(L"C:\\ExportShader.asset");
 		mTestMaterial = gResources().load<Material>(L"C:\\ExportMaterial.mat");
 
 		testRenderable->setMesh(mDbgMeshRef);

+ 4 - 4
BansheeEngine/Include/BsBuiltinResources.h

@@ -175,10 +175,10 @@ namespace BansheeEngine
 
 		HSpriteTexture mWhiteSpriteTexture;
 
-		ShaderPtr mShaderSpriteText;
-		ShaderPtr mShaderSpriteImage;
-		ShaderPtr mShaderSpriteNonAlphaImage;
-		ShaderPtr mShaderDummy;
+		HShader mShaderSpriteText;
+		HShader mShaderSpriteImage;
+		HShader mShaderSpriteNonAlphaImage;
+		HShader mShaderDummy;
 
 		WString mActiveShaderSubFolder;
 		String mActiveRenderSystem;

+ 5 - 0
BansheeRenderer/Source/BsBansheeLitTexRenderableController.cpp

@@ -133,6 +133,11 @@ namespace BansheeEngine
 		PerObjectData* rendererData = any_cast_unsafe<PerObjectData>(&element.rendererData);
 
 		SPtr<ShaderCore> shader = element.material->getShader();
+		if (shader == nullptr)
+		{
+			LOGWRN("Missing shader on material.");
+			return;
+		}
 
 		const Map<String, SHADER_PARAM_BLOCK_DESC>& paramBlockDescs = shader->getParamBlocks();
 		const Map<String, SHADER_DATA_PARAM_DESC>& dataParamDescs = shader->getDataParams();

+ 1 - 1
ExampleProject/Main/Main.cpp

@@ -264,7 +264,7 @@ namespace BansheeEngine
 
 		// Create a shader that references our vertex and fragment GPU programs, and set
 		// up shader input parameters. 
-		ShaderPtr exampleShader = Shader::create("ExampleShader", exampleShaderDesc,{ technique });
+		HShader exampleShader = Shader::create("ExampleShader", exampleShaderDesc, { technique });
 
 		/************************************************************************/
 		/* 							CREATE MATERIAL                      		*/