Przeglądaj źródła

Check in before removing a bunch of GL shader methods

Marko Pintera 13 lat temu
rodzic
commit
828e5f3dcd

+ 2 - 2
CamelotClient/CamelotClient.cpp

@@ -26,8 +26,8 @@ using namespace CamelotEngine;
 
 
 int _tmain(int argc, _TCHAR* argv[])
 int _tmain(int argc, _TCHAR* argv[])
 {
 {
-	//gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
-	gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
+	gApplication().startUp("CamelotGLRenderSystem", "CamelotForwardRenderer");
+	//gApplication().startUp("CamelotD3D9RenderSystem", "CamelotForwardRenderer");
 
 
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
 	RenderSystem* renderSystem = RenderSystem::instancePtr();
 	RenderWindowPtr renderWindow = gApplication().getPrimaryRenderWindow();
 	RenderWindowPtr renderWindow = gApplication().getPrimaryRenderWindow();

+ 4 - 4
CamelotD3D11RenderSystem/Include/CmD3D11RenderSystem.h

@@ -11,14 +11,14 @@ namespace CamelotEngine
 		~D3D11RenderSystem();
 		~D3D11RenderSystem();
 
 
 		const String& getName() const;
 		const String& getName() const;
-
-		void setSamplerState(UINT16 texUnit, const SamplerState& samplerState);
+		
 		void setBlendState(const BlendState& blendState);
 		void setBlendState(const BlendState& blendState);
 		void setRasterizerState(const RasterizerState& rasterizerState);
 		void setRasterizerState(const RasterizerState& rasterizerState);
 		void setDepthStencilState(const DepthStencilState& depthStencilState);
 		void setDepthStencilState(const DepthStencilState& depthStencilState);
 
 
-		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr );
-		void disableTextureUnit(UINT16 texUnit);
+		void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerState& samplerState);
+		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
+		void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit);
 
 
 		void setStencilRefValue(UINT32 refValue);
 		void setStencilRefValue(UINT32 refValue);
 
 

+ 3 - 3
CamelotD3D11RenderSystem/Source/CmD3D11RenderSystem.cpp

@@ -107,7 +107,7 @@ namespace CamelotEngine
 		RenderSystem::destroy_internal();
 		RenderSystem::destroy_internal();
 	}
 	}
 
 
-	void D3D11RenderSystem::setSamplerState(UINT16 texUnit, const SamplerState& samplerState)
+	void D3D11RenderSystem::setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerState& samplerState)
 	{
 	{
 		throw std::exception("The method or operation is not implemented.");
 		throw std::exception("The method or operation is not implemented.");
 	}
 	}
@@ -132,12 +132,12 @@ namespace CamelotEngine
 		throw std::exception("The method or operation is not implemented.");
 		throw std::exception("The method or operation is not implemented.");
 	}
 	}
 
 
-	void D3D11RenderSystem::setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr)
+	void D3D11RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
 	{
 	{
 		throw std::exception("The method or operation is not implemented.");
 		throw std::exception("The method or operation is not implemented.");
 	}
 	}
 
 
-	void D3D11RenderSystem::disableTextureUnit(UINT16 texUnit)
+	void D3D11RenderSystem::disableTextureUnit(GpuProgramType gptype, UINT16 texUnit)
 	{
 	{
 		throw std::exception("The method or operation is not implemented.");
 		throw std::exception("The method or operation is not implemented.");
 	}
 	}

+ 3 - 5
CamelotD3D9Renderer/Include/CmD3D9RenderSystem.h

@@ -56,17 +56,16 @@ namespace CamelotEngine
 
 
 		void bindGpuProgram(GpuProgramHandle prg);
 		void bindGpuProgram(GpuProgramHandle prg);
 		void unbindGpuProgram(GpuProgramType gptype);
 		void unbindGpuProgram(GpuProgramType gptype);
-		void bindGpuProgramParameters(GpuProgramType gptype, 
-			GpuProgramParametersSharedPtr params, UINT16 variabilityMask);
+		void bindGpuProgramParameters(GpuProgramType gptype, GpuProgramParametersSharedPtr params, UINT16 variabilityMask);
 
 
 		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
 		void bindGpuParams(GpuProgramType gptype, GpuParamsPtr params);
 
 
-		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr);
+		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
 
 
 		/**
 		/**
 		 * @copydoc RenderSystem::setSamplerState()
 		 * @copydoc RenderSystem::setSamplerState()
 		 */
 		 */
-		void setSamplerState(UINT16 unit, const SamplerState& state);
+		void setSamplerState(GpuProgramType gptype, UINT16 unit, const SamplerState& state);
 
 
 		/**
 		/**
 		 * @copydoc RenderSystem::setBlendState()
 		 * @copydoc RenderSystem::setBlendState()
@@ -88,7 +87,6 @@ namespace CamelotEngine
 		 */
 		 */
 		void setStencilRefValue(UINT32 refValue);
 		void setStencilRefValue(UINT32 refValue);
 
 
-		void disableTextureUnit(UINT16 texUnit);
 		void setViewport(const Viewport& vp);		
 		void setViewport(const Viewport& vp);		
 		void beginFrame();
 		void beginFrame();
 		void endFrame();		
 		void endFrame();		

+ 2 - 0
CamelotD3D9Renderer/Source/CmD3D9HLSLProgram.cpp

@@ -90,6 +90,8 @@ namespace CamelotEngine {
 		{ }
 		{ }
 
 
 		GpuParamDesc buildParameterDescriptions();
 		GpuParamDesc buildParameterDescriptions();
+
+	private:
 		void processParameter(GpuParamBlockDesc& blockDesc, D3DXHANDLE parent, String prefix, UINT32 index);
 		void processParameter(GpuParamBlockDesc& blockDesc, D3DXHANDLE parent, String prefix, UINT32 index);
 		void populateParamMemberDesc(GpuParamMemberDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc);
 		void populateParamMemberDesc(GpuParamMemberDesc& memberDesc, D3DXCONSTANT_DESC& d3dDesc);
 
 

+ 55 - 53
CamelotD3D9Renderer/Source/CmD3D9RenderSystem.cpp

@@ -55,6 +55,7 @@ THE SOFTWARE.
 #include "CmGpuParams.h"
 #include "CmGpuParams.h"
 #include "CmGpuParamDesc.h"
 #include "CmGpuParamDesc.h"
 #include "CmGpuParamBlock.h"
 #include "CmGpuParamBlock.h"
+#include "CmDebug.h"
 
 
 #if CM_DEBUG_MODE
 #if CM_DEBUG_MODE
 #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
 #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
@@ -337,9 +338,9 @@ namespace CamelotEngine
 
 
 					SamplerStatePtr samplerState = params->getSamplerState(i->second.physicalIndex);
 					SamplerStatePtr samplerState = params->getSamplerState(i->second.physicalIndex);
 					if(samplerState == nullptr)
 					if(samplerState == nullptr)
-						setSamplerState(logicalIndex, SamplerState::getDefault());
+						setSamplerState(gptype, logicalIndex, SamplerState::getDefault());
 					else
 					else
-						setSamplerState(logicalIndex, *samplerState);
+						setSamplerState(gptype, logicalIndex, *samplerState);
 				}
 				}
 			}
 			}
 
 
@@ -353,7 +354,7 @@ namespace CamelotEngine
 					if(!texture.isLoaded())
 					if(!texture.isLoaded())
 						continue;
 						continue;
 
 
-					setTexture(logicalIndex, true, texture.getInternalPtr());
+					setTexture(gptype, logicalIndex, true, texture.getInternalPtr());
 				}
 				}
 			}
 			}
 		}
 		}
@@ -467,9 +468,9 @@ namespace CamelotEngine
 			SamplerStatePtr samplerState = params->getSamplerState(iter->second.slot);
 			SamplerStatePtr samplerState = params->getSamplerState(iter->second.slot);
 
 
 			if(samplerState == nullptr)
 			if(samplerState == nullptr)
-				setSamplerState(iter->second.slot, SamplerState::getDefault());
+				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault());
 			else
 			else
-				setSamplerState(iter->second.slot, *samplerState);
+				setSamplerState(gptype, iter->second.slot, *samplerState);
 		}
 		}
 
 
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
 		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
@@ -477,9 +478,9 @@ namespace CamelotEngine
 			TextureHandle texture = params->getTexture(iter->second.slot);
 			TextureHandle texture = params->getTexture(iter->second.slot);
 
 
 			if(!texture.isLoaded())
 			if(!texture.isLoaded())
-				setTexture(iter->second.slot, false, nullptr);
+				setTexture(gptype, iter->second.slot, false, nullptr);
 			else
 			else
-				setTexture(iter->second.slot, true, texture.getInternalPtr());
+				setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
 		}
 		}
 
 
 		HRESULT hr;
 		HRESULT hr;
@@ -616,18 +617,29 @@ namespace CamelotEngine
 		RenderSystem::destroyRenderTarget(renderTarget);	
 		RenderSystem::destroyRenderTarget(renderTarget);	
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
-	void D3D9RenderSystem::setTexture( UINT16 stage, bool enabled, const TexturePtr& tex )
+	void D3D9RenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& tex)
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
+		if(gptype != GPT_FRAGMENT_PROGRAM && gptype != GPT_VERTEX_PROGRAM)
+		{
+			LOGWRN("D3D9 cannot assign textures to this gpu program type: " + toString(gptype));
+			return;
+		}
+
+		if(gptype == GPT_VERTEX_PROGRAM)
+		{
+			unit = D3DVERTEXTEXTURESAMPLER0 + unit; // Vertex stage uses special samplers
+		}
+
 		HRESULT hr;
 		HRESULT hr;
 		D3D9TexturePtr dt = std::static_pointer_cast<D3D9Texture>(tex);
 		D3D9TexturePtr dt = std::static_pointer_cast<D3D9Texture>(tex);
 		if (enabled && (dt != nullptr))
 		if (enabled && (dt != nullptr))
 		{
 		{
 			IDirect3DBaseTexture9 *pTex = dt->getTexture_internal();
 			IDirect3DBaseTexture9 *pTex = dt->getTexture_internal();
-			if (mTexStageDesc[stage].pTex != pTex)
+			if (mTexStageDesc[unit].pTex != pTex)
 			{
 			{
-				hr = getActiveD3D9Device()->SetTexture(static_cast<DWORD>(stage), pTex);
+				hr = getActiveD3D9Device()->SetTexture(static_cast<DWORD>(unit), pTex);
 				if( hr != S_OK )
 				if( hr != S_OK )
 				{
 				{
 					String str = "Unable to set texture in D3D9";
 					String str = "Unable to set texture in D3D9";
@@ -635,57 +647,61 @@ namespace CamelotEngine
 				}
 				}
 
 
 				// set stage desc.
 				// set stage desc.
-				mTexStageDesc[stage].pTex = pTex;
-				mTexStageDesc[stage].texType = D3D9Mappings::get(dt->getTextureType());
+				mTexStageDesc[unit].pTex = pTex;
+				mTexStageDesc[unit].texType = D3D9Mappings::get(dt->getTextureType());
 
 
 				// Set gamma now too
 				// Set gamma now too
 				if (dt->isHardwareGammaReadToBeUsed())
 				if (dt->isHardwareGammaReadToBeUsed())
 				{
 				{
-					__SetSamplerState(static_cast<DWORD>(stage), D3DSAMP_SRGBTEXTURE, TRUE);
+					__SetSamplerState(static_cast<DWORD>(unit), D3DSAMP_SRGBTEXTURE, TRUE);
 				}
 				}
 				else
 				else
 				{
 				{
-					__SetSamplerState(static_cast<DWORD>(stage), D3DSAMP_SRGBTEXTURE, FALSE);
+					__SetSamplerState(static_cast<DWORD>(unit), D3DSAMP_SRGBTEXTURE, FALSE);
 				}
 				}
 			}
 			}
 		}
 		}
 		else
 		else
 		{
 		{
-			if (mTexStageDesc[stage].pTex != 0)
+			if (mTexStageDesc[unit].pTex != 0)
 			{
 			{
-				hr = getActiveD3D9Device()->SetTexture(static_cast<DWORD>(stage), 0);
+				hr = getActiveD3D9Device()->SetTexture(static_cast<DWORD>(unit), 0);
 				if( hr != S_OK )
 				if( hr != S_OK )
 				{
 				{
-					String str = "Unable to disable texture '" + toString(stage) + "' in D3D9";
+					String str = "Unable to disable texture '" + toString(unit) + "' in D3D9";
 					CM_EXCEPT(RenderingAPIException, str);
 					CM_EXCEPT(RenderingAPIException, str);
 				}
 				}
 			}
 			}
 
 
-			hr = __SetTextureStageState(static_cast<DWORD>(stage), D3DTSS_COLOROP, D3DTOP_DISABLE);
+			hr = __SetTextureStageState(static_cast<DWORD>(unit), D3DTSS_COLOROP, D3DTOP_DISABLE);
 			if( hr != S_OK )
 			if( hr != S_OK )
 			{
 			{
-				String str = "Unable to disable texture '" + toString(stage) + "' in D3D9";
+				String str = "Unable to disable texture '" + toString(unit) + "' in D3D9";
 				CM_EXCEPT(RenderingAPIException, str);
 				CM_EXCEPT(RenderingAPIException, str);
 			}
 			}
 
 
 			// set stage desc. to defaults
 			// set stage desc. to defaults
-			mTexStageDesc[stage].pTex = 0;
-			mTexStageDesc[stage].coordIndex = 0;
-			mTexStageDesc[stage].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL;
+			mTexStageDesc[unit].pTex = 0;
+			mTexStageDesc[unit].coordIndex = 0;
+			mTexStageDesc[unit].texType = D3D9Mappings::D3D_TEX_TYPE_NORMAL;
 		}
 		}
 	}
 	}
