#include "Maya_lightView_vertex.cg"

struct vert2frag
{
    float4 position            : POSITION;
    float4 texcoord            : TEXCOORD0;
    float4 tangentToCubeMatrix1  : TEXCOORD1;
    float4 tangentToCubeMatrix2  : TEXCOORD2;
    float4 tangentToCubeMatrix3  : TEXCOORD3;
};

// define inputs from application
struct app2vert
{
    float4 position           : POSITION;
    float3 normal             : NORMAL;
    float3 tangent            : TEXCOORD0;
    float4 texcoord           : TEXCOORD1;
};

vert2frag main(app2vert IN, 
               uniform float4x4 modelViewProj : _GL_MVP,
               uniform float4 cameraPosWorld,
               uniform float4x4 textureProjMatrix,
               uniform float4x4 objToWorldMatrix,
               uniform float4x4 worldToCubeRotationMatrix,
               uniform float4x4 objToCubeTransposeMatrix)
{
    vert2frag OUT;


    float3x3 tangentToObjMatrix;
    computeTangentToObjMatrix(
        IN.normal,
        IN.tangent, 
        tangentToObjMatrix);

    float3 tangentToCubeMatrix1 = mul(tangentToObjMatrix, objToCubeTransposeMatrix._m00_m10_m20);
    float3 tangentToCubeMatrix2 = mul(tangentToObjMatrix, objToCubeTransposeMatrix._m01_m11_m21);
    float3 tangentToCubeMatrix3 = mul(tangentToObjMatrix, objToCubeTransposeMatrix._m02_m12_m22);


    float4 positionWorld = mul(objToWorldMatrix, IN.position);
	float3 eyeDirWorldSpace = (cameraPosWorld - positionWorld).xyz;
	float3 eyeDirCubeSpace = mul(worldToCubeRotationMatrix, float4(eyeDirWorldSpace, 0)).xyz;
	eyeDirCubeSpace = normalize(eyeDirCubeSpace);


    OUT.position = mul(modelViewProj, IN.position);
    OUT.texcoord = mul(textureProjMatrix, IN.texcoord);
	// This functionality relies on the NV_texture_shader's complex
	// DOT_PRODUCT_REFLECT_CUBE_MAP_NV texture function. Here is an excerpt:
	//
	//	18.  DOT_PRODUCT_REFLECT_CUBE_MAP_NV - When preceded by two
    //	     DOT_PRODUCT_NV programs in the previous two texture shader
    //	     stages, computes a third similar dot product and composes the
    //	     three dot products into a normal vector (Nx,Ny,Nz).  An eye
    //	     vector (Ex,Ey,Ez) is composed from the q texture coordinates of
    //	     the three stages.  A reflection vector (Rx,Ry,Rz) is computed
    //	     based on the normal and eye vectors.  The reflection vector
    //	     forms an (s,t,r) texture coordinate set to access a cube map
    //	     texture.
	//
	//
	// Also, note that the second and third sets of texture coordinates are negated.
	// This effectively causes a rotation of 180 degrees around the X axis, in cube map
	// space. This rotation accounts for the different environment map schemes used in
	// Maya and OpenGL.
	// 
    OUT.tangentToCubeMatrix1 = float4(tangentToCubeMatrix1, eyeDirCubeSpace.x);
    OUT.tangentToCubeMatrix2 = float4(-tangentToCubeMatrix2, -eyeDirCubeSpace.y);
    OUT.tangentToCubeMatrix3 = float4(-tangentToCubeMatrix3, -eyeDirCubeSpace.z);


    return OUT;
}
