Kaynağa Gözat

More material and renderer stuff

Marko Pintera 13 yıl önce
ebeveyn
işleme
12b3f490bc

+ 8 - 3
CamelotRenderer/CamelotRenderer.vcxproj

@@ -103,7 +103,7 @@
     <ClInclude Include="Include\CmComponentRTTI.h" />
     <ClInclude Include="Include\CmConfigOptionMap.h" />
     <ClInclude Include="Include\CmDefaultHardwareBufferManager.h" />
-    <ClInclude Include="Include\CmForwardRenderManager.h" />
+    <ClInclude Include="Include\CmForwardRenderer.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
@@ -118,6 +118,7 @@
     <ClInclude Include="Include\CmImporter.h" />
     <ClInclude Include="Include\CmInput.h" />
     <ClInclude Include="Include\CmInputHandler.h" />
+    <ClInclude Include="Include\CmMaterial.h" />
     <ClInclude Include="Include\CmMesh.h" />
     <ClInclude Include="Include\CmMeshData.h" />
     <ClInclude Include="Include\CmMeshDataRTTI.h" />
@@ -125,7 +126,9 @@
     <ClInclude Include="Include\CmPrerequisites.h" />
     <ClInclude Include="Include\CmRenderable.h" />
     <ClInclude Include="Include\CmRenderableRTTI.h" />
-    <ClInclude Include="Include\CmRenderManager.h" />
+    <ClInclude Include="Include\CmRenderer.h" />
+    <ClInclude Include="Include\CmRendererFactory.h" />
+    <ClInclude Include="Include\CmRendererManager.h" />
     <ClInclude Include="Include\CmRenderOperation.h" />
     <ClInclude Include="Include\CmRenderSystem.h" />
     <ClInclude Include="Include\CmRenderSystemCapabilities.h" />
@@ -162,7 +165,7 @@
     <ClCompile Include="Source\CmCgProgram.cpp" />
     <ClCompile Include="Source\CmCgProgramFactory.cpp" />
     <ClCompile Include="Source\CmDefaultHardwareBufferManager.cpp" />
-    <ClCompile Include="Source\CmForwardRenderManager.cpp" />
+    <ClCompile Include="Source\CmForwardRenderer.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />
@@ -175,10 +178,12 @@
     <ClCompile Include="Source\CmHighLevelGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmImporter.cpp" />
     <ClCompile Include="Source\CmInput.cpp" />
+    <ClCompile Include="Source\CmMaterial.cpp" />
     <ClCompile Include="Source\CmMesh.cpp" />
     <ClCompile Include="Source\CmMeshData.cpp" />
     <ClCompile Include="Source\CmPass.cpp" />
     <ClCompile Include="Source\CmRenderable.cpp" />
+    <ClCompile Include="Source\CmRendererManager.cpp" />
     <ClCompile Include="Source\CmRenderSystem.cpp" />
     <ClCompile Include="Source\CmRenderSystemCapabilities.cpp" />
     <ClCompile Include="Source\CmRenderSystemManager.cpp" />

+ 24 - 9
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -232,12 +232,6 @@
     <ClInclude Include="Include\CmInputHandler.h">
       <Filter>Header Files\Input</Filter>
     </ClInclude>
-    <ClInclude Include="Include\CmRenderManager.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="Include\CmForwardRenderManager.h">
-      <Filter>Header Files\MOVETODLL</Filter>
-    </ClInclude>
     <ClInclude Include="Include\CmComponentRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
@@ -259,6 +253,21 @@
     <ClInclude Include="Include\CmShader.h">
       <Filter>Header Files\Material</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmMaterial.h">
+      <Filter>Header Files\Material</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmForwardRenderer.h">
+      <Filter>Header Files\MOVETODLL</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmRenderer.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmRendererManager.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmRendererFactory.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -375,9 +384,6 @@
     <ClCompile Include="Source\CmInput.cpp">
       <Filter>Source Files\Input</Filter>
     </ClCompile>
-    <ClCompile Include="Source\CmForwardRenderManager.cpp">
-      <Filter>Source Files\MOVETODLL</Filter>
-    </ClCompile>
     <ClCompile Include="Source\CmRenderable.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -390,5 +396,14 @@
     <ClCompile Include="Source\CmTechnique.cpp">
       <Filter>Source Files\Material</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmMaterial.cpp">
+      <Filter>Source Files\Material</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmForwardRenderer.cpp">
+      <Filter>Source Files\MOVETODLL</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmRendererManager.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 4 - 2
CamelotRenderer/Include/CmForwardRenderManager.h → CamelotRenderer/Include/CmForwardRenderer.h

@@ -1,13 +1,15 @@
 #pragma once
 
 #include "CmPrerequisites.h"
