Переглянути джерело

Rendering meshes straight from GameObject

Marko Pintera 13 роки тому
батько
коміт
26bb37f13b

+ 140 - 8
CamelotClient/CamelotClient.cpp

@@ -6,8 +6,20 @@
 #include "CmApplication.h"
 #include "CmDynLibManager.h"
 
-#include "TestingGround.h"
-#include "CmIReflectable.h"
+#include "CmGameObject.h"
+#include "CmCamera.h"
+#include "CmHighLevelGpuProgramManager.h"
+#include "CmRenderSystemManager.h"
+#include "CmRenderSystem.h"
+#include "CmRenderWindow.h"
+#include "CmResources.h"
+#include "CmRenderable.h"
+#include "CmMaterial.h"
+#include "CmShader.h"
+#include "CmTechnique.h"
+#include "CmPass.h"
+#include "CmImporter.h"
+#include "CmMesh.h"
 
 using namespace CamelotEngine;
 
@@ -16,16 +28,136 @@ int _tmain(int argc, _TCHAR* argv[])
 	gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
 	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
 
-	//RTTITypeBase* st = DbgSrlzTest::getRTTIStatic();
+	RenderSystem* renderSystem = RenderSystemManager::getActive();
+	RenderWindow* renderWindow = gApplication().getPrimaryRenderWindow();
 
-//	DbgSrlzTestST::startUp();
-//	TextureST::startUp();
+	GameObjectPtr cameraGO = GameObject::create("MainCamera");
+	CameraPtr camera = cameraGO->addComponent<Camera>();
 
-	test();
+	camera->init(renderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
+	cameraGO->setPosition(Vector3(0,50,1240));
+	cameraGO->lookAt(Vector3(0,50,-300));
+	camera->setNearClipDistance(5);
+	camera->setAspectRatio(800.0f / 600.0f);
 
-	gApplication().runMainLoop();
+	GameObjectPtr testModelGO = GameObject::create("TestMesh");
+	RenderablePtr testRenderable = testModelGO->addComponent<Renderable>();
+
+	HighLevelGpuProgramPtr fragProg;
+	HighLevelGpuProgramPtr vertProg;
+
+	/////////////////// HLSL SHADERS //////////////////////////
+	//String fragShaderCode = "sampler2D tex;			\
+	//						float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
+	//						{														\
+	//						float4 color = tex2D(tex, uv);				\
+	//						return color;										\
+	//						}";
+
+	//fragProg =  HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "ps_main", "hlsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+	//fragProg->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;											\
+	//						}";
+
+	//vertProg =  HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "vs_main", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	//vertProg->load();
+
+
+
+	/////////////////// CG SHADERS //////////////////////////
+	String fragShaderCode = "sampler2D tex;					\
+							float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
+							{														\
+							float4 color = tex2D(tex, uv);						\
+							return color;										\
+							}";
+
+	fragProg =  HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "ps_main", "cg", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+	fragProg->init();
+
+	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;											\
+							}";
+
+	vertProg =  HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "vs_main", "cg", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	vertProg->init();
+
+	HighLevelGpuProgramRef vertProgRef(vertProg);
+
+	gResources().create(vertProgRef, "C:\\vertProgCg.vprog", true);
+	vertProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\vertProgCg.vprog"));
+
+	HighLevelGpuProgramRef fragProgRef(fragProg);
 
-	int a = 5;
+	gResources().create(fragProgRef, "C:\\fragProgCg.vprog", true);
+	fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
+
+	///////////////// GLSL SHADERS ////////////////////////////
+	//String fragShaderCode = "uniform sampler2D tex; \
+	//							void main() \
+	//							  {\
+	//							  vec4 texColor = texture2D(tex,gl_TexCoord[0].st);\
+	//							  gl_FragColor = texColor; \
+	//							  }";
+
+	//fragProg = HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "main", "glsl", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
+	//fragProg->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; \
+	//							  }";
+
+	//vertProg = HighLevelGpuProgramManager::instance().createProgram(vertShaderCode, "main", "glsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
+	//vertProg->load();
+
+	ShaderPtr testShader = ShaderPtr(new Shader("TestShader"));
+	TechniquePtr newTechnique = testShader->addTechnique("GLRenderSystem", "ForwardRenderer");
+	PassPtr newPass = newTechnique->addPass();
+	newPass->setVertexProgram(vertProgRef);
+	newPass->setFragmentProgram(fragProgRef);
+
+	MaterialRef testMaterial = MaterialPtr(new Material());
+	testMaterial->setShader(testShader);
+
+	TextureRef testTex = static_resource_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
+	MeshRef dbgMesh = static_resource_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
+
+	gResources().create(testTex, "C:\\ExportTest.tex", true);
+	gResources().create(dbgMesh, "C:\\ExportMesh.mesh", true);
+
+	testTex = static_resource_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
+	dbgMesh = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
+
+	testMaterial->setTexture("tex", testTex);
+	gResources().create(testMaterial, "C:\\ExportMaterial.mat", true);
+
+	testMaterial = gResources().load("C:\\ExportMaterial.mat");
+
+	testRenderable->setMesh(dbgMesh);
+	testRenderable->setMaterial(testMaterial);
+
+	gApplication().runMainLoop();
 
 	gApplication().shutDown();
 

