// Software vertex shader generated by Wild Magic.
//
// var float3   kModelPosition   $vin.POSITION
// var float2   kInBaseTCoord    $vin.TEXCOORD0
// var float2   kInDetailTCoord  $vin.TEXCOORD1
// var float4   kClipPosition    $vout.POSITION
// var float2   kOutBaseTCoord   $vout.TEXCOORD0
// var float2   kOutDetailTCoord $vout.TEXCOORD1
// var float    fFogFactor       $vout.TEXCOORD2
// var float4x4 WVPMatrix        c[0]
// var float4x4 WVMatrix         c[4]
// var float4   FogColorDensity  c[8]

#include "Wm4SoftRenderer.h"
#include "Wm4Matrix4.h"
#include "Wm4Vector2.h"
#include "Wm4Vector3.h"

namespace Wm4
{

void v_BaseMulDetailFogExpSqr (const float* afRegister,
    const float* afInVertex, float* afOutVertex)
{
    // Get the register items.
    const Matrix4f& rkWVPMatrix = *(const Matrix4f*)&afRegister[0];
    const Matrix4f& rkWVMatrix = *(const Matrix4f*)&afRegister[16];
    const float* afFogColorDensity = &afRegister[32];

    // Get the input items.
    Vector4f kModelPosition(afInVertex[0],afInVertex[1],afInVertex[2],1.0f);
    const Vector2f& rkInBaseTCoord = *(const Vector2f*)&afInVertex[3];
    const Vector2f& rkInDetailTCoord = *(const Vector2f*)&afInVertex[5];

    // Access the output items.
    Vector4f& rkClipPosition = *(Vector4f*)&afOutVertex[0];
    Vector2f& rkOutBaseTCoord = *(Vector2f*)&afOutVertex[4];
    Vector2f& rkOutDetailTCoord = *(Vector2f*)&afOutVertex[6];
    float& rfFogFactor = afOutVertex[8];

    // *** program ***

    // Transform the position from model space to clip space.
    rkClipPosition = kModelPosition*rkWVPMatrix;

    // Transform the position from model space to view space.  This is the
    // vector from the view-space eye position (the origin) to the view-space
    // vertex position.  The fog factor uses the z-component of this vector,
    // which is z-based depth, not range-based depth.
    Vector3f kViewPosition = (Vector3f)(kModelPosition*rkWVMatrix);
    float fFogSqrDistance = kViewPosition.SquaredLength();
    float fFogSqrDensity = afFogColorDensity[3]*afFogColorDensity[3];
    float fFogExpArg = -fFogSqrDensity*fFogSqrDistance;
    rfFogFactor = Mathf::Exp(fFogExpArg);

    // Pass through the texture coordinates.
    rkOutBaseTCoord = rkInBaseTCoord;
    rkOutDetailTCoord = rkInDetailTCoord;
}

WM4_IMPLEMENT_VPROGRAM(BaseMulDetailFogExpSqr);
WM4_REGISTER_VPROGRAM(BaseMulDetailFogExpSqr);

}
