cbuffer cbPerObject :register(b0)
{
    matrix WVP;
		matrix WorldMatrix;
		float4 MaterialDiffuseColor;
		float4 MaterialAmbientColor;
		float4 MaterialSpecularColor;
		float fMaterialSelfIllumination;
		float fMaterialShininess;
		float _padding_00;
		float _padding_01;
		float4 WorldCameraPosition;
};

struct light_t {
	float4 position;
	float4 color;
	float attenuationConstant;
	float attenuationLinear;
	float attenuationQuadratic;
	float _padding_00;
};

cbuffer cbLighting : register(b1){
	light_t lights[8];

	int lightCount;
}

struct VOut
{
    float4 position : SV_POSITION;
    //float3 unprocessed_pos : TEXCOORD;
		float4 normal : NORMAL;
		float4 worldPosition: TEXCOORD;
    float2 texcoord : COLOR;
};

//TODO: rajonni miert nem muxik a float4 position
struct VertexIn
{
    float3 position : POSITION;
    float3 normal : NORMAL;
    float3 tangent : TANGENT;
    float3 bitangent : BITANGENT;
    float2 texcoord : TEXCOORD;
};

Texture2D diffuse : register(t0);
Texture2D normal : register(t1);
Texture2D specular : register(t2);
SamplerState ss;

VOut VertexMain(VertexIn vin)
{
    VOut output;

    output.position = mul(WVP, float4(vin.position, 1)); // transform the vertex from 3D to 2D
    //output.unprocessed_pos = vin.position.xyz;
    output.texcoord = vin.texcoord;

		output.worldPosition = mul(WorldMatrix, float4(vin.position, 1));
		output.normal = mul(WorldMatrix, float4(vin.normal, 0.0));

    return output;
}

float4 PixelMain(VOut vin) : SV_TARGET
{
	float4 map_diff = diffuse.Sample(ss, vin.texcoord);
	float4 map_spec = specular.Sample(ss, vin.texcoord);
	float4 map_norm = normal.Sample(ss, vin.texcoord);

	float3 surface_normal = normalize(vin.normal.xyz);
	float3 ray_dir = normalize(vin.worldPosition.xyz - WorldCameraPosition.xyz);

	float fresnel = 1.0 + dot(surface_normal, ray_dir);
	fresnel *= fresnel;

	float3 colorAccumulator = fMaterialSelfIllumination*MaterialDiffuseColor.xyz;

	for (int i = 0; i < lightCount; i++)
	{
		float3 lightDirection;
		float3 lightColor = lights[i].color.xyz;
			float attenuation;

		if (lights[i].position.w < .01f) //directional light
		{
			lightDirection = normalize(lights[i].position.xyz);
			attenuation = 1.0; //disable
		}
		else { //point light
			float3 difference = lights[i].position.xyz - vin.worldPosition.xyz;
			lightDirection = normalize(difference);
			float distance = length(difference);
			attenuation = 1.0f / (lights[i].attenuationConstant + lights[i].attenuationLinear*distance + lights[i].attenuationQuadratic*distance*distance);
		}

		float diffuse_coef = dot(lightDirection, surface_normal);
		diffuse_coef = max(diffuse_coef, .0);
		colorAccumulator += diffuse_coef * MaterialDiffuseColor.xyz * lightColor * attenuation;

		float3 reflected_light = reflect(lightDirection, surface_normal);
		float specular = pow(max(dot(ray_dir, reflected_light), 0.0), fMaterialShininess);
		colorAccumulator += MaterialSpecularColor.xyz * lightColor * specular;
	}

	return float4(colorAccumulator, 1.0);

}