void UniformHandler::CalculateMeshUniform(const Uniform& sUniform, SPODMesh *pMesh, SPODNode *pNode)
	{
		switch(sUniform.getSemantic())
		{
		case eUsPosition:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsNormal:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsTangent:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sTangents.nStride, pMesh->sTangents.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBinormal:
			{
				glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->sBinormals.nStride, pMesh->sBinormals.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsUV:
			{
				glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBoneIndex:
			{
				glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneIdx.n, GL_UNSIGNED_BYTE, GL_FALSE, pMesh->sBoneIdx.nStride, pMesh->sBoneIdx.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBoneWeight:
			{
				glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneWeight.n, GL_FLOAT, GL_FALSE, pMesh->sBoneWeight.nStride, pMesh->sBoneWeight.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsWORLD:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorld.f);
			}
			break;
		case eUsWORLDI:
			{
				PVRTMat4 mWorldI;
				mWorldI =  m_mWorld.inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldI.f);
			}
			break;
		case eUsWORLDIT:
			{
				PVRTMat3 mWorldIT;
				mWorldIT = m_mWorld.inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldIT.f);
			}
			break;
		case eUsWORLDVIEW:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldView.f);
			}
			break;
		case eUsWORLDVIEWI:
			{
				PVRTMat4 mWorldViewI;
				mWorldViewI = m_mWorldView.inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewI.f);
			}
			break;
		case eUsWORLDVIEWIT:
			{
				PVRTMat3 mWorldViewIT;
				mWorldViewIT = m_mWorldView.inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewIT.f);
			}
			break;
		case eUsWORLDVIEWPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldViewProjection.f);
			}
			break;
		case eUsWORLDVIEWPROJECTIONI:
			{
				PVRTMat4 mWorldViewProjectionI = (m_mProjection * m_mWorldView ).inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionI.f);
			}
			break;
		case eUsWORLDVIEWPROJECTIONIT:
			{
				PVRTMat3 mWorldViewProjectionIT = (m_mProjection * m_mWorldView).inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionIT.f);
			}
			break;
		case eUsLIGHTPOSMODEL:
			{
				// Passes the light position in eye space to the shader
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypePoint:
					{
						PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPoint*)pLight)->getPositionPVRTVec4() ;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
					break;
				case eLightTypePODPoint:
					{
						PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPODPoint*)pLight)->getPositionPVRTVec4() ;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
					break;
				default:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						// if you hit this code then the types of your lights do not match the types expected by your shaders
						PVRTVec4 vLightPosModel = (((LightDirectional*)pLight)->getDirectionPVRTVec4()*c_fFarDistance) ;
						vLightPosModel.w = f2vt(1.0f);
						vLightPosModel = m_mWorld * vLightPosModel;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
				}
			}
			break;
		case eUsOBJECT:
			{
				// Scale
				PVRTMat4 mObject = m_psScene->GetScalingMatrix(*pNode);
				// Rotation
				mObject = m_psScene->GetRotationMatrix(*pNode) * mObject;
				// Translation
				mObject = m_psScene->GetTranslationMatrix(*pNode) * mObject;

				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mObject.f);
			}
			break;
		case eUsOBJECTI:
			{
				if(!getFlag(eUsOBJECT))
				{
					// Scale
					m_mObject = m_psScene->GetScalingMatrix(*pNode);
					// Rotation
					m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject;
					// Translation
					m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject);
					setFlag(eUsOBJECT);
				}
				m_mObjectI = m_mObject.inverse();

				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectI.f);
			}
			break;
		case eUsOBJECTIT:
			{
				if(!getFlag(eUsOBJECTI))
				{
					if(!getFlag(eUsOBJECT))
					{
						// Scale
						m_mObject = m_psScene->GetScalingMatrix(*pNode);
						// Rotation
						m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject;
						// Translation
						m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject);
						setFlag(eUsOBJECT);
					}
					m_mObjectI = m_mObject.inverse();
					setFlag(eUsOBJECTI);
				}

				m_mObjectIT = PVRTMat3(m_mObjectI).transpose();

				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectIT.f);
			}
			break;
		case eUsLIGHTDIRMODEL:
			{
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypeDirectional:
					{
						// Passes the light direction in model space to the shader
						PVRTVec4 vLightDirectionModel,
							vLightDirection =((LightDirectional*)pLight)->getDirectionPVRTVec4();
						vLightDirectionModel = m_mWorld.inverse() * vLightDirection ;
						glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z);
					}
				case eLightTypePODDirectional:
					{
						// Passes the light direction in model space to the shader
						PVRTVec4 vLightDirectionModel,
							vLightDirection =((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						vLightDirectionModel = m_mWorld.inverse() * vLightDirection ;
						glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z);
					}
				default:
					{	// could mimic point lights
						// calculate vector between light position and mesh

						// implemented by getting hold of the nice centre point I calculated for all these meshes and using this point
					}
				}
			}
			break;
		case eUsEYEPOSMODEL:
			{	
				m_vEyePositionModel = m_mWorld.inverse() * PVRTVec4(m_vEyePositionWorld,VERTTYPE(1.0f));
				glUniform3f(sUniform.getLocation(), m_vEyePositionModel.x, m_vEyePositionModel.y, m_vEyePositionModel.z);
			}
			break;
		default:
			{	// something went wrong
				ConsoleLog::inst().log("Error: non-mesh uniform being interpreted as mesh uniform\n");
				return;
			}
		}
	}
	void UniformHandler::CalculateFrameUniform(const Uniform& sUniform)
	{
		unsigned int u32Semantic = sUniform.getSemantic();
		unsigned int index = sUniform.getIdx();
		switch(sUniform.getSemantic())
		{
		case eUsVIEW:
			{
				// calculation not required
			}
			break;
		case eUsVIEWI:
			{
				m_mViewI = m_mView.inverse();
			}
			break;
		case eUsVIEWIT:
			{
				if(!getFlag(eUsVIEWI))
				{
					m_mViewI = m_mView.inverse();
					setFlag(eUsVIEWI);
				}
				m_mViewIT = m_mViewI.transpose();
			}
			break;
		case eUsPROJECTION:
			{
				// calculation not required
			}
			break;
		case eUsPROJECTIONI:
			{
				m_mProjectionI = m_mProjection.inverse();
			}
			break;
		case eUsPROJECTIONIT:
			{
				if(!getFlag(eUsPROJECTIONI))
				{
					m_mProjectionI = m_mProjection.inverse();
					setFlag(eUsPROJECTIONI);
				}
				m_mProjectionIT = m_mProjectionI.transpose();
			}
			break;
		case eUsVIEWPROJECTION:
			{
				// calculation not required
			}
			break;
		case eUsVIEWPROJECTIONI:
			{
				if(!getFlag(eUsVIEWPROJECTION))
				{
					m_mViewProjection = m_mProjection * m_mView;
					setFlag(eUsVIEWPROJECTION);
				}
				m_mViewProjectionI = m_mProjection.inverse();
			}
			break;
		case eUsVIEWPROJECTIONIT:
			{
				if(!getFlag(eUsVIEWPROJECTIONI))
				{
					if(!getFlag(eUsVIEWPROJECTION))
					{
						m_mViewProjection = m_mProjection * m_mView;
						setFlag(eUsVIEWPROJECTION);
					}
					m_mViewProjectionI = m_mProjection.inverse();
					setFlag(eUsVIEWPROJECTIONI);
				}
				m_mViewProjectionIT = m_mViewProjectionI.transpose();
			}
			break;
		case eUsLIGHTCOLOR:
			{
				m_pfLightColor[sUniform.getIdx()] = m_psScene->pLight[sUniform.getIdx()].pfColour;
			}
			break;

		case eUsLIGHTPOSWORLD:
			{
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypePoint:
					{
						m_vLightPosWorld[index] = ((LightPoint*)pLight)->getPositionPVRTVec4();
						break;
					}
				case eLightTypePODPoint:
					{
						m_vLightPosWorld[index] = ((LightPODPoint*)pLight)->getPositionPVRTVec4();
						break;
					}
				case eLightTypeDirectional:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						m_vLightDirWorld[index] = ((LightDirectional*)pLight)->getDirectionPVRTVec4();
						setFlag(eUsLIGHTDIRWORLD,index);

						m_vLightPosWorld[index] = m_vLightDirWorld[index]*c_fFarDistance;
						m_vLightPosWorld[index].w = f2vt(1.0f);

					}
				case eLightTypePODDirectional:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						m_vLightDirWorld[index] = ((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						setFlag(eUsLIGHTDIRWORLD,index);

						m_vLightPosWorld[index] = m_vLightDirWorld[index]*c_fFarDistance;
						m_vLightPosWorld[index].w = f2vt(1.0f);

					}
				default:
					{
						ConsoleLog::inst().log((char*)"Unsupported light type for LIGHTPOSWORLD semantic.\n");
						return;
					}
				}
				break;
			}
		case eUsLIGHTPOSEYE:
			{
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypePoint:
					{
						m_vLightPosWorld[index] = ((LightPoint*)pLight)->getPositionPVRTVec4();
						break;
					}
				case eLightTypePODPoint:
					{
						m_vLightPosWorld[index] = ((LightPODPoint*)pLight)->getPositionPVRTVec4();
						break;
					}
				case eLightTypeDirectional:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						m_vLightDirWorld[index] = ((LightDirectional*)pLight)->getDirectionPVRTVec4();
						setFlag(eUsLIGHTDIRWORLD,index);

						m_vLightPosWorld[index] = m_vLightDirWorld[index]*c_fFarDistance;
						m_vLightPosWorld[index].w = f2vt(1.0f);

					}
				case eLightTypePODDirectional:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						m_vLightDirWorld[index] = ((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						setFlag(eUsLIGHTDIRWORLD,index);

						m_vLightPosWorld[index] = m_vLightDirWorld[index]*c_fFarDistance;
						m_vLightPosWorld[index].w = f2vt(1.0f);

					}
				default:
					{
						ConsoleLog::inst().log((char*)"Unsupported light type for LIGHTPOSEYE semantic.\n");
						return;
					}
				}
				setFlag(eUsLIGHTPOSWORLD, index);	// mark that this has been calculated
				// store light position in eye space 
				m_vLightPosEye[index] =  m_mView * m_vLightPosWorld[index];
			}
			break;
		case eUsLIGHTDIRWORLD:
			{
				// gets the light direction.
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypeDirectional:
					{
						m_vLightDirWorld[index] = ((LightDirectional*)pLight)->getDirectionPVRTVec4();
						break;
					}
				case eLightTypePODDirectional:
					{
						m_vLightDirWorld[index] = ((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						break;
					}
				default:
					{	// hack for point lights
						// TODO: get centre from mesh
						// which may be difficult for the entire frame...
						ConsoleLog::inst().log((char*)"Unsupported light type for LIGHTDIRWORLD semantic.\n");
						return;
					}
				}
			}
			break;
		case eUsLIGHTDIREYE:
			{
				// gets the light direction.
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypeDirectional:
					{
						m_vLightDirWorld[index] = ((LightDirectional*)pLight)->getDirectionPVRTVec4();
						setFlag(eUsLIGHTDIRWORLD,index);
					}
				case eLightTypePODDirectional:
					{
						m_vLightDirWorld[index] = ((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						setFlag(eUsLIGHTDIRWORLD,index);
						break;
					}
				default:
					{	// hack for point lights
						// TODO: get centre from mesh
						// which may be difficult for the entire frame...
						ConsoleLog::inst().log((char*)"Unsupported light type for LIGHTDIREYE semantic.\n");
						return;
					}
				}
				// Passes the light direction in eye space to the shader
				m_vLightDirEye[index] = m_vLightDirWorld[index] * m_mView;
			}
			break;
		case eUsEYEPOSWORLD:
			// calculation not required
			break;
		case eUsANIMATION:
			{
				if(m_psScene->nNumFrame > 0.0 && m_fFrame > 0.0)
				{
					// Float in the range 0..1: contains this objects distance through its animation.
					m_fAnimation = (float)m_fFrame / (float)m_psScene->nNumFrame;
				}
				else
				{
					m_fAnimation=0.0f;
				}
			}
			break;
		default:
			{	// something went wrong
				ConsoleLog::inst().log("Error: non-frame uniform being interpreted as frame uniform\n");
				return;
			}
		}
		setFlag(u32Semantic,index);	// this uniform is now set - may return above if this can't be set
	}
	void UniformHandler::BindFrameUniform(const Uniform& sUniform)
	{
		EUniformSemantic eSemantic = sUniform.getSemantic();
		unsigned int index = sUniform.getIdx();
		_ASSERT(getFlag(eSemantic,index));

		switch(eSemantic)
		{
		case eUsVIEW:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mView.f);
			}
			break;
		case eUsVIEWI:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewI.f);
			}
			break;
		case eUsVIEWIT:
			{
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewIT.f);
			}
			break;
		case eUsPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mProjection.f);
			}
			break;
		case eUsPROJECTIONI:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mProjectionI.f);
			}
			break;
		case eUsPROJECTIONIT:
			{
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mProjectionIT.f);
			}
			break;
		case eUsVIEWPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewProjection.f);
			}
			break;
		case eUsVIEWPROJECTIONI:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewProjectionI.f);
			}
			break;
		case eUsVIEWPROJECTIONIT:
			{
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mViewProjectionIT.f);
			}
			break;
		case eUsLIGHTCOLOR:
			{
				glUniform3f(sUniform.getLocation(), m_pfLightColor[index][0],
					m_pfLightColor[index][1], m_pfLightColor[index][2]);
			}
			break;
		case eUsLIGHTPOSWORLD:
			{
				glUniform3f(sUniform.getLocation(), m_vLightPosWorld[index].x,
					m_vLightPosWorld[index].y, m_vLightPosWorld[index].z);
			}
			break;
		case eUsLIGHTPOSEYE:
			{
				glUniform3f(sUniform.getLocation(), m_vLightPosEye[index].x,
					m_vLightPosEye[index].y, m_vLightPosEye[index].z);
			}
			break;
		case eUsLIGHTDIRWORLD:
			{
				glUniform3f(sUniform.getLocation(), m_vLightDirWorld[index].x,
					m_vLightDirWorld[index].y, m_vLightDirWorld[index].z);
			}
			break;
		case eUsLIGHTDIREYE:
			{
				glUniform3f(sUniform.getLocation(), m_vLightDirEye[index].x,
					m_vLightDirEye[index].y, m_vLightDirEye[index].z);
			}
			break;
		case eUsEYEPOSWORLD:
			{
				glUniform3f(sUniform.getLocation(),
					m_vEyePositionWorld.x, m_vEyePositionWorld.y, m_vEyePositionWorld.z);
			}
			break;
		case eUsANIMATION:
			{
				glUniform1f(sUniform.getLocation(), m_fAnimation);
			}
			break;
		default:
			{	// something went wrong
				ConsoleLog::inst().log("Error: non-frame uniform being interpreted as frame uniform\n");
				return;
			}
		}
	}
	void UniformHandler::DoFrameUniform(const Uniform& sUniform)
	{
		if(!getFlag(sUniform.getSemantic(),sUniform.getIdx()))
			CalculateFrameUniform(sUniform);
		BindFrameUniform(sUniform);
	}