  <shader compiler="xmlshader" name="simpleshader4" lights="4">
    <technique priority="100">
      <pass>
	<buffer source="texture coordinate" destination="IN.texCoord" />
	<buffer source="normal" destination="IN.normal" />
	<texture name="tex diffuse" destination="textureDiffuse" />
	<vp plugin="glcg">
	  <cgvp>
	    <variablemap variable="light count" destination="IN.numLights" />
	    <variablemap variable="light position world" destination="IN.lightPosWorld" />
	    <variablemap variable="light diffuse" destination="IN.lightColorDiffuse" />
	    <variablemap variable="object2world transform" destination="objectToWorld" />
	    <variablemap variable="object2world transform inverse" destination="objectToWorldInv" />
	    <variablemap variable="light ambient" destination="IN.ambient" />
	    <program>
	    <![CDATA[
	    #define NUMLIGHTS 4
	    
	    struct App2Vertex
	    {
	      float4 Position : POSITION;
	      float2 texCoord;
	      float3 normal;
	      
	      // Number of lights provided
	      uniform int numLights;
	      // Light world-space position
	      uniform float4 lightPosWorld[NUMLIGHTS];
	      // Diffuse color
	      uniform float3 lightColorDiffuse[NUMLIGHTS];
	      
	      uniform float3 ambient;
	    };
	    
	    struct Vertex2Fragment
	    {
	      float4 Position : POSITION;
	      float2 texCoord;
	      float3 litColor;
	    };
	    
	    Vertex2Fragment main (App2Vertex IN,
		    uniform float4x4 ModelViewProj : state.matrix.mvp,
		    uniform float4x4 objectToWorld,
		    uniform float4x4 objectToWorldInv)
	    {
		    Vertex2Fragment OUT;
		    OUT.Position = mul (ModelViewProj, IN.Position);
		    OUT.texCoord = IN.texCoord;
		    
		    /* Transform vertex normal to world space by transforming
		       with transposed inverse of objectToWorld transform */
		    float3 normalWorld = mul (float4 (IN.normal, 0), objectToWorldInv).xyz;
		    
		    float3 lightingDiffuse = float3 (0);
		    float4 posWorld = mul (objectToWorld, IN.Position);
		    /* Limit light count - for some hardware loops must be 
		       unrolled, and an upper limit is required there */
		    int lightCount = min (IN.numLights, NUMLIGHTS);
		    for (int i = 0; i < lightCount; i++)
		    {
		      float3 vertToLight = normalize ((IN.lightPosWorld[i] - posWorld).xyz);
		      lightingDiffuse += IN.lightColorDiffuse[i] * saturate (dot (vertToLight, IN.normal));
		    }
		    OUT.litColor = lightingDiffuse + IN.ambient;
		    return OUT;
	    }
	    ]]>
	    </program>
	  </cgvp>
	</vp>
	<fp plugin="glcg">
	  <cgfp>
	    <program>
	    <![CDATA[
	    struct Vertex2Fragment
	    {
	      float4 Position : POSITION;
	      float2 texCoord;
	      float3 litColor;
	    };
	    
	    float4 main (Vertex2Fragment IN, sampler2D textureDiffuse) : COLOR
	    {
		    return tex2D (textureDiffuse, IN.texCoord) * float4 (IN.litColor, 1);
	    }
	    ]]>
	    </program>
	  </cgfp>
	</fp>
      </pass>
    </technique>
  </shader>
