
/* CgFX 1.4 file for bumpdemo effect. */

/* Includes verbatim shaders from The Cg Tutorial (ISBN: 0321194969). */
#include "C8E4f_specSurf.cg"  /* page 209 */
#include "C8E6v_torus.cg"     /* page 223 */

float4x4 ModelViewProj : ModelViewProjection;
float OuterRadius = 6;
float InnerRadius = 2;
float3 LightPosition = { -8, 0, 15 };
float3 EyePosition = { 0, 0, 18 };

float Ambient<
  string type = "ambient";
  float minValue = 0.0;
  float maxValue = 1.0;
> = 0.3;

float3 DiffuseMaterial<
  string type = "color";
  float3 minValue = float3(0,0,0);
  float3 maxValue = float3(1,1,1);
> = { 0.9, 0.6, 0.3 };

float3 SpecularMaterial<
  string type = "color";
  float3 minValue = float3(0,0,0);
  float3 maxValue = float3(1,1,1);
> = { 1, 1, 1 };

float3 LightColor<
  string type = "color";
  float3 minValue = float3(0,0,0);
  float3 maxValue = float3(1,1,1);
> = { 1.0, 0.9, 0.9 };

sampler2D normalMap = sampler_state {
  minFilter = LinearMipMapLinear;
  magFilter = Linear;
  
  AddressU = Mirror;
  AddressV = Mirror;
};

samplerCUBE normalizeCube = sampler_state {
  minFilter = Linear;
  magFilter = Linear;
  wrapS = ClampToEdge;
  wrapT = ClampToEdge;
};

// Modernized version of specSurf
void dx_specSurf( float2 normalMapTexCoord : TEXCOORD0,
                  float3 lightDirection    : TEXCOORD1,
                  float3 halfAngle         : TEXCOORD2,

                  out float4 color : COLOR,

                  uniform float  ambient,
                  uniform float4 LMd, // Light-material diffuse
                  uniform float4 LMs, // Light-material specular
                  uniform sampler2D   normalMap
               )
{
      float3 normalTex = tex2D(normalMap, normalMapTexCoord).xyz;
      float3 normal = expand(normalTex) * float3( 1.0f, 1.0f, -1.0f ); // Make the bricks stick out by negating the Z
     
      float3 normLightDir = normalize( lightDirection );
      float3 normHalfAngle = normalize( halfAngle );

      float diffuse = saturate(dot(normal, normLightDir));
      float specular = saturate(dot(normal, normHalfAngle));
      
      color = LMd * (ambient + diffuse) + LMs * pow( specular, 8 );
}

// Because bumpdemo.c picks the first valid technique, list techniques
// in relative order of preference...

technique bumpdemo_nv40 {
  pass {
    FragmentProgram =
      compile fp40 C8E4f_specSurf(Ambient,
                                  float4(DiffuseMaterial  * LightColor, 1),
                                  float4(SpecularMaterial * LightColor, 1),
                                  normalMap,
                                  normalizeCube,
                                  normalizeCube);
    VertexProgram =
      compile vp40 C8E6v_torus(LightPosition,
                               EyePosition,
                               ModelViewProj,
                               float2(OuterRadius, InnerRadius));
  }
}

technique bumpdemo_nv30 {
  pass {
    FragmentProgram =
      compile fp30 C8E4f_specSurf(Ambient,
                                  float4(DiffuseMaterial  * LightColor, 1),
                                  float4(SpecularMaterial * LightColor, 1),
                                  normalMap,
                                  normalizeCube,
                                  normalizeCube);
    VertexProgram =
      compile vp30 C8E6v_torus(LightPosition,
                               EyePosition,
                               ModelViewProj,
                               float2(OuterRadius, InnerRadius));
  }
}

technique bumpdemo_arb {
  pass {
    FragmentProgram =
      compile arbfp1 C8E4f_specSurf(Ambient,
                                    float4(DiffuseMaterial  * LightColor, 1),
                                    float4(SpecularMaterial * LightColor, 1),
                                    normalMap,
                                    normalizeCube,
                                    normalizeCube);
    VertexProgram =
      compile arbvp1 C8E6v_torus(LightPosition,
                                 EyePosition,
                                 ModelViewProj,
                                 float2(OuterRadius, InnerRadius));
  }
}

technique bumpdemo_nv20 {
  pass {
    FragmentProgram =
      compile fp20 C8E4f_specSurf(Ambient,
                                  float4(DiffuseMaterial  * LightColor, 1),
                                  float4(SpecularMaterial * LightColor, 1),
                                  normalMap,
                                  normalizeCube,
                                  normalizeCube);
    VertexProgram =
      compile vp20 C8E6v_torus(LightPosition,
                               EyePosition,
                               ModelViewProj,
                               float2(OuterRadius, InnerRadius));
  }
}

technique bumpdemo_dx11 {
  pass {
    FragmentProgram = compile ps_5_0 dx_specSurf( Ambient,
                                                  float4(DiffuseMaterial  * LightColor, 1),
                                                  float4(SpecularMaterial * LightColor, 1),
                                                  normalMap );

    VertexProgram =
      compile vs_5_0 C8E6v_torus(LightPosition,
                                 EyePosition,
                                 ModelViewProj,
                                 float2(OuterRadius, InnerRadius));
  }
}

technique bumpdemo_dx10 {
  pass {
    FragmentProgram = compile ps_4_0 dx_specSurf( Ambient,
                                                  float4(DiffuseMaterial  * LightColor, 1),
                                                  float4(SpecularMaterial * LightColor, 1),
                                                  normalMap );
    VertexProgram =
      compile vs_4_0 C8E6v_torus(LightPosition,
                                 EyePosition,
                                 ModelViewProj,
                                 float2(OuterRadius, InnerRadius));
  }
}