+ 0 - 2
CamelotClient/CamelotClient.vcxproj

@@ -90,13 +90,11 @@
     <ClInclude Include="CmDebugCamera.h" />
     <ClInclude Include="stdafx.h" />
     <ClInclude Include="targetver.h" />
-    <ClInclude Include="TestingGround.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="CamelotClient.cpp" />
     <ClCompile Include="CmDebugCamera.cpp" />
     <ClCompile Include="stdafx.cpp" />
-    <ClCompile Include="TestingGround.cpp" />
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">

+ 0 - 6
CamelotClient/CamelotClient.vcxproj.filters

@@ -24,9 +24,6 @@
     <ClInclude Include="targetver.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="TestingGround.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="CmDebugCamera.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -38,9 +35,6 @@
     <ClCompile Include="CamelotClient.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="TestingGround.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="CmDebugCamera.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 0 - 25
CamelotClient/TestingGround.cpp

@@ -1,25 +0,0 @@
-#include "TestingGround.h"
-
-#include "CmFileSerializer.h"
-#include "CmResource.h"
-#include "CmTextureData.h"
-#include "CmTextureManager.h"
-#include "CmImporter.h"
-
-using namespace CamelotEngine;
-
-void test()
-{
-	//FileSerializer fs;
-
-	//TexturePtr dbgTexture = TextureManager::instance().create(TEX_TYPE_2D, 128, 128, 1, PF_A8B8G8R8);
-	//dbgTexture->setFSAA(0, "test");
-	//fs.encode(dbgTexture.get(), "C:\\DbgTexture.tex");
-
-	//TexturePtr emptyTexture = std::static_pointer_cast<Texture>(fs.decode("C:\\DbgTexture.tex"));
-	//
-	//TextureDataPtr data = emptyTexture->mTextureData[0];
-	//UINT32 size2 = data->getSize();
-
-	//int a = 5;
-}

+ 0 - 3
CamelotClient/TestingGround.h

@@ -1,3 +0,0 @@
-#pragma once
-
-void test();

+ 1 - 1
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -184,7 +184,7 @@ namespace CamelotEngine
 		String validateConfigOptions();
 		RenderWindow* _initialise( bool autoCreateWindow, const String& windowTitle = "OGRE Render Window"  );
 		/// @copydoc RenderSystem::_createRenderWindow
-		RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, 
+		RenderWindow* createRenderWindow(const String &name, unsigned int width, unsigned int height, 
 			bool fullScreen, const NameValuePairList *miscParams = 0);
 		
 		/// @copydoc RenderSystem::_createRenderWindows

+ 3 - 3
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -593,7 +593,7 @@ namespace CamelotEngine
 			miscParams["gamma"] = toString(hwGamma);
 			miscParams["monitorIndex"] = toString(static_cast<int>(mActiveD3DDriver->getAdapterNumber()));
 
-			autoWindow = _createRenderWindow( windowTitle, width, height, 
+			autoWindow = createRenderWindow( windowTitle, width, height, 
 				fullScreen, &miscParams );
 
 			// If we have 16bit depth buffer enable w-buffering.
@@ -635,7 +635,7 @@ namespace CamelotEngine
 		GpuProgramManager::shutDown();		
 	}
 	//---------------------------------------------------------------------
