extern DWORD gEnableVertexLighting;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
	CLASSNAME::Lighting (
		MLRLight* const* lights,
		int nrLights,
		BYTE what
	)
{
	Check_Object(this);

	//
	//----------------------------------------------------------------------
	// If no lights or normals are specified, use the original vertex colors
	//----------------------------------------------------------------------
	//
	actualColors = &colors;
	int state_mask = GetCurrentState().GetLightingMode();

	if (state_mask == MLRState::LightingOffMode || gEnableVertexLighting==0)
	{
		return;
	}

	Check_Pointer(lights);

	//
	//-------------------------------
	// See if we need vertex lighting
	//-------------------------------
	//
	if (state_mask & MLRState::VertexLightingMode)
	{
		if (nrLights == 0)
		{
			return;
		}

		MLR_RENDER("Vertex Lighting::MLRTriangleLighting");
		Start_Timer(Vertex_Light_Time);
		Verify(!colors.GetLength() || normals.GetLength() == colors.GetLength());
		Verify(!colors.GetLength() || coords.GetLength() == colors.GetLength());

		int i, k, len = coords.GetLength();

		MLRVertexData vertexData;

		const ColorType *color = colors.GetData();

		if(!(state_mask & MLRState::FaceLightingMode))
		{
			RGBAColor andLetThereBeLight(0.0f, 0.0f, 0.0f, 1.0f);

			for (i=0;i<nrLights;i++)
			{
				MLRLight *light = lights[i];
				Check_Object(light);

				if(light->GetIntensity() < Limits::LightThreshold)
				{
					continue;
				}

				light->LightCenter(andLetThereBeLight);
			}

			if(color!=NULL)
			{
				for(k=0;k<len;k++)
				{
					if((*visibleIndexedVertices)[k] != 0)
					{
#if COLOR_AS_DWORD==0

						(*litColors)[k] = colors[k];
						
						(*litColors)[k].red *= andLetThereBeLight.red;
						(*litColors)[k].green *= andLetThereBeLight.green;
						(*litColors)[k].blue *= andLetThereBeLight.blue;
#else
						RGBAColor theColor, theLitColor(andLetThereBeLight);
						DWORD2Color(theColor, color[k]);
						theLitColor.red *= theColor.red;
						theLitColor.green *= theColor.green;
						theLitColor.blue *= theColor.blue;

						(*litColors)[k] = GOSCopyColor(&theLitColor);
#endif
						Set_Statistic(LitVertices, LitVertices+1);
					}
				}
			}
			else
			{
				const Scalar one_Over_255 = 1.0f/255.0f;
				Stuff::RGBAColor tc;

				tc.blue = andLetThereBeLight.blue * (paintMeColorDW & 0xff) * one_Over_255;

				paintMeColorDW >>= 8;

				tc.green = andLetThereBeLight.green * (paintMeColorDW & 0xff) * one_Over_255;

				paintMeColorDW >>= 8;

				tc.red = andLetThereBeLight.red * (paintMeColorDW & 0xff) * one_Over_255;

				paintMeColorDW >>= 8;

				tc.alpha = andLetThereBeLight.alpha * (paintMeColorDW & 0xff) * one_Over_255;

				paintMeColorDW = GOSCopyColor(&tc);
#if COLOR_AS_DWORD==0
				paintMeColorF = tc;
#endif

				actualColors = &colors;
				Stop_Timer(Vertex_Light_Time);

				return;
			}
		}
		else
		{
			if (normals.GetLength() == 0)
			{
				return;
			}

			//
			//--------------------------------
			// Now light the array of vertices
			//--------------------------------
			//
			vertexData.point = &coords[0];
#if COLOR_AS_DWORD>0
			RGBAColor andLetThereBeLight;
			vertexData.color = &andLetThereBeLight;
#else
			vertexData.color = litColors->GetData();
#endif
			vertexData.normal = &normals[0];
			for(k=0;k<len;k++)
			{
				if((*visibleIndexedVertices)[k] != 0)
				{
#if COLOR_AS_DWORD==0
					(*litColors)[k].red = 0.0f;
					(*litColors)[k].green = 0.0f;
					(*litColors)[k].blue = 0.0f;
					(*litColors)[k].alpha = 1.0f;
#else
					andLetThereBeLight.red = 0.0f;
					andLetThereBeLight.green = 0.0f;
					andLetThereBeLight.blue = 0.0f;
					andLetThereBeLight.alpha = 1.0f;
#endif
					for (i=0;i<nrLights;i++)
					{
						MLRLight *light = lights[i];
						Check_Object(light);

						if(light->GetIntensity() < Limits::LightThreshold)
						{
							continue;
						}

						int mask = state_mask & light->GetLightMask();
						if (!mask)
							continue;
						if (mask & MLRState::VertexLightingMode)
						{
							if (
								GetCurrentState().GetBackFaceMode() != MLRState::BackFaceOffMode
								 || light->GetLightType() == MLRLight::AmbientLight
							)
							{
								light->LightVertex(vertexData);
								Set_Statistic(LitVertices, LitVertices+1);
							}
						}
					}
				}
				vertexData.point++;
#if COLOR_AS_DWORD==0
				vertexData.color++;
				if(color!=NULL)
				{
					(*litColors)[k].red *= color[k].red;
					(*litColors)[k].green *= color[k].green;
					(*litColors)[k].blue *= color[k].blue;
				}
#else
				if(color!=NULL)
				{
					RGBAColor theColor;
					DWORD2Color(theColor, color[k]);
					andLetThereBeLight.red *= theColor.red;
					andLetThereBeLight.green *= theColor.green;
					andLetThereBeLight.blue *= theColor.blue;
				}
				(*litColors)[k] = GOSCopyColor(&andLetThereBeLight);
#endif
				vertexData.normal++;
			}
		}
		actualColors = litColors;
		Stop_Timer(Vertex_Light_Time);
	}
	
	if (state_mask & MLRState::LightMapLightingMode)
	{
		if (nrLights == 0)
		{
			return;
		}

		MLR_RENDER("Lightmap Lighting::MLRTriangleLighting");
		Start_Timer(LightMap_Light_Time);
		int i;

		for (i=0;i<nrLights;i++)
		{
			MLRLight *light = lights[i];
			Check_Object(light);

			if(light->GetIntensity() < Limits::LightThreshold)
			{
				continue;
			}

			MLRLightMap *lm = light->GetLightMap();

			if(lm==NULL)
			{
				continue;
			}

//			Verify(state.GetAlphaMode() == MLRState::OneZeroMode);

			int mask = state_mask & light->GetLightMask();

			if (!mask)
				continue;

			if (mask & MLRState::LightMapLightingMode)
			{
				LightMapLighting(lights[i]);
			}
		}
		Stop_Timer(LightMap_Light_Time);
	}
}

