////////////////////////////////////////////////////////////////////////////////
// Filename: billboard.vs
////////////////////////////////////////////////////////////////////////////////


/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer
{
	matrix worldMatrix;
	matrix viewMatrix;
	matrix projectionMatrix;
};

//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
    float4 position : POSITION;
	float2 size: SIZE;
	uint flags: FLAGS;
};

struct GeoOut
{
	float4 Pos : SV_POSITION;
//	float3 PosW : POSITION;
//	float3 NormalW : NORMAL;
	float2 Tex : TEXCOORD0;
//	uint PrimID : SV_PrimitiveID;
};

////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
VertexInputType BillboardVertexShader(VertexInputType input)
{
    return input;
}

////////////////////////////////////////////////////////////////////////////////
// Geometry Shader
////////////////////////////////////////////////////////////////////////////////

[maxvertexcount(4)]
void BillboardGeometryShader(point VertexInputType gin[1], inout TriangleStream<GeoOut> triStream)
{
	//
	// Compute the local coordinate system of the sprite relative to the
	// world space such that the billboard is aligned with the y-axis
	// and faces the eye.
	//
	gin[0].position.w=1.0f;
	//gin[0].position = mul(gin[0].position, worldMatrix);
	float4 up = float4(viewMatrix._12_22_32, 0.0f);
	float4 right = float4(viewMatrix._11_21_31, 0.0f);
	//float3 look = - viewMatrix._13_23_33;
	//look.y = 0.0f; // y-axis aligned, so project to xz-plane
	//look.x = 0.0f;
	//look = normalize(look);
	//float3 right = cross(up, look);
	//
	// Compute triangle strip vertices (quad) in world space.
	//
	float halfWidth = gin[0].size.x;
	float halfHeight = gin[0].size.y;
	float4 v[4];
	v[0] = float4(gin[0].position - halfWidth*right - halfHeight*up);
	v[1] = float4(gin[0].position - halfWidth*right + halfHeight*up);
	v[2] = float4(gin[0].position + halfWidth*right - halfHeight*up);
	v[3] = float4(gin[0].position + halfWidth*right + halfHeight*up);

	float2 texCoord[4];
	texCoord[0] = float2(0, 1);
	texCoord[1] = float2(0, 0);
	texCoord[2] = float2(1, 1);
	texCoord[3] = float2(1, 0);

	//
	// Transform quad vertices to world space and output
	// them as a triangle strip.
	GeoOut gout;
	[unroll]
	for(int i = 0; i < 4; ++i)
	{
		//gout.Pos = mul(v[i], objectMatrix);
		//gout.Pos = mul(v[i], worldMatrix);
		gout.Pos = mul(v[i], viewMatrix);
		gout.Pos = mul(gout.Pos, projectionMatrix);
		//gout.PosH = mul(v[i], worldViewProjMatrix);
		//gout.NormalW = look;
		gout.Tex = texCoord[i];
		//gout.PrimID = primID;
		triStream.Append(gout);
	}
}

Texture2D shaderTexture;
SamplerState SampleType;

////////////////////////////////////////////////////////////////////////////////
// Pixel Shader
////////////////////////////////////////////////////////////////////////////////
float4 BillboardPixelShader(GeoOut pin) : SV_TARGET
{
	//float4 textureColor;
	//float4 finalColor;

    // Sample the pixel color from the texture using the sampler at this texture coordinate location.
    //textureColor = shaderTexture.Sample(SampleType, pin.Tex);

	// Combine the texture color and the particle color to get the final color result.
    //finalColor = textureColor * pin.color;

    
	return shaderTexture.Sample(SampleType, pin.Tex);//finalColor;
}