#include "world.inc"
#include "material.inc"
#if OIT
#include "oit.inc"
#endif

struct VS_INPUT
{
	float4 Pos : POSITION;
	float4 Color : COLOR0;
};

struct GS_INPUT
{
	float4 Pos : SV_POSITION;
	float4 WorldPos : TEXCOORD0;
	float4 Color : COLOR0;
};

struct GS_OUTPUT
{
	float4 Pos : SV_POSITION;
	float4 WorldPos : TEXCOORD0;
	float4 Col : COLOR0;
};

struct PS_INPUT
{
	float4 Pos : SV_POSITION;
	float4 WorldPos : TEXCOORD0;
	float4 Col : COLOR0;
#if MSAA
    uint Coverage : SV_COVERAGE;
#endif
};

#include "oit_store.inc"


GS_INPUT VS(const VS_INPUT In)
{
	GS_INPUT Out;
	Out.Pos = mul(In.Pos, WorldViewProj);
	Out.WorldPos = In.Pos;
	Out.Color = In.Color;
	return Out;
}

// Geometry shader for a wire
[maxvertexcount(8)]
void GS(lineadj GS_INPUT input[4], inout LineStream<GS_OUTPUT> stream)
{
	GS_OUTPUT output;

	for(uint i=0; i<4; i++){
		if(input[i].Color.a > 0){
			uint i1 = (i+1)%4;
#if OIT
			//if(OITRenderMode == 1 && (input[i].Color.a < 1.0 || input[i1].Color.a < 1.0)) continue; // opaque only
			//if(OITRenderMode == 2 && input[i].Color.a == 1.0 && input[i1].Color.a == 1.0) continue; // transparent only
#endif
			output.Pos = input[i].Pos;
			output.Col = float4(0.0, 0.0, 0.0, input[i].Color.a);
			output.WorldPos = input[i].WorldPos;
			stream.Append(output);

			output.Pos = input[i1].Pos;
			output.Col = float4(0.0, 0.0, 0.0, input[i].Color.a);
			output.WorldPos = input[i1].WorldPos;
			stream.Append(output);

			stream.RestartStrip();
		}
	}
}

#if OIT
[earlydepthstencil]
#endif
float4 PS(PS_INPUT In) : SV_Target
{
	if(IsArbClipped(In.WorldPos.xyz))
		discard;
#if OIT
	StoreOIT(In, In.Col);
	return float4(0, 0, 0, 0);	// This does not affect anything because RenderTargetWriteMask is 0.
#else
	return In.Col;
#endif
}