-	//---------------------------------------------------------------------
-	void D3D9RenderSystem::disableTextureUnit(UINT16 texUnit)
-	{
-		THROW_IF_NOT_RENDER_THREAD;
-
-		RenderSystem::disableTextureUnit(texUnit);
-	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	void D3D9RenderSystem::setSamplerState(UINT16 unit, const SamplerState& state)
+	void D3D9RenderSystem::setSamplerState(GpuProgramType gptype, UINT16 unit, const SamplerState& state)
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
+		if(gptype != GPT_FRAGMENT_PROGRAM || gptype != GPT_VERTEX_PROGRAM)
+		{
+			LOGWRN("D3D9 doesn't support this gpu program type: " + toString(gptype));
+			return;
+		}
+
+		if(gptype == GPT_VERTEX_PROGRAM)
+		{
+			unit = D3DVERTEXTEXTURESAMPLER0 + unit; // Vertex stage uses special samplers
+		}
+
 		// Set texture layer filtering
 		// Set texture layer filtering
 		setTextureFiltering(unit, FT_MIN, state.getTextureFiltering(FT_MIN));
 		setTextureFiltering(unit, FT_MIN, state.getTextureFiltering(FT_MIN));
 		setTextureFiltering(unit, FT_MAG, state.getTextureFiltering(FT_MAG));
 		setTextureFiltering(unit, FT_MAG, state.getTextureFiltering(FT_MAG));
@@ -1766,7 +1782,6 @@ namespace CamelotEngine
 
 
 
 
 		// Init caps to maximum.		
 		// Init caps to maximum.		
-		rsc->setNumTextureUnits(1024);
 		rsc->setCapability(RSC_ANISOTROPY);
 		rsc->setCapability(RSC_ANISOTROPY);
 		rsc->setCapability(RSC_AUTOMIPMAP);
 		rsc->setCapability(RSC_AUTOMIPMAP);
 		rsc->setCapability(RSC_DOT3);
 		rsc->setCapability(RSC_DOT3);
@@ -1829,10 +1844,7 @@ namespace CamelotEngine
 			D3D9Driver* pCurDriver       = mDriverList->item(i);			
 			D3D9Driver* pCurDriver       = mDriverList->item(i);			
 			const D3DCAPS9& rkCurCaps    = pCurDriver->getD3D9DeviceCaps();
 			const D3DCAPS9& rkCurCaps    = pCurDriver->getD3D9DeviceCaps();
 
 
-			if (rkCurCaps.MaxSimultaneousTextures < rsc->getNumTextureUnits())
-			{
-				rsc->setNumTextureUnits(static_cast<UINT16>(rkCurCaps.MaxSimultaneousTextures));
-			}
+			rsc->setNumTextureUnits(GPT_FRAGMENT_PROGRAM, 16); // We don't support anything lower than SM3, and 16 is the sampler count determined by the specification
 
 
 			// Check for Anisotropy.
 			// Check for Anisotropy.
 			if (rkCurCaps.MaxAnisotropy <= 1)
 			if (rkCurCaps.MaxAnisotropy <= 1)
@@ -2020,24 +2032,18 @@ namespace CamelotEngine
 
 
 		}
 		}
 
 
-
-		// TODO: make convertVertex/Fragment fill in rsc
-		// TODO: update the below line to use rsc
 		// Vertex textures
 		// Vertex textures
 		if (rsc->isShaderProfileSupported("vs_3_0"))
 		if (rsc->isShaderProfileSupported("vs_3_0"))
 		{
 		{
-			// Run through all the texture formats looking for any which support
-			// vertex texture fetching. Must have at least one!
-			// All ATI Radeon up to X1n00 say they support vs_3_0, 
-			// but they support no texture formats for vertex texture fetch (cheaters!)
-			if (checkVertexTextureFormats(renderWindow))
-			{
-				rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
-				// always 4 vertex texture units in vs_3_0, and never shared
-				rsc->setNumVertexTextureUnits(4);
-				rsc->setVertexTextureUnitsShared(false);
-			}
+			rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
+			rsc->setNumTextureUnits(GPT_VERTEX_PROGRAM, 4);
+			rsc->setNumCombinedTextureUnits(rsc->getNumTextureUnits(GPT_FRAGMENT_PROGRAM) +
+				rsc->getNumTextureUnits(GPT_VERTEX_PROGRAM));
 		}		
 		}		
+		else
+		{
+			rsc->setNumCombinedTextureUnits(rsc->getNumTextureUnits(GPT_FRAGMENT_PROGRAM));
+		}
 
 
 		// Check alpha to coverage support
 		// Check alpha to coverage support
 		// this varies per vendor! But at least SM3 is required
 		// this varies per vendor! But at least SM3 is required
@@ -2473,10 +2479,6 @@ namespace CamelotEngine
 
 
 		// Invalidate active view port.
 		// Invalidate active view port.
 		mActiveViewport = Viewport();
 		mActiveViewport = Viewport();
-
-		// Reset the texture stages, they will need to be rebound
-		for (UINT16 i = 0; i < CM_MAX_TEXTURE_LAYERS; ++i)
-			setTexture(i, false, TexturePtr());
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void D3D9RenderSystem::determineFSAASettings(IDirect3DDevice9* d3d9Device,
 	void D3D9RenderSystem::determineFSAASettings(IDirect3DDevice9* d3d9Device,

+ 22 - 19
CamelotGLRenderer/Include/CmGLRenderSystem.h

@@ -74,12 +74,12 @@ namespace CamelotEngine {
 		/**
 		/**
 		 * @copydoc RenderSystem::setTexture()
 		 * @copydoc RenderSystem::setTexture()
 		 */
 		 */
-        void setTexture(UINT16 unit, bool enabled, const TexturePtr &tex);
+        void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &tex);
         
         
 		/**
 		/**
 		 * @copydoc RenderSystem::setSamplerState()
 		 * @copydoc RenderSystem::setSamplerState()
 		 */
 		 */
-		void setSamplerState(UINT16 unit, const SamplerState& state);
+		void setSamplerState(GpuProgramType gptype, UINT16 unit, const SamplerState& state);
 
 
 		/**
 		/**
 		 * @copydoc RenderSystem::setBlendState()
 		 * @copydoc RenderSystem::setBlendState()
@@ -208,11 +208,8 @@ namespace CamelotEngine {
         FilterOptions mMinFilter;
         FilterOptions mMinFilter;
         FilterOptions mMipFilter;
         FilterOptions mMipFilter;
 
 
-        /// What texture coord set each texture unit is using
-        UINT32 mTextureCoordIndex[CM_MAX_TEXTURE_LAYERS];
-
         /// Holds texture type settings for every stage
         /// Holds texture type settings for every stage
-        GLenum mTextureTypes[CM_MAX_TEXTURE_LAYERS];
+        GLenum* mTextureTypes;
 
 
 		/// Number of fixed-function texture units
 		/// Number of fixed-function texture units
 		unsigned short mFixedFunctionTextureUnits;
 		unsigned short mFixedFunctionTextureUnits;
@@ -257,9 +254,15 @@ namespace CamelotEngine {
 
 
         GLuint getCombinedMinMipFilter(void) const;
         GLuint getCombinedMinMipFilter(void) const;
 
 
-        GLGpuProgram* mCurrentVertexProgram;
-        GLGpuProgram* mCurrentFragmentProgram;
-		GLGpuProgram* mCurrentGeometryProgram;
+        GLSLGpuProgram* mCurrentVertexProgram;
+        GLSLGpuProgram* mCurrentFragmentProgram;
+		GLSLGpuProgram* mCurrentGeometryProgram;
+		GLSLGpuProgram* mCurrentHullProgram;
+		GLSLGpuProgram* mCurrentDomainProgram;
+
+		UINT32 mFragmentTexOffset;
+		UINT32 mVertexTexOffset;
+		UINT32 mGeometryTexOffset;
 
 
 		/* The main GL context - main thread only */
 		/* The main GL context - main thread only */
         GLContext *mMainContext;
         GLContext *mMainContext;
@@ -507,9 +510,6 @@ namespace CamelotEngine {
 		 */
 		 */
 		void setStencilBufferWriteMask(UINT32 mask = 0xFFFFFFFF);
 		void setStencilBufferWriteMask(UINT32 mask = 0xFFFFFFFF);
 
 
-		// ----------------------------------
-        // GLRenderSystem specific members
-        // ----------------------------------
         /** One time initialization for the RenderState of a context. Things that
         /** One time initialization for the RenderState of a context. Things that
             only need to be set once, like the LightingModel can be defined here.
             only need to be set once, like the LightingModel can be defined here.
          */
          */
@@ -517,13 +517,16 @@ namespace CamelotEngine {
         /** Switch GL context, dealing with involved internal cached states too
         /** Switch GL context, dealing with involved internal cached states too
         */
         */
         void switchContext(GLContext *context);
         void switchContext(GLContext *context);
-        /** Unregister a render target->context mapping. If the context of target 
-            is the current context, change the context to the main context so it
-            can be destroyed safely. 
-            
-            @note This is automatically called by the destructor of 
-            GLContext.
-         */
+
+		/**
+		 * @brief	OpenGL shares all texture slots, but the engine prefers to keep textures
+		 * 			separate per-stage. This will convert texture unit that is set per stage
+		 * 			into a global texture unit usable by OpenGL.
+		 */
+		UINT32 getGLTextureUnit(GpuProgramType gptype, UINT32 unit);
+
+		void setActiveProgram(GpuProgramType gptype, GLSLGpuProgram* program);
+		GLSLGpuProgram* getActiveProgram(GpuProgramType gptype) const;
 
 
 		/** Returns the main context */
 		/** Returns the main context */
 		GLContext* _getMainContext() {return mMainContext;} 
 		GLContext* _getMainContext() {return mMainContext;} 

+ 0 - 2
CamelotGLRenderer/Source/CmGLHardwarePixelBuffer.cpp

@@ -501,8 +501,6 @@ namespace CamelotEngine
 			GL_TEXTURE_BIT | GL_VIEWPORT_BIT);
 			GL_TEXTURE_BIT | GL_VIEWPORT_BIT);
 
 
 		// Important to disable all other texture units
 		// Important to disable all other texture units
-		RenderSystem* rsys = CamelotEngine::RenderSystem::instancePtr();
-		rsys->disableTextureUnitsFrom(0);
 		if (GLEW_VERSION_1_2)
 		if (GLEW_VERSION_1_2)
 		{
 		{
 			glActiveTextureARB(GL_TEXTURE0);
 			glActiveTextureARB(GL_TEXTURE0);

+ 306 - 333
CamelotGLRenderer/Source/CmGLRenderSystem.cpp

@@ -36,6 +36,8 @@ THE SOFTWARE.s
 #include "CmGLDefaultHardwareBufferManager.h"
 #include "CmGLDefaultHardwareBufferManager.h"
 #include "CmGLUtil.h"
 #include "CmGLUtil.h"
 #include "CmGLGpuProgram.h"
 #include "CmGLGpuProgram.h"
+#include "CmGLSLGpuProgram.h"
+#include "CmGLSLProgram.h"
 #include "CmGLGpuProgramManager.h"
 #include "CmGLGpuProgramManager.h"
 #include "CmException.h"
 #include "CmException.h"
 #include "CmGLSLExtSupport.h"
 #include "CmGLSLExtSupport.h"
@@ -47,6 +49,8 @@ THE SOFTWARE.s
 #include "CmDepthStencilState.h"
 #include "CmDepthStencilState.h"
 #include "CmGLRenderTexture.h"
 #include "CmGLRenderTexture.h"
 #include "CmGLRenderWindowManager.h"
 #include "CmGLRenderWindowManager.h"
+#include "CmGpuParams.h"
+#include "CmDebug.h"
 
 
 #if CM_DEBUG_MODE
 #if CM_DEBUG_MODE
 #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
 #define THROW_IF_NOT_RENDER_THREAD throwIfNotRenderThread();
@@ -77,7 +81,11 @@ namespace CamelotEngine
 		mStencilWriteMask(0xFFFFFFFF),
 		mStencilWriteMask(0xFFFFFFFF),
 		mStencilCompareFront(CMPF_ALWAYS_PASS),
 		mStencilCompareFront(CMPF_ALWAYS_PASS),
 		mStencilCompareBack(CMPF_ALWAYS_PASS),
 		mStencilCompareBack(CMPF_ALWAYS_PASS),
-		mStencilRefValue(0)
+		mStencilRefValue(0),
+		mFragmentTexOffset(0),
+		mVertexTexOffset(0),
+		mGeometryTexOffset(0),
+		mTextureTypes(nullptr)
 	{
 	{
 		size_t i;
 		size_t i;
 
 
@@ -88,13 +96,6 @@ namespace CamelotEngine
 
 
 		mColourWrite[0] = mColourWrite[1] = mColourWrite[2] = mColourWrite[3] = true;
 		mColourWrite[0] = mColourWrite[1] = mColourWrite[2] = mColourWrite[3] = true;
 
 
-		for (i = 0; i < CM_MAX_TEXTURE_LAYERS; i++)
-		{
-			// Dummy value
-			mTextureCoordIndex[i] = 99;
-			mTextureTypes[i] = 0;
-		}
-
 		mActiveRenderTarget = 0;
 		mActiveRenderTarget = 0;
 		mCurrentContext = 0;
 		mCurrentContext = 0;
 		mMainContext = 0;
 		mMainContext = 0;
@@ -103,10 +104,11 @@ namespace CamelotEngine
 
 
 		mMinFilter = FO_LINEAR;
 		mMinFilter = FO_LINEAR;
 		mMipFilter = FO_POINT;
 		mMipFilter = FO_POINT;
-		mCurrentVertexProgram = 0;
-		mCurrentGeometryProgram = 0;
-		mCurrentFragmentProgram = 0;
-
+		mCurrentVertexProgram = nullptr;
+		mCurrentGeometryProgram = nullptr;
+		mCurrentFragmentProgram = nullptr;
+		mCurrentHullProgram = nullptr;
+		mCurrentDomainProgram = nullptr;
 	}
 	}
 
 
 	GLRenderSystem::~GLRenderSystem()
 	GLRenderSystem::~GLRenderSystem()
@@ -198,7 +200,7 @@ namespace CamelotEngine
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
 		GpuProgram* bindingPrg = prg->getBindingDelegate_internal();
 		GpuProgram* bindingPrg = prg->getBindingDelegate_internal();
-		GLGpuProgram* glprg = static_cast<GLGpuProgram*>(bindingPrg);
+		GLSLGpuProgram* glprg = static_cast<GLSLGpuProgram*>(bindingPrg);
 
 
 		// Unbind previous gpu program first.
 		// Unbind previous gpu program first.
 		//
 		//
@@ -217,13 +219,13 @@ namespace CamelotEngine
 		//     itself, if type is changing (during load/unload, etc), and it's inuse,
 		//     itself, if type is changing (during load/unload, etc), and it's inuse,
 		//     unbind and notify render system to correct for its state.
 		//     unbind and notify render system to correct for its state.
 		//
 		//
+
 		switch (glprg->getType())
 		switch (glprg->getType())
 		{
 		{
 		case GPT_VERTEX_PROGRAM:
 		case GPT_VERTEX_PROGRAM:
 			if (mCurrentVertexProgram != glprg)
 			if (mCurrentVertexProgram != glprg)
 			{
 			{
-				if (mCurrentVertexProgram)
-					mCurrentVertexProgram->unbindProgram();
+				unbindGpuProgram(glprg->getType());
 				mCurrentVertexProgram = glprg;
 				mCurrentVertexProgram = glprg;
 			}
 			}
 			break;
 			break;
@@ -231,19 +233,31 @@ namespace CamelotEngine
 		case GPT_FRAGMENT_PROGRAM:
 		case GPT_FRAGMENT_PROGRAM:
 			if (mCurrentFragmentProgram != glprg)
 			if (mCurrentFragmentProgram != glprg)
 			{
 			{
-				if (mCurrentFragmentProgram)
-					mCurrentFragmentProgram->unbindProgram();
+				unbindGpuProgram(glprg->getType());
 				mCurrentFragmentProgram = glprg;
 				mCurrentFragmentProgram = glprg;
 			}
 			}
 			break;
 			break;
 		case GPT_GEOMETRY_PROGRAM:
 		case GPT_GEOMETRY_PROGRAM:
 			if (mCurrentGeometryProgram != glprg)
 			if (mCurrentGeometryProgram != glprg)
 			{
 			{
-				if (mCurrentGeometryProgram)
-					mCurrentGeometryProgram->unbindProgram();
+				unbindGpuProgram(glprg->getType());
 				mCurrentGeometryProgram = glprg;
 				mCurrentGeometryProgram = glprg;
 			}
 			}
 			break;
 			break;
+		case GPT_DOMAIN_PROGRAM:
+			if (mCurrentDomainProgram != glprg)
+			{
+				unbindGpuProgram(glprg->getType());
+				mCurrentDomainProgram = glprg;
+			}
+			break;
+		case GPT_HULL_PROGRAM:
+			if (mCurrentHullProgram != glprg)
+			{
+				unbindGpuProgram(glprg->getType());
+				mCurrentHullProgram = glprg;
+			}
+			break;
 		}
 		}
 
 
 		// Bind the program
 		// Bind the program
@@ -274,6 +288,17 @@ namespace CamelotEngine
 			mCurrentFragmentProgram->unbindProgram();
 			mCurrentFragmentProgram->unbindProgram();
 			mCurrentFragmentProgram = 0;
 			mCurrentFragmentProgram = 0;
 		}
 		}
+		else if (gptype == GPT_DOMAIN_PROGRAM && mCurrentDomainProgram)
+		{
+			mCurrentDomainProgram->unbindProgram();
+			mCurrentDomainProgram = 0;
+		}
+		else if (gptype == GPT_HULL_PROGRAM && mCurrentHullProgram)
+		{
+			mCurrentHullProgram->unbindProgram();
+			mCurrentHullProgram = 0;
+		}
+
 		RenderSystem::unbindGpuProgram(gptype);
 		RenderSystem::unbindGpuProgram(gptype);
 	}
 	}
 
 
