//! Called by the engine when the vertex and/or pixel shader constants for an
	//! material renderer should be set.
	void COpenGLNormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, SINT32 userData)
	{
		IVideoDriver* driver = services->getVideoDriver();

		// set transposed world matrix
		//const Matrix4& tWorld = driver->getTransform(ETS_WORLD).getTransposed();
		Matrix4 tWorld = driver->getTransform(ETS_WORLD);
		services->setVertexShaderConstant(tWorld.pointer(), 0, 4);

		// set transposed worldViewProj matrix
		Matrix4 worldViewProj(driver->getTransform(ETS_PROJECTION));
		//worldViewProj *= driver->getTransform(ETS_VIEW);
		//worldViewProj *= driver->getTransform(ETS_WORLD);
		worldViewProj = driver->getTransform(ETS_VIEW)*worldViewProj;
		worldViewProj = driver->getTransform(ETS_WORLD)*worldViewProj;
		//Matrix4 tr(worldViewProj.getTransposed());
		Matrix4 tr(worldViewProj);
		services->setVertexShaderConstant(tr.pointer(), 8, 4);

		// here we fetch the fixed function lights from the driver
		// and set them as constants

		UINT32 cnt = driver->getDynamicLightCount();

		// Load the inverse world matrix.
		Matrix4 invWorldMat;
		driver->getTransform(ETS_WORLD).getInverse(invWorldMat);

		for (UINT32 i = 0; i<2; ++i)
		{
			SLight light;

			if (i<cnt)
				light = driver->getDynamicLight(i);
			else
			{
				//light.DiffuseColor.set(0, 0, 0); // make light dark
				light.DiffuseColor = ColourValue(0, 0, 0); // make light dark
				light.Radius = 1.0f;
			}

			light.DiffuseColor.a = 1.0f / (light.Radius*light.Radius); // set attenuation

			// Transform the light by the inverse world matrix to get it into object space.
			//invWorldMat.transformVect(light.Position);
			light.Position = invWorldMat.transformAffine(light.Position);
			

			services->setVertexShaderConstant(
				reinterpret_cast<const Real*>(&light.Position), 12 + (i * 2), 1);

			services->setVertexShaderConstant(
				reinterpret_cast<const Real*>(&light.DiffuseColor), 13 + (i * 2), 1);
		}
	}
void COGLES2MaterialParallaxMapCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
{
	IVideoDriver* driver = services->getVideoDriver();

	if (FirstUpdate)
	{
		WVPMatrixID = services->getVertexShaderConstantID("uWVPMatrix");
		WVMatrixID = services->getVertexShaderConstantID("uWVMatrix");
		EyePositionID = services->getVertexShaderConstantID("uEyePosition");
		LightPositionID = services->getVertexShaderConstantID("uLightPosition");
		LightColorID = services->getVertexShaderConstantID("uLightColor");
		FactorID = services->getVertexShaderConstantID("uFactor");
		TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
		TextureUnit1ID = services->getVertexShaderConstantID("uTextureUnit1");
		FogEnableID = services->getVertexShaderConstantID("uFogEnable");
		FogTypeID = services->getVertexShaderConstantID("uFogType");
		FogColorID = services->getVertexShaderConstantID("uFogColor");
		FogStartID = services->getVertexShaderConstantID("uFogStart");
		FogEndID = services->getVertexShaderConstantID("uFogEnd");
		FogDensityID = services->getVertexShaderConstantID("uFogDensity");

		FirstUpdate = false;
	}

	const core::matrix4 W = driver->getTransform(ETS_WORLD);
	const core::matrix4 V = driver->getTransform(ETS_VIEW);
	const core::matrix4 P = driver->getTransform(ETS_PROJECTION);

	/*core::matrix4 Matrix = P * V * W;
	services->setPixelShaderConstant(WVPMatrixID, Matrix.pointer(), 16);

	Matrix = V * W;
	services->setPixelShaderConstant(WVMatrixID, Matrix.pointer(), 16);

	core::vector3df EyePosition(0.0f, 0.0f, 0.0f);

	Matrix.makeInverse();
	Matrix.transformVect(EyePosition);
	services->setPixelShaderConstant(EyePositionID, reinterpret_cast<f32*>(&EyePosition), 3);

	Matrix = W;
	Matrix.makeInverse();*/
    
    core::matrix4   Matrix_W      = W;
    core::matrix4   Matrix_V_W    = V * W;
    core::matrix4   Matrix_P_V_W  = P * Matrix_V_W;
    core::vector3df EyePosition(0.0f, 0.0f, 0.0f);
    
    services->setPixelShaderConstant(WVPMatrixID, Matrix_P_V_W.pointer(), 16);
    services->setPixelShaderConstant(WVMatrixID, Matrix_V_W.pointer(), 16);
    
    Matrix_V_W.makeInverse();
	Matrix_V_W.transformVect(EyePosition);
	services->setPixelShaderConstant(EyePositionID, reinterpret_cast<f32*>(&EyePosition), 3);
    
    Matrix_W.makeInverse();
    
	const u32 LightCount = driver->getDynamicLightCount();

	for (u32 i = 0; i < 2; ++i)
	{
		SLight CurrentLight;

		if (i < LightCount)
			CurrentLight = driver->getDynamicLight(i);
		else
		{
			CurrentLight.DiffuseColor.set(0.f, 0.f, 0.f);
			CurrentLight.Radius = 1.f;
		}

		CurrentLight.DiffuseColor.a = 1.f / (CurrentLight.Radius*CurrentLight.Radius);

		//Matrix.transformVect(CurrentLight.Position);
        Matrix_W.transformVect(CurrentLight.Position);

		LightPosition[i] = CurrentLight.Position;
		LightColor[i] = CurrentLight.DiffuseColor;
	}

	services->setPixelShaderConstant(LightPositionID, reinterpret_cast<f32*>(LightPosition), 6);
	services->setPixelShaderConstant(LightColorID, reinterpret_cast<f32*>(LightColor), 8);

	services->setPixelShaderConstant(FactorID, &Factor, 1);
	services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
	services->setPixelShaderConstant(TextureUnit1ID, &TextureUnit1, 1);

	services->setPixelShaderConstant(FogEnableID, &FogEnable, 1);

	if (FogEnable)
	{
		SColor TempColor(0);
		E_FOG_TYPE TempType = EFT_FOG_LINEAR;
		bool TempPerFragment = false;
		bool TempRange = false;

		driver->getFog(TempColor, TempType, FogStart, FogEnd, FogDensity, TempPerFragment, TempRange);

		FogType = (s32)TempType;
		FogColor = SColorf(TempColor);

		services->setPixelShaderConstant(FogTypeID, &FogType, 1);
		services->setPixelShaderConstant(FogColorID, reinterpret_cast<f32*>(&FogColor), 4);
		services->setPixelShaderConstant(FogStartID, &FogStart, 1);
		services->setPixelShaderConstant(FogEndID, &FogEnd, 1);
		services->setPixelShaderConstant(FogDensityID, &FogDensity, 1);
	}
}