瀏覽代碼

Gpu program include importer

Marko Pintera 13 年之前
父節點
當前提交
2de43e95a4
共有 39 個文件被更改,包括 280 次插入144 次删除
  1. 4 0
      CamelotClient/CamelotClient.cpp
  2. 2 1
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h
  3. 2 1
      CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgramFactory.h
  4. 1 1
      CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp
  5. 25 25
      CamelotD3D11RenderSystem/Source/CmD3D11GpuProgramManager.cpp
  6. 2 2
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp
  7. 4 3
      CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgramFactory.cpp
  8. 2 1
      CamelotD3D9Renderer/Include/CmD3D9GpuProgram.h
  9. 2 1
      CamelotD3D9Renderer/Include/CmD3D9HLSLProgram.h
  10. 2 1
      CamelotD3D9Renderer/Include/CmD3D9HLSLProgramFactory.h
  11. 3 2
      CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp
  12. 3 50
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp
  13. 4 3
      CamelotD3D9Renderer/Source/CmD3D9HLSLProgramFactory.cpp
  14. 1 1
      CamelotGLRenderer/Source/CmGLGpuProgramManager.cpp
  15. 1 1
      CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h
  16. 2 1
      CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h
  17. 2 1
      CamelotGLRenderer/Source/GLSL/include/CmGLSLProgramFactory.h
  18. 2 2
      CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp
  19. 2 2
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp
  20. 4 3
      CamelotGLRenderer/Source/GLSL/src/CmGLSLProgramFactory.cpp
  21. 4 0
      CamelotRenderer/CamelotRenderer.vcxproj
  22. 12 0
      CamelotRenderer/CamelotRenderer.vcxproj.filters
  23. 2 1
      CamelotRenderer/Include/CmCgProgram.h
  24. 2 1
      CamelotRenderer/Include/CmCgProgramFactory.h
  25. 19 0
      CamelotRenderer/Include/CmGpuProgInclude.h
  26. 24 0
      CamelotRenderer/Include/CmGpuProgIncludeImporter.h
  27. 2 1
      CamelotRenderer/Include/CmGpuProgram.h
  28. 3 2
      CamelotRenderer/Include/CmHighLevelGpuProgram.h
  29. 4 2
      CamelotRenderer/Include/CmHighLevelGpuProgramManager.h
  30. 3 0
      CamelotRenderer/Include/CmPrerequisites.h
  31. 3 3
      CamelotRenderer/Source/CmCgProgram.cpp
  32. 4 3
      CamelotRenderer/Source/CmCgProgramFactory.cpp
  33. 19 0
      CamelotRenderer/Source/CmGpuProgInclude.cpp
  34. 42 0
      CamelotRenderer/Source/CmGpuProgIncludeImporter.cpp
  35. 21 2
      CamelotRenderer/Source/CmGpuProgram.cpp
  36. 5 5
      CamelotRenderer/Source/CmHighLevelGpuProgram.cpp
  37. 5 4
      CamelotRenderer/Source/CmHighLevelGpuProgramManager.cpp
  38. 2 1
      CamelotRenderer/Source/CmImporter.cpp
  39. 34 17
      CamelotRenderer/TODO.txt

+ 4 - 0
CamelotClient/CamelotClient.cpp

@@ -20,6 +20,7 @@
 #include "CmPass.h"
 #include "CmImporter.h"
 #include "CmMesh.h"
+#include "CmGpuProgInclude.h" // DEBUG ONLY
 
 #include "CmDebugCamera.h"
 