-#include "CmRenderManager.h"
+#include "CmRenderer.h"
 
 namespace CamelotEngine
 {
-	class ForwardRenderManager : public RenderManager
+	class ForwardRenderer : public Renderer
 	{
 	public:
+		virtual const String& getName() const;
+
 		virtual void renderAll();
 
 		virtual void render(const CameraPtr camera);

+ 33 - 0
CamelotRenderer/Include/CmMaterial.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotEngine
+{
+	class Material
+	{
+		// Required for initialization
+		void setShader(ShaderPtr shader);
+
+		void setTexture(const String& name, TexturePtr value);
+		void setFloat(const String& name, float value);
+		void setColor(const String& name, const Color& value);
+		void setVec(const String& name, const Vector2& value);
+		void setVec(const String& name, const Vector3& value);
+		void setVec(const String& name, const Vector4& value);
+		void setMat(const String& name, const Matrix3& value);
+		void setMat(const String& name, const Matrix4& value);
+
+		/**
+		 * @brief	Use the provided pass for rendering of all following objects.
+		 */
+		void applyPass(UINT32 passIdx);
+
+		UINT32 getNumPasses() const;
+
+	private:
+		ShaderPtr mShader;
+
+		void throwIfNotInitialized() const;
+	};
+}

+ 4 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -99,6 +99,8 @@ namespace CamelotEngine {
 	class Input;
 	class InputHandler;
 	class Renderable;
+	class Renderer;
+	class RendererFactory;
 	// Asset import
 	class SpecificImporter;
 	class Importer;
@@ -130,6 +132,8 @@ namespace CamelotEngine
 	typedef std::shared_ptr<Technique> TechniquePtr;
 	typedef std::shared_ptr<Pass> PassPtr;
 	typedef std::shared_ptr<Shader> ShaderPtr;
+	typedef std::shared_ptr<Renderer> RendererPtr;
+	typedef std::shared_ptr<RendererFactory> RendererFactoryPtr;
 
 	typedef std::shared_ptr<Component> ComponentPtr;
 	typedef std::shared_ptr<GameObject> GameObjectPtr;

+ 3 - 1
CamelotRenderer/Include/CmRenderManager.h → CamelotRenderer/Include/CmRenderer.h

@@ -4,9 +4,11 @@
 
 namespace CamelotEngine
 {
-	class RenderManager
+	class Renderer
 	{
 	public:
+		virtual const String& getName() const = 0;
+
 		/**
 		 * @brief	Renders all cameras.
 		 */

+ 13 - 0
CamelotRenderer/Include/CmRendererFactory.h

@@ -0,0 +1,13 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+
+namespace CamelotEngine
+{
+	class RendererFactory
+	{
+	public:
+		virtual RendererPtr create() = 0;
+		virtual const std::string& name() const = 0;
+	};
+}

+ 21 - 0
CamelotRenderer/Include/CmRendererManager.h

@@ -0,0 +1,21 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmRendererFactory.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT RendererManager
+	{
+	public:
+		static void initialize(const String& name);
+		static RendererPtr getActive() { return mActiveRenderer; }
+
+		static void registerFactory(RendererFactoryPtr factory);
+	private:
+		static std::vector<RendererFactoryPtr>& getAvailableFactories();
+
+		static RendererPtr mActiveRenderer;
+	};
+}
+

+ 6 - 0
CamelotRenderer/Include/CmShader.h

@@ -25,6 +25,12 @@ namespace CamelotEngine
 
 		UINT32 getNumTechniques() const { return mTechniques.size(); }
 
+		/**
+		 * @brief	Gets the best supported technique based on current render and other systems.
+		 * 			Throws an exception if not a single technique is supported.
+		 */
+		TechniquePtr getBestTechnique() const;
+
 	private:
 		String mName;
 		vector<TechniquePtr>::type mTechniques;

+ 5 - 3
CamelotRenderer/Include/CmTechnique.h

@@ -7,16 +7,18 @@ namespace CamelotEngine
 	class CM_EXPORT Technique
 	{
 	public:
-		Technique(const String& renderSystem, const String& renderManager);
+		Technique(const String& renderSystem, const String& renderer);
 
 		void addPass(PassPtr pass);
 		void removePass(UINT32 idx);
 
-		UINT32 getNumPassess() const { return mPasses.size(); }
+		UINT32 getNumPasses() const { return mPasses.size(); }
+
+		bool isSupported() const;
 
 	private:
 		String mRenderSystem;
-		String mRenderManager;
+		String mRenderer;
 
 		vector<PassPtr>::type mPasses;
 	};

+ 41 - 41
CamelotRenderer/Source/CmApplication.cpp

@@ -83,54 +83,54 @@ namespace CamelotEngine
 
 
 		/////////////////// CG SHADERS //////////////////////////
-		String fragShaderCode = "sampler2D diffuseMap;			\
-			float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
-		{														\
-			float4 color = tex2D(diffuseMap, uv);				\
-			return color;										\
-		}";
-
-		mFragProg =  HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "ps_main", "cg", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-		mFragProg->load();
+		//String fragShaderCode = "sampler2D diffuseMap;			\
+		//	float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
+		//{														\
+		//	float4 color = tex2D(diffuseMap, uv);				\
+		//	return color;										\
+		//}";
 
-		String vertShaderCode = "float4x4 matViewProjection;	\
-								void vs_main(										\
-								float4 inPos : POSITION,							\
-								float2 uv : TEXCOORD0,								\
-								out float4 oPosition : POSITION,					\
-								out float2 oUv : TEXCOORD0)							\
-								{														\
-								oPosition = mul(matViewProjection, inPos);			\
-								oUv = uv;											\
-								}";
-
-		mVertProg =  HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		mVertProg->load();
+		//mFragProg =  HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "ps_main", "cg", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		//mFragProg->load();
+
+		//String vertShaderCode = "float4x4 matViewProjection;	\
+		//						void vs_main(										\
+		//						float4 inPos : POSITION,							\
+		//						float2 uv : TEXCOORD0,								\
+		//						out float4 oPosition : POSITION,					\
+		//						out float2 oUv : TEXCOORD0)							\
+		//						{														\
+		//						oPosition = mul(matViewProjection, inPos);			\
+		//						oUv = uv;											\
+		//						}";
+
+		//mVertProg =  HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		//mVertProg->load();
 		
 
 
 		///////////////// GLSL SHADERS ////////////////////////////
-		//String fragShaderCode = "uniform sampler2D tex; \
-		//							void main() \
-		//							  {\
-		//							  vec4 texColor = texture2D(tex,gl_TexCoord[0].st);\
-		//							  gl_FragColor = texColor; \
-		//							  }";
-
-		//mFragProg = HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-		//mFragProg->load();
+		String fragShaderCode = "uniform sampler2D tex; \
+									void main() \
+									  {\
+									  vec4 texColor = texture2D(tex,gl_TexCoord[0].st);\
+									  gl_FragColor = texColor; \
+									  }";
+
+		mFragProg = HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+		mFragProg->load();
 
-		//// TODO - Ogres GLSL parsing requires some strict parameter naming, can that be avoided?
-		//String vertShaderCode = "uniform mat4 matViewProjection; \
-		//							  attribute vec4 vertex; \
-		//						void main() \
-		//							  { \
-		//							  gl_TexCoord[0] = gl_MultiTexCoord0; \
-		//							  gl_Position = matViewProjection * vertex; \
-		//							  }";
+		// TODO - Ogres GLSL parsing requires some strict parameter naming, can that be avoided?
+		String vertShaderCode = "uniform mat4 matViewProjection; \
+									  attribute vec4 vertex; \
+								void main() \
+									  { \
+									  gl_TexCoord[0] = gl_MultiTexCoord0; \
+									  gl_Position = matViewProjection * vertex; \
+									  }";
 
-		//mVertProg = HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		//mVertProg->load();
+		mVertProg = HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+		mVertProg->load();
 
 
 		// IMPORTER TEST

+ 9 - 3
CamelotRenderer/Source/CmForwardRenderManager.cpp → CamelotRenderer/Source/CmForwardRenderer.cpp

@@ -1,10 +1,16 @@
-#include "CmForwardRenderManager.h"
+#include "CmForwardRenderer.h"
 #include "CmCamera.h"
 #include "CmSceneManager.h"
 
 namespace CamelotEngine
 {
-	void ForwardRenderManager::renderAll() 
+	const String& ForwardRenderer::getName() const
+	{
+		static String name = "ForwardRenderer";
+		return name;
+	}
+
+	void ForwardRenderer::renderAll() 
 	{
 		const vector<CameraPtr>::type& allCameras = gSceneManager().getAllCameras();
 
@@ -14,7 +20,7 @@ namespace CamelotEngine
 		}
 	}
 
-	void ForwardRenderManager::render(const CameraPtr camera) 
+	void ForwardRenderer::render(const CameraPtr camera) 
 	{
 		vector<RenderablePtr>::type allRenderables = gSceneManager().getVisibleRenderables(camera);
 

+ 74 - 0
CamelotRenderer/Source/CmMaterial.cpp

@@ -0,0 +1,74 @@
+#include "CmMaterial.h"
+#include "CmException.h"
+#include "CmShader.h"
+#include "CmTechnique.h"
+
+namespace CamelotEngine
+{
+	void Material::setShader(ShaderPtr shader)
+	{
+		mShader = shader;
+	}
+
+	void Material::throwIfNotInitialized() const
+	{
+		if(mShader == nullptr)
+		{
+			CM_EXCEPT(InternalErrorException, "Material does not have shader set.");
+		}
+	}
+
+	void Material::setTexture(const String& name, TexturePtr value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setFloat(const String& name, float value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setColor(const String& name, const Color& value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setVec(const String& name, const Vector2& value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setVec(const String& name, const Vector3& value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setVec(const String& name, const Vector4& value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setMat(const String& name, const Matrix3& value)
+	{
+		throwIfNotInitialized();
+	}
+
+	void Material::setMat(const String& name, const Matrix4& value)
+	{
+		throwIfNotInitialized();
+	}
+
+	UINT32 Material::getNumPasses() const
+	{
+		throwIfNotInitialized();
+
+		return mShader->getBestTechnique()->getNumPasses();
+	}
+
+	void Material::applyPass(UINT32 passIdx)
+	{
+		throwIfNotInitialized();
+
+
+	}
+}

+ 55 - 0
CamelotRenderer/Source/CmRendererManager.cpp

@@ -0,0 +1,55 @@
+#include "CmRendererManager.h"
+#include "CmException.h"
+#include "CmRenderer.h"
+#include "CmDynLib.h"
+#include "CmDynLibManager.h"
+
+namespace CamelotEngine
+{
+	RendererPtr RendererManager::mActiveRenderer;
+
+	void RendererManager::initialize(const String& pluginFilename)
+	{
+		DynLib* loadedLibrary = gDynLibManager().load(pluginFilename);
+		String name = "";
+
+		if(loadedLibrary != nullptr)
+		{
+			typedef const String& (*GetPluginNameFunc)();
+
+			GetPluginNameFunc getPluginNameFunc = (GetPluginNameFunc)loadedLibrary->getSymbol("getPluginName");
+			name = getPluginNameFunc();
+		}
+
+		for(auto iter = getAvailableFactories().begin(); iter != getAvailableFactories().end(); ++iter)
+		{
+			if((*iter)->name() == name)
+			{
+				RendererPtr newRenderSystem = (*iter)->create();
+				if(newRenderSystem != nullptr)
+				{
+					mActiveRenderer = newRenderSystem;
+				}				
+			}
+		}
+
+		if(mActiveRenderer == nullptr)
+		{
+			CM_EXCEPT(InternalErrorException, 
+				"Cannot initialize renderer. Renderer with the name '" + name + "' cannot be found.")
+		}
+	}
+
+	void RendererManager::registerFactory(RendererFactoryPtr factory)
+	{
+		assert(factory != nullptr);
+
+		getAvailableFactories().push_back(factory);
+	}
+
+	std::vector<RendererFactoryPtr>& RendererManager::getAvailableFactories()
+	{
+		static std::vector<RendererFactoryPtr> availableFactories;
+		return availableFactories;
+	}
+}

+ 14 - 0
CamelotRenderer/Source/CmShader.cpp

@@ -1,4 +1,5 @@
 #include "CmShader.h"
+#include "CmTechnique.h"
 #include "CmException.h"
 #include "CmDebug.h"
 
@@ -45,4 +46,17 @@ namespace CamelotEngine
 
 		mTechniques.erase(iterFind);
 	}
+
+	TechniquePtr Shader::getBestTechnique() const
+	{
+		for(auto iter = mTechniques.begin(); iter != mTechniques.end(); ++iter)
+		{
+			if((*iter)->isSupported())
+				return *iter;
+		}
+
+		CM_EXCEPT(InternalErrorException, "No techniques are supported!");
+
+		// TODO - Low priority. Instead of throwing an exception use an extremely simple technique that will be supported almost everywhere as a fallback.
+	}
 }

+ 17 - 2
CamelotRenderer/Source/CmTechnique.cpp

@@ -1,10 +1,14 @@
 #include "CmTechnique.h"
 #include "CmException.h"
+#include "CmRenderSystemManager.h"
+#include "CmRenderSystem.h"
+#include "CmRendererManager.h"
+#include "CmRenderer.h"
 
 namespace CamelotEngine
 {
-	Technique::Technique(const String& renderSystem, const String& renderManager)
-		:mRenderSystem(renderSystem), mRenderManager(renderManager)
+	Technique::Technique(const String& renderSystem, const String& renderer)
+		:mRenderSystem(renderSystem), mRenderer(renderer)
 	{
 
 	}
@@ -29,4 +33,15 @@ namespace CamelotEngine
 
 		mPasses.erase(iter);
 	}
+
+	bool Technique::isSupported() const
+	{
+		if(RenderSystemManager::getActive()->getName() == mRenderSystem &&
+			RendererManager::getActive()->getName() == mRenderer)
+		{
+			return true;
+		}
+
+		return false;
+	}
 }