瀏覽代碼

Cg up and running

Marko Pintera 13 年之前
父節點
當前提交
3da577fc99

+ 2 - 2
CamelotClient/CamelotClient.cpp

@@ -13,8 +13,8 @@ using namespace CamelotEngine;
 
 int _tmain(int argc, _TCHAR* argv[])
 {
-	//gApplication().startUp("CamelotGLRenderer.dll");
-	gApplication().startUp("CamelotD3D9Renderer.dll");
+	gApplication().startUp("CamelotGLRenderer.dll");
+	//gApplication().startUp("CamelotD3D9Renderer.dll");
 
 	//RTTITypeBase* st = DbgSrlzTest::getRTTIStatic();
 

+ 4 - 43
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -80,45 +80,6 @@ namespace CamelotEngine {
 
 	};
 
-	String gpuProgramProfileToHLSLProfile(GpuProgramProfile profile)
-	{
-		switch(profile)
-		{
-		case GPP_PS_1_1:
-			return "ps_1_1";
-		case GPP_PS_1_2:
-			return "ps_1_2";
-		case GPP_PS_1_3:
-			return "ps_1_3";
-		case GPP_PS_1_4:
-			return "ps_1_4";
-		case GPP_PS_2_0:
-			return "ps_2_0";
-		case GPP_PS_2_a:
-			return "ps_2_a";
-		case GPP_PS_2_b:
-			return "ps_2_b";
-		case GPP_PS_3_0:
-			return "ps_3_0";
-		case GPP_PS_4_0:
-			return "ps_4_0";
-		case GPP_VS_1_1:
-			return "vs_1_1";
-		case GPP_VS_2_0:
-			return "vs_2_0";
-		case GPP_VS_2_a:
-			return "vs_2_a";
-		case GPP_VS_3_0:
-			return "vs_3_0";
-		case GPP_VS_4_0:
-			return "vs_4_0";
-		default:
-			assert(false); // Unsupported profile
-		}
-
-		return "";
-	}
-
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
     void D3D9HLSLProgram::loadFromSource(void)
@@ -237,7 +198,7 @@ namespace CamelotEngine {
 		// include handler
 		HLSLIncludeHandler includeHandler(this);
 
-		String hlslProfile = gpuProgramProfileToHLSLProfile(mProfile);
+		String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 
         // Compile & assemble into microcode
         HRESULT hr = D3DXCompileShader(
@@ -272,7 +233,7 @@ namespace CamelotEngine {
     {
 		if (!mCompileError)
 		{
-			String hlslProfile = gpuProgramProfileToHLSLProfile(mProfile);
+			String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 
 			// Create a low-level program, give it the same name as us
 			mAssemblerProgram = 
@@ -528,7 +489,7 @@ namespace CamelotEngine {
 
 	const String D3D9HLSLProgram::getTarget(void) const
 	{
-		return gpuProgramProfileToHLSLProfile(mProfile);
+		return GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 	}
 
     //-----------------------------------------------------------------------
@@ -551,7 +512,7 @@ namespace CamelotEngine {
         if (mCompileError || !isRequiredCapabilitiesSupported())
             return false;
 
-		String hlslProfile = gpuProgramProfileToHLSLProfile(mProfile);
+		String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 
 		RenderSystem* rs = CamelotEngine::RenderSystemManager::getActive();
 		return rs->getCapabilities()->isShaderProfileSupported(hlslProfile);

+ 33 - 0
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -1151,15 +1151,24 @@ namespace CamelotEngine
 		{
 		case 3:
 			rsc->addShaderProfile("vs_3_0");
+			rsc->addGpuProgramProfile(GPP_VS_3_0, "vs_3_0");
 		case 2:
 			if (vs2x)
+			{
 				rsc->addShaderProfile("vs_2_x");
+				rsc->addGpuProgramProfile(GPP_VS_2_x, "vs_2_x");
+			}
 			if (vs2a)
+			{
 				rsc->addShaderProfile("vs_2_a");
+				rsc->addGpuProgramProfile(GPP_VS_2_a, "vs_2_a");
+			}
 
 			rsc->addShaderProfile("vs_2_0");
+			rsc->addGpuProgramProfile(GPP_VS_2_0, "vs_2_0");
 		case 1:
 			rsc->addShaderProfile("vs_1_1");
+			rsc->addGpuProgramProfile(GPP_VS_1_1, "vs_1_1");
 			rsc->setCapability(RSC_VERTEX_PROGRAM);
 		}
 	}
@@ -1256,27 +1265,51 @@ namespace CamelotEngine
 		{
 		case 3:
 			if (minor > 0)
+			{
 				rsc->addShaderProfile("ps_3_x");
+				rsc->addGpuProgramProfile(GPP_PS_3_x, "ps_3_x");
+			}
 
 			rsc->addShaderProfile("ps_3_0");
+			rsc->addGpuProgramProfile(GPP_PS_3_0, "ps_3_0");
 		case 2:
 			if (ps2x)
+			{
 				rsc->addShaderProfile("ps_2_x");
+				rsc->addGpuProgramProfile(GPP_PS_2_x, "ps_2_x");
+			}
 			if (ps2a)
+			{
 				rsc->addShaderProfile("ps_2_a");
+				rsc->addGpuProgramProfile(GPP_PS_2_a, "ps_2_a");
+			}
 			if (ps2b)
+			{
 				rsc->addShaderProfile("ps_2_b");
+				rsc->addGpuProgramProfile(GPP_PS_2_b, "ps_2_b");
+			}
 
 			rsc->addShaderProfile("ps_2_0");
+			rsc->addGpuProgramProfile(GPP_PS_2_0, "ps_2_0");
 		case 1:
 			if (major > 1 || minor >= 4)
+			{
 				rsc->addShaderProfile("ps_1_4");
+				rsc->addGpuProgramProfile(GPP_PS_1_4, "ps_1_4");
+			}
 			if (major > 1 || minor >= 3)
+			{
 				rsc->addShaderProfile("ps_1_3");
+				rsc->addGpuProgramProfile(GPP_PS_1_3, "ps_1_3");
+			}
 			if (major > 1 || minor >= 2)
+			{
 				rsc->addShaderProfile("ps_1_2");
+				rsc->addGpuProgramProfile(GPP_PS_1_2, "ps_1_2");
+			}
 
 			rsc->addShaderProfile("ps_1_1");
+			rsc->addGpuProgramProfile(GPP_PS_1_1, "ps_1_1");
 			rsc->setCapability(RSC_FRAGMENT_PROGRAM);
 		}
 	}

+ 29 - 0
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -328,14 +328,23 @@ namespace CamelotEngine {
 			rsc->setVertexProgramConstantFloatCount(floatConstantCount);
 
 			rsc->addShaderProfile("arbvp1");
+			rsc->addGpuProgramProfile(GPP_VS_1_1, "arbvp1"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+			rsc->addGpuProgramProfile(GPP_VS_2_0, "arbvp1");
+			rsc->addGpuProgramProfile(GPP_VS_2_a, "arbvp1");
+			rsc->addGpuProgramProfile(GPP_VS_2_x, "arbvp1");
+
 			if (GLEW_NV_vertex_program2_option)
 			{
 				rsc->addShaderProfile("vp30");
+				rsc->addGpuProgramProfile(GPP_VS_3_0, "vp30"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+				rsc->addGpuProgramProfile(GPP_VS_4_0, "vp30");
 			}
 
 			if (GLEW_NV_vertex_program3)
 			{
 				rsc->addShaderProfile("vp40");
+				rsc->addGpuProgramProfile(GPP_VS_3_0, "vp40"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+				rsc->addGpuProgramProfile(GPP_VS_4_0, "vp40");
 			}
 
 			if (GLEW_NV_vertex_program4)
@@ -367,6 +376,11 @@ namespace CamelotEngine {
 			rsc->addShaderProfile("ps_1_3");
 			rsc->addShaderProfile("ps_1_2");
 			rsc->addShaderProfile("ps_1_1");
+
+			rsc->addGpuProgramProfile(GPP_PS_1_1, "ps_1_1"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+			rsc->addGpuProgramProfile(GPP_PS_1_2, "ps_1_2");
+			rsc->addGpuProgramProfile(GPP_PS_1_3, "ps_1_3");
+			rsc->addGpuProgramProfile(GPP_PS_1_4, "ps_1_4");
 		}
 
 		if (GLEW_ARB_fragment_program)
@@ -382,14 +396,29 @@ namespace CamelotEngine {
 			rsc->setFragmentProgramConstantFloatCount(floatConstantCount);
 
 			rsc->addShaderProfile("arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_1_1, "arbfp1"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+			rsc->addGpuProgramProfile(GPP_PS_1_2, "arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_1_3, "arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_1_4, "arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_2_0, "arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_2_a, "arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_2_b, "arbfp1");
+			rsc->addGpuProgramProfile(GPP_PS_2_x, "arbfp1");
+
 			if (GLEW_NV_fragment_program_option)
 			{
 				rsc->addShaderProfile("fp30");
+				rsc->addGpuProgramProfile(GPP_PS_3_0, "fp30"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+				rsc->addGpuProgramProfile(GPP_PS_3_x, "fp30");
+				rsc->addGpuProgramProfile(GPP_PS_4_0, "fp30");
 			}
 
 			if (GLEW_NV_fragment_program2)
 			{
 				rsc->addShaderProfile("fp40");
+				rsc->addGpuProgramProfile(GPP_PS_3_0, "fp40"); // TODO - I don't know if any of these GpuProgramProfile mappings are correct!
+				rsc->addGpuProgramProfile(GPP_PS_3_x, "fp40");
+				rsc->addGpuProgramProfile(GPP_PS_4_0, "fp40");
 			}        
 		}
 

+ 1 - 19
CamelotRenderer/Include/CmGpuProgram.h

@@ -32,6 +32,7 @@ THE SOFTWARE.
 #include "CmPrerequisites.h"
 #include "CmRenderOperation.h"
 #include "CmGpuProgramParams.h"
+#include "CmRenderSystemCapabilities.h"
 
 namespace CamelotEngine {
 
@@ -49,25 +50,6 @@ namespace CamelotEngine {
 		GPT_GEOMETRY_PROGRAM
 	};
 
-	enum GpuProgramProfile
-	{
-		GPP_NONE,
-		GPP_PS_1_1,
-		GPP_PS_1_2,
-		GPP_PS_1_3,
-		GPP_PS_1_4,
-		GPP_PS_2_0,
-		GPP_PS_2_a,
-		GPP_PS_2_b,
-		GPP_PS_3_0,
-		GPP_PS_4_0,
-		GPP_VS_1_1,
-		GPP_VS_2_0,
-		GPP_VS_2_a,
-		GPP_VS_3_0,
-		GPP_VS_4_0
-	};
-
 	/** Defines a program which runs on the GPU such as a vertex or fragment program. 
 	@remarks
 		This class defines the low-level program in assembler code, the sort used to

+ 7 - 0
CamelotRenderer/Include/CmGpuProgramManager.h

@@ -83,6 +83,13 @@ namespace CamelotEngine {
         /** Returns whether a given syntax code (e.g. "ps_1_3", "fp20", "arbvp1") is supported. */
         virtual bool isSyntaxSupported(const String& syntaxCode) const;
 		
+		
+		/** Converts a generic GpuProgramProfile identifier into a render-system specific one.  
+		* 
+		*  Returns an empty string if it can't convert it.
+		*/
+		virtual String gpuProgProfileToRSSpecificProfile(GpuProgramProfile gpuProgProfile) const;
+
 		/** Creates a new GpuProgramParameters instance which can be used to bind
             parameters to your programs.
         @remarks

+ 45 - 0
CamelotRenderer/Include/CmRenderSystemCapabilities.h

@@ -222,6 +222,28 @@ namespace CamelotEngine
 		GPU_VENDOR_COUNT = 11
 	};
 
+	enum GpuProgramProfile
+	{
+		GPP_NONE,
+		GPP_PS_1_1,
+		GPP_PS_1_2,
+		GPP_PS_1_3,
+		GPP_PS_1_4,
+		GPP_PS_2_0,
+		GPP_PS_2_x,
+		GPP_PS_2_a,
+		GPP_PS_2_b,
+		GPP_PS_3_0,
+		GPP_PS_3_x,
+		GPP_PS_4_0,
+		GPP_VS_1_1,
+		GPP_VS_2_0,
+		GPP_VS_2_x,
+		GPP_VS_2_a,
+		GPP_VS_3_0,
+		GPP_VS_4_0
+	};
+
 	/** singleton class for storing the capabilities of the graphics card. 
 	@remarks
 	This class stores the capabilities of the graphics card.  This
@@ -296,6 +318,8 @@ namespace CamelotEngine
 		/// The list of supported shader profiles
 		ShaderProfiles mSupportedShaderProfiles;
 
+		// Allows us to convert a generic shader profile to a render-system specific one
+		unordered_map<GpuProgramProfile, String>::type mGenericToSpecificShaderProfileMap;
 	public:	
 		RenderSystemCapabilities ();
 		virtual ~RenderSystemCapabilities ();
@@ -485,6 +509,13 @@ namespace CamelotEngine
 
 		}
 
+		/** Adds the profile to the list of supported profiles
+		*/
+		void addGpuProgramProfile(GpuProgramProfile gpuProgProfile, const String& rsSpecificProfile)
+		{
+			mGenericToSpecificShaderProfileMap[gpuProgProfile] = rsSpecificProfile;
+		}
+
 		/** Remove a given shader profile, if present.
 		*/
 		void removeShaderProfile(const String& profile)
@@ -507,6 +538,20 @@ namespace CamelotEngine
 			return mSupportedShaderProfiles;
 		}
 
+		/** Converts a generic GpuProgramProfile identifier into a render-system specific one.  
+		* 
+		*  Returns an empty string if it can't convert it.
+		*/
+		String gpuProgProfileToRSSpecificProfile(GpuProgramProfile gpuProgProfile) const
+		{
+			auto iterFind = mGenericToSpecificShaderProfileMap.find(gpuProgProfile);
+			if(mGenericToSpecificShaderProfileMap.end() != iterFind)
+			{
+				return iterFind->second;
+			}
+
+			return "";
+		}
 
 		/// The number of floating-point constants vertex programs support
 		UINT16 getVertexProgramConstantFloatCount(void) const

+ 9 - 9
CamelotRenderer/Source/CmApplication.cpp

@@ -83,15 +83,15 @@ namespace CamelotEngine
 		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;											\
-		}";
+								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();

+ 7 - 83
CamelotRenderer/Source/CmCgProgram.cpp

@@ -49,99 +49,23 @@ namespace CamelotEngine {
 			CM_EXCEPT(InternalErrorException, msg);
 		}
 	}
-
-	GpuProgramProfile cgProfileToGpuProgramProfile(const String& profile)
-	{
-		if(profile == "ps_1_1")
-			return GPP_PS_1_1;
-		else if(profile == "ps_1_2")
-			return GPP_PS_1_2;
-		else if(profile == "ps_1_3")
-			return GPP_PS_1_3;
-		else if(profile == "ps_1_4")
-			return GPP_PS_1_4;
-		else if(profile == "ps_2_0")
-			return GPP_PS_2_0;
-		else if(profile == "ps_2_a")
-			return GPP_PS_2_a;
-		else if(profile == "ps_2_b")
-			return GPP_PS_2_b;
-		else if(profile == "ps_3_0")
-			return GPP_PS_3_0;
-		else if(profile == "ps_4_0")
-			return GPP_PS_4_0;
-		else if(profile == "vs_1_1")
-			return GPP_VS_1_1;
-		else if(profile == "vs_2_0")
-			return GPP_VS_2_0;
-		else if(profile == "vs_2_a")
-			return GPP_VS_2_a;
-		else if(profile == "vs_3_0")
-			return GPP_VS_3_0;
-		else if(profile == "vs_4_0")
-			return GPP_VS_4_0;
-		else
-			assert(false); // Unsupported profile
-
-		return GPP_NONE;
-	}
-
-	String gpuProgramProfileToCgProfile(GpuProgramProfile profile)
-	{
-		switch(profile)
-		{
-		case GPP_PS_1_1:
-			return "ps_1_1";
-		case GPP_PS_1_2:
-			return "ps_1_2";
-		case GPP_PS_1_3:
-			return "ps_1_3";
-		case GPP_PS_1_4:
-			return "ps_1_4";
-		case GPP_PS_2_0:
-			return "ps_2_0";
-		case GPP_PS_2_a:
-			return "ps_2_a";
-		case GPP_PS_2_b:
-			return "ps_2_b";
-		case GPP_PS_3_0:
-			return "ps_3_0";
-		case GPP_PS_4_0:
-			return "ps_4_0";
-		case GPP_VS_1_1:
-			return "vs_1_1";
-		case GPP_VS_2_0:
-			return "vs_2_0";
-		case GPP_VS_2_a:
-			return "vs_2_a";
-		case GPP_VS_3_0:
-			return "vs_3_0";
-		case GPP_VS_4_0:
-			return "vs_4_0";
-		default:
-			assert(false); // Unsupported profile
-		}
-
-		return "";
-	}
-
     //-----------------------------------------------------------------------
     void CgProgram::selectProfile(void)
     {
         mSelectedProfile.clear();
         mSelectedCgProfile = CG_PROFILE_UNKNOWN;
 
-		mSelectedProfile = gpuProgramProfileToCgProfile(mProfile);
+		mSelectedProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
 		GpuProgramManager& gpuMgr = GpuProgramManager::instance();
-		//if (gpuMgr.isSyntaxSupported(mSelectedProfile))
+		if (gpuMgr.isSyntaxSupported(mSelectedProfile))
 		{
 			mSelectedCgProfile = cgGetProfile(mSelectedProfile.c_str());
 			// Check for errors
 			checkForCgError("CgProgram::selectProfile", 
 				"Unable to find CG profile enum for program.", mCgContext);
 		}
-		//else
-		//	mSelectedProfile.clear();
+		else
+			mSelectedProfile.clear();
     }
     //-----------------------------------------------------------------------
     void CgProgram::buildArgs(void)
@@ -242,7 +166,7 @@ namespace CamelotEngine {
 				// Create a high-level program, give it the same name as us
 				HighLevelGpuProgramPtr vp = 
 					HighLevelGpuProgramManager::instance().createProgram(
-					hlslSourceFromCg, "main", "hlsl", mType, cgProfileToGpuProgramProfile(mSelectedProfile));
+					hlslSourceFromCg, "main", "hlsl", mType, mProfile);
 
 				vp->load();
 
@@ -532,8 +456,8 @@ namespace CamelotEngine {
         if (mCompileError || !isRequiredCapabilitiesSupported())
             return false;
 
-		//String selectedProfile = gpuProgramProfileToCgProfile(mProfile);
-		//if (GpuProgramManager::instance().isSyntaxSupported(selectedProfile))
+		String selectedProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
+		if (GpuProgramManager::instance().isSyntaxSupported(selectedProfile))
 			return true;
 
         return false;

+ 9 - 0
CamelotRenderer/Source/CmGpuProgramManager.cpp

@@ -84,6 +84,15 @@ namespace CamelotEngine {
 			// Get the supported syntaxed from RenderSystemCapabilities 
 			return rs->getCapabilities()->isShaderProfileSupported(syntaxCode);
 		}
+
+	//---------------------------------------------------------------------------
+	String GpuProgramManager::gpuProgProfileToRSSpecificProfile(GpuProgramProfile gpuProgProfile) const
+	{
+		// Use the current render system
+		RenderSystem* rs = CamelotEngine::RenderSystemManager::getActive();
+
+		return  rs->getCapabilities()->gpuProgProfileToRSSpecificProfile(gpuProgProfile);
+	}
 	//-----------------------------------------------------------------------------
 	GpuProgramParametersSharedPtr GpuProgramManager::createParameters(void)
 	{

+ 3 - 1
CamelotRenderer/TODO.txt

@@ -45,7 +45,9 @@ TODO:
  - OpenGL too
 
 TOMORROW:
- - Incorporate CG into the engine!
+ - Profile checking in isSupported and setProfile for CG shaders is temporarily disabled
+   - In general I need to handle this better. 
+   - CG shaders don't work with OpenGL
  - Are resource getting properly unloaded? e.g. when shared_ptr destroys a texture is it removed from gpu?
  - Depth test is disabled by default (OpenGL renderer at least)
  - Serializable callbacks can't be null otherwise compiler complains

+ 6 - 6
CamelotUtility/Include/CmStdHeaders.h

@@ -194,22 +194,22 @@ namespace CamelotEngine
 		typedef typename std::multimap<K, V, P> type; 
 	}; 
 
-	template <typename T, typename P = std::less<T>, typename A = char > 
+	template <typename T, typename A = char, typename B = char, typename C = char> 
 	struct unordered_set 
 	{ 
-		typedef typename std::unordered_set<T, P> type;    
+		typedef typename std::unordered_set<T> type;    
 	}; 
 
-	template <typename K, typename V, typename P = std::less<K>, typename A = char > 
+	template <typename K, typename V, typename A = char, typename B = char, typename C = char> 
 	struct unordered_map 
 	{ 
-		typedef typename std::unordered_map<K, V, P> type; 
+		typedef typename std::unordered_map<K, V> type; 
 	}; 
 
-	template <typename K, typename V, typename P = std::less<K>, typename A = char > 
+	template <typename K, typename V, typename A = char, typename B = char, typename C = char> 
 	struct unordered_multimap 
 	{ 
-		typedef typename std::unordered_multimap<K, V, P> type; 
+		typedef typename std::unordered_multimap<K, V> type; 
 	}; 
 
 	// TODO - Once VC2012 grows up and adds proper C++11 support, uncomment this