-	RenderWindow* D3D9RenderSystem::_createRenderWindow(const String &name, 
+	RenderWindow* D3D9RenderSystem::createRenderWindow(const String &name, 
 		unsigned int width, unsigned int height, bool fullScreen,
 		const NameValuePairList *miscParams)
 	{		
@@ -712,7 +712,7 @@ namespace CamelotEngine
 			const RenderWindowDescription& curRenderWindowDescription = renderWindowDescriptions[i];			
 			RenderWindow* curWindow = NULL;
 
-			curWindow = _createRenderWindow(curRenderWindowDescription.name, 
+			curWindow = createRenderWindow(curRenderWindowDescription.name, 
 				curRenderWindowDescription.width, 
 				curRenderWindowDescription.height, 
 				curRenderWindowDescription.useFullScreen, 

+ 8 - 2
CamelotForwardRenderer/Include/CmForwardRenderer.h

@@ -1,6 +1,6 @@
 #pragma once
 
-#include "CmPrerequisites.h"
+#include "CmForwardRendererPrerequisites.h"
 #include "CmRenderer.h"
 
 namespace CamelotEngine
@@ -11,6 +11,12 @@ namespace CamelotEngine
 		virtual const String& getName() const;
 
 		virtual void renderAll();
-		virtual void render(const CameraPtr camera);
+		virtual void render(CameraPtr camera);
+
+	protected:
+		/**
+		 * @brief	Overriden from Renderer
+		 */
+		virtual void setPass(const PassPtr pass);
 	};
 }

+ 165 - 1
CamelotForwardRenderer/Source/CmForwardRenderer.cpp

@@ -1,6 +1,12 @@
 #include "CmForwardRenderer.h"
 #include "CmCamera.h"
 #include "CmSceneManager.h"
+#include "CmRenderSystemManager.h"
+#include "CmRenderSystem.h"
+#include "CmRenderable.h"
+#include "CmMaterial.h"
+#include "CmMesh.h"
+#include "CmPass.h"
 
 namespace CamelotEngine
 {
@@ -12,20 +18,178 @@ namespace CamelotEngine
 
 	void ForwardRenderer::renderAll() 
 	{
-		const vector<CameraPtr>::type& allCameras = gSceneManager().getAllCameras();
+		RenderSystem* renderSystem = RenderSystemManager::getActive();
+
+		// TODO - No point in setting these each frame?
+		renderSystem->setInvertVertexWinding(false);
+		renderSystem->_setDepthBufferParams();
 
+
+		const vector<CameraPtr>::type& allCameras = gSceneManager().getAllCameras();
 		for(auto iter = allCameras.begin(); iter != allCameras.end(); ++iter)
 		{
 			render(*iter);
 		}
+
+		renderSystem->_swapAllRenderTargetBuffers(false);
 	}
 
 	void ForwardRenderer::render(const CameraPtr camera) 
 	{
 		vector<RenderablePtr>::type allRenderables = gSceneManager().getVisibleRenderables(camera);
 
+		RenderSystem* renderSystem = RenderSystemManager::getActive();
+		renderSystem->_setViewport(camera->getViewport());
+
+		Matrix4 projMatrixCstm = camera->getProjectionMatrix();
+		Matrix4 viewMatrixCstm = camera->getViewMatrix();
+
+		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
+
+		renderSystem->clearFrameBuffer(FBT_COLOUR | FBT_DEPTH, Color::Blue);
+		renderSystem->_beginFrame();
+
+		// TODO - sort renderables by material/pass/parameters to minimize state changes
+		for(auto iter = allRenderables.begin(); iter != allRenderables.end(); ++iter)
+		{
+			MaterialRef material = (*iter)->getMaterial();
+
+			if(material == nullptr || !material.isResolved())
+				continue;
+
+			MeshRef mesh = (*iter)->getMesh();
+
+			if(mesh == nullptr || !mesh.isResolved())
+				continue;
+
+			// TODO - Renderer should ensure shader is compatible with it, and it contains all the needed parameters
+			// (probably at an earlier stage). e.g. I want the user to be warned if the shader doesn't contain matViewProjection param
+			// (or should we just ignore such missing parameters?)
+			material->setMat4("matViewProjection", viewProjMatrix);
+
+			for(int i = 0; i < material->getNumPasses(); i++)
+			{
+				setPass(material->getPass(i));
+
+				material->applyPass(i); // TODO - applyPass method should be more like RenderSystem::applyPass(Material, passIdx)
+				renderSystem->_render(mesh->getRenderOperation());
+			}
+		}
+
+		renderSystem->_endFrame();
+
 		// TODO - Sort renderables
 		// Render them
 	}
 
+	void ForwardRenderer::setPass(PassPtr pass)
+	{
+		RenderSystem* renderSystem = RenderSystemManager::getActive();
+
+		GpuProgramRef vertProgram = pass->getVertexProgram();
+		if(vertProgram)
+		{
+			renderSystem->bindGpuProgram(vertProgram->_getBindingDelegate());
+		}
+		else
+		{
+			if(renderSystem->isGpuProgramBound(GPT_VERTEX_PROGRAM))
+				renderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM);
+		}
+
+		GpuProgramRef fragProgram = pass->getFragmentProgram();
+		if(fragProgram)
+		{
+			renderSystem->bindGpuProgram(fragProgram->_getBindingDelegate());
+		}
+		else
+		{
+			if(renderSystem->isGpuProgramBound(GPT_FRAGMENT_PROGRAM))
+				renderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
+		}
+
+		GpuProgramRef geomProgram = pass->getGeometryProgram();
+		if(geomProgram)
+		{
+			renderSystem->bindGpuProgram(geomProgram->_getBindingDelegate());
+		}	
+		else
+		{
+			if(renderSystem->isGpuProgramBound(GPT_GEOMETRY_PROGRAM))
+				renderSystem->unbindGpuProgram(GPT_GEOMETRY_PROGRAM);
+		}
+
+		// The rest of the settings are the same no matter whether we use programs or not
+
+		// Set scene blending
+		if ( pass->hasSeparateSceneBlending( ) )
+		{
+			renderSystem->_setSeparateSceneBlending(
+				pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
+				pass->getSourceBlendFactorAlpha(), pass->getDestBlendFactorAlpha(),
+				pass->getSceneBlendingOperation(), 
+				pass->hasSeparateSceneBlendingOperations() ? pass->getSceneBlendingOperation() : pass->getSceneBlendingOperationAlpha() );
+		}
+		else
+		{
+			if(pass->hasSeparateSceneBlendingOperations( ) )
+			{
+				renderSystem->_setSeparateSceneBlending(
+					pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
+					pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
+					pass->getSceneBlendingOperation(), pass->getSceneBlendingOperationAlpha() );
+			}
+			else
+			{
+				renderSystem->_setSceneBlending(
+					pass->getSourceBlendFactor(), pass->getDestBlendFactor(), pass->getSceneBlendingOperation() );
+			}
+		}
+
+		// Set point parameters
+		renderSystem->_setPointParameters(
+			pass->getPointSize(),
+			false, 
+			false, 
+			false, 
+			false, 
+			pass->getPointMinSize(), 
+			pass->getPointMaxSize());
+
+
+
+
+
+		// TODO - Set texture sampler states!
+
+		// TODO - Try to limit amount of state changes, if previous state is already the same (especially with textures)
+
+		// TODO: Disable remaining texture units
+		//renderSystem->_disableTextureUnitsFrom(pass->getNumTextureUnitStates());
+
+
+
+
+		// Set up non-texture related material settings
+		// Depth buffer settings
+		renderSystem->_setDepthBufferFunction(pass->getDepthFunction());
+		renderSystem->_setDepthBufferCheckEnabled(pass->getDepthCheckEnabled());
+		renderSystem->_setDepthBufferWriteEnabled(pass->getDepthWriteEnabled());
+		renderSystem->_setDepthBias(pass->getDepthBiasConstant(), pass->getDepthBiasSlopeScale());
+
+		// Alpha-reject settings
+		renderSystem->_setAlphaRejectSettings(
+			pass->getAlphaRejectFunction(), pass->getAlphaRejectValue(), pass->isAlphaToCoverageEnabled());
+
+		// Set colour write mode
+		// Right now we only use on/off, not per-channel
+		bool colWrite = pass->getColourWriteEnabled();
+		renderSystem->_setColourBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite);
+
+		// Culling mode
+		renderSystem->_setCullingMode(pass->getCullingMode());
+
+		// Polygon mode
+		renderSystem->_setPolygonMode(pass->getPolygonMode());
+	}
 }