@@ -296,13 +321,13 @@ namespace CamelotEngine
 					if(!curTexture.isLoaded())
 					if(!curTexture.isLoaded())
 						continue;
 						continue;
 
 
-					setTexture(def.physicalIndex, true, curTexture.getInternalPtr());
+					setTexture(gptype, def.physicalIndex, true, curTexture.getInternalPtr());
 
 
 					SamplerStatePtr samplerState = params->getSamplerState(def.physicalIndex);
 					SamplerStatePtr samplerState = params->getSamplerState(def.physicalIndex);
 					if(samplerState == nullptr)
 					if(samplerState == nullptr)
-						setSamplerState(def.physicalIndex, SamplerState::getDefault());
+						setSamplerState(gptype, def.physicalIndex, SamplerState::getDefault());
 					else
 					else
-						setSamplerState(def.physicalIndex, *samplerState);
+						setSamplerState(gptype, def.physicalIndex, *samplerState);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -325,62 +350,149 @@ namespace CamelotEngine
 	}
 	}
 	//-----------------------------------------------------------------------------
 	//-----------------------------------------------------------------------------
 	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
 	void GLRenderSystem::bindGpuParams(GpuProgramType gptype, GpuParamsPtr params)
-	{
-		// TODO - Not implemented
-	}
-	//-----------------------------------------------------------------------------
-	void GLRenderSystem::setTexture(UINT16 stage, bool enabled, const TexturePtr &texPtr)
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
-		GLTexturePtr tex = std::static_pointer_cast<GLTexture>(texPtr);
+		params->updateIfDirty();
 
 
-		GLenum lastTextureType = mTextureTypes[stage];
+		const GpuParamDesc& paramDesc = params->getParamDesc();
+		GLSLGpuProgram* activeProgram = getActiveProgram(gptype);
+		GLuint glProgram = activeProgram->getGLSLProgram()->getGLHandle();
 
 
-		if (!activateGLTextureUnit(stage))
-			return;
+		for(auto iter = paramDesc.textures.begin(); iter != paramDesc.textures.end(); ++iter)
+		{
+			TextureHandle texture = params->getTexture(iter->second.slot);
 
 
-		if (enabled)
+			if(!texture.isLoaded())
+				setTexture(gptype, iter->second.slot, false, nullptr);
+			else
+				setTexture(gptype, iter->second.slot, true, texture.getInternalPtr());
+		}
+
+		UINT32 texUnit = 0;
+		for(auto iter = paramDesc.samplers.begin(); iter != paramDesc.samplers.end(); ++iter)
 		{
 		{
-			if (tex)
-			{
-				// note used
-				mTextureTypes[stage] = tex->getGLTextureTarget();
-			}
+			SamplerStatePtr samplerState = params->getSamplerState(iter->second.slot);
+
+			if(samplerState == nullptr)
+				setSamplerState(gptype, iter->second.slot, SamplerState::getDefault());
 			else
 			else
-				// assume 2D
-				mTextureTypes[stage] = GL_TEXTURE_2D;
+				setSamplerState(gptype, iter->second.slot, *samplerState);
+
+			glProgramUniform1i(glProgram, iter->second.slot, getGLTextureUnit(gptype, texUnit));
 
 
-			if(lastTextureType != mTextureTypes[stage] && lastTextureType != 0)
+			texUnit++;
+		}
+
+		for(auto iter = paramDesc.params.begin(); iter != paramDesc.params.end(); ++iter)
+		{
+			const GpuParamMemberDesc& paramDesc = iter->second;
+
+			GpuParamBlockPtr paramBlock = params->getParamBlock(paramDesc.paramBlockSlot);
+			
+			if(paramDesc.paramBlockSlot == 0) // 0 means uniforms are not in a block
 			{
 			{
-				if (stage < mFixedFunctionTextureUnits)
+				const UINT8* ptrData = paramBlock->getDataPtr(paramDesc.cpuMemOffset * sizeof(UINT32));
+
+				switch(paramDesc.type)
 				{
 				{
-					glDisable( lastTextureType );
+				case GCT_FLOAT1:
+					glProgramUniform1fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
+					break;
+				case GCT_FLOAT2:
+					glProgramUniform2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
+					break;
+				case GCT_FLOAT3:
+					glProgramUniform3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
+					break;
+				case GCT_FLOAT4:
+					glProgramUniform4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_2X2:
+					glProgramUniformMatrix2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_2X3:
+					glProgramUniformMatrix2x3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_2X4:
+					glProgramUniformMatrix2x4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_3X2:
+					glProgramUniformMatrix3x2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_3X3:
+					glProgramUniformMatrix3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_3X4:
+					glProgramUniformMatrix3x4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_4X2:
+					glProgramUniformMatrix4x2fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_4X3:
+					glProgramUniformMatrix4x3fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_MATRIX_4X4:
+					glProgramUniformMatrix4fv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, 
+						GL_TRUE, (GLfloat*)ptrData);
+					break;
+				case GCT_INT1:
+					glProgramUniform1iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
+					break;
+				case GCT_INT2:
+					glProgramUniform2iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
+					break;
+				case GCT_INT3:
+					glProgramUniform3iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
+					break;
+				case GCT_INT4:
+					glProgramUniform4iv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLint*)ptrData);
+					break;
+				case GMT_BOOL:
+					glProgramUniform1uiv(glProgram, paramDesc.gpuMemOffset, paramDesc.arraySize, (GLuint*)ptrData);
+					break;
+				case GCT_UNKNOWN:
+					break;
 				}
 				}
 			}
 			}
-
-			if (stage < mFixedFunctionTextureUnits)
-			{
-				glEnable( mTextureTypes[stage] );
-			}
-
-			if(tex)
-				glBindTexture( mTextureTypes[stage], tex->getGLID() );
 			else
 			else
 			{
 			{
-				glBindTexture( mTextureTypes[stage], static_cast<GLTextureManager*>(&TextureManager::instance())->getWarningTextureID() );
+				CM_EXCEPT(NotImplementedException, "Support for uniform blocks not implemented yet");
 			}
 			}
 		}
 		}
+	}
+	//-----------------------------------------------------------------------------
+	void GLRenderSystem::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr)
+	{
+		THROW_IF_NOT_RENDER_THREAD;
+
+		unit = getGLTextureUnit(gptype, unit);
+
+		GLTexturePtr tex = std::static_pointer_cast<GLTexture>(texPtr);
+
+		GLenum lastTextureType = mTextureTypes[unit];
+
+		if (!activateGLTextureUnit(unit))
+			return;
+
+		if (enabled && tex)
+		{
+			mTextureTypes[unit] = tex->getGLTextureTarget();
+			glBindTexture(mTextureTypes[unit], tex->getGLID());
+		}
 		else
 		else
 		{
 		{
-			if (stage < mFixedFunctionTextureUnits)
-			{
-				if (lastTextureType != 0)
-				{
-					glDisable( mTextureTypes[stage] );
-				}
-				glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-			}
+			// TODO - This doesn't actually disable all textures set on this image unit, only the 2D ones
+			//      - If a non-2D sampler is used, the texture will still be displayed
+
 			// bind zero texture
 			// bind zero texture
 			glBindTexture(GL_TEXTURE_2D, 0); 
 			glBindTexture(GL_TEXTURE_2D, 0); 
 		}
 		}
@@ -388,10 +500,12 @@ namespace CamelotEngine
 		activateGLTextureUnit(0);
 		activateGLTextureUnit(0);
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
-	void GLRenderSystem::setSamplerState(UINT16 unit, const SamplerState& state)
+	void GLRenderSystem::setSamplerState(GpuProgramType gptype, UINT16 unit, const SamplerState& state)
 	{
 	{
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
+		unit = getGLTextureUnit(gptype, unit);
+
 		// Set texture layer filtering
 		// Set texture layer filtering
 		setTextureFiltering(unit, FT_MIN, state.getTextureFiltering(FT_MIN));
 		setTextureFiltering(unit, FT_MIN, state.getTextureFiltering(FT_MIN));
 		setTextureFiltering(unit, FT_MAG, state.getTextureFiltering(FT_MAG));
 		setTextureFiltering(unit, FT_MAG, state.getTextureFiltering(FT_MAG));
@@ -586,8 +700,6 @@ namespace CamelotEngine
 		RenderSystem::render(op);
 		RenderSystem::render(op);
 
 
 		void* pBufferData = 0;
 		void* pBufferData = 0;
-		bool multitexturing = (getCapabilities()->getNumTextureUnits() > 1);
-
 
 
         const VertexDeclaration::VertexElementList& decl = 
         const VertexDeclaration::VertexElementList& decl = 
             op.vertexData->vertexDeclaration->getElements();
             op.vertexData->vertexDeclaration->getElements();
@@ -658,87 +770,8 @@ namespace CamelotEngine
  
  
  				attribsBound.push_back(attrib);
  				attribsBound.push_back(attrib);
  			}
  			}
- 			else
- 			{
- 				// fixed-function & builtin attribute support
- 				switch(sem)
-  				{
- 				case VES_POSITION:
- 					glVertexPointer(VertexElement::getTypeCount(
- 						elem->getType()), 
-  						GLHardwareBufferManager::getGLType(elem->getType()), 
-  						static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
-  						pBufferData);
- 					glEnableClientState( GL_VERTEX_ARRAY );
- 					break;
- 				case VES_NORMAL:
- 					glNormalPointer(
- 						GLHardwareBufferManager::getGLType(elem->getType()), 
-  						static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
-  						pBufferData);
- 					glEnableClientState( GL_NORMAL_ARRAY );
- 					break;
- 				case VES_DIFFUSE:
- 					glColorPointer(4, 
-  						GLHardwareBufferManager::getGLType(elem->getType()), 
-  						static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
-  						pBufferData);
- 					glEnableClientState( GL_COLOR_ARRAY );
- 					break;
- 				case VES_SPECULAR:
- 					if (GLEW_EXT_secondary_color)
- 					{
- 						glSecondaryColorPointerEXT(4, 
- 							GLHardwareBufferManager::getGLType(elem->getType()), 
- 							static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
- 							pBufferData);
- 						glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
- 					}
- 					break;
- 				case VES_TEXTURE_COORDINATES:
-  
- 					if (mCurrentVertexProgram)
- 					{
- 						// Programmable pipeline - direct UV assignment
- 						glClientActiveTextureARB(GL_TEXTURE0 + elem->getIndex());
- 						glTexCoordPointer(
- 							VertexElement::getTypeCount(elem->getType()), 
- 							GLHardwareBufferManager::getGLType(elem->getType()),
- 							static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
- 							pBufferData);
- 						glEnableClientState( GL_TEXTURE_COORD_ARRAY );
- 					}
- 					else
- 					{
- 						// fixed function matching to units based on tex_coord_set
- 						for (i = 0; i < mDisabledTexUnitsFrom; i++)
- 						{
- 							// Only set this texture unit's texcoord pointer if it
- 							// is supposed to be using this element's index
- 							if (mTextureCoordIndex[i] == elem->getIndex() && i < mFixedFunctionTextureUnits)
- 							{
-								if (multitexturing)
- 								glClientActiveTextureARB(GL_TEXTURE0 + i);
- 								glTexCoordPointer(
- 									VertexElement::getTypeCount(elem->getType()), 
- 									GLHardwareBufferManager::getGLType(elem->getType()),
- 									static_cast<GLsizei>(vertexBuffer->getVertexSize()), 
- 									pBufferData);
- 								glEnableClientState( GL_TEXTURE_COORD_ARRAY );
- 							}
- 						}
- 					}
- 					break;
- 				default:
- 					break;
- 				};
- 			} // isCustomAttrib
-  
         }
         }
 
 
-		if (multitexturing)
-		glClientActiveTextureARB(GL_TEXTURE0);
-
 		// Find the correct type to render
 		// Find the correct type to render
 		GLint primType;
 		GLint primType;
 		//Use adjacency if there is a geometry program and it requested adjacency info
 		//Use adjacency if there is a geometry program and it requested adjacency info
@@ -793,40 +826,13 @@ namespace CamelotEngine
 			glDrawArrays(primType, 0, op.vertexData->vertexCount);
 			glDrawArrays(primType, 0, op.vertexData->vertexCount);
 		}
 		}
 
 
-        glDisableClientState( GL_VERTEX_ARRAY );
-		// only valid up to GL_MAX_TEXTURE_UNITS, which is recorded in mFixedFunctionTextureUnits
-		if (multitexturing)
-        {
-			for (int i = 0; i < mFixedFunctionTextureUnits; i++)
-			{
-            glClientActiveTextureARB(GL_TEXTURE0 + i);
-				glDisableClientState( GL_TEXTURE_COORD_ARRAY );
-			}
-			glClientActiveTextureARB(GL_TEXTURE0);
-		}
-		else
-		{
-            glDisableClientState( GL_TEXTURE_COORD_ARRAY );
-        }
-        glDisableClientState( GL_NORMAL_ARRAY );
-        glDisableClientState( GL_COLOR_ARRAY );
-		if (GLEW_EXT_secondary_color)
-		{
-			glDisableClientState( GL_SECONDARY_COLOR_ARRAY );
-		}
  		// unbind any custom attributes
  		// unbind any custom attributes
 		for (vector<GLuint>::type::iterator ai = attribsBound.begin(); ai != attribsBound.end(); ++ai)
 		for (vector<GLuint>::type::iterator ai = attribsBound.begin(); ai != attribsBound.end(); ++ai)
  		{
  		{
  			glDisableVertexAttribArrayARB(*ai); 
  			glDisableVertexAttribArrayARB(*ai); 
- 
   		}
   		}
 		
 		
 		glColor4f(1,1,1,1);
 		glColor4f(1,1,1,1);
