#version 400 core
subroutine vec4 SurfaceColor();

uniform sampler2D U_MainTexture;
subroutine uniform SurfaceColor U_SurfaceColor;
varying vec3 V_Normal;
varying vec4 V_WorldPos;//µ±Ç°µÄλÖÃ
varying vec2 V_Texcoord;

subroutine (SurfaceColor) vec4 Ambient(){
	
	//ambient
	vec4 AmbientLightColor = vec4(0.4, 0.4, 0.4, 1.0);
	vec4 AmbientMaterial = vec4(0.2, 0.2, 0.2, 1.0);
	vec4 AmbientColor = AmbientLightColor*AmbientMaterial;

	vec4 ret = AmbientColor;
	return ret;
}

subroutine (SurfaceColor) vec4 Diffuse(){
	
	vec3 lightPos = vec3(10.0, 10.0, 0.0);
	vec3 L=lightPos;
	L = normalize(L);
	vec3 n = normalize(V_Normal);

	//ambient
	vec4 AmbientLightColor = vec4(0.4, 0.4, 0.4, 1.0);
	vec4 AmbientMaterial = vec4(0.2, 0.2, 0.2, 1.0);
	vec4 AmbientColor = AmbientLightColor*AmbientMaterial;

	//diffuse
	vec4 DiffuseLightColor = vec4(1.0,1.0,1.0,1.0);
	vec4 DiffuseMaterial = vec4(0.8, 0.8, 0.8, 1.0);
	vec4 diffuseColor = DiffuseLightColor*DiffuseMaterial*max(0.0, dot(L,n));

	vec4 ret = AmbientColor + texture2D(U_MainTexture, V_Texcoord) * diffuseColor;
	return ret;
}

subroutine (SurfaceColor) vec4 Specular(){
	vec3 lightPos = vec3(10.0, 10.0, 0.0);
	vec3 L=lightPos;
	L = normalize(L);
	vec3 n = normalize(V_Normal);

	//ambient
	vec4 AmbientLightColor = vec4(0.4, 0.4, 0.4, 1.0);
	vec4 AmbientMaterial = vec4(0.2, 0.2, 0.2, 1.0);
	vec4 AmbientColor = AmbientLightColor*AmbientMaterial;

	//diffuse
	vec4 DiffuseLightColor = vec4(1.0,1.0,1.0,1.0);
	vec4 DiffuseMaterial = vec4(0.8, 0.8, 0.8, 1.0);
	vec4 diffuseColor = DiffuseLightColor*DiffuseMaterial*max(0.0, dot(L,n));

	//specular
	vec4 SpecularLightColor = vec4(1.0,1.0,1.0,1.0);
	vec4 SpecularMaterial = vec4(0.9,0.9,0.9,1.0);
	vec3 reflectDir = normalize(reflect(-L,n));//-L¾ÍÊǹâÏßµÄÈëÉä·½ÏòÏòÁ¿£¬ÒÔ·¨ÏßΪ»ù´¡¼ÆË㷽ʽÏòÁ¿
	vec3 viewDir = normalize(vec3(0.0) - V_WorldPos.xyz);//vec3(0.0)±íʾÒÑÖÐÐÄΪ¹Û²ìµã£¬ÕâÀïÇóµÄÊÇÑÛ¾¦µ½ÎïÌåµÄÊÓÏßÏòÁ¿
	vec4 specularColor = SpecularLightColor*SpecularMaterial*pow(max(0.0,dot(viewDir,reflectDir)),128.0);

	vec4 ret = AmbientColor + texture2D(U_MainTexture, V_Texcoord) * diffuseColor + specularColor;
	return ret;
}

void main() {
	gl_FragColor = U_SurfaceColor();
}