+ 1 - 1
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -182,7 +182,7 @@ namespace CamelotEngine {
         void setLightingEnabled(bool enabled);
         
 		/// @copydoc RenderSystem::_createRenderWindow
-		RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, 
+		RenderWindow* createRenderWindow(const String &name, unsigned int width, unsigned int height, 
 			bool fullScreen, const NameValuePairList *miscParams = 0);
 
 		/// @copydoc RenderSystem::_createRenderWindows

+ 2 - 2
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -956,7 +956,7 @@ namespace CamelotEngine {
 			const RenderWindowDescription& curRenderWindowDescription = renderWindowDescriptions[i];			
 			RenderWindow* curWindow = NULL;
 
-			curWindow = _createRenderWindow(curRenderWindowDescription.name, 
+			curWindow = createRenderWindow(curRenderWindowDescription.name, 
 				curRenderWindowDescription.width, 
 				curRenderWindowDescription.height, 
 				curRenderWindowDescription.useFullScreen, 
@@ -968,7 +968,7 @@ namespace CamelotEngine {
 		return true;
 	}
 	//---------------------------------------------------------------------
-	RenderWindow* GLRenderSystem::_createRenderWindow(const String &name, 
+	RenderWindow* GLRenderSystem::createRenderWindow(const String &name, 
 		unsigned int width, unsigned int height, bool fullScreen,
 		const NameValuePairList *miscParams)
 	{

+ 1 - 1
CamelotGLRenderer/Source/CmWin32GLSupport.cpp

@@ -287,7 +287,7 @@ namespace CamelotEngine {
 			bool hwGamma = (opt->second.currentValue == "Yes");
 			winOptions["gamma"] = toString(hwGamma);
 
-            return renderSystem->_createRenderWindow(windowTitle, w, h, fullscreen, &winOptions);
+            return renderSystem->createRenderWindow(windowTitle, w, h, fullscreen, &winOptions);
         }
         else
         {

+ 0 - 2
CamelotRenderer/CamelotRenderer.vcxproj

@@ -104,7 +104,6 @@
     <ClInclude Include="Include\CmComponentRTTI.h" />
     <ClInclude Include="Include\CmConfigOptionMap.h" />
     <ClInclude Include="Include\CmDefaultHardwareBufferManager.h" />
-    <ClInclude Include="Include\CmForwardRenderer.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
@@ -174,7 +173,6 @@
     <ClCompile Include="Source\CmCgProgram.cpp" />
     <ClCompile Include="Source\CmCgProgramFactory.cpp" />
     <ClCompile Include="Source\CmDefaultHardwareBufferManager.cpp" />
-    <ClCompile Include="Source\CmForwardRenderer.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />

+ 0 - 12
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -58,12 +58,6 @@
     <Filter Include="Source Files\Input">
       <UniqueIdentifier>{7f8e94f3-6990-4723-965a-2b4f9346a7ee}</UniqueIdentifier>
     </Filter>
-    <Filter Include="Header Files\MOVETODLL">
-      <UniqueIdentifier>{f42d28e0-bbe6-4f52-a574-0e2725e3c223}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="Source Files\MOVETODLL">
-      <UniqueIdentifier>{677211c0-a3d1-4e6a-8acf-f457349f1777}</UniqueIdentifier>
-    </Filter>
     <Filter Include="Header Files\Input">
       <UniqueIdentifier>{724588b9-04e2-4e9b-9467-b064ed44f05e}</UniqueIdentifier>
     </Filter>
@@ -265,9 +259,6 @@
     <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\CmResourceRef.h">
       <Filter>Header Files\Resources</Filter>
     </ClInclude>
@@ -435,9 +426,6 @@
     <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\CmResourceRef.cpp">
       <Filter>Source Files\Resources</Filter>
     </ClCompile>

+ 4 - 13
CamelotRenderer/Include/CmApplication.h

@@ -22,10 +22,10 @@ namespace CamelotEngine
 			void runMainLoop();
 			void shutDown();
 
-			void DBG_renderSimpleFrame();
-
 			UINT32 getAppWindowId();
 
+			RenderWindow* getPrimaryRenderWindow() const { return mPrimaryRenderWindow; }
+
 			/**
 			 * @brief	Loads a plugin.
 			 *
@@ -33,17 +33,8 @@ namespace CamelotEngine
 			 */
 			void loadPlugin(const String& pluginName);
 
-		private:
-			RenderWindow* mRenderWindow;
-			std::shared_ptr<Camera> mCamera;
-			HighLevelGpuProgramPtr mFragProg;
-			HighLevelGpuProgramPtr mVertProg;
-			TextureRef mDbgTexture;
-			MeshRef mDbgMesh;
-			GameObjectPtr mCameraGO;
-
-			ShaderPtr mTestShader;
-			MaterialRef mTestMaterial;
+	private:
+		RenderWindow* mPrimaryRenderWindow;
 	};
 
 	CM_EXPORT Application& gApplication();

+ 0 - 32
CamelotRenderer/Include/CmForwardRenderer.h

@@ -1,32 +0,0 @@
-#pragma once
-
-#include "CmPrerequisites.h"
-#include "CmRenderer.h"
-
-namespace CamelotEngine
-{
-	class CM_EXPORT ForwardRenderer : public Renderer
-	{
-	public:
-		/**
-		 * @brief	Overriden from Renderer
-		 */
-		virtual const String& getName() const;
-
-		/**
-		 * @brief	Overriden from Renderer
-		 */
-		virtual void renderAll();
-
-		/**
-		 * @brief	Overriden from Renderer
-		 */
-		virtual void render(const CameraPtr camera);
-
-	protected:
-		/**
-		 * @brief	Overriden from Renderer
-		 */
-		virtual void setPass(const Pass* pass);
-	};
-}

+ 2 - 1
CamelotRenderer/Include/CmGameObject.h

@@ -5,6 +5,7 @@
 #include "CmVector3.h"
 #include "CmQuaternion.h"
 #include "CmRTTIType.h"
+#include "CmSceneManager.h"
 
 #include "boost/static_assert.hpp"
 
@@ -205,7 +206,7 @@ namespace CamelotEngine
 			BOOST_STATIC_ASSERT_MSG((boost::is_base_of<CamelotEngine::Component, T>::value), 
 				"Specified type is not a valid Component.");
 
-			std::shared_ptr<T> newComponent = std::shared_ptr<T>(new T(mThis.lock()));
+			std::shared_ptr<T> newComponent(new T(mThis.lock()));
 			mComponents.push_back(newComponent);
 
 			gSceneManager().notifyComponentAdded(newComponent);

+ 3 - 1
CamelotRenderer/Include/CmMaterial.h

@@ -5,7 +5,7 @@
 
 namespace CamelotEngine
 {
-	class Material : public Resource
+	class CM_EXPORT Material : public Resource
 	{
 		struct ParamsPerPass
 		{
@@ -50,6 +50,8 @@ namespace CamelotEngine
 
 		UINT32 getNumPasses() const;
 
+		PassPtr getPass(UINT32 passIdx) const;
+
 	private:
 		ShaderPtr mShader;
 		TechniquePtr mBestTechnique;

+ 1 - 1
CamelotRenderer/Include/CmRenderSystem.h

@@ -439,7 +439,7 @@ namespace CamelotEngine
 			<td>&nbsp;</td>
 		</tr>
 		*/
-		virtual RenderWindow* _createRenderWindow(const String &name, unsigned int width, unsigned int height, 
+		virtual RenderWindow* createRenderWindow(const String &name, unsigned int width, unsigned int height, 
 			bool fullScreen, const NameValuePairList *miscParams = 0) = 0;
 
 		/** Creates multiple rendering windows.		

+ 20 - 1
CamelotRenderer/Include/CmRenderable.h

@@ -5,11 +5,30 @@
 
 namespace CamelotEngine
 {
-	class Renderable : public Component
+	class CM_EXPORT Renderable : public Component
 	{
+	public:
+		void setMesh(MeshRef mesh) { mMesh = mesh; }
+		void setMaterial(MaterialRef material) { mMaterial = material; }
+
+		MeshRef getMesh() const { return mMesh; }
+		MaterialRef getMaterial() const { return mMaterial; }
+	private:
+		MeshRef mMesh;
+		MaterialRef mMaterial;
+
 		/************************************************************************/
 		/* 							COMPONENT OVERRIDES                    		*/
 		/************************************************************************/
+
+	private:
+		friend class GameObject;
+
+		/** Standard constructor.
+        */
+		Renderable(GameObjectPtr parent);
+
+	public:
 		virtual void update() {}
 
 		/************************************************************************/

+ 1 - 1
CamelotRenderer/Include/CmRenderer.h

@@ -23,6 +23,6 @@ namespace CamelotEngine
 		/**
 		 * @brief	Sets the currently active pass.
 		 */
-		virtual void setPass(const Pass* pass) = 0;
+		virtual void setPass(PassPtr pass) = 0;
 	};
 }

+ 8 - 180
CamelotRenderer/Source/CmApplication.cpp

@@ -20,6 +20,8 @@
 #include "CmGameObject.h"
 #include "CmTime.h"
 #include "CmInput.h"
+#include "CmRendererManager.h"
+#include "CmRenderer.h"
 
 #include "CmMaterial.h"
 #include "CmShader.h"
@@ -31,7 +33,7 @@
 namespace CamelotEngine
 {
 	Application::Application()
-		:mRenderWindow(nullptr), mCamera(nullptr)
+		:mPrimaryRenderWindow(nullptr)
 	{ }
 
 	void Application::startUp(const String& renderSystemDll, const String& rendererDll)
@@ -49,154 +51,17 @@ namespace CamelotEngine
 		RenderSystem* renderSystem = RenderSystemManager::getActive();
 		renderSystem->_initialise(false, "Camelot Renderer");
 
+		mPrimaryRenderWindow = renderSystem->createRenderWindow("Camelot Renderer", 800, 600, false);
+
 		SceneManager::startUp(new SceneManager());
 		Resources::startUp(new Resources("D:\\CamelotResourceMetas"));
 
-		mRenderWindow = renderSystem->_createRenderWindow("Camelot Renderer", 800, 600, false);
-
-		//renderSystem->setAmbientLight(1.0f, 1.0f, 1.0f);
 		renderSystem->setLightingEnabled(false);
 
-		mCameraGO = GameObject::create("MainCamera");
-		mCamera = mCameraGO->addComponent<Camera>();
-
-		mCamera->init(mRenderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
-		mCameraGO->setPosition(Vector3(0,50,1240));
-		mCameraGO->lookAt(Vector3(0,50,-300));
-		mCamera->setNearClipDistance(5);
-		mCamera->setAspectRatio(800.0f / 600.0f);
-
-		/////////////////// HLSL SHADERS //////////////////////////
-		//String fragShaderCode = "sampler2D tex;			\
-		//						float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
-		//						{														\
-		//						float4 color = tex2D(tex, uv);				\
-		//						return color;										\
-		//						}";
-
-		//mFragProg =  HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "ps_main", "hlsl", 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", "hlsl", GPT_VERTEX_PROGRAM, GPP_VS_2_0);
-		//mVertProg->load();
-		
-
-
-		/////////////////// CG SHADERS //////////////////////////
-		String fragShaderCode = "sampler2D tex;					\
-			float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\
-		{														\
-			float4 color = tex2D(tex, uv);						\
-			return color;										\
-		}";
-
-		mFragProg =  HighLevelGpuProgramManager::instance().createProgram(fragShaderCode, "ps_main", "cg", GPT_FRAGMENT_PROGRAM, GPP_PS_2_0);
-		mFragProg->init();
-
-		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->init();
-
-		HighLevelGpuProgramRef vertProgRef(mVertProg);
-
-		gResources().create(vertProgRef, "C:\\vertProgCg.vprog", true);
-		vertProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\vertProgCg.vprog"));
-
-		HighLevelGpuProgramRef fragProgRef(mFragProg);
-
-		gResources().create(fragProgRef, "C:\\fragProgCg.vprog", true);
-		fragProgRef = static_resource_cast<HighLevelGpuProgram>(gResources().load("C:\\fragProgCg.vprog"));
-
-		///////////////// 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();
-
-		//// 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();
-
-		mTestShader = ShaderPtr(new Shader("TestShader"));
-		TechniquePtr newTechnique = mTestShader->addTechnique("GLRenderSystem", "ForwardRenderer");
-		PassPtr newPass = newTechnique->addPass();
-		newPass->setVertexProgram(vertProgRef);
-		newPass->setFragmentProgram(fragProgRef);
-
-		mTestMaterial = MaterialPtr(new Material());
-		mTestMaterial->setShader(mTestShader);
-
-		// IMPORTER TEST
 		Importer::startUp(new Importer());
 		loadPlugin("CamelotFreeImgImporter"); // TODO - Load this automatically somehow
 		loadPlugin("CamelotFBXImporter"); // TODO - Load this automatically somehow
 
-		//mDbgTexture = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
-		TextureRef testTex = static_resource_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
-		mDbgMesh = static_resource_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
-		//mDbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\BarrelMesh.fbx"));
-
-		//// Get current flag
-		//int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
-		//tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;
-		//// Set flag to the new value.
-		//_CrtSetDbgFlag( tmpFlag );
-
-		gResources().create(testTex, "C:\\ExportTest.tex", true);
-		gResources().create(mDbgMesh, "C:\\ExportMesh.mesh", true);
-
-		mDbgTexture = static_resource_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
-		mDbgMesh = static_resource_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
-
-		mTestMaterial->setTexture("tex", mDbgTexture);
-		gResources().create(mTestMaterial, "C:\\ExportMaterial.mat", true);
-
-		//if(!_CrtCheckMemory())
-		//{
-		//	assert(false);
-		//}
-
-		mTestMaterial = gResources().load("C:\\ExportMaterial.mat");
-
-		//if(!_CrtCheckMemory())
-		//{
-		//	assert(false);
-		//}
-
 		loadPlugin("CamelotOISInput"); // TODO - Load this automatically somehow
 	}
 
@@ -206,7 +71,7 @@ namespace CamelotEngine
 		{
 			WindowEventUtilities::messagePump();
 
-			DBG_renderSimpleFrame();
+			RendererManager::getActive()->renderAll();
 
 			gTime().update();
 			gInput().update();
@@ -259,54 +124,17 @@ namespace CamelotEngine
 
 	UINT32 Application::getAppWindowId()
 	{
-		if(!mRenderWindow)
+		if(!mPrimaryRenderWindow)
 		{
 			CM_EXCEPT(InternalErrorException, "Unable to get window handle. No active window is set!");
 		}
 
 		UINT32 windowId;
-		mRenderWindow->getCustomAttribute("WINDOW", &windowId);
+		mPrimaryRenderWindow->getCustomAttribute("WINDOW", &windowId);
 
 		return windowId;
 	}
 
-	void Application::DBG_renderSimpleFrame()
-	{
-		if(!mDbgTexture.isResolved() || !mDbgMesh.isResolved())
-		{
-			return;
-		}
-
-		RenderSystem* renderSystem = RenderSystemManager::getActive();
-		renderSystem->_setViewport(mCamera->getViewport());
-
-		//Matrix4 projMatrix = mCamera->getProjectionMatrixRS();
-		//renderSystem->_setProjectionMatrix(projMatrix);
-
-		//Matrix4 viewMatrix = mCamera->getViewMatrix(true);
-		//renderSystem->_setViewMatrix(viewMatrix);
-
-		Matrix4 projMatrixCstm = mCamera->getProjectionMatrix();
-		Matrix4 viewMatrixCstm = mCamera->getViewMatrix();
-
-		Matrix4 viewProjMatrix = projMatrixCstm * viewMatrixCstm;
-
-		renderSystem->setInvertVertexWinding(false);
-		renderSystem->_setDepthBufferParams();
-		renderSystem->clearFrameBuffer(FBT_COLOUR | FBT_DEPTH, Color::Blue);
-		renderSystem->_beginFrame();
-
-		mTestMaterial->setMat4("matViewProjection", viewProjMatrix);
-
-		mTestMaterial->applyPass(0);
-		
-		renderSystem->_render(mDbgMesh->getRenderOperation());
-
-		renderSystem->_endFrame();
-
-		renderSystem->_swapAllRenderTargetBuffers(false);
-	}
-
 	Application& gApplication()
 	{
 		static Application application;

+ 0 - 144
CamelotRenderer/Source/CmForwardRenderer.cpp

@@ -1,144 +0,0 @@
-#include "CmForwardRenderer.h"
-#include "CmCamera.h"
-#include "CmSceneManager.h"
-#include "CmPass.h"
-#include "CmRenderSystem.h"
-#include "CmRenderSystemManager.h"
-
-namespace CamelotEngine
-{
-	const String& ForwardRenderer::getName() const
-	{
-		static String name = "ForwardRenderer";
-		return name;
-	}
-
-	void ForwardRenderer::renderAll() 
-	{
-		const vector<CameraPtr>::type& allCameras = gSceneManager().getAllCameras();
-
-		for(auto iter = allCameras.begin(); iter != allCameras.end(); ++iter)
-		{
-			render(*iter);
-		}
-	}
-
-	void ForwardRenderer::render(const CameraPtr camera) 
-	{
-		vector<RenderablePtr>::type allRenderables = gSceneManager().getVisibleRenderables(camera);
-
-		// TODO - Sort renderables
-		// Render them
-	}
-
-	void ForwardRenderer::setPass(const Pass* pass)
-	{
-		RenderSystem* renderSystem = RenderSystemManager::getActive();
-
-		GpuProgramRef vertProgram = pass->getVertexProgram();
-		if(vertProgram)
-		{
-			renderSystem->bindGpuProgram(vertProgram->_getBindingDelegate());
-		}
-		else
-		{
-			if(renderSystem->isGpuProgramBound(GPT_VERTEX_PROGRAM))
-				renderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM);
-		}
-
-		GpuProgramRef fragProgram = pass->getFragmentProgram();
-		if(fragProgram)
-		{
-			renderSystem->bindGpuProgram(fragProgram->_getBindingDelegate());
-		}
-		else
-		{
-			if(renderSystem->isGpuProgramBound(GPT_FRAGMENT_PROGRAM))
-				renderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
-		}
-
-		GpuProgramRef geomProgram = pass->getGeometryProgram();
-		if(geomProgram)
-		{
-			renderSystem->bindGpuProgram(geomProgram->_getBindingDelegate());
-		}	
-		else
-		{
-			if(renderSystem->isGpuProgramBound(GPT_GEOMETRY_PROGRAM))
-				renderSystem->unbindGpuProgram(GPT_GEOMETRY_PROGRAM);
-		}
-
-		// The rest of the settings are the same no matter whether we use programs or not
-
-		// Set scene blending
-		if ( pass->hasSeparateSceneBlending( ) )
-		{
-			renderSystem->_setSeparateSceneBlending(
-				pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
-				pass->getSourceBlendFactorAlpha(), pass->getDestBlendFactorAlpha(),
-				pass->getSceneBlendingOperation(), 
-				pass->hasSeparateSceneBlendingOperations() ? pass->getSceneBlendingOperation() : pass->getSceneBlendingOperationAlpha() );
-		}
-		else
-		{
-			if(pass->hasSeparateSceneBlendingOperations( ) )
-			{
-				renderSystem->_setSeparateSceneBlending(
-					pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
-					pass->getSourceBlendFactor(), pass->getDestBlendFactor(),
-					pass->getSceneBlendingOperation(), pass->getSceneBlendingOperationAlpha() );
-			}
-			else
-			{
-				renderSystem->_setSceneBlending(
-					pass->getSourceBlendFactor(), pass->getDestBlendFactor(), pass->getSceneBlendingOperation() );
-			}
-		}
-
-		// Set point parameters
-		renderSystem->_setPointParameters(
-			pass->getPointSize(),
-			false, 
-			false, 
-			false, 
-			false, 
-			pass->getPointMinSize(), 
-			pass->getPointMaxSize());
-
-
-
-
-
-		// TODO - Set texture sampler states!
-		
-		// TODO - Try to limit amount of state changes, if previous state is already the same (especially with textures)
-		
-		// TODO: Disable remaining texture units
-		//renderSystem->_disableTextureUnitsFrom(pass->getNumTextureUnitStates());
-
-
-
-
-		// Set up non-texture related material settings
-		// Depth buffer settings
-		renderSystem->_setDepthBufferFunction(pass->getDepthFunction());
-		renderSystem->_setDepthBufferCheckEnabled(pass->getDepthCheckEnabled());
-		renderSystem->_setDepthBufferWriteEnabled(pass->getDepthWriteEnabled());
-		renderSystem->_setDepthBias(pass->getDepthBiasConstant(), pass->getDepthBiasSlopeScale());
-
-		// Alpha-reject settings
-		renderSystem->_setAlphaRejectSettings(
-			pass->getAlphaRejectFunction(), pass->getAlphaRejectValue(), pass->isAlphaToCoverageEnabled());
-
-		// Set colour write mode
-		// Right now we only use on/off, not per-channel
-		bool colWrite = pass->getColourWriteEnabled();
-		renderSystem->_setColourBufferWriteEnabled(colWrite, colWrite, colWrite, colWrite);
-
-		// Culling mode
-		renderSystem->_setCullingMode(pass->getCullingMode());
-		
-		// Polygon mode
-		renderSystem->_setPolygonMode(pass->getPolygonMode());
-	}
-}

+ 8 - 0
CamelotRenderer/Source/CmMaterial.cpp

@@ -121,6 +121,14 @@ namespace CamelotEngine
 		return mShader->getBestTechnique()->getNumPasses();
 	}
 
+	PassPtr Material::getPass(UINT32 passIdx) const
+	{
+		if(passIdx < 0 || passIdx >= mShader->getBestTechnique()->getNumPasses())
+			CM_EXCEPT(InvalidParametersException, "Invalid pass index.");
+
+		return mShader->getBestTechnique()->getPass(passIdx);
+	}
+
 	void Material::applyPass(UINT32 passIdx)
 	{
 		throwIfNotInitialized();

+ 4 - 0
CamelotRenderer/Source/CmRenderable.cpp

@@ -3,6 +3,10 @@
 
 namespace CamelotEngine
 {
+	Renderable::Renderable(GameObjectPtr parent)
+		:Component(parent)
+	{ }
+
 	RTTITypeBase* Renderable::getRTTIStatic()
 	{
 		return RenderableRTTI::instance();

+ 21 - 2
CamelotRenderer/Source/CmSceneManager.cpp

@@ -2,6 +2,7 @@
 #include "CmGameObject.h"
 #include "CmComponent.h"
 #include "CmCamera.h"
+#include "CmRenderable.h"
 
 namespace CamelotEngine
 {
@@ -18,9 +19,27 @@ namespace CamelotEngine
 
 	vector<RenderablePtr>::type SceneManager::getVisibleRenderables(const CameraPtr camera) const
 	{
-		// TODO - Actually iterate over all game objects and find visible renderables
+		// TODO - Cull invisible objects
 
-		return vector<RenderablePtr>::type();
+		vector<RenderablePtr>::type renderables;
+
+		stack<GameObjectPtr>::type todo;
+		todo.push(mRootNode);
+
+		while(!todo.empty())
+		{
+			GameObjectPtr currentGO = todo.top();
+			todo.pop();
+
+			RenderablePtr curRenderable = currentGO->getComponent<Renderable>();
+			if(curRenderable != nullptr)
+				renderables.push_back(curRenderable);
+
+			for(int i = 0; i < currentGO->getNumChildren(); i++)
+				todo.push(currentGO->getChild(i));
+		}
+
+		return renderables;
 	}
 
 	void SceneManager::registerNewGO(GameObjectPtr node)