@@ -53,6 +54,9 @@ int CALLBACK WinMain(
 	GameObjectPtr testModelGO = GameObject::create("TestMesh");
 	RenderablePtr testRenderable = testModelGO->addComponent<Renderable>();
 
+	GpuProgIncludeHandle gpuProgInclude = Importer::instance().import("C:\\testInclude.gpuproginc");
+	const String& debugString = gpuProgInclude->getString();
+
 	/////////////////// HLSL 9 SHADERS //////////////////////////
 	//String fragShaderCode = "sampler2D tex;			\
 	//						float4 ps_main(float2 uv : TEXCOORD0) : COLOR0		\

+ 2 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgram.h

@@ -35,7 +35,8 @@ namespace CamelotEngine
 		friend class D3D11HLSLProgramFactory;
 
 		D3D11HLSLProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, 
+			bool isAdjacencyInfoRequired = false);
 
         /**
          * @copydoc HighLevelGpuProgram::initialize_internal()

+ 2 - 1
CamelotD3D11RenderSystem/Include/CmD3D11HLSLProgramFactory.h

@@ -14,7 +14,8 @@ namespace CamelotEngine
 		~D3D11HLSLProgramFactory();
 
 		const String& getLanguage(void) const;
-		HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
+		HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, 
+			GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes);
 		HighLevelGpuProgram* create();
 	};
 }

+ 1 - 1
CamelotD3D11RenderSystem/Source/CmD3D11GpuProgram.cpp

@@ -6,7 +6,7 @@
 namespace CamelotEngine
 {
 	D3D11GpuProgram::D3D11GpuProgram(GpuProgramType type, const String& profile) 
-		: GpuProgram("", "", profile, type, GPP_NONE)
+		: GpuProgram("", "", profile, type, GPP_NONE, nullptr)
 	{
 
 	}

+ 25 - 25
CamelotD3D11RenderSystem/Source/CmD3D11GpuProgramManager.cpp

@@ -3,30 +3,30 @@
 
 namespace CamelotEngine
 {
-	D3D11GpuProgramManager::D3D11GpuProgramManager(D3D11Device& device)
-		:mDevice(device)
-	{ }
-
-	D3D11GpuProgramManager::~D3D11GpuProgramManager()
-	{ }
-
-	GpuProgram* D3D11GpuProgramManager::create(const String& source, const String& entryPoint, 
-		const String& language, GpuProgramType gptype, GpuProgramProfile profile)
-	{
-		switch(gptype)
-		{
-		case GPT_VERTEX_PROGRAM:
-			return new D3D11GpuVertexProgram(language);
-		case GPT_FRAGMENT_PROGRAM:
-			return new D3D11GpuFragmentProgram(language);
-		case GPT_HULL_PROGRAM:
-			return new D3D11GpuHullProgram(language);
-		case GPT_DOMAIN_PROGRAM:
-			return new D3D11GpuDomainProgram(language);
-		case GPT_GEOMETRY_PROGRAM:
-			return new D3D11GpuGeometryProgram(language);
-		}
-		
-		return nullptr;
+	D3D11GpuProgramManager::D3D11GpuProgramManager(D3D11Device& device)
+		:mDevice(device)
+	{ }
+
+	D3D11GpuProgramManager::~D3D11GpuProgramManager()
+	{ }
+
+	GpuProgram* D3D11GpuProgramManager::create(const String& source, const String& entryPoint, 
+		const String& language, GpuProgramType gptype, GpuProgramProfile profile)
+	{
+		switch(gptype)
+		{
+		case GPT_VERTEX_PROGRAM:
+			return new D3D11GpuVertexProgram(language);
+		case GPT_FRAGMENT_PROGRAM:
+			return new D3D11GpuFragmentProgram(language);
+		case GPT_HULL_PROGRAM:
+			return new D3D11GpuHullProgram(language);
+		case GPT_DOMAIN_PROGRAM:
+			return new D3D11GpuDomainProgram(language);
+		case GPT_GEOMETRY_PROGRAM:
+			return new D3D11GpuGeometryProgram(language);
+		}
+		
+		return nullptr;
 	}
 }

+ 2 - 2
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgram.cpp

@@ -16,8 +16,8 @@ namespace CamelotEngine
 	UINT32 D3D11HLSLProgram::globalProgramId = 0;
 
 	D3D11HLSLProgram::D3D11HLSLProgram(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
-		: HighLevelGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired),
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, bool isAdjacencyInfoRequired)
+		: HighLevelGpuProgram(source, entryPoint, language, gptype, profile, includes, isAdjacencyInfoRequired),
 		mColumnMajorMatrices(true), mEnableBackwardsCompatibility(false), mProgramId(0)
 	{
 	}

+ 4 - 3
CamelotD3D11RenderSystem/Source/CmD3D11HLSLProgramFactory.cpp

@@ -18,16 +18,17 @@ namespace CamelotEngine
         return sLanguageName;
     }
 
-	HighLevelGpuProgram* D3D11HLSLProgramFactory::create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile)
+	HighLevelGpuProgram* D3D11HLSLProgramFactory::create(const String& source, const String& entryPoint, 
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
     {
-		D3D11HLSLProgram* prog = new D3D11HLSLProgram(source, entryPoint, sLanguageName, gptype, profile);
+		D3D11HLSLProgram* prog = new D3D11HLSLProgram(source, entryPoint, sLanguageName, gptype, profile, includes);
 
         return prog;
     }
 
 	HighLevelGpuProgram* D3D11HLSLProgramFactory::create()
 	{
-		D3D11HLSLProgram* prog = new D3D11HLSLProgram("", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE);
+		D3D11HLSLProgram* prog = new D3D11HLSLProgram("", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE, nullptr);
 
 		return prog;
 	}

+ 2 - 1
CamelotD3D9Renderer/Include/CmD3D9GpuProgram.h

@@ -59,7 +59,8 @@ namespace CamelotEngine {
     protected:
 		friend class D3D9GpuProgramManager;
 
-		D3D9GpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
+		D3D9GpuProgram(const String& source, const String& entryPoint, const String& language, 
+			GpuProgramType gptype, GpuProgramProfile profile);
 
 		void createInternalResources(IDirect3DDevice9* d3d9Device);
 

+ 2 - 1
CamelotD3D9Renderer/Include/CmD3D9HLSLProgram.h

@@ -89,7 +89,8 @@ namespace CamelotEngine {
 		friend class D3D9HLSLProgramFactory;
 
 		D3D9HLSLProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, 
+			bool isAdjacencyInfoRequired = false);
  
 		/**
 		 * @copydoc HighLevelGpuProgram::initialize_internal().

+ 2 - 1
CamelotD3D9Renderer/Include/CmD3D9HLSLProgramFactory.h

@@ -43,7 +43,8 @@ namespace CamelotEngine
         ~D3D9HLSLProgramFactory();
 		/// Get the name of the language this factory creates programs for
 		const String& getLanguage(void) const;
-        HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
+        HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, 
+			GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes);
 		HighLevelGpuProgram* create();
     };
 }

+ 3 - 2
CamelotD3D9Renderer/Source/CmD3D9GpuProgram.cpp

@@ -36,8 +36,9 @@ THE SOFTWARE.
 
 namespace CamelotEngine {
     //-----------------------------------------------------------------------------
-    D3D9GpuProgram::D3D9GpuProgram(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile) 
-        : GpuProgram(source, entryPoint, language, gptype, profile), mpExternalMicrocode(NULL), mColumnMajorMatrices(false)
+    D3D9GpuProgram::D3D9GpuProgram(const String& source, const String& entryPoint, const String& language, 
+		GpuProgramType gptype, GpuProgramProfile profile) 
+        : GpuProgram(source, entryPoint, language, gptype, profile, nullptr), mpExternalMicrocode(NULL), mColumnMajorMatrices(false)
     {
     }
 

+ 3 - 50
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -36,56 +36,10 @@ THE SOFTWARE.
 #include "CmD3D9HLSLProgramRTTI.h"
 
 namespace CamelotEngine {
-	class CM_D3D9_EXPORT HLSLIncludeHandler : public ID3DXInclude
-	{
-	public:
-		HLSLIncludeHandler(HighLevelGpuProgram* sourceProgram) 
-			: mProgram(sourceProgram) {}
-		~HLSLIncludeHandler() {}
-		
-		STDMETHOD(Open)(D3DXINCLUDE_TYPE IncludeType,
-			LPCSTR pFileName,
-			LPCVOID pParentData,
-			LPCVOID *ppData,
-			UINT *pByteLen
-			)
-		{
-			// TODO PORT - I'm not sure what to do with this. It will probably break something in its current state.
-
-			//// find & load source code
-			//DataStreamPtr stream = 
-			//	ResourceGroupManager::getSingleton().openResource(
-			//	String(pFileName), mProgram->getGroup(), true, mProgram);
-
-			//String source = stream->getAsString();
-			//// copy into separate c-string
-			//// Note - must NOT copy the null terminator, otherwise this will terminate
-			//// the entire program string!
-			//*pByteLen = static_cast<UINT>(source.length());
-			//char* pChar = new char[*pByteLen];
-			//memcpy(pChar, source.c_str(), *pByteLen);
-			//*ppData = pChar;
-
-			assert(false); // TODO - Include files not supported until I can figure out how to handle them
-
-			return S_OK;
-		}
-
-		STDMETHOD(Close)(LPCVOID pData)
-		{
-			char* pChar = (char*)pData;
-			delete [] pChar;
-			return S_OK;
-		}
-	protected:
-		HighLevelGpuProgram* mProgram;
-
-
-	};
 	//-----------------------------------------------------------------------
 	D3D9HLSLProgram::D3D9HLSLProgram(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
-		: HighLevelGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired)
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, bool isAdjacencyInfoRequired)
+		: HighLevelGpuProgram(source, entryPoint, language, gptype, profile, includes, isAdjacencyInfoRequired)
 		, mPreprocessorDefines()
 		, mColumnMajorMatrices(true)
 		, mpMicroCode(NULL)
@@ -213,7 +167,6 @@ namespace CamelotEngine {
 			LPD3DXBUFFER errors = 0;
 
 			// include handler
-			HLSLIncludeHandler includeHandler(this);
 			LPD3DXCONSTANTTABLE constTable;
 
 			String hlslProfile = GpuProgramManager::instance().gpuProgProfileToRSSpecificProfile(mProfile);
@@ -223,7 +176,7 @@ namespace CamelotEngine {
 				mSource.c_str(),
 				static_cast<UINT>(mSource.length()),
 				pDefines,
-				&includeHandler, 
+				nullptr, 
 				mEntryPoint.c_str(),
 				hlslProfile.c_str(),
 				compileFlags,

+ 4 - 3
CamelotD3D9Renderer/Source/CmD3D9HLSLProgramFactory.cpp

@@ -47,16 +47,17 @@ namespace CamelotEngine {
         return sLanguageName;
     }
     //-----------------------------------------------------------------------
-	HighLevelGpuProgram* D3D9HLSLProgramFactory::create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile)
+	HighLevelGpuProgram* D3D9HLSLProgramFactory::create(const String& source, const String& entryPoint, 
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
     {
-		D3D9HLSLProgram* prog = new D3D9HLSLProgram(source, entryPoint, sLanguageName, gptype, profile);
+		D3D9HLSLProgram* prog = new D3D9HLSLProgram(source, entryPoint, sLanguageName, gptype, profile, includes);
 
         return prog;
     }
 	//-----------------------------------------------------------------------
 	HighLevelGpuProgram* D3D9HLSLProgramFactory::create()
 	{
-		D3D9HLSLProgram* prog = new D3D9HLSLProgram("", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE);
+		D3D9HLSLProgram* prog = new D3D9HLSLProgram("", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE, nullptr);
 
 		return prog;
 	}

+ 1 - 1
CamelotGLRenderer/Source/CmGLGpuProgramManager.cpp

@@ -43,6 +43,6 @@ GLGpuProgramManager::~GLGpuProgramManager()
 
 GpuProgram* GLGpuProgramManager::create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile)
 {
-    return new GLSLGpuProgram(source, entryPoint, language, gptype, profile);
+    return new GLSLGpuProgram(source, entryPoint, language, gptype, profile, nullptr);
 }
 

+ 1 - 1
CamelotGLRenderer/Source/GLSL/include/CmGLSLGpuProgram.h

@@ -61,7 +61,7 @@ namespace CamelotEngine {
 		friend class GLGpuProgramManager;
 
 		GLSLGpuProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes);
 
 		/// GL Handle for the shader object
 		GLSLProgram* mGLSLProgram;

+ 2 - 1
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h

@@ -102,7 +102,8 @@ namespace CamelotEngine {
 		friend class GLSLProgramFactory;
 
 		GLSLProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, 
+			bool isAdjacencyInfoRequired = false);
 
 		/**
 		 * @copydoc HighLevelGpuProgram::initialize_internal()

+ 2 - 1
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgramFactory.h

@@ -44,7 +44,8 @@ namespace CamelotEngine
 		/// Get the name of the language this factory creates programs for
 		const String& getLanguage(void) const;
 		/// create an instance of GLSLProgram
-        HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
+        HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, 
+			GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes);
 		HighLevelGpuProgram* create();
     };
 }

+ 2 - 2
CamelotGLRenderer/Source/GLSL/src/CmGLSLGpuProgram.cpp

@@ -40,8 +40,8 @@ namespace CamelotEngine {
 	UINT32 GLSLGpuProgram::mHullShaderCount = 0;
     //-----------------------------------------------------------------------------
 	GLSLGpuProgram::GLSLGpuProgram(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile) 
-		:GpuProgram(source, entryPoint, language, gptype, profile)
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes) 
+		:GpuProgram(source, entryPoint, language, gptype, profile, includes)
     {
         mSyntaxCode = "glsl";
 

+ 2 - 2
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp

@@ -47,8 +47,8 @@ namespace CamelotEngine
 {
 	//-----------------------------------------------------------------------
 	GLSLProgram::GLSLProgram(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
-		: HighLevelGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired),
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, bool isAdjacencyInfoRequired)
+		: HighLevelGpuProgram(source, entryPoint, language, gptype, profile, includes, isAdjacencyInfoRequired),
 		mInputOperationType(DOT_TRIANGLE_LIST),
 		mOutputOperationType(DOT_TRIANGLE_LIST), mMaxOutputVertices(3)
 	{

+ 4 - 3
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgramFactory.cpp

@@ -38,16 +38,17 @@ namespace CamelotEngine {
         return sLanguageName;
     }
     //-----------------------------------------------------------------------
-    HighLevelGpuProgram* GLSLProgramFactory::create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile)
+    HighLevelGpuProgram* GLSLProgramFactory::create(const String& source, const String& entryPoint, 
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
     {
-		GLSLProgram* prog = new GLSLProgram(source, entryPoint, sLanguageName, gptype, profile);
+		GLSLProgram* prog = new GLSLProgram(source, entryPoint, sLanguageName, gptype, profile, includes);
 
 		return prog;
     }
 	//-----------------------------------------------------------------------
 	HighLevelGpuProgram* GLSLProgramFactory::create()
 	{
-		GLSLProgram* prog = new GLSLProgram("", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE);
+		GLSLProgram* prog = new GLSLProgram("", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE, nullptr);
 
 		return prog;
 	}

+ 4 - 0
CamelotRenderer/CamelotRenderer.vcxproj

@@ -201,6 +201,7 @@
     <ClInclude Include="Include\CmGpuParamBlock.h" />
     <ClInclude Include="Include\CmGpuParamDesc.h" />
     <ClInclude Include="Include\CmGpuParams.h" />
+    <ClInclude Include="Include\CmGpuProgInclude.h" />
     <ClInclude Include="Include\CmGpuProgram.h" />
     <ClInclude Include="Include\CmGpuProgramManager.h" />
     <ClInclude Include="Include\CmGpuProgramParams.h" />
@@ -212,6 +213,7 @@
     <ClInclude Include="Include\CmMeshManager.h" />
     <ClInclude Include="Include\CmOcclusionQuery.h" />
     <ClInclude Include="Include\CmPixelBuffer.h" />
+    <ClInclude Include="Include\CmGpuProgIncludeImporter.h" />
     <ClInclude Include="Include\CmTextureView.h" />
     <ClInclude Include="Include\CmVertexBuffer.h" />
     <ClInclude Include="Include\CmHighLevelGpuProgram.h" />
@@ -294,6 +296,7 @@
     <ClCompile Include="Source\CmGpuBufferView.cpp" />
     <ClCompile Include="Source\CmGpuParamBlock.cpp" />
     <ClCompile Include="Source\CmGpuParams.cpp" />
+    <ClCompile Include="Source\CmGpuProgInclude.cpp" />
     <ClCompile Include="Source\CmGpuProgram.cpp" />
     <ClCompile Include="Source\CmGpuProgramManager.cpp" />
     <ClCompile Include="Source\CmGpuProgramParams.cpp" />
@@ -303,6 +306,7 @@
     <ClCompile Include="Source\CmMeshManager.cpp" />
     <ClCompile Include="Source\CmOcclusionQuery.cpp" />
     <ClCompile Include="Source\CmPixelBuffer.cpp" />
+    <ClCompile Include="Source\CmGpuProgIncludeImporter.cpp" />
     <ClCompile Include="Source\CmTextureView.cpp" />
     <ClCompile Include="Source\CmVertexBuffer.cpp" />
     <ClCompile Include="Source\CmHighLevelGpuProgram.cpp" />

+ 12 - 0
CamelotRenderer/CamelotRenderer.vcxproj.filters

@@ -377,6 +377,12 @@
     <ClInclude Include="Include\CmMaterialManager.h">
       <Filter>Header Files\Material</Filter>
     </ClInclude>
+    <ClInclude Include="Include\CmGpuProgIncludeImporter.h">
+      <Filter>Header Files\Importer</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\CmGpuProgInclude.h">
+      <Filter>Header Files\Resources</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\CamelotRenderer.cpp">
@@ -577,5 +583,11 @@
     <ClCompile Include="Include\CmMaterialManager.cpp">
       <Filter>Source Files\Material</Filter>
     </ClCompile>
+    <ClCompile Include="Source\CmGpuProgIncludeImporter.cpp">
+      <Filter>Source Files\Importer</Filter>
+    </ClCompile>
+    <ClCompile Include="Source\CmGpuProgInclude.cpp">
+      <Filter>Source Files\Resources</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 2 - 1
CamelotRenderer/Include/CmCgProgram.h

@@ -72,7 +72,8 @@ namespace CamelotEngine {
 		CGprofile mSelectedCgProfile;
 
 		CgProgram(CGcontext context, const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, 
+			bool isAdjacencyInfoRequired = false);
 
         /** Internal load implementation, must be implemented by subclasses.
         */