-		if (GLEW_EXT_secondary_color)
-		{
-			glSecondaryColor3fEXT(0.0f, 0.0f, 0.0f);
-		}
-
 	}
 	}
 	//---------------------------------------------------------------------
 	//---------------------------------------------------------------------
 	void GLRenderSystem::setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
 	void GLRenderSystem::setScissorRect(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
@@ -1475,15 +1481,11 @@ namespace CamelotEngine
 		// Unbind GPU programs and rebind to new context later, because
 		// Unbind GPU programs and rebind to new context later, because
 		// scene manager treat render system as ONE 'context' ONLY, and it
 		// scene manager treat render system as ONE 'context' ONLY, and it
 		// cached the GPU programs using state.
 		// cached the GPU programs using state.
-		if (mCurrentVertexProgram)
-			mCurrentVertexProgram->unbindProgram();
-		if (mCurrentGeometryProgram)
-			mCurrentGeometryProgram->unbindProgram();
-		if (mCurrentFragmentProgram)
-			mCurrentFragmentProgram->unbindProgram();
-
-		// Disable textures
-		disableTextureUnitsFrom(0);
+		unbindGpuProgram(GPT_VERTEX_PROGRAM);
+		unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
+		unbindGpuProgram(GPT_GEOMETRY_PROGRAM);
+		unbindGpuProgram(GPT_HULL_PROGRAM);
+		unbindGpuProgram(GPT_DOMAIN_PROGRAM);
 
 
 		// It's ready for switching
 		// It's ready for switching
 		if (mCurrentContext)
 		if (mCurrentContext)
@@ -1567,9 +1569,9 @@ namespace CamelotEngine
 	{
 	{
 		if (mActiveTextureUnit != unit)
 		if (mActiveTextureUnit != unit)
 		{
 		{
-			if (GLEW_VERSION_1_2 && unit < getCapabilities()->getNumTextureUnits())
+			if (unit < getCapabilities()->getNumCombinedTextureUnits())
 			{
 			{
-				glActiveTextureARB(GL_TEXTURE0 + unit);
+				glActiveTexture(GL_TEXTURE0 + unit);
 				mActiveTextureUnit = unit;
 				mActiveTextureUnit = unit;
 				return true;
 				return true;
 			}
 			}
@@ -1580,6 +1582,8 @@ namespace CamelotEngine
 			}
 			}
 			else
 			else
 			{
 			{
+				LOGWRN("Provided texture unit index is higher than OpenGL supports. Provided: " + toString(unit) + 
+					". Supported range: 0 .. " + toString(getCapabilities()->getNumCombinedTextureUnits() - 1));
 				return false;
 				return false;
 			}
 			}
 		}
 		}
@@ -1877,11 +1881,25 @@ namespace CamelotEngine
 			CM_EXCEPT(RenderingAPIException, "GPU doesn't support frame buffer objects. OpenGL versions lower than 3.0 are not supported.");
 			CM_EXCEPT(RenderingAPIException, "GPU doesn't support frame buffer objects. OpenGL versions lower than 3.0 are not supported.");
 		}
 		}
 
 
+		mFragmentTexOffset = 0;
+		mVertexTexOffset = caps->getNumTextureUnits(GPT_FRAGMENT_PROGRAM);
+		mGeometryTexOffset = mVertexTexOffset + caps->getNumTextureUnits(GPT_VERTEX_PROGRAM);
+
+		UINT16 numCombinedTexUnits = caps->getNumCombinedTextureUnits();
+
+		if((mFragmentTexOffset + mVertexTexOffset + mGeometryTexOffset) > numCombinedTexUnits)
+			CM_EXCEPT(InternalErrorException, "Number of combined texture units less than the number of individual units!?");
+
+		mTextureTypes = new GLenum[numCombinedTexUnits];
+		for(UINT16 i = 0; i < numCombinedTexUnits; i++)
+			mTextureTypes[i] = 0;
+
 		/// Create the texture manager        
 		/// Create the texture manager        
 		TextureManager::startUp(new GLTextureManager(*mGLSupport)); 
 		TextureManager::startUp(new GLTextureManager(*mGLSupport)); 
 
 
 		mGLInitialised = true;
 		mGLInitialised = true;
 	}
 	}
+
 	RenderSystemCapabilities* GLRenderSystem::createRenderSystemCapabilities() const
 	RenderSystemCapabilities* GLRenderSystem::createRenderSystemCapabilities() const
 	{
 	{
 		RenderSystemCapabilities* rsc = new RenderSystemCapabilities();
 		RenderSystemCapabilities* rsc = new RenderSystemCapabilities();
@@ -1945,30 +1963,6 @@ namespace CamelotEngine
 			rsc->setCapability(RSC_BLENDING);
 			rsc->setCapability(RSC_BLENDING);
 		}
 		}
 
 
-		// Check for Multitexturing support and set number of texture units
-		if(GLEW_VERSION_1_3 || 
-			GLEW_ARB_multitexture)
-		{
-			GLint units;
-			glGetIntegerv( GL_MAX_TEXTURE_UNITS, &units );
-
-			if (GLEW_ARB_fragment_program)
-			{
-				// Also check GL_MAX_TEXTURE_IMAGE_UNITS_ARB since NV at least
-				// only increased this on the FX/6x00 series
-				GLint arbUnits;
-				glGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &arbUnits );
-				if (arbUnits > units)
-					units = arbUnits;
-			}
-			rsc->setNumTextureUnits(units);
-		}
-		else
-		{
-			// If no multitexture support then set one texture unit
-			rsc->setNumTextureUnits(1);
-		}
-
 		// Check for Anisotropy support
 		// Check for Anisotropy support
 		if(GLEW_EXT_texture_filter_anisotropic)
 		if(GLEW_EXT_texture_filter_anisotropic)
 		{
 		{
@@ -2021,7 +2015,6 @@ namespace CamelotEngine
 			rsc->setStencilBufferBitDepth(stencil);
 			rsc->setStencilBufferBitDepth(stencil);
 		}
 		}
 
 
-
 		if(GLEW_VERSION_1_5 || GLEW_ARB_vertex_buffer_object)
 		if(GLEW_VERSION_1_5 || GLEW_ARB_vertex_buffer_object)
 		{
 		{
 			if (!GLEW_ARB_vertex_buffer_object)
 			if (!GLEW_ARB_vertex_buffer_object)
@@ -2031,112 +2024,8 @@ namespace CamelotEngine
 			rsc->setCapability(RSC_VBO);
 			rsc->setCapability(RSC_VBO);
 		}
 		}
 
 
-		if(GLEW_ARB_vertex_program)
-		{
-			rsc->setCapability(RSC_VERTEX_PROGRAM);
-
-			// Vertex Program Properties
-			rsc->setVertexProgramConstantBoolCount(0);
-			rsc->setVertexProgramConstantIntCount(0);
-
-			GLint floatConstantCount;
-			glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &floatConstantCount);
-			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)
-			{
-				rsc->addShaderProfile("gp4vp");
-				rsc->addShaderProfile("gpu_vp");
-			}
-		}
-
-		if (GLEW_NV_register_combiners2 &&
-			GLEW_NV_texture_shader)
-		{
-			rsc->setCapability(RSC_FRAGMENT_PROGRAM);
-		}
-
-		// NFZ - check for ATI fragment shader support
-		if (GLEW_ATI_fragment_shader)
-		{
-			rsc->setCapability(RSC_FRAGMENT_PROGRAM);
-			// no boolean params allowed
-			rsc->setFragmentProgramConstantBoolCount(0);
-			// no integer params allowed
-			rsc->setFragmentProgramConstantIntCount(0);
-
-			// only 8 Vector4 constant floats supported
-			rsc->setFragmentProgramConstantFloatCount(8);
-
-			rsc->addShaderProfile("ps_1_4");
-			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)
-		{
-			rsc->setCapability(RSC_FRAGMENT_PROGRAM);
-
-			// Fragment Program Properties
-			rsc->setFragmentProgramConstantBoolCount(0);
-			rsc->setFragmentProgramConstantIntCount(0);
-
-			GLint floatConstantCount;
-			glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &floatConstantCount);
-			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");
-			}        
-		}
+		rsc->setCapability(RSC_VERTEX_PROGRAM);
+		rsc->setCapability(RSC_FRAGMENT_PROGRAM);
 
 
 		rsc->addShaderProfile("cg");
 		rsc->addShaderProfile("cg");
 
 
@@ -2253,7 +2142,7 @@ namespace CamelotEngine
 			rsc->setCapability(RSC_TEXTURE_FLOAT);
 			rsc->setCapability(RSC_TEXTURE_FLOAT);
 		}
 		}
 
 
-		// 3D textures should be supported by GL 1.2, which is our minimum version
+		// 3D textures should always be supported
 		rsc->setCapability(RSC_TEXTURE_3D);
 		rsc->setCapability(RSC_TEXTURE_3D);
 
 
 		// Check for framebuffer object extension
 		// Check for framebuffer object extension
@@ -2293,39 +2182,52 @@ namespace CamelotEngine
 		}
 		}
 
 
 		// Point size
 		// Point size
-		if (GLEW_VERSION_1_4)
+		float ps;
+		glGetFloatv(GL_POINT_SIZE_MAX, &ps);
+		rsc->setMaxPointSize(ps);
+
+		// Max number of fragment shader textures
+		GLint units;
+		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &units);
+		rsc->setNumTextureUnits(GPT_FRAGMENT_PROGRAM, static_cast<UINT16>(units));
+
+		// Max number of vertex shader textures
+		GLint vUnits;
+		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vUnits);
+		rsc->setNumTextureUnits(GPT_VERTEX_PROGRAM, static_cast<UINT16>(vUnits));
+		if (vUnits > 0)
 		{
 		{
-			float ps;
-			glGetFloatv(GL_POINT_SIZE_MAX, &ps);
-			rsc->setMaxPointSize(ps);
+			rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
 		}
 		}
-		else
+
+		if (mGLSupport->checkExtension("ARB_geometry_shader4"))
 		{
 		{
-			GLint vSize[2];
-			glGetIntegerv(GL_POINT_SIZE_RANGE,vSize);
-			rsc->setMaxPointSize((float)vSize[1]);
+			GLint geomUnits;
+			glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &geomUnits);
+			rsc->setNumTextureUnits(GPT_GEOMETRY_PROGRAM, static_cast<UINT16>(geomUnits));
 		}
 		}
 
 
-		// Vertex texture fetching
-		if (mGLSupport->checkExtension("GL_ARB_vertex_shader"))
+		if (mGLSupport->checkExtension("ARB_tessellation_shader"))
 		{
 		{
-			GLint vUnits;
-			glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &vUnits);
-			rsc->setNumVertexTextureUnits(static_cast<UINT16>(vUnits));
-			if (vUnits > 0)
-			{
-				rsc->setCapability(RSC_VERTEX_TEXTURE_FETCH);
-			}
-			// GL always shares vertex and fragment texture units (for now?)
-			rsc->setVertexTextureUnitsShared(true);
+			rsc->setCapability(RSC_TESSELLATION_PROGRAM);
 		}
 		}
 
 
-		// Mipmap LOD biasing?
-		if (GLEW_VERSION_1_4 || GLEW_EXT_texture_lod_bias)
+		if (mGLSupport->checkExtension("ARB_compute_shader")) // Enable once I include GL 4.3
 		{
 		{
-			rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
+			//rsc->setCapability(RSC_COMPUTE_PROGRAM);
+
+			//GLint computeUnits;
+			//glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &computeUnits);
+			//rsc->setNumTextureUnits(GPT_COMPUTE_PROGRAM, static_cast<UINT16>(computeUnits));
 		}
 		}
 
 
+		GLint combinedTexUnits;
+		glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &combinedTexUnits);
+		rsc->setNumCombinedTextureUnits(static_cast<UINT16>(combinedTexUnits));
+
+		// Mipmap LOD biasing
+		rsc->setCapability(RSC_MIPMAP_LOD_BIAS);
+
 		// Alpha to coverage?
 		// Alpha to coverage?
 		if (mGLSupport->checkExtension("GL_ARB_multisample"))
 		if (mGLSupport->checkExtension("GL_ARB_multisample"))
 		{
 		{
@@ -2342,7 +2244,78 @@ namespace CamelotEngine
 
 
 		return rsc;
 		return rsc;
 	}
 	}
+	//---------------------------------------------------------------------
+	UINT32 GLRenderSystem::getGLTextureUnit(GpuProgramType gptype, UINT32 unit)
+	{
+		if(gptype != GPT_VERTEX_PROGRAM && gptype != GPT_FRAGMENT_PROGRAM && gptype != GPT_GEOMETRY_PROGRAM)
+		{
+			LOGWRN("OpenGL cannot assign textures to this gpu program type: " + toString(gptype));
+			return;
+		}
+
+		UINT32 numSupportedUnits = mCurrentCapabilities->getNumTextureUnits(gptype);
+		if(unit < 0 || unit >= numSupportedUnits)
+		{
+			LOGWRN("Invalid texture unit index for the provided stage. Unit index: " + toString(unit) + ". Stage: " + 
+				toString(gptype) + ". Supported range is 0 .. " + toString(numSupportedUnits - 1));
+		}
+
+		switch(gptype)
+		{
+		case GPT_FRAGMENT_PROGRAM:
+			return mFragmentTexOffset + unit;
+		case GPT_VERTEX_PROGRAM:
+			return mVertexTexOffset + unit;
+		case GPT_GEOMETRY_PROGRAM:
+			return mGeometryTexOffset + unit;
+		default:
+			CM_EXCEPT(InternalErrorException, "Invalid program type: " + toString(gptype));
+		}
+	}
+
+	void GLRenderSystem::setActiveProgram(GpuProgramType gptype, GLSLGpuProgram* program)
+	{
+		switch (gptype)
+		{
+		case GPT_VERTEX_PROGRAM:
+				mCurrentVertexProgram = program;
+			break;
+		case GPT_FRAGMENT_PROGRAM:
+				mCurrentFragmentProgram = program;
+			break;
+		case GPT_GEOMETRY_PROGRAM:
+				mCurrentGeometryProgram = program;
+			break;
+		case GPT_DOMAIN_PROGRAM:
+				mCurrentDomainProgram = program;
+			break;
+		case GPT_HULL_PROGRAM:
+				mCurrentHullProgram = program;
+			break;
+		}
+	}
 
 
+	GLSLGpuProgram* GLRenderSystem::getActiveProgram(GpuProgramType gptype) const
+	{
+		switch (gptype)
+		{
+		case GPT_VERTEX_PROGRAM:
+			return mCurrentVertexProgram;
+			break;
+		case GPT_FRAGMENT_PROGRAM:
+			return mCurrentFragmentProgram;
+			break;
+		case GPT_GEOMETRY_PROGRAM:
+			return mCurrentGeometryProgram;
+			break;
+		case GPT_DOMAIN_PROGRAM:
+			return mCurrentDomainProgram;
+			break;
+		case GPT_HULL_PROGRAM:
+			return mCurrentHullProgram;
+			break;
+		}
+	}
 	/************************************************************************/
 	/************************************************************************/
 	/* 								UTILITY		                     		*/
 	/* 								UTILITY		                     		*/
 	/************************************************************************/
 	/************************************************************************/

