// Software vertex shader generated by Wild Magic.
//
// var float4    kVertexColor     $vin.COLOR
// var float2    kContrastTCoord  $vin.TEXCOORD0
// var float2    kRandomTCoord    $vin.TEXCOORD1
// var float2    kPaperTCoord     $vin.TEXCOORD2
// var float4    kPixelColor      $vout.COLOR
// var sampler2D ConstrastSampler texunit 0
// var sampler2D RandomSampler    texunit 1
// var sampler2D PaperSampler     texunit 2
// var float2    Constants        c[0]

#include "Wm4SoftRenderer.h"
#include "Wm4ColorRGBA.h"
#include "Wm4SoftSampler.h"

namespace Wm4
{

ColorRGBA p_Charcoal (const float* afRegister, SoftSampler** apkSampler,
    const float* afInPixel)
{
    // Get the register items.
    const float* afConstants = &afRegister[0];

    // Get samplers.
    SoftSampler& rkConstrastSampler = *apkSampler[0];
    SoftSampler& rkRandomSampler = *apkSampler[1];
    SoftSampler& rkPaperSampler = *apkSampler[2];

    // Get the input items.
    const ColorRGBA& rkVertexColor = *(const ColorRGBA*)&afInPixel[0];
    const float* afContrastTCoord = &afInPixel[4];
    const float* afRandomTCoord = &afInPixel[6];
    const float* afPaperTCoord = &afInPixel[8];

    // *** program ***

	// Generate a random number in [0,1] for this fragment.
	ColorRGBA kRandomColor = rkRandomSampler(afRandomTCoord);
	
	// Sample the overlaying paper texture.
	ColorRGBA kPaperColor = rkPaperSampler(afPaperTCoord);

    // The constants allow for Boolean logic with creative use of floats.
    // Smudge:
    //   0.5 = normal smudge
    //   0.0 = no lighting smudging
    //   1.0 = no contrast map, only diffuse lighting
    float fSmudgeFactor = afConstants[0];

    // Paper:
    //   0.0 = display paper
    //   1.0 = no paper
    float fPaperFactor = afConstants[1];

	// Perform a lookup into the contrast-enhanced texture map.
	// s' = 0 + RandomNumber.x 
	// t' = t, the contrast-enhanced color from the vertex shader
    float afNewContrastTCoord[2] =
    {
        afContrastTCoord[0] + kRandomColor[0],
        afContrastTCoord[1]
    };
    ColorRGBA kContrastColor = rkConstrastSampler(afNewContrastTCoord);

	// Blend the contrast-enhanced texel with the contrast-enhanced vertex 
    // color.
    ColorRGBA kSmudgedColor = Lerp(kContrastColor,rkVertexColor,
        fSmudgeFactor);

    // We may want to just display the object without the paper.  If
    // fPaperFactor is large enough it will saturate the paper color to 
    // white which cancels out the alpha blending in the next step.
    kPaperColor[0] += fPaperFactor;
    kPaperColor[1] += fPaperFactor;
    kPaperColor[2] += fPaperFactor;
    kPaperColor[3] += fPaperFactor;
    kPaperColor = Saturate(kPaperColor);

    // Do alpha blending with the background.  The background is drawn as a
    // screen polygon in the distance.  However, there is the chance that
    // whatever is drawn on top of the background will touch the same pixel
    // multiple times and the alpha blending will not look right.  What we
    // really want is to have only those pixels that are visible without
    // alpha blending to be drawn with blending.  The alpha blending is done
    // with the background and the z-buffer can sort out the work of which
    //  pixel is actually on top.
	ColorRGBA kPixelColor = kPaperColor*kSmudgedColor;
    return kPixelColor;
}

WM4_IMPLEMENT_PPROGRAM(Charcoal);
WM4_REGISTER_PPROGRAM(Charcoal);

}
