//default effect

//texturing left to application (only sets the sun)

string XFile = "tiger.x";   // model
int    BCLR = 0xff202080;   // background

// light intensity
shared const float4 ambient = { 0.3f, 0.3f, 0.3f, 1.0f };    // ambient
shared const float4 lightdiffuse = { 1.0f, 1.0f, 1.0f, 1.0f };    // diffuse
shared const float4 lightspecular = { 1.0f, 1.0f, 1.0f, 1.0f };    // specular

// material reflectivity
shared const float4 k_a;    // ambient
shared const float4 k_d;    // diffuse
shared const float4 k_s;    // specular
shared const int    n;		// specular exponent

// light direction (view space)
shared const float3 lightdir < string UIDirectional = "Light Direction"; > = {0, -1, 0};
shared const float3 camerapos;

// texture
texture diffuse < string name = "tiger.bmp"; >;

// transformations
shared const float4x4 World          : WORLD;
shared const float4x4 View           : VIEW;
shared const float4x4 Projection     : PROJECTION;
shared const float4x4 WorldView      : WORLDVIEW;
shared const float4x4 ViewProjection : VIEWPROJECTION;

struct VS_OUTPUT
{
    float4 Pos  : POSITION;
    float2 Tex  : TEXCOORD0;
    float3 Norm : TEXCOORD1;
    float3 View : TEXCOORD2;
};

VS_OUTPUT VS(float3 Pos  : POSITION, float3 Norm : NORMAL, float2 Tex  : TEXCOORD0)
{
    VS_OUTPUT Out = (VS_OUTPUT)0;

	//float3 camerapos = float3(-dot(View[3],View[0]),-dot(View[3],View[1]),-dot(View[3],View[2]));    
    float3 P = mul(float4(Pos, 1), (float4x3)World);  // position (view space)

    Out.Pos  = mul(float4(P, 1), ViewProjection);             // position (projected)
    Out.View = (camerapos - P); // view direction (view space);
    Out.Norm = mul(Norm, (float3x3)World); // normal (view space)
    Out.Tex  = Tex;

    return Out;
}

sampler Sampler = sampler_state
{
    Texture   = (diffuse);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
};

float4 PS(VS_OUTPUT In) : COLOR
{
    float4 Out = (float4)0;

    float3 L = -lightdir;
    float3 N = normalize(In.Norm);
    float3 V = normalize(In.View);
    float3 R = 2*dot(N,L)*N - L;

    float4 Diff = ambient * k_a + lightdiffuse * k_d * max(0, dot(N, L)); // diffuse + ambient
    float4 Spec = lightspecular * k_s * pow(max(0, dot(V,R)), n);   // specular

    return tex2D(Sampler, In.Tex) * Diff + Spec;
}

struct VS_OUT_color
{
    float4 Pos  : POSITION;
    float2 Tex  : TEXCOORD0;
    float3 Norm : COLOR0;
    float3 View : COLOR1;
};

VS_OUT_color VS_color(float3 Pos  : POSITION, float3 Norm : NORMAL, float2 Tex  : TEXCOORD0)
{
    VS_OUT_color Out = (VS_OUT_color)0;
    
    float3 P = mul(float4(Pos, 1), (float4x3)World);  // position (view space)

    Out.Pos  = mul(float4(P, 1), ViewProjection);             // position (projected)

    Out.View = (camerapos-P)*0.5 + 0.5; // view direction (view space);
    Out.Norm = mul(Norm, (float3x3)World)*0.5 + 0.5; // normal (view space)

    Out.Tex  = Tex;

    return Out;
}

float4 PS_color(VS_OUT_color In) : COLOR
{
    float4 Out = (float4)0;

    float3 L = -lightdir;
    float3 N = normalize((In.Norm-0.5)*2);
    float3 V = normalize((In.View-0.5)*2);
    float3 R = 2*dot(N,L)*N - L;

    float4 Diff = ambient * k_a + lightdiffuse * k_d * max(0, dot(N, L)); // diffuse + ambient
    float4 Spec = lightspecular * k_s * pow(max(0, dot(V,R)), n);   // specular

    return tex2D(Sampler, In.Tex) * Diff + Spec;
    //return Spec;
}

technique TNoShader
{
    pass P0
    {
        // transforms
        //WorldTransform[0]   = (World);
        //ViewTransform       = (View);
        //ProjectionTransform = (Projection);

        // material
        MaterialAmbient  = (k_a); 
        MaterialDiffuse  = (k_d); 
        MaterialSpecular = (k_s); 
        MaterialPower    = (n);
        
        // lighting
        LightType[0]      = DIRECTIONAL;
        LightAmbient[0]   = (ambient);
		LightDiffuse[0]   = (lightdiffuse);
        LightSpecular[0]  = (lightspecular); 
        LightDirection[0] = (lightdir);
        LightRange[0]     = 100000.0f;

        LightEnable[0] = TRUE;
        Lighting       = TRUE;
        SpecularEnable = TRUE;
        
        // samplers
        Sampler[0] = (Sampler);
        
        // texture stages
        ColorOp[0]   = MODULATE;
        ColorArg1[0] = TEXTURE;
        ColorArg2[0] = DIFFUSE;
        AlphaOp[0]   = MODULATE;
        AlphaArg1[0] = TEXTURE;
        AlphaArg2[0] = DIFFUSE;

        ColorOp[1]   = DISABLE;
        AlphaOp[1]   = DISABLE;

        // shaders
        VertexShader = NULL;
        PixelShader  = NULL;
    }
}

technique TVertexAndPixelShader
{
    pass P0
    {
        // shaders
        VertexShader = compile vs_2_0 VS();
        PixelShader  = compile ps_2_0 PS();
    }
}

technique TVPCOLOR
{
    pass P0
    {
        // shaders
        VertexShader = compile vs_2_0 VS_color();
        PixelShader  = compile ps_2_0 PS_color();
    }
}

technique empty
{
}
