// force vc7 to group all shader related stuff into the Shader namespace
#define PS_1_1

#ifdef WIN32
namespace Shader {
#endif

// Expand a range-compressed vector
float3 expand(float3 v)
{
  return (v - 0.5) * 2;
}

// define inputs from vertex program
struct in_fragment
{
  float2 diffuseUV : TEXCOORD0;
  float2 normalUV  : TEXCOORD1;
  float3 lightDir  : TEXCOORD2;
  float3 halfAngle : TEXCOORD3;
};
 
// define outputs from fragment program
struct out_fragment
{
  float4 color : COLOR0;
};

// fragment program
out_fragment main
(
 // varying parameters
 in_fragment f_in,
 
 // uniform samplers (textures)
 uniform sampler2D   diffuseMap     : TEXUNIT0,
 uniform sampler2D   normalMap      : TEXUNIT1,
 uniform samplerCUBE normalCubeMap  : TEXUNIT2,
 uniform samplerCUBE normalCubeMap2 : TEXUNIT3,

 uniform float4 lightDiffuse0,
 uniform float4 lightSpecular0)
 {
   out_fragment f_out;

   // retrieve normalised light vector, expand from range-compressed
   float3 lightVec = expand(texCUBE(normalCubeMap, f_in.lightDir).xyz);
   
   // retrieve half angle and normalise through cube map
   float3 halfAngle = expand(texCUBE(normalCubeMap2, f_in.halfAngle).xyz);
   
   // get bump map vector, again expand from range-compressed
   float3 bumpVec = expand(tex2D(normalMap, f_in.normalUV).xyz);

#ifdef PS_1_1
   // Pre-raise the specular exponent to the eight power
   // Note we have no 'pow' function in basic fragment programs, if we were willing to accept compatibility
   // with ps_2_0 / arbfp1 and above, we could have a variable shininess parameter
   // This is equivalent to 
   float specFactor = dot(bumpVec, halfAngle);
   for (int i = 0; i < 3; ++i)
     specFactor *= specFactor;
#else
   float shininess = 25;
   float specFactor = pow(max(dot(bumpVec,halfAngle),0),shininess);
#endif  
   
   // Calculate dot product for diffuse
   f_out.color = 
     (tex2D(diffuseMap, f_in.diffuseUV) * (lightDiffuse0 * dot(bumpVec, lightVec)));// +
   //(lightSpecular0 * specFactor);

   //f_out.color *= tex2D(diffuseMap, f_in.texCoord0.xy);
   //f_out.color += lightSpecular0 * specFactor;

   f_out.color += specFactor.xxxx;
   //f_out.color = (lightDiffuse0 * dot(bumpVec, lightVec));

   return f_out;
 }

#ifdef WIN32
}
#endif