+ 2 - 1
CamelotRenderer/Include/CmCgProgramFactory.h

@@ -45,7 +45,8 @@ namespace CamelotEngine
         ~CgProgramFactory();
 		/// Get the name of the language this factory creates programs for
 		const String& getLanguage(void) const;
-        HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile);
+        HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, 
+			GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes = nullptr);
 		HighLevelGpuProgram* create();
 		void destroy_internal(HighLevelGpuProgram* prog);
 

+ 19 - 0
CamelotRenderer/Include/CmGpuProgInclude.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmResource.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT GpuProgInclude : public Resource
+	{
+	public:
+		const String& getString() const { return mString; }
+
+		static GpuProgIncludeHandle create(const String& includeString);
+	private:
+		GpuProgInclude(const String& includeString);
+
+		String mString;
+	};
+}

+ 24 - 0
CamelotRenderer/Include/CmGpuProgIncludeImporter.h

@@ -0,0 +1,24 @@
+#pragma once
+
+#include "CmPrerequisites.h"
+#include "CmSpecificImporter.h"
+
+namespace CamelotEngine
+{
+	class CM_EXPORT GpuProgIncludeImporter : public SpecificImporter
+	{
+	public:
+		GpuProgIncludeImporter();
+		virtual ~GpuProgIncludeImporter();
+
+		/** Inherited from SpecificImporter */
+		virtual bool isExtensionSupported(const String& ext) const;
+
+		/** Inherited from SpecificImporter */
+		virtual bool isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const; 
+
+		/** Inherited from SpecificImporter */
+		virtual BaseResourceHandle import(const String& filePath);
+	private:
+	};
+}