+ 0 - 7
CamelotGLRenderer/Source/GLSL/include/CmGLSLProgram.h

@@ -111,13 +111,6 @@ namespace CamelotEngine {
 		 */
 		 */
 		void unload_internal();
 		void unload_internal();
 
 
-        /// Populate the passed parameters with name->index map
-        void populateParameterNames(GpuProgramParametersSharedPtr params);
-        /// Populate the passed parameters with name->index map, must be overridden
-        void buildConstantDefinitions() const;
-		/// compile source into shader object
-		bool compile( const bool checkErrors = true);
-
 	private:
 	private:
 		/// GL handle for shader object
 		/// GL handle for shader object
 		GLhandleARB mGLHandle;
 		GLhandleARB mGLHandle;

+ 0 - 245
CamelotGLRenderer/Source/GLSL/src/CmGLSLLinkProgramManager.cpp

@@ -173,249 +173,4 @@ namespace CamelotEngine
 			glUseProgramObjectARB(0);
 			glUseProgramObjectARB(0);
 		}
 		}
 	}
 	}
-	//---------------------------------------------------------------------
-	void GLSLLinkProgramManager::extractGpuParams(GLSLLinkProgram* linkProgram, GpuParamDesc& returnParamDesc)
-	{
-		assert(linkProgram != nullptr);
-
-		// scan through the active uniforms and add them to the reference list
-		GLint uniformCount = 0;
-		GLuint glProgram = linkProgram->getGLHandle();
-
-		GLint maxBufferSize = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
-
-		GLint maxBlockNameBufferSize = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
-
-		if(maxBlockNameBufferSize > maxBufferSize)
-			maxBufferSize = maxBlockNameBufferSize;
-
-		GLchar* uniformName = new GLchar[maxBufferSize];
-
-		GpuParamBlockDesc globalBlockDesc;
-		globalBlockDesc.slot = 0;
-		globalBlockDesc.name = "CM_INTERNAL_Globals";
-		globalBlockDesc.blockSize = 0;
-
-		returnParamDesc.paramBlocks[globalBlockDesc.name] = globalBlockDesc;
-
-		GLint uniformBlockCount = 0;
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &uniformBlockCount);
-
-		map<UINT32, String>::type blockSlotToName;
-		for (GLuint index = 0; index < (GLuint)uniformBlockCount; index++)
-		{
-			GLsizei unusedSize = 0;
-			glGetActiveUniformBlockName(glProgram, index, maxBufferSize, &unusedSize, uniformName);
-
-			GpuParamBlockDesc newBlockDesc;
-			newBlockDesc.slot = index + 1;
-			newBlockDesc.name = uniformName;
-			newBlockDesc.blockSize = 0;
-
-			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
-			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
-		}
-
-		// get the number of active uniforms
-		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
-
-		// Loop over each of the active uniforms, and add them to the reference container
-		// only do this for user defined uniforms, ignore built in gl state uniforms
-		for (GLuint index = 0; index < (GLuint)uniformCount; index++)
-		{
-			GLsizei arraySize = 0;
-			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
-
-			String paramName = String(uniformName);
-
-			// If the uniform name has a "[" in it then its an array element uniform.
-			String::size_type arrayStart = paramName.find("[");
-			if (arrayStart != String::npos)
-			{
-				// if not the first array element then skip it and continue to the next uniform
-				if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0)
-					CM_EXCEPT(NotImplementedException, "No support for array parameters yet.");
-
-				paramName = paramName.substr(0, arrayStart);
-			}
-
-			GLint uniformType;
-			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
-
-			bool isSampler = false;
-			switch(uniformType)
-			{
-			case GL_SAMPLER_1D:
-			case GL_SAMPLER_2D:
-			case GL_SAMPLER_3D:
-			case GL_SAMPLER_CUBE:
-				isSampler = true;
-			}
-
-			if(isSampler)
-			{
-				GpuParamSpecialDesc samplerParam;
-				samplerParam.name = paramName;
-				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
-
-				GpuParamSpecialDesc textureParam;
-				textureParam.name = paramName;
-				textureParam.slot = samplerParam.slot;
-
-				switch(uniformType)
-				{
-				case GL_SAMPLER_1D:
-					samplerParam.type = GST_SAMPLER1D;
-					textureParam.type = GST_TEXTURE1D;
-					break;
-				case GL_SAMPLER_2D:
-					samplerParam.type = GST_SAMPLER2D;
-					textureParam.type = GST_TEXTURE2D;
-					break;
-				case GL_SAMPLER_3D:
-					samplerParam.type = GST_SAMPLER3D;
-					textureParam.type = GST_TEXTURE3D;
-					break;
-				case GL_SAMPLER_CUBE:
-					samplerParam.type = GST_SAMPLERCUBE;
-					textureParam.type = GST_TEXTURECUBE;
-					break;
-				}
-
-				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
-				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
-			}
-			else
-			{
-				GpuParamMemberDesc gpuParam;
-				gpuParam.name = paramName;
-				
-				GLint blockIndex;
-				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
-
-				determineParamInfo(gpuParam, paramName, glProgram, index);
-
-				if(blockIndex != -1)
-				{
-					GLint blockOffset;
-					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
-					gpuParam.gpuMemOffset = blockOffset;
-
-					GLint arrayStride;
-					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
-					gpuParam.elementSize = arrayStride;
-
-					gpuParam.paramBlockSlot = blockIndex + 1; // 0 is reserved for globals
-
-					String& blockName = blockSlotToName[gpuParam.paramBlockSlot];
-					GpuParamBlockDesc& curBlockDesc = returnParamDesc.paramBlocks[blockName];
-
-					gpuParam.cpuMemOffset = curBlockDesc.blockSize;
-					curBlockDesc.blockSize += gpuParam.elementSize * gpuParam.arraySize;
-				}
-				else
-				{
-					gpuParam.gpuMemOffset = glGetUniformLocationARB(glProgram, uniformName);
-					gpuParam.paramBlockSlot = 0;
-					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
-
-					globalBlockDesc.blockSize += gpuParam.elementSize * gpuParam.arraySize;
-				}
-
-				returnParamDesc.params.insert(std::make_pair(gpuParam.name, gpuParam));
-			}
-		}
-
-		delete[] uniformName;
-	}
-	//---------------------------------------------------------------------
-	void GLSLLinkProgramManager::determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
-	{
-		GLint arraySize;
-		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
-		desc.arraySize = arraySize;
-
-		GLint uniformType;
-		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
-
-		switch (uniformType)
-		{
-		case GL_BOOL:
-			desc.type = GMT_BOOL;
-			desc.elementSize = 1;
-			break;
-		case GL_FLOAT:
-			desc.type = GMT_FLOAT1;
-			desc.elementSize = 1;
-			break;
-		case GL_FLOAT_VEC2:
-			desc.type = GMT_FLOAT2;
-			desc.elementSize = 2;
-			break;
-		case GL_FLOAT_VEC3:
-			desc.type = GMT_FLOAT3;
-			desc.elementSize = 3;
-			break;
-		case GL_FLOAT_VEC4:
-			desc.type = GMT_FLOAT4;
-			desc.elementSize = 4;
-			break;
-		case GL_INT:
-			desc.type = GMT_INT1;
-			desc.elementSize = 1;
-			break;
-		case GL_INT_VEC2:
-			desc.type = GMT_INT2;
-			desc.elementSize = 2;
-			break;
-		case GL_INT_VEC3:
-			desc.type = GMT_INT3;
-			desc.elementSize = 3;
-			break;
-		case GL_INT_VEC4:
-			desc.type = GMT_INT4;
-			desc.elementSize = 4;
-			break;
-		case GL_FLOAT_MAT2:
-			desc.type = GMT_MATRIX_2X2;
-			desc.elementSize = 4;
-			break;
-		case GL_FLOAT_MAT3:
-			desc.type = GMT_MATRIX_3X3;
-			desc.elementSize = 9;
-			break;
-		case GL_FLOAT_MAT4:
-			desc.type = GMT_MATRIX_4X4;
-			desc.elementSize = 16;
-			break;
-		case GL_FLOAT_MAT2x3:
-			desc.type = GMT_MATRIX_2X3;
-			desc.elementSize = 6;
-			break;
-		case GL_FLOAT_MAT3x2:
-			desc.type = GMT_MATRIX_3X2;
-			desc.elementSize = 6;
-			break;
-		case GL_FLOAT_MAT2x4:
-			desc.type = GMT_MATRIX_2X4;
-			desc.elementSize = 8;
-			break;
-		case GL_FLOAT_MAT4x2:
-			desc.type = GMT_MATRIX_4X2;
-			desc.elementSize = 8;
-			break;
-		case GL_FLOAT_MAT3x4:
-			desc.type = GMT_MATRIX_3X4;
-			desc.elementSize = 12;
-			break;
-		case GL_FLOAT_MAT4x3:
-			desc.type = GMT_MATRIX_4X3;
-			desc.elementSize = 12;
-			break;
-		default:
-			CM_EXCEPT(InternalErrorException, "Invalid shader parameter type: " + toString(uniformType) + " for parameter " + paramName);
-		}
-	}
 }
 }

+ 253 - 39
CamelotGLRenderer/Source/GLSL/src/CmGLSLProgram.cpp

@@ -40,16 +40,259 @@ THE SOFTWARE.
 
 
 #include "CmGLSLProgramRTTI.h"
 #include "CmGLSLProgramRTTI.h"
 
 
-namespace CamelotEngine {
-
+namespace CamelotEngine 
+{
 	class GLSLParamParser
 	class GLSLParamParser
 	{
 	{
 	public:
 	public:
-		GLSLParamParser()
+		void buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc);
+
+	private:
+		void determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex);
+	};
+
+	void GLSLParamParser::buildUniformDescriptions(GLuint glProgram, GpuParamDesc& returnParamDesc)
+	{
+		// scan through the active uniforms and add them to the reference list
+		GLint maxBufferSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxBufferSize);
+
+		GLint maxBlockNameBufferSize = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxBlockNameBufferSize);
+
+		if(maxBlockNameBufferSize > maxBufferSize)
+			maxBufferSize = maxBlockNameBufferSize;
+
+		GLchar* uniformName = new GLchar[maxBufferSize];
+
+		GpuParamBlockDesc globalBlockDesc;
+		globalBlockDesc.slot = 0;
+		globalBlockDesc.name = "CM_INTERNAL_Globals";
+		globalBlockDesc.blockSize = 0;
+
+		UINT32 textureSlot = 0;
+
+		returnParamDesc.paramBlocks[globalBlockDesc.name] = globalBlockDesc;
+
+		GLint uniformBlockCount = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORM_BLOCKS, &uniformBlockCount);
+
+		map<UINT32, String>::type blockSlotToName;
+		for (GLuint index = 0; index < (GLuint)uniformBlockCount; index++)
 		{
 		{
+			GLsizei unusedSize = 0;
+			glGetActiveUniformBlockName(glProgram, index, maxBufferSize, &unusedSize, uniformName);
 
 
+			GpuParamBlockDesc newBlockDesc;
+			newBlockDesc.slot = index + 1;
+			newBlockDesc.name = uniformName;
+			newBlockDesc.blockSize = 0;
+
+			returnParamDesc.paramBlocks[newBlockDesc.name] = newBlockDesc;
+			blockSlotToName.insert(std::make_pair(newBlockDesc.slot, newBlockDesc.name));
 		}
 		}
