
// The data structure from the vertex shader to the geometry shader
struct VS_to_GS {
	float4 Pos : SV_POSITION;
	float Visible : COLOR;
};

// The data structure from the geometry shader to the pixel shader
struct GS_to_PS {
	float4 Pos : SV_POSITION;
	float2 Pos_Quad : TEXCOORD0;
};

//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
VS_to_GS VS( VS_structure input ) {
	VS_to_GS output = (VS_to_GS)0;
	
	// Convert vertice positions from object space to 2D projection
	output.Pos = mul(mul(input.Pos, ObjectToWorld), WorldToImage);
	
	output.Visible = input.Color.a * input.Selected;
	
	return output;
}

#define THICKNESS 1.8f

//--------------------------------------------------------------------------------------
// Geometry Shader
//--------------------------------------------------------------------------------------
[maxvertexcount(24)]
void GS( triangle VS_to_GS input[3], inout TriangleStream<GS_to_PS> TriStream ) {
	GS_to_PS output = (GS_to_PS)0;
	int I;
	int J;
	for( I = 0; I < 3; I++ ) {
		if (input[I].Visible > 0.0001f) {
			J = (I + 1) % 3;
			float2 Direction = normalize(input[I].Pos.xy - input[J].Pos.xy);
			float2 OffsetA = float2(Direction.x * THICKNESS / Dimensions.x, Direction.y * THICKNESS / Dimensions.y);
			float2 OffsetB = float2(Direction.y * THICKNESS / Dimensions.x, -Direction.x * THICKNESS / Dimensions.y);
			
			output.Pos = input[I].Pos + float4(OffsetB + OffsetA,0.0f,0.0f);
			output.Pos_Quad = float2(1.0f, 1.0f);
			TriStream.Append( output );
			output.Pos = input[I].Pos + float4(-OffsetB + OffsetA,0.0f,0.0f);
			output.Pos_Quad = float2(-1.0f, 1.0f);
			TriStream.Append( output );
			
			output.Pos = input[I].Pos + float4(OffsetB,0.0f,0.0f);
			output.Pos_Quad = float2(1.0f, 0.0f);
			TriStream.Append( output );
			output.Pos = input[I].Pos + float4(-OffsetB,0.0f,0.0f);
			output.Pos_Quad = float2(-1.0f, 0.0f);
			TriStream.Append( output );
			
			output.Pos = input[J].Pos + float4(OffsetB,0.0f,0.0f);
			output.Pos_Quad = float2(1.0f, 0.0f);
			TriStream.Append( output );
			output.Pos = input[J].Pos + float4(-OffsetB,0.0f,0.0f);
			output.Pos_Quad = float2(-1.0f, 0.0f);
			TriStream.Append( output );
			
			output.Pos = input[J].Pos + float4(OffsetB - OffsetA,0.0f,0.0f);
			output.Pos_Quad = float2(1.0f, -1.0f);
			TriStream.Append( output );
			output.Pos = input[J].Pos + float4(-OffsetB - OffsetA,0.0f,0.0f);
			output.Pos_Quad = float2(-1.0f, -1.0f);
			TriStream.Append( output );
			
			TriStream.RestartStrip();
		}
	}
}

//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( GS_to_PS input) : SV_Target {
	return float4(InstanceColor.rgb, InstanceColor.a * saturate(1.0f - length(input.Pos_Quad)));
}