+ 2 - 1
CamelotRenderer/Include/CmGpuProgram.h

@@ -148,7 +148,8 @@ namespace CamelotEngine {
 		friend class GpuProgramManager;
 
 		GpuProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, 
+			bool isAdjacencyInfoRequired = false);
 
         /** Internal method returns whether required capabilities for this program is supported.
         */

+ 3 - 2
CamelotRenderer/Include/CmHighLevelGpuProgram.h

@@ -73,7 +73,8 @@ namespace CamelotEngine {
 
 		/** Constructor, should be used only by factory classes. */
 		HighLevelGpuProgram(const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired = false);
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes,
+			bool isAdjacencyInfoRequired = false);
 
 		/**
 		 * @copydoc Resource::initialize_internal.
@@ -93,7 +94,7 @@ namespace CamelotEngine {
 		/************************************************************************/
 	public:
 		static HighLevelGpuProgramHandle create(const String& source, const String& entryPoint, 
-			const String& language, GpuProgramType gptype, GpuProgramProfile profile);
+			const String& language, GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes = nullptr);
     };
 
 	/** @} */

+ 4 - 2
CamelotRenderer/Include/CmHighLevelGpuProgramManager.h

@@ -49,7 +49,8 @@ namespace CamelotEngine {
         virtual ~HighLevelGpuProgramFactory();
 		/// Get the name of the language this factory creates programs for
 		virtual const String& getLanguage(void) const = 0;
-        virtual HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile) = 0;
+        virtual HighLevelGpuProgram* create(const String& source, const String& entryPoint, 
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes) = 0;
 		virtual HighLevelGpuProgram* create() = 0;
 	};
 	/** This ResourceManager manages high-level vertex and fragment programs. 
@@ -98,7 +99,8 @@ namespace CamelotEngine {
 		@param language Code of the language to use (e.g. "cg")
 		@param gptype The type of program to create
 		*/