-	};
+
+		// get the number of active uniforms
+		GLint uniformCount = 0;
+		glGetProgramiv(glProgram, GL_ACTIVE_UNIFORMS, &uniformCount);
+
+		// Loop over each of the active uniforms, and add them to the reference container
+		// only do this for user defined uniforms, ignore built in gl state uniforms
+		for (GLuint index = 0; index < (GLuint)uniformCount; index++)
+		{
+			GLsizei arraySize = 0;
+			glGetActiveUniformName(glProgram, index, maxBufferSize, &arraySize, uniformName);
+
+			String paramName = String(uniformName);
+
+			// If the uniform name has a "[" in it then its an array element uniform.
+			String::size_type arrayStart = paramName.find("[");
+			if (arrayStart != String::npos)
+			{
+				// if not the first array element then skip it and continue to the next uniform
+				if (paramName.compare(arrayStart, paramName.size() - 1, "[0]") != 0)
+					CM_EXCEPT(NotImplementedException, "No support for array parameters yet.");
+
+				paramName = paramName.substr(0, arrayStart);
+			}
+
+			GLint uniformType;
+			glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_TYPE, &uniformType);
+
+			bool isSampler = false;
+			switch(uniformType)
+			{
+			case GL_SAMPLER_1D:
+			case GL_SAMPLER_2D:
+			case GL_SAMPLER_3D:
+			case GL_SAMPLER_CUBE:
+				isSampler = true;
+			}
+
+			if(isSampler)
+			{
+				GpuParamSpecialDesc samplerParam;
+				samplerParam.name = paramName;
+				samplerParam.slot = glGetUniformLocation(glProgram, uniformName);
+
+				GpuParamSpecialDesc textureParam;
+				textureParam.name = paramName;
+				textureParam.slot = samplerParam.slot;
+
+				switch(uniformType)
+				{
+				case GL_SAMPLER_1D:
+					samplerParam.type = GST_SAMPLER1D;
+					textureParam.type = GST_TEXTURE1D;
+					break;
+				case GL_SAMPLER_2D:
+					samplerParam.type = GST_SAMPLER2D;
+					textureParam.type = GST_TEXTURE2D;
+					break;
+				case GL_SAMPLER_3D:
+					samplerParam.type = GST_SAMPLER3D;
+					textureParam.type = GST_TEXTURE3D;
+					break;
+				case GL_SAMPLER_CUBE:
+					samplerParam.type = GST_SAMPLERCUBE;
+					textureParam.type = GST_TEXTURECUBE;
+					break;
+				}
+
+				returnParamDesc.samplers.insert(std::make_pair(paramName, samplerParam));
+				returnParamDesc.textures.insert(std::make_pair(paramName, textureParam));
+			}
+			else
+			{
+				GpuParamMemberDesc gpuParam;
+				gpuParam.name = paramName;
+
+				GLint blockIndex;
+				glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_BLOCK_INDEX, &blockIndex);
+
+				determineParamInfo(gpuParam, paramName, glProgram, index);
+
+				if(blockIndex != -1)
+				{
+					GLint blockOffset;
+					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_OFFSET, &blockOffset);
+					gpuParam.gpuMemOffset = blockOffset;
+
+					GLint arrayStride;
+					glGetActiveUniformsiv(glProgram, 1, &index, GL_UNIFORM_ARRAY_STRIDE, &arrayStride);
+					gpuParam.elementSize = arrayStride;
+
+					gpuParam.paramBlockSlot = blockIndex + 1; // 0 is reserved for globals
+
+					String& blockName = blockSlotToName[gpuParam.paramBlockSlot];
+					GpuParamBlockDesc& curBlockDesc = returnParamDesc.paramBlocks[blockName];
+
+					gpuParam.cpuMemOffset = curBlockDesc.blockSize;
+					curBlockDesc.blockSize += gpuParam.elementSize * gpuParam.arraySize;
+				}
+				else
+				{
+					gpuParam.gpuMemOffset = glGetUniformLocationARB(glProgram, uniformName);
+					gpuParam.paramBlockSlot = 0;
+					gpuParam.cpuMemOffset = globalBlockDesc.blockSize;
+
+					globalBlockDesc.blockSize += gpuParam.elementSize * gpuParam.arraySize;
+				}
+
+				returnParamDesc.params.insert(std::make_pair(gpuParam.name, gpuParam));
+			}
+		}
+
+		delete[] uniformName;
+	}
+
+	void GLSLParamParser::determineParamInfo(GpuParamMemberDesc& desc, const String& paramName, GLuint programHandle, GLuint uniformIndex)
+	{
+		GLint arraySize;
+		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_SIZE, &arraySize);
+		desc.arraySize = arraySize;
+
+		GLint uniformType;
+		glGetActiveUniformsiv(programHandle, 1, &uniformIndex, GL_UNIFORM_TYPE, &uniformType);
+
+		switch (uniformType)
+		{
+		case GL_BOOL:
+			desc.type = GMT_BOOL;
+			desc.elementSize = 1;
+			break;
+		case GL_FLOAT:
+			desc.type = GMT_FLOAT1;
+			desc.elementSize = 1;
+			break;
+		case GL_FLOAT_VEC2:
+			desc.type = GMT_FLOAT2;
+			desc.elementSize = 2;
+			break;
+		case GL_FLOAT_VEC3:
+			desc.type = GMT_FLOAT3;
+			desc.elementSize = 3;
+			break;
+		case GL_FLOAT_VEC4:
+			desc.type = GMT_FLOAT4;
+			desc.elementSize = 4;
+			break;
+		case GL_INT:
+			desc.type = GMT_INT1;
+			desc.elementSize = 1;
+			break;
+		case GL_INT_VEC2:
+			desc.type = GMT_INT2;
+			desc.elementSize = 2;
+			break;
+		case GL_INT_VEC3:
+			desc.type = GMT_INT3;
+			desc.elementSize = 3;
+			break;
+		case GL_INT_VEC4:
+			desc.type = GMT_INT4;
+			desc.elementSize = 4;
+			break;
+		case GL_FLOAT_MAT2:
+			desc.type = GMT_MATRIX_2X2;
+			desc.elementSize = 4;
+			break;
+		case GL_FLOAT_MAT3:
+			desc.type = GMT_MATRIX_3X3;
+			desc.elementSize = 9;
+			break;
+		case GL_FLOAT_MAT4:
+			desc.type = GMT_MATRIX_4X4;
+			desc.elementSize = 16;
+			break;
+		case GL_FLOAT_MAT2x3:
+			desc.type = GMT_MATRIX_2X3;
+			desc.elementSize = 6;
+			break;
+		case GL_FLOAT_MAT3x2:
+			desc.type = GMT_MATRIX_3X2;
+			desc.elementSize = 6;
+			break;
+		case GL_FLOAT_MAT2x4:
+			desc.type = GMT_MATRIX_2X4;
+			desc.elementSize = 8;
+			break;
+		case GL_FLOAT_MAT4x2:
+			desc.type = GMT_MATRIX_4X2;
+			desc.elementSize = 8;
+			break;
+		case GL_FLOAT_MAT3x4:
+			desc.type = GMT_MATRIX_3X4;
+			desc.elementSize = 12;
+			break;
+		case GL_FLOAT_MAT4x3:
+			desc.type = GMT_MATRIX_4X3;
+			desc.elementSize = 12;
+			break;
+		default:
+			CM_EXCEPT(InternalErrorException, "Invalid shader parameter type: " + toString(uniformType) + " for parameter " + paramName);
+		}
+	}
 
 
     //---------------------------------------------------------------------------
     //---------------------------------------------------------------------------
     GLSLProgram::~GLSLProgram()
     GLSLProgram::~GLSLProgram()
@@ -71,12 +314,11 @@ namespace CamelotEngine {
 	void GLSLProgram::loadFromSource(void)
 	void GLSLProgram::loadFromSource(void)
 	{
 	{
 		// only create a shader object if glsl is supported
 		// only create a shader object if glsl is supported
+		GLenum shaderType = 0x0000;
 		if (isSupported())
 		if (isSupported())
 		{
 		{
 			checkForGLSLError( "GLSLProgram::loadFromSource", "GL Errors before creating shader object", 0, GLSLOT_SHADER);
 			checkForGLSLError( "GLSLProgram::loadFromSource", "GL Errors before creating shader object", 0, GLSLOT_SHADER);
-			// create shader object
 
 
-			GLenum shaderType = 0x0000;
 			switch (mType)
 			switch (mType)
 			{
 			{
 			case GPT_VERTEX_PROGRAM:
 			case GPT_VERTEX_PROGRAM:
@@ -95,10 +337,6 @@ namespace CamelotEngine {
 				shaderType = GL_TESS_EVALUATION_SHADER;
 				shaderType = GL_TESS_EVALUATION_SHADER;
 				break;
 				break;
 			}
 			}
-
-			mGLHandle = glCreateShader(shaderType);
-
-			checkForGLSLError( "GLSLProgram::loadFromSource", "Error creating GLSL shader object", 0, GLSLOT_SHADER);
 		}
 		}
 
 
 		// Preprocess the GLSL shader in order to get a clean source
 		// Preprocess the GLSL shader in order to get a clean source
@@ -161,8 +399,7 @@ namespace CamelotEngine {
 		if (!out || !out_size)
 		if (!out || !out_size)
 		{
 		{
 			// Failed to preprocess, break out
 			// Failed to preprocess, break out
-			CM_EXCEPT(RenderingAPIException,
-						 "Failed to preprocess shader ");
+			CM_EXCEPT(RenderingAPIException, "Failed to preprocess shader ");
 		}
 		}
 
 
 		mSource = String (out, out_size);
 		mSource = String (out, out_size);
@@ -173,38 +410,15 @@ namespace CamelotEngine {
 		if (!mSource.empty())
 		if (!mSource.empty())
 		{
 		{
 			const char *source = mSource.c_str();
 			const char *source = mSource.c_str();
-			glShaderSource(mGLHandle, 1, &source, nullptr);
+			mGLHandle = glCreateShaderProgramv(shaderType, 1, &source);
 			// check for load errors
 			// check for load errors
-			checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot load GLSL high-level shader source : ", 0, GLSLOT_SHADER);
+			checkForGLSLError( "GLSLProgram::loadFromSource", "Cannot load GLSL high-level shader source : ", 0, GLSLOT_PROGRAM);
 		}
 		}
 
 
-		compile();
-
 		mAssemblerProgram = GpuProgramPtr(new GLSLGpuProgram(this, mSource, mEntryPoint, mSyntaxCode, mType, mProfile));
 		mAssemblerProgram = GpuProgramPtr(new GLSLGpuProgram(this, mSource, mEntryPoint, mSyntaxCode, mType, mProfile));
-	}
-    
-    //---------------------------------------------------------------------------
-	bool GLSLProgram::compile(const bool checkErrors)
-	{
-        if (checkErrors)
-            logShaderInfo("GLSL compiling: ", mGLHandle);
-
-		glCompileShader(mGLHandle);
-
-		// check for compile errors
-		glGetShaderiv(mGLHandle, GL_COMPILE_STATUS, &mCompiled);
 
 
-		// force exception if not compiled
-		if (checkErrors)
-		{
-			checkForGLSLError("GLSLProgram::compile", "Cannot compile GLSL high-level shader : ", mGLHandle, GLSLOT_SHADER, !mCompiled, !mCompiled);
-			
-			if (mCompiled)
-			{
-				logShaderInfo("GLSL compiled : ", mGLHandle);
-			}
-		}
-		return (mCompiled == 1);
+		GLSLParamParser paramParser;
+		paramParser.buildUniformDescriptions(mGLHandle, mParametersDesc);
 	}
 	}
 	//---------------------------------------------------------------------------
 	//---------------------------------------------------------------------------
 	void GLSLProgram::unload_internal()
 	void GLSLProgram::unload_internal()

+ 3 - 5
CamelotRenderer/Include/CmDeferredRenderContext.h

@@ -26,18 +26,16 @@ namespace CamelotEngine
 		bool getWaitForVerticalBlank(void) const;
 		bool getWaitForVerticalBlank(void) const;
 
 
 		/** @copydoc RenderSystem::disableTextureUnit() */
 		/** @copydoc RenderSystem::disableTextureUnit() */
-		void disableTextureUnit(UINT16 texUnit);
-		/** @copydoc RenderSystem::disableTextureUnitsFrom() */
-		void disableTextureUnitsFrom(UINT16 texUnit);
+		void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit);
 
 
 		/** @copydoc RenderSystem::setPointParameters() */
 		/** @copydoc RenderSystem::setPointParameters() */
 		void setPointParameters(float size, bool attenuationEnabled, float constant, float linear, float quadratic, float minSize, float maxSize);
 		void setPointParameters(float size, bool attenuationEnabled, float constant, float linear, float quadratic, float minSize, float maxSize);
 
 
 		/** @copydoc RenderSystem::setTexture() */
 		/** @copydoc RenderSystem::setTexture() */
-		void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr);
+		void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr);
 
 
 		/** @copydoc RenderSystem::setSamplerState() */
 		/** @copydoc RenderSystem::setSamplerState() */
-		void setSamplerState(UINT16 texUnit, const SamplerState& samplerState);
+		void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerState& samplerState);
 
 
 		/** @copydoc RenderSystem::setBlendState() */
 		/** @copydoc RenderSystem::setBlendState() */
 		void setBlendState(const BlendState& blendState);
 		void setBlendState(const BlendState& blendState);

+ 4 - 6
CamelotRenderer/Include/CmRenderSystem.h

@@ -130,11 +130,9 @@ namespace CamelotEngine
 		 * @brief	Sets a sampler state for the specified texture unit.
 		 * @brief	Sets a sampler state for the specified texture unit.
 		 * @see		SamplerState
 		 * @see		SamplerState
 		 */
 		 */
-		virtual void setSamplerState(UINT16 texUnit, const SamplerState& samplerState) = 0;
+		virtual void setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerState& samplerState) = 0;
 		/** Turns off a texture unit. */
 		/** Turns off a texture unit. */
-		virtual void disableTextureUnit(UINT16 texUnit);
-		/** Disables all texture units from the given unit upwards */
-		virtual void disableTextureUnitsFrom(UINT16 texUnit);
+		virtual void disableTextureUnit(GpuProgramType gptype, UINT16 texUnit);
 
 
 		/**
 		/**
 		 * @brief	Sets a blend state used for all active render targets.
 		 * @brief	Sets a blend state used for all active render targets.
@@ -183,7 +181,7 @@ namespace CamelotEngine
 		@param enabled Boolean to turn the unit on/off
 		@param enabled Boolean to turn the unit on/off
 		@param texPtr Pointer to the texture to use.
 		@param texPtr Pointer to the texture to use.
 		*/
 		*/
-		virtual void setTexture(UINT16 unit, bool enabled, const TexturePtr &texPtr) = 0;
+		virtual void setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr &texPtr) = 0;
 
 
 		/**
 		/**
 		* Signifies the beginning of a frame, i.e. the start of rendering on a single viewport. Will occur
 		* Signifies the beginning of a frame, i.e. the start of rendering on a single viewport. Will occur
@@ -431,7 +429,7 @@ namespace CamelotEngine
 		DriverVersion mDriverVersion;
 		DriverVersion mDriverVersion;
 
 
 		/************************************************************************/
 		/************************************************************************/
-		/* 								THREADING	                     		*/
+		/* 							RENDER THREAD	                     		*/
 		/************************************************************************/
 		/************************************************************************/
 
 
 		class RenderWorkerFunc CM_THREAD_WORKER_INHERIT
 		class RenderWorkerFunc CM_THREAD_WORKER_INHERIT

+ 87 - 95
CamelotRenderer/Include/CmRenderSystemCapabilities.h

@@ -31,6 +31,7 @@ THE SOFTWARE.
 // Precompiler options
 // Precompiler options
 #include "CmPrerequisites.h"
 #include "CmPrerequisites.h"
 #include "CmString.h"
 #include "CmString.h"
+#include "CmGpuProgram.h"
 
 
 // Because there are more than 32 possible Capabilities, more than 1 int is needed to store them all.
 // Because there are more than 32 possible Capabilities, more than 1 int is needed to store them all.
 // In fact, an array of integers is used to store capabilities. However all the capabilities are defined in the single
 // In fact, an array of integers is used to store capabilities. However all the capabilities are defined in the single
@@ -41,9 +42,9 @@ THE SOFTWARE.
 // Identifies how many bits are reserved for categories
 // Identifies how many bits are reserved for categories
 // NOTE: Although 4 bits (currently) are enough
 // NOTE: Although 4 bits (currently) are enough
 #define CAPS_CATEGORY_SIZE 4
 #define CAPS_CATEGORY_SIZE 4
-#define OGRE_CAPS_BITSHIFT (32 - CAPS_CATEGORY_SIZE)
-#define CAPS_CATEGORY_MASK (((1 << CAPS_CATEGORY_SIZE) - 1) << OGRE_CAPS_BITSHIFT)
-#define OGRE_CAPS_VALUE(cat, val) ((cat << OGRE_CAPS_BITSHIFT) | (1 << val))
+#define CM_CAPS_BITSHIFT (32 - CAPS_CATEGORY_SIZE)
+#define CAPS_CATEGORY_MASK (((1 << CAPS_CATEGORY_SIZE) - 1) << CM_CAPS_BITSHIFT)
+#define CM_CAPS_VALUE(cat, val) ((cat << CM_CAPS_BITSHIFT) | (1 << val))
 
 
 namespace CamelotEngine 
 namespace CamelotEngine 
 {
 {
@@ -61,8 +62,9 @@ namespace CamelotEngine
 		CAPS_CATEGORY_COMMON_2 = 1,
 		CAPS_CATEGORY_COMMON_2 = 1,
 		CAPS_CATEGORY_D3D9 = 2,
 		CAPS_CATEGORY_D3D9 = 2,
 		CAPS_CATEGORY_GL = 3,
 		CAPS_CATEGORY_GL = 3,
+		CAPS_CATEGORY_COMMON_3 = 4,
 		/// Placeholder for max value
 		/// Placeholder for max value
-		CAPS_CATEGORY_COUNT = 4
+		CAPS_CATEGORY_COUNT = 5
 	};
 	};
 
 
 	/// Enum describing the different hardware capabilities we want to check for
 	/// Enum describing the different hardware capabilities we want to check for
