#include "ParticleEffect.fxh"


// Custom vertex shader animates particles entirely on the GPU.
VertexShaderOutput VSMain(VertexShaderInput input)
{
    VertexShaderOutput output;
    
    float age;
    float normalizedAge;

	GetParticleAge(input.Time, age, normalizedAge, input.Random.x);

    // Compute the particle position, size, color, and rotation.
    output.Position = ComputeParticlePosition(input.Position, input.Velocity,
                                              age, normalizedAge);
    
    output.Size = ComputeParticleSize(output.Position, input.Random.y, normalizedAge);
    output.Color = ComputeParticleColor(output.Position, input.Random.z, normalizedAge);
    output.Rotation = ComputeParticleRotation(input.Random.w, age);
    
    return output;
}

// Pixel shader for drawing particles that do not rotate.
float4 NonRotatingPixelShader(NonRotatingPixelShaderInput input) : COLOR0
{
    return tex2D(Sampler, input.TextureCoordinate) * input.Color;
}


// Pixel shader for drawing particles that can rotate. It is not actually
// possible to rotate a point sprite, so instead we rotate our texture
// coordinates. Leaving the sprite the regular way up but rotating the
// texture has the exact same effect as if we were able to rotate the
// point sprite itself.
float4 RotatingPixelShader(RotatingPixelShaderInput input) : COLOR0
{
    float2 textureCoordinate = GetRotationTextureCoordinate(input.TextureCoordinate, input.Rotation);


    return tex2D(Sampler, textureCoordinate) * input.Color;
}


// Effect technique for drawing particles that do not rotate.
technique NonRotatingParticles
{
    pass P0
    {
        VertexShader = compile vs_3_0 VSMain();
        PixelShader = compile ps_3_0 NonRotatingPixelShader();
    }
}


// Effect technique for drawing particles that can rotate.
technique Particles
{
    pass P0
    {
        VertexShader = compile vs_3_0 VSMain();
        PixelShader = compile ps_3_0 RotatingPixelShader();
    }
}