-		HighLevelGpuProgramPtr create(const String& source, const String& entryPoint, const String& language, GpuProgramType gptype, GpuProgramProfile profile);
+		HighLevelGpuProgramPtr create(const String& source, const String& entryPoint, const String& language, 
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes);
 
 		/** Create a new HighLevelGpuProgram. 
 		@par

+ 3 - 0
CamelotRenderer/Include/CmPrerequisites.h

@@ -141,6 +141,7 @@ namespace CamelotEngine {
 	struct GpuParamDataDesc;
 	struct GpuParamObjectDesc;
 	struct GpuParamBlockDesc;
+	class GpuProgInclude;
 	class TextureView;
 	class CoreGpuObject;
 	// Asset import
@@ -204,6 +205,7 @@ namespace CamelotEngine
 	typedef std::shared_ptr<GpuParams> GpuParamsPtr;
 	typedef std::shared_ptr<TextureView> TextureViewPtr;
 	typedef std::shared_ptr<Viewport> ViewportPtr;
+	typedef std::shared_ptr<GpuProgInclude> GpuProgIncludePtr;
 }
 
 // All type IDs used for RTTI
@@ -269,6 +271,7 @@ namespace CamelotEngine
 	typedef ResourceHandle<RasterizerState> RasterizerStateHandle;
 	typedef ResourceHandle<DepthStencilState> DepthStencilStateHandle;
 	typedef ResourceHandle<BlendState> BlendStateHandle;
+	typedef ResourceHandle<GpuProgInclude> GpuProgIncludeHandle;
 }
 
 #endif

+ 3 - 3
CamelotRenderer/Source/CmCgProgram.cpp

@@ -102,7 +102,7 @@ namespace CamelotEngine {
 			// Create a low-level program, give it the same name as us
 			mAssemblerProgram = 
 				HighLevelGpuProgramManager::instance().create(
-				sourceFromCg, mEntryPoint, RenderSystem::instance().getShadingLanguageName(), mType, mProfile);
+				sourceFromCg, mEntryPoint, RenderSystem::instance().getShadingLanguageName(), mType, mProfile, nullptr);
 
 			// Shader params need to be forwarded to low level implementation
 			mAssemblerProgram->setAdjacencyInfoRequired(isAdjacencyInfoRequired());
@@ -139,8 +139,8 @@ namespace CamelotEngine {
 	}
 
 	CgProgram::CgProgram(CGcontext context, const String& source, const String& entryPoint, const String& language, 
-			GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
-        : HighLevelGpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired), 
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, bool isAdjacencyInfoRequired)
+        : HighLevelGpuProgram(source, entryPoint, language, gptype, profile, includes, isAdjacencyInfoRequired), 
         mCgContext(context), mCgProgram(0), 
         mSelectedCgProfile(CG_PROFILE_UNKNOWN)
     {

+ 4 - 3
CamelotRenderer/Source/CmCgProgramFactory.cpp

@@ -54,16 +54,17 @@ namespace CamelotEngine {
         return sLanguageName;
     }
     //-----------------------------------------------------------------------
-    HighLevelGpuProgram* CgProgramFactory::create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile)
+    HighLevelGpuProgram* CgProgramFactory::create(const String& source, const String& entryPoint, 
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
     {
-		CgProgram* prog = new CgProgram(mCgContext, source, entryPoint, sLanguageName, gptype, profile);
+		CgProgram* prog = new CgProgram(mCgContext, source, entryPoint, sLanguageName, gptype, profile, includes);
 
 		return prog;
     }
 	//----------------------------------------------------------------------
 	HighLevelGpuProgram* CgProgramFactory::create()
 	{
-		CgProgram* prog = new CgProgram(mCgContext, "", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE);
+		CgProgram* prog = new CgProgram(mCgContext, "", "", sLanguageName, GPT_VERTEX_PROGRAM, GPP_NONE, nullptr);
 
 		return prog;
 	}

+ 19 - 0
CamelotRenderer/Source/CmGpuProgInclude.cpp

@@ -0,0 +1,19 @@
+#include "CmGpuProgInclude.h"
+
+namespace CamelotEngine
+{
+	GpuProgInclude::GpuProgInclude(const String& includeString)
+		:mString(includeString)
+	{
+
+	}
+
+	GpuProgIncludeHandle GpuProgInclude::create(const String& includeString)
+	{
+		GpuProgIncludePtr gpuProgIncludePtr = GpuProgIncludePtr(new GpuProgInclude(includeString));
+		gpuProgIncludePtr->setThisPtr(gpuProgIncludePtr);
+		gpuProgIncludePtr->initialize();
+
+		return static_resource_cast<GpuProgInclude>(Resource::_createResourceHandle(gpuProgIncludePtr));
+	}
+}

+ 42 - 0
CamelotRenderer/Source/CmGpuProgIncludeImporter.cpp

@@ -0,0 +1,42 @@
+#include "CmGpuProgIncludeImporter.h"
+#include "CmGpuProgInclude.h"
+#include "CmDataStream.h"
+#include "CmFileSystem.h"
+
+namespace CamelotEngine
+{
+	GpuProgIncludeImporter::GpuProgIncludeImporter()
+		:SpecificImporter()
+	{
+
+	}
+
+	GpuProgIncludeImporter::~GpuProgIncludeImporter()
+	{
+
+	}
+
+	bool GpuProgIncludeImporter::isExtensionSupported(const String& ext) const
+	{
+		String lowerCaseExt = ext;
+		StringUtil::toLowerCase(lowerCaseExt);
+
+		return lowerCaseExt == "gpuproginc";
+	}
+
+	bool GpuProgIncludeImporter::isMagicNumberSupported(const UINT8* magicNumPtr, UINT32 numBytes) const
+	{
+		return true; // Plain-text so I don't even check for magic number
+	}
+
+	BaseResourceHandle GpuProgIncludeImporter::import(const String& filePath)
+	{
+		DataStreamPtr stream = FileSystem::open(filePath);
+		String includeString = stream->getAsString();
+
+		GpuProgIncludeHandle gpuProgInclude = GpuProgInclude::create(includeString);
+		gpuProgInclude.waitUntilLoaded();
+
+		return gpuProgInclude;
+	}
+}

+ 21 - 2
CamelotRenderer/Source/CmGpuProgram.cpp

@@ -34,6 +34,7 @@ THE SOFTWARE.
 #include "CmRenderSystem.h"
 #include "CmAsyncOp.h"
 #include "CmGpuParams.h"
+#include "CmGpuProgInclude.h"
 #include "CmGpuProgramRTTI.h"
 
 #if CM_DEBUG_MODE
@@ -46,11 +47,29 @@ namespace CamelotEngine
 {
     //-----------------------------------------------------------------------------
     GpuProgram::GpuProgram(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired) 
-        :mSource(source), mEntryPoint(entryPoint), mSyntaxCode(language), mType(gptype),
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, bool isAdjacencyInfoRequired) 
+        :mEntryPoint(entryPoint), mSyntaxCode(language), mType(gptype),
 		mProfile(profile), mNeedsAdjacencyInfo(isAdjacencyInfoRequired)
     {
+		if(includes != nullptr)
+		{
+			std::ostringstream stringStream;
+			for(auto iter = includes->begin(); iter != includes->end(); ++iter)
+			{
+				if(*iter != nullptr)
+				{
+					stringStream << (*iter)->getString();
+				}
+			}
 
+			stringStream << source;
+
+			mSource = stringStream.str();
+		}
+		else
+		{
+			mSource = source;
+		}
     }
 	//----------------------------------------------------------------------------
 	GpuProgram::~GpuProgram()

+ 5 - 5
CamelotRenderer/Source/CmHighLevelGpuProgram.cpp

@@ -42,9 +42,9 @@ namespace CamelotEngine
 {
     //---------------------------------------------------------------------------
 	HighLevelGpuProgram::HighLevelGpuProgram(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile, bool isAdjacencyInfoRequired)
-        : GpuProgram(source, entryPoint, language, gptype, profile, isAdjacencyInfoRequired), 
-        mAssemblerProgram(0)
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes, bool isAdjacencyInfoRequired)
+        : GpuProgram(source, entryPoint, language, gptype, profile, includes, isAdjacencyInfoRequired), 
+        mAssemblerProgram(nullptr)
     {
     }
 	//---------------------------------------------------------------------------
@@ -75,9 +75,9 @@ namespace CamelotEngine
     }
 	//---------------------------------------------------------------------
 	HighLevelGpuProgramHandle HighLevelGpuProgram::create(const String& source, const String& entryPoint, 
-		const String& language, GpuProgramType gptype, GpuProgramProfile profile)
+		const String& language, GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
 	{
-		HighLevelGpuProgramPtr programPtr = HighLevelGpuProgramManager::instance().create(source, entryPoint, language, gptype, profile);
+		HighLevelGpuProgramPtr programPtr = HighLevelGpuProgramManager::instance().create(source, entryPoint, language, gptype, profile, includes);
 
 		return static_resource_cast<HighLevelGpuProgram>(Resource::_createResourceHandle(programPtr));
 	}

+ 5 - 4
CamelotRenderer/Source/CmHighLevelGpuProgramManager.cpp

@@ -51,7 +51,7 @@ namespace CamelotEngine {
 		}
 	public:
 		NullProgram()
-			: HighLevelGpuProgram("", "", "", GPT_VERTEX_PROGRAM, GPP_NONE){}
+			: HighLevelGpuProgram("", "", "", GPT_VERTEX_PROGRAM, GPP_NONE, nullptr){}
 		~NullProgram() {}
 		/// Overridden from GpuProgram - never supported
 		bool isSupported(void) const { return false; }
@@ -77,7 +77,8 @@ namespace CamelotEngine {
 		{ 
 			return sNullLang;
 		}
-		HighLevelGpuProgram* create(const String& source, const String& entryPoint, GpuProgramType gptype, GpuProgramProfile profile)
+		HighLevelGpuProgram* create(const String& source, const String& entryPoint, 
+			GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
 		{
 			return new NullProgram();
 		}
@@ -142,10 +143,10 @@ namespace CamelotEngine {
 	}
     //---------------------------------------------------------------------------
     HighLevelGpuProgramPtr HighLevelGpuProgramManager::create(const String& source, const String& entryPoint, const String& language, 
-		GpuProgramType gptype, GpuProgramProfile profile)
+		GpuProgramType gptype, GpuProgramProfile profile, const vector<GpuProgIncludePtr>::type* includes)
     {
 		HighLevelGpuProgramFactory* factory = getFactory(language);
-        HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create(source, entryPoint, gptype, profile), &CoreGpuObject::_deleteDelayed);
+        HighLevelGpuProgramPtr ret = HighLevelGpuProgramPtr(factory->create(source, entryPoint, gptype, profile, includes), &CoreGpuObject::_deleteDelayed);
 		ret->setThisPtr(ret);
 		ret->initialize();
 

+ 2 - 1
CamelotRenderer/Source/CmImporter.cpp

@@ -3,6 +3,7 @@
 #include "CmResource.h"
 #include "CmFileSystem.h"
 #include "CmSpecificImporter.h"
+#include "CmGpuProgIncludeImporter.h"
 #include "CmDebug.h"
 #include "CmDataStream.h"
 #include "CmException.h"
@@ -11,7 +12,7 @@ namespace CamelotEngine
 {
 	Importer::Importer()
 	{
-
+		registerAssetImporter(new GpuProgIncludeImporter());
 	}
 
 	Importer::~Importer()

+ 34 - 17
CamelotRenderer/TODO.txt

@@ -14,31 +14,47 @@ Pass
  - A way to bind buffers to a Pass, while specifying buffer range
  - GpuParams support for bools, buffers, structs
 
-Support loading of compound objects:
-   - Loading Material also loads attached Shader and Textures/Samplers
-
 Add support for include file resource
 Make sure we can add an include file to a HighLevelGpuProgram, and make sure it uses it
  - Also a way to list all referenced includes, and a way to remove them
 
+ Importer for shaders
+  - If GpuProgram is immutable then how do I add an include file to it after calling import()?
+  - Figure out a better way of assigning include files
+
 Seems there is a possible deadlock when starting the render thread, while waiting for the thread to be started
 Get rid of resource handlers in Resources?
 
+Deserialization issues:
+ - Currently Reflectable is not allowed to hold a ReflectablePtr
+   - Because Reflectable might be assigned before a pointer is decoded and assigned, therefore
+      ending up with a null pointer. Changing the order when we decode pointers would solve this issue.
+ - Changing the order of pointer decoding increases the chance of getting an uninitialized pointer in your RTTI class. 
+    e.g. Mesh::setMeshData expects an initialized MeshDataPtr to be provided.
+
+SOLUTION: Decode all pointers ON THE SPOT (whether they are referenced by Reflectable or ReflectablePtr), before we assign them
+ - Recusive references remain an issue though
+   - Objects referencing themselves are checked during application start-up (or compile time?). User is warned of the situation, 
+      and he has so remedy it by making one of the references Weak (a special property assigned to the RTTI field)
+
 Can be delayed:
- Make sure that I am able to blit contents from render textures on all render systems
- Once I get DX11 running make sure to test if driver complains about missing shader attributes or invalid size ones
- Better creation of PrimaryWindow
-  - RENDERWINDOWDESC accepts a "externalWindow" flag and an "externalHandle" so when creating the primary window with RenderSystem::initialize we don't always need to create a new window
-  - Actually new OpenGL seems to support creating context without a window with the help of wglCreateContextAttribsARB and wglMakeCurrent:
- ImportOptions
- Instead of doing setThisPtr on every CoreGpuObject, use intrusive shared_ptr instead?
- OpenGL render window no longer looks for a monitor index
- Test if async loading still works
- Material RTTI should also serialize shared buffers (they need to be made into a resource)
- - BE CAREFUL on how this will be implemented. Likely it will have much of the same interface as a material and/or GpuParams
- Mesh::setMeshData is currently always synced
- queueGpuCommand is handled weird. shared_ptr isn't used for setting (this) parameter, and could be optimized out by the compiler
-  - test if everything is okay in release mode
+ - Make sure that I am able to blit contents from render textures on all render systems
+ - Once I get DX11 running make sure to test if driver complains about missing shader attributes or invalid size ones
+ - Better creation of PrimaryWindow
+   - RENDERWINDOWDESC accepts a "externalWindow" flag and an "externalHandle" so when creating the primary window with RenderSystem::initialize we don't always need to create a new window
+   - Actually new OpenGL seems to support creating context without a window with the help of wglCreateContextAttribsARB and wglMakeCurrent:
+ - ImportOptions
+ - Instead of doing setThisPtr on every CoreGpuObject, use intrusive shared_ptr instead?
+ - OpenGL render window no longer looks for a monitor index
+ - Test if async loading still works
+ - Material RTTI should also serialize shared buffers (they need to be made into a resource)
+   - BE CAREFUL on how this will be implemented. Likely it will have much of the same interface as a material and/or GpuParams
+ - Mesh::setMeshData is currently always synced
+ - queueGpuCommand is handled weird. shared_ptr isn't used for setting (this) parameter, and could be optimized out by the compiler
+   - test if everything is okay in release mode
+ - Resources::unload will deadlock if the resource isn't being loaded!
+   - Maybe re-think how I handle ResourceHandle.isCreated?
+ - Check D3D9/D3D11/GL resource usages. DX11 reports many unreleased objects. I'm guessing DX9 will as well. Not sure how to check OpenGL.
 >>>>>>>>>>>>>>>START WORKING ON THE EDITOR!
  
 
@@ -164,6 +180,7 @@ Optional TODO:
   - Value types are only set at the end of deserialization, because I want to be sure all of their fields are initialized. 
      However there is nothing stopping a custom RTTI method from accessing a (yet uninitialized) value in a ptr field. 
 	 (See CmMaterialRTTI, setTexParam). I need to initialize fields in a better order.)
+ - Creating stuff like gpu program include and shader, etc. still require initialize() (call to render thread)
 
  -----------------------------------------------------------------------------------------------