@@ -72,96 +74,100 @@ namespace CamelotEngine
 	enum Capabilities
 	enum Capabilities
 	{
 	{
 		/// Supports generating mipmaps in hardware
 		/// Supports generating mipmaps in hardware
-		RSC_AUTOMIPMAP              = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0),
-		RSC_BLENDING                = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1),
+		RSC_AUTOMIPMAP              = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 0),
+		RSC_BLENDING                = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 1),
 		/// Supports anisotropic texture filtering
 		/// Supports anisotropic texture filtering
-		RSC_ANISOTROPY              = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2),
+		RSC_ANISOTROPY              = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 2),
 		/// Supports fixed-function DOT3 texture blend
 		/// Supports fixed-function DOT3 texture blend
-		RSC_DOT3                    = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3),
+		RSC_DOT3                    = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 3),
 		/// Supports cube mapping
 		/// Supports cube mapping
-		RSC_CUBEMAPPING             = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4),
+		RSC_CUBEMAPPING             = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 4),
 		/// Supports hardware stencil buffer
 		/// Supports hardware stencil buffer
-		RSC_HWSTENCIL               = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5),
+		RSC_HWSTENCIL               = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 5),
 		/// Supports hardware vertex and index buffers
 		/// Supports hardware vertex and index buffers
-		RSC_VBO                     = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7),
+		RSC_VBO                     = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 7),
 		/// Supports vertex programs (vertex shaders)
 		/// Supports vertex programs (vertex shaders)
-		RSC_VERTEX_PROGRAM          = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9),
+		RSC_VERTEX_PROGRAM          = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 9),
 		/// Supports fragment programs (pixel shaders)
 		/// Supports fragment programs (pixel shaders)
-		RSC_FRAGMENT_PROGRAM        = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10),
+		RSC_FRAGMENT_PROGRAM        = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 10),
 		/// Supports performing a scissor test to exclude areas of the screen
 		/// Supports performing a scissor test to exclude areas of the screen
-		RSC_SCISSOR_TEST            = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11),
+		RSC_SCISSOR_TEST            = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 11),
 		/// Supports separate stencil updates for both front and back faces
 		/// Supports separate stencil updates for both front and back faces
-		RSC_TWO_SIDED_STENCIL       = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 12),
+		RSC_TWO_SIDED_STENCIL       = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 12),
 		/// Supports wrapping the stencil value at the range extremeties
 		/// Supports wrapping the stencil value at the range extremeties
-		RSC_STENCIL_WRAP            = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 13),
+		RSC_STENCIL_WRAP            = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 13),
 		/// Supports hardware occlusion queries
 		/// Supports hardware occlusion queries
-		RSC_HWOCCLUSION             = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 14),
+		RSC_HWOCCLUSION             = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 14),
 		/// Supports user clipping planes
 		/// Supports user clipping planes
-		RSC_USER_CLIP_PLANES        = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 15),
+		RSC_USER_CLIP_PLANES        = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 15),
 		/// Supports the VET_UBYTE4 vertex element type
 		/// Supports the VET_UBYTE4 vertex element type
-		RSC_VERTEX_FORMAT_UBYTE4    = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 16),
+		RSC_VERTEX_FORMAT_UBYTE4    = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 16),
 		/// Supports infinite far plane projection
 		/// Supports infinite far plane projection
-		RSC_INFINITE_FAR_PLANE      = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 17),
+		RSC_INFINITE_FAR_PLANE      = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 17),
 		/// Supports hardware render-to-texture (bigger than framebuffer)
 		/// Supports hardware render-to-texture (bigger than framebuffer)
-		RSC_HWRENDER_TO_TEXTURE     = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 18),
+		RSC_HWRENDER_TO_TEXTURE     = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 18),
 		/// Supports float textures and render targets
 		/// Supports float textures and render targets
-		RSC_TEXTURE_FLOAT           = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 19),
+		RSC_TEXTURE_FLOAT           = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 19),
 		/// Supports non-power of two textures
 		/// Supports non-power of two textures
-		RSC_NON_POWER_OF_2_TEXTURES = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 20),
+		RSC_NON_POWER_OF_2_TEXTURES = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 20),
 		/// Supports 3d (volume) textures
 		/// Supports 3d (volume) textures
-		RSC_TEXTURE_3D              = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 21),
+		RSC_TEXTURE_3D              = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 21),
 		/// Supports basic point sprite rendering
 		/// Supports basic point sprite rendering
-		RSC_POINT_SPRITES           = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 22),
+		RSC_POINT_SPRITES           = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 22),
 		/// Supports extra point parameters (minsize, maxsize, attenuation)
 		/// Supports extra point parameters (minsize, maxsize, attenuation)
-		RSC_POINT_EXTENDED_PARAMETERS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 23),
+		RSC_POINT_EXTENDED_PARAMETERS = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 23),
 		/// Supports vertex texture fetch
 		/// Supports vertex texture fetch
-		RSC_VERTEX_TEXTURE_FETCH = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 24),
+		RSC_VERTEX_TEXTURE_FETCH = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 24),
 		/// Supports mipmap LOD biasing
 		/// Supports mipmap LOD biasing
-		RSC_MIPMAP_LOD_BIAS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 25),
+		RSC_MIPMAP_LOD_BIAS = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 25),
 		/// Supports hardware geometry programs
 		/// Supports hardware geometry programs
-		RSC_GEOMETRY_PROGRAM = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 26),
+		RSC_GEOMETRY_PROGRAM = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 26),
 		/// Supports rendering to vertex buffers
 		/// Supports rendering to vertex buffers
-		RSC_HWRENDER_TO_VERTEX_BUFFER = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON, 27),
+		RSC_HWRENDER_TO_VERTEX_BUFFER = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON, 27),
 
 
 		/// Supports compressed textures
 		/// Supports compressed textures
-		RSC_TEXTURE_COMPRESSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 0),
+		RSC_TEXTURE_COMPRESSION = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 0),
 		/// Supports compressed textures in the DXT/ST3C formats
 		/// Supports compressed textures in the DXT/ST3C formats
-		RSC_TEXTURE_COMPRESSION_DXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 1),
+		RSC_TEXTURE_COMPRESSION_DXT = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 1),
 		/// Supports compressed textures in the VTC format
 		/// Supports compressed textures in the VTC format
-		RSC_TEXTURE_COMPRESSION_VTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 2),
+		RSC_TEXTURE_COMPRESSION_VTC = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 2),
 		/// Supports compressed textures in the PVRTC format
 		/// Supports compressed textures in the PVRTC format
-		RSC_TEXTURE_COMPRESSION_PVRTC = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 3),
+		RSC_TEXTURE_COMPRESSION_PVRTC = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 3),
 		/// Supports fixed-function pipeline
 		/// Supports fixed-function pipeline
-		RSC_FIXED_FUNCTION = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 4),
+		RSC_FIXED_FUNCTION = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 4),
 		/// Supports MRTs with different bit depths
 		/// Supports MRTs with different bit depths
-		RSC_MRT_DIFFERENT_BIT_DEPTHS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 5),
+		RSC_MRT_DIFFERENT_BIT_DEPTHS = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 5),
 		/// Supports Alpha to Coverage (A2C)
 		/// Supports Alpha to Coverage (A2C)
-		RSC_ALPHA_TO_COVERAGE = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 6),
+		RSC_ALPHA_TO_COVERAGE = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 6),
 		/// Supports Blending operations other than +
 		/// Supports Blending operations other than +
-		RSC_ADVANCED_BLEND_OPERATIONS = OGRE_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 7),
+		RSC_ADVANCED_BLEND_OPERATIONS = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_2, 7),
 
 
 		// ***** DirectX specific caps *****
 		// ***** DirectX specific caps *****
 		/// Is DirectX feature "per stage constants" supported
 		/// Is DirectX feature "per stage constants" supported
-		RSC_PERSTAGECONSTANT = OGRE_CAPS_VALUE(CAPS_CATEGORY_D3D9, 0),
+		RSC_PERSTAGECONSTANT = CM_CAPS_VALUE(CAPS_CATEGORY_D3D9, 0),
 
 
 		// ***** GL Specific Caps *****
 		// ***** GL Specific Caps *****
 		/// Supports openGL GLEW version 1.5
 		/// Supports openGL GLEW version 1.5
-		RSC_GL1_5_NOVBO    = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 1),
+		RSC_GL1_5_NOVBO    = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 1),
 		/// Support for Frame Buffer Objects (FBOs)
 		/// Support for Frame Buffer Objects (FBOs)
-		RSC_FBO              = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 2),
+		RSC_FBO              = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 2),
 		/// Support for Frame Buffer Objects ARB implementation (regular FBO is higher precedence)
 		/// Support for Frame Buffer Objects ARB implementation (regular FBO is higher precedence)
-		RSC_FBO_ARB          = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 3),
+		RSC_FBO_ARB          = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 3),
 		/// Support for Frame Buffer Objects ATI implementation (ARB FBO is higher precedence)
 		/// Support for Frame Buffer Objects ATI implementation (ARB FBO is higher precedence)
-		RSC_FBO_ATI          = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 4),
+		RSC_FBO_ATI          = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 4),
 		/// Support for PBuffer
 		/// Support for PBuffer
-		RSC_PBUFFER          = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 5),
+		RSC_PBUFFER          = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 5),
 		/// Support for GL 1.5 but without HW occlusion workaround
 		/// Support for GL 1.5 but without HW occlusion workaround
-		RSC_GL1_5_NOHWOCCLUSION = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 6),
+		RSC_GL1_5_NOHWOCCLUSION = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 6),
 		/// Support for point parameters ARB implementation
 		/// Support for point parameters ARB implementation
-		RSC_POINT_EXTENDED_PARAMETERS_ARB = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 7),
+		RSC_POINT_EXTENDED_PARAMETERS_ARB = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 7),
 		/// Support for point parameters EXT implementation
 		/// Support for point parameters EXT implementation
-		RSC_POINT_EXTENDED_PARAMETERS_EXT = OGRE_CAPS_VALUE(CAPS_CATEGORY_GL, 8)
+		RSC_POINT_EXTENDED_PARAMETERS_EXT = CM_CAPS_VALUE(CAPS_CATEGORY_GL, 8),
 
 
+		/// Supports hardware tessellation programs
+		RSC_TESSELLATION_PROGRAM = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_3, 0),
+		/// Supports hardware compute programs
+		RSC_COMPUTE_PROGRAM = CM_CAPS_VALUE(CAPS_CATEGORY_COMMON_3, 1),
 
 
 	};
 	};
 
 
@@ -236,12 +242,19 @@ namespace CamelotEngine
 		GPP_PS_3_0,
 		GPP_PS_3_0,
 		GPP_PS_3_x,
 		GPP_PS_3_x,
 		GPP_PS_4_0,
 		GPP_PS_4_0,
+		GPP_PS_5_0,
 		GPP_VS_1_1,
 		GPP_VS_1_1,
 		GPP_VS_2_0,
 		GPP_VS_2_0,
 		GPP_VS_2_x,
 		GPP_VS_2_x,
 		GPP_VS_2_a,
 		GPP_VS_2_a,
 		GPP_VS_3_0,
 		GPP_VS_3_0,
-		GPP_VS_4_0
+		GPP_VS_4_0,
+		GPP_VS_5_0,
+		GPP_GS_4_0,
+		GPP_GS_5_0,
+		GPP_HS_5_0,
+		GPP_DS_5_0,
+		GPP_CS_5_0
 	};
 	};
 
 
 	/** singleton class for storing the capabilities of the graphics card. 
 	/** singleton class for storing the capabilities of the graphics card. 
@@ -268,8 +281,10 @@ namespace CamelotEngine
 
 
 		/// The number of world matrices available
 		/// The number of world matrices available
 		UINT16 mNumWorldMatrices;
 		UINT16 mNumWorldMatrices;
-		/// The number of texture units available
-		UINT16 mNumTextureUnits;
+		/// The number of texture units available per stage
+		map<GpuProgramType, UINT16>::type mNumTextureUnitsPerStage;
+		/// Total number of texture units available
+		UINT16 mNumCombinedTextureUnits;
 		/// The stencil buffer bit depth
 		/// The stencil buffer bit depth
 		UINT16 mStencilBufferBitDepth;
 		UINT16 mStencilBufferBitDepth;
 		/// The number of matrices available for hardware blending
 		/// The number of matrices available for hardware blending
@@ -307,14 +322,9 @@ namespace CamelotEngine
 		float mMaxPointSize;
 		float mMaxPointSize;
 		/// Are non-POW2 textures feature-limited?
 		/// Are non-POW2 textures feature-limited?
 		bool mNonPOW2TexturesLimited;
 		bool mNonPOW2TexturesLimited;
-		/// The number of vertex texture units supported
-		UINT16 mNumVertexTextureUnits;
-		/// Are vertex texture units shared with fragment processor?
-		bool mVertexTextureUnitsShared;
 		/// The number of vertices a geometry program can emit in a single run
 		/// The number of vertices a geometry program can emit in a single run
 		int mGeometryProgramNumOutputVertices;
 		int mGeometryProgramNumOutputVertices;
 
 
-
 		/// The list of supported shader profiles
 		/// The list of supported shader profiles
 		ShaderProfiles mSupportedShaderProfiles;
 		ShaderProfiles mSupportedShaderProfiles;
 
 
@@ -390,9 +400,14 @@ namespace CamelotEngine
 			mNumWorldMatrices = num;
 			mNumWorldMatrices = num;
 		}
 		}
 
 
-		void setNumTextureUnits(UINT16 num)
+		void setNumTextureUnits(GpuProgramType type, UINT16 num)
 		{
 		{
-			mNumTextureUnits = num;
+			mNumTextureUnitsPerStage[type] = num;
+		}
+
+		void setNumCombinedTextureUnits(UINT16 num) const
+		{
+			mNumCombinedTextureUnits = num;
 		}
 		}
 
 
 		void setStencilBufferBitDepth(UINT16 num)
 		void setStencilBufferBitDepth(UINT16 num)
@@ -417,20 +432,19 @@ namespace CamelotEngine
 		}
 		}
 
 
 		/** Returns the number of texture units the current output hardware
 		/** Returns the number of texture units the current output hardware
-		supports.
-
-		For use in rendering, this determines how many texture units the
-		are available for multitexturing (i.e. rendering multiple 
-		textures in a single pass). Where a Material has multiple 
-		texture layers, it will try to use multitexturing where 
-		available, and where it is not available, will perform multipass
-		rendering to achieve the same effect. This property only applies
-		to the fixed-function pipeline, the number available to the 
-		programmable pipeline depends on the shader model in use.
+		supports, for the specified stage.
+		*/
+		UINT16 getNumTextureUnits(GpuProgramType stage) const
+		{
+			return mNumTextureUnitsPerStage[type];
+		}
+
+		/** Returns the number of texture units the current output hardware
+		supports, total for all stages combined.
 		*/
 		*/
-		UINT16 getNumTextureUnits(void) const
+		UINT16 getNumCombinedTextureUnits() const
 		{
 		{
-			return mNumTextureUnits;
+			return mNumCombinedTextureUnits;
 		}
 		}
 
 
 		/** Determines the bit depth of the hardware accelerated stencil 
 		/** Determines the bit depth of the hardware accelerated stencil 
@@ -461,7 +475,7 @@ namespace CamelotEngine
 		*/
 		*/
 		bool isCapabilityRenderSystemSpecific(const Capabilities c)
 		bool isCapabilityRenderSystemSpecific(const Capabilities c)
 		{
 		{
-			int cat = c >> OGRE_CAPS_BITSHIFT;
+			int cat = c >> CM_CAPS_BITSHIFT;
 			if(cat == CAPS_CATEGORY_GL || cat == CAPS_CATEGORY_D3D9)
 			if(cat == CAPS_CATEGORY_GL || cat == CAPS_CATEGORY_D3D9)
 				return true;
 				return true;
 			return false;
 			return false;
@@ -471,7 +485,7 @@ namespace CamelotEngine
 		*/
 		*/
 		void setCapability(const Capabilities c) 
 		void setCapability(const Capabilities c) 
 		{ 
 		{ 
-			int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT;
+			int index = (CAPS_CATEGORY_MASK & c) >> CM_CAPS_BITSHIFT;
 			// zero out the index from the stored capability
 			// zero out the index from the stored capability
 			mCapabilities[index] |= (c & ~CAPS_CATEGORY_MASK);
 			mCapabilities[index] |= (c & ~CAPS_CATEGORY_MASK);
 		}
 		}
@@ -480,7 +494,7 @@ namespace CamelotEngine
 		*/
 		*/
 		void unsetCapability(const Capabilities c) 
 		void unsetCapability(const Capabilities c) 
 		{ 
 		{ 
-			int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT;
+			int index = (CAPS_CATEGORY_MASK & c) >> CM_CAPS_BITSHIFT;
 			// zero out the index from the stored capability
 			// zero out the index from the stored capability
 			mCapabilities[index] &= (~c | CAPS_CATEGORY_MASK);
 			mCapabilities[index] &= (~c | CAPS_CATEGORY_MASK);
 		}
 		}
@@ -489,7 +503,7 @@ namespace CamelotEngine
 		*/
 		*/
 		bool hasCapability(const Capabilities c) const
 		bool hasCapability(const Capabilities c) const
 		{
 		{
-			int index = (CAPS_CATEGORY_MASK & c) >> OGRE_CAPS_BITSHIFT;
+			int index = (CAPS_CATEGORY_MASK & c) >> CM_CAPS_BITSHIFT;
 			// test against
 			// test against
 			if(mCapabilities[index] & (c & ~CAPS_CATEGORY_MASK))
 			if(mCapabilities[index] & (c & ~CAPS_CATEGORY_MASK))
 			{
 			{
@@ -683,28 +697,6 @@ namespace CamelotEngine
 		{
 		{
 			return mNonPOW2TexturesLimited;
 			return mNonPOW2TexturesLimited;
 		}
 		}
-
-		/// Set the number of vertex texture units supported
-		void setNumVertexTextureUnits(UINT16 n)
-		{
-			mNumVertexTextureUnits = n;
-		}
-		/// Get the number of vertex texture units supported
-		UINT16 getNumVertexTextureUnits(void) const
-		{
-			return mNumVertexTextureUnits;
-		}
-		/// Set whether the vertex texture units are shared with the fragment processor
-		void setVertexTextureUnitsShared(bool shared)
-		{
-			mVertexTextureUnitsShared = shared;
-		}
-		/// Get whether the vertex texture units are shared with the fragment processor
-		bool getVertexTextureUnitsShared(void) const
-		{
-			return mVertexTextureUnitsShared;
-		}
-
 		/// Set the number of vertices a single geometry program run can emit
 		/// Set the number of vertices a single geometry program run can emit
 		void setGeometryProgramNumOutputVertices(int numOutputVertices)
 		void setGeometryProgramNumOutputVertices(int numOutputVertices)
 		{
 		{

+ 6 - 11
CamelotRenderer/Source/CmDeferredRenderContext.cpp

@@ -31,9 +31,9 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, mRenderSystem, vp));
 		mCommandQueue->queue(boost::bind(&RenderSystem::setViewport, mRenderSystem, vp));
 	}
 	}
 
 
-	void DeferredRenderContext::setSamplerState(UINT16 texUnit, const SamplerState& samplerState)
+	void DeferredRenderContext::setSamplerState(GpuProgramType gptype, UINT16 texUnit, const SamplerState& samplerState)
 	{
 	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setSamplerState, mRenderSystem, texUnit, samplerState));
+		mCommandQueue->queue(boost::bind(&RenderSystem::setSamplerState, mRenderSystem, gptype, texUnit, samplerState));
 	}
 	}
 
 
 	void DeferredRenderContext::setBlendState(const BlendState& blendState)
 	void DeferredRenderContext::setBlendState(const BlendState& blendState)
@@ -56,19 +56,14 @@ namespace CamelotEngine
 		mCommandQueue->queue(boost::bind(&RenderSystem::setStencilRefValue, mRenderSystem, refValue));
 		mCommandQueue->queue(boost::bind(&RenderSystem::setStencilRefValue, mRenderSystem, refValue));
 	}
 	}
 
 
-	void DeferredRenderContext::setTexture(UINT16 unit, bool enabled, const TexturePtr& texPtr)
+	void DeferredRenderContext::setTexture(GpuProgramType gptype, UINT16 unit, bool enabled, const TexturePtr& texPtr)
 	{
 	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, unit, enabled, texPtr));
+		mCommandQueue->queue(boost::bind(&RenderSystem::setTexture, mRenderSystem, gptype, unit, enabled, texPtr));
 	}
 	}
 
 
-	void DeferredRenderContext::disableTextureUnit(UINT16 texUnit)
+	void DeferredRenderContext::disableTextureUnit(GpuProgramType gptype, UINT16 texUnit)
 	{
 	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnit, mRenderSystem, texUnit));
-	}
-
-	void DeferredRenderContext::disableTextureUnitsFrom(UINT16 texUnit)
-	{
-		mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnitsFrom, mRenderSystem, texUnit));
+		mCommandQueue->queue(boost::bind(&RenderSystem::disableTextureUnit, mRenderSystem, gptype, texUnit));
 	}
 	}
 
 
 	void DeferredRenderContext::setScissorTest(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)
 	void DeferredRenderContext::setScissorTest(UINT32 left, UINT32 top, UINT32 right, UINT32 bottom)

+ 2 - 16
CamelotRenderer/Source/CmRenderSystem.cpp

@@ -227,25 +227,11 @@ namespace CamelotEngine {
         return mActiveViewport;
         return mActiveViewport;
     }
     }
     //-----------------------------------------------------------------------
     //-----------------------------------------------------------------------
-    void RenderSystem::disableTextureUnit(UINT16 texUnit)
+    void RenderSystem::disableTextureUnit(GpuProgramType gptype, UINT16 texUnit)
     {
     {
 		THROW_IF_NOT_RENDER_THREAD;
 		THROW_IF_NOT_RENDER_THREAD;
 
 
-        setTexture(texUnit, false, sNullTexPtr);
-    }
-    //---------------------------------------------------------------------
-    void RenderSystem::disableTextureUnitsFrom(UINT16 texUnit)
-    {
-		THROW_IF_NOT_RENDER_THREAD;
-
-        UINT16 disableTo = CM_MAX_TEXTURE_LAYERS;
-        if (disableTo > mDisabledTexUnitsFrom)
-            disableTo = mDisabledTexUnitsFrom;
-        mDisabledTexUnitsFrom = texUnit;
-        for (UINT16 i = texUnit; i < disableTo; ++i)
-        {
-            disableTextureUnit(i);
-        }
+        setTexture(gptype, texUnit, false, sNullTexPtr);
     }
     }
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	bool RenderSystem::getWaitForVerticalBlank(void) const
 	bool RenderSystem::getWaitForVerticalBlank(void) const

+ 7 - 2
CamelotRenderer/Source/CmRenderSystemCapabilities.cpp

@@ -35,7 +35,7 @@ namespace CamelotEngine {
 	RenderSystemCapabilities::RenderSystemCapabilities()
 	RenderSystemCapabilities::RenderSystemCapabilities()
 		: mVendor(GPU_UNKNOWN)
 		: mVendor(GPU_UNKNOWN)
 		, mNumWorldMatrices(0)
 		, mNumWorldMatrices(0)
-		, mNumTextureUnits(0)
+		, mNumCombinedTextureUnits(0)
 		, mStencilBufferBitDepth(0)
 		, mStencilBufferBitDepth(0)
 		, mNumVertexBlendMatrices(0)
 		, mNumVertexBlendMatrices(0)
 		, mNumMultiRenderTargets(1)
 		, mNumMultiRenderTargets(1)
@@ -52,7 +52,12 @@ namespace CamelotEngine {
 		mCategoryRelevant[CAPS_CATEGORY_D3D9] = false;
 		mCategoryRelevant[CAPS_CATEGORY_D3D9] = false;
 		mCategoryRelevant[CAPS_CATEGORY_GL] = false;
 		mCategoryRelevant[CAPS_CATEGORY_GL] = false;
 
 
-
+		mNumTextureUnitsPerStage[GPT_VERTEX_PROGRAM] = 0;
+		mNumTextureUnitsPerStage[GPT_FRAGMENT_PROGRAM] = 0;
+		mNumTextureUnitsPerStage[GPT_GEOMETRY_PROGRAM] = 0;
+		mNumTextureUnitsPerStage[GPT_HULL_PROGRAM] = 0;
+		mNumTextureUnitsPerStage[GPT_DOMAIN_PROGRAM] = 0;
+		mNumTextureUnitsPerStage[GPT_COMPUTE_PROGRAM] = 0;
 	}
 	}
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
 	RenderSystemCapabilities::~RenderSystemCapabilities()
 	RenderSystemCapabilities::~RenderSystemCapabilities()

+ 9 - 2
CamelotRenderer/TODO.txt

@@ -20,6 +20,8 @@
 -----------GpuProgramParameters/Pass/Material REFACTOR------------------------------
 -----------GpuProgramParameters/Pass/Material REFACTOR------------------------------
 
 
 Finish up GL port:
 Finish up GL port:
+ - IMPORTANT: Use GL_ARB_separate_shader_objects to set shaders without program objects. And more importantly to set uniforms per stage.
+   - Use CreateShaderProgramv to compile & link shader program
  - GL shader and param binding happens in the shader itself, while it should happen on the RenderSystem (to be consistent with DX9 and DX11)
  - GL shader and param binding happens in the shader itself, while it should happen on the RenderSystem (to be consistent with DX9 and DX11)
  - Remove those DefaultHardwareBuffermanagers as I don't think they serve a purpose anymore (OpenGL seems to only use them if API doesn't support hardware buffers, which won't happen on modern hardware)
  - Remove those DefaultHardwareBuffermanagers as I don't think they serve a purpose anymore (OpenGL seems to only use them if API doesn't support hardware buffers, which won't happen on modern hardware)
  - Re-do GL attribute bindings (currently it parses program source manually)
  - Re-do GL attribute bindings (currently it parses program source manually)
@@ -27,6 +29,9 @@ Finish up GL port:
  - Uniforms or uniform blocks aren't assigned anywhere
  - Uniforms or uniform blocks aren't assigned anywhere
  - Implement GLRenderSystem::bindGpuParams
  - Implement GLRenderSystem::bindGpuParams
 
 
+ http://www.opengl.org/wiki/Uniform_(GLSL)
+http://www.opengl.org/wiki/Program_Introspection
+
 Re-enable DX11 and GL project dependencies in CamelotClient
 Re-enable DX11 and GL project dependencies in CamelotClient
 Saving/loading of material params isn't completed (in MAterialRTTI)
 Saving/loading of material params isn't completed (in MAterialRTTI)
 Delete old bindGpuProgramParameters and old unused classes/files
 Delete old bindGpuProgramParameters and old unused classes/files
@@ -34,6 +39,7 @@ Port DX11 to new shader param system
 Ability to switch out GpuParamBlocks (i.e. share them between programs)
 Ability to switch out GpuParamBlocks (i.e. share them between programs)
 Ability to create Pass without automatically creating param blocks
 Ability to create Pass without automatically creating param blocks
 Automatically creating a pass should be smart about not creating duplicate param blocks
 Automatically creating a pass should be smart about not creating duplicate param blocks
+Port CG so it doesn't attempt to use low level GL shaders (which I have removed)
 
 
 Handling of array parameters? This needs testing
 Handling of array parameters? This needs testing
  - I'm currently ignoring array elements in GL due to the name their names are handled
  - I'm currently ignoring array elements in GL due to the name their names are handled
@@ -44,6 +50,9 @@ Handling of array parameters? This needs testing
 RenderSystem::setTexture(STAGE, UINT32 slot, Texture)
 RenderSystem::setTexture(STAGE, UINT32 slot, Texture)
 RenderSystem::setBuffer(STAGE, UINT32 slot, Buffer)
 RenderSystem::setBuffer(STAGE, UINT32 slot, Buffer)
 RenderSystem::setSampler(STAGE, UINT32 slot, Sampler)
 RenderSystem::setSampler(STAGE, UINT32 slot, Sampler)
+ - Maybe do all these without "slot" parameter? Instead accept an array of elements
+   per stage, and when they're about to be used set them up into proper slots as needed?
+   (based on currently set shader)
 
 
 RenderSystem::clearFrameBuffer
 RenderSystem::clearFrameBuffer
  - Change so it accepts a RenderTarget as a parameter
  - Change so it accepts a RenderTarget as a parameter
@@ -136,10 +145,8 @@ HIGH PRIORITY TODO:
  - GetRenderOperation doesn't consider sub-meshes
  - GetRenderOperation doesn't consider sub-meshes
 
 
 Mid priority TODO:
 Mid priority TODO:
- - Compiler2Pass in GL renderer doesn't seem to be 64bit ready. I hacked it together but it will likely cause problems.
  - Resource handle should store a unique integer ID, which just points to a table of GUIDs. Keeping GUID string everywhere in not efficient.
  - Resource handle should store a unique integer ID, which just points to a table of GUIDs. Keeping GUID string everywhere in not efficient.
  - Add a field that tracks % of resource deserialization in BinarySerializer
  - Add a field that tracks % of resource deserialization in BinarySerializer
- - GpuProgram default parameters might not be needed. The parameters change with each use of the gpu program anyway
  - Mesh loading:
  - Mesh loading:
   - Example Freefall mesh has one index per vertex, and there are 17k+ vertices. I think I need a post-process step that optimizes them.
   - Example Freefall mesh has one index per vertex, and there are 17k+ vertices. I think I need a post-process step that optimizes them.
   - Imported FBX meshes are too big
   - Imported FBX meshes are too big