/**
 *
 * Diplomova prace
 * Stinove techniky na dnesnim hardware a jejich porovnani
 *
 * Michal Toth
 *
 * Fakulta informacnich technologii
 * Vysoke uceni technicke v Brne
 *
 * 2013/2014
 *
 */

/*
 * Fragment shader oznacujici hrany stinu a plnici stencil buffer
 */

#version 420

layout(early_fragment_tests) in;

in vec3 position;
in vec3 normal;
in vec2 tc;

uniform sampler2D KaTex;
uniform vec3 Ka;
uniform vec3 La;
uniform vec3 Ld;
uniform vec3 Ls;
uniform vec3 lightPos;
uniform vec3 cameraPos;
uniform bool shadowColors;

in vec4 shadowPos;
uniform sampler2DShadow shadowTexture;

layout(location=0)out vec4 unlit;
layout(location=1)out vec4 lit;
layout(location=2)out vec3 stencil;

uniform float offset;
uniform float dt;
uniform float shininess=32;

int getShadow(vec4 pos){
    // out of texture
    if (pos.w <= 0.0f || pos.z>1 ||
	    pos.x < 0 || pos.y < 0 ||
	    pos.x >= 1 || pos.y >= 1){
	return 1;

    } else {
	return int(textureProj(shadowTexture,vec4(pos.xy,pos.z-offset,1)).x);
    }
}

vec3 onEdge(){
    vec4 posNorm =shadowPos/ shadowPos.w;
    int center = getShadow(posNorm);

    vec3 shadow = shadowColors?vec3(1,1-center,0):vec3(0);
    //vec3 shadow = shadowColors?vec3(1,0,0):vec3(0);

    stencil=vec3(1);


    if(center!=getShadow(posNorm+vec4(0,-dt,0,0))){
	return shadow;
    }
    if(center!=getShadow(posNorm+vec4(0,+dt,0,0))){
	return shadow;
    }
    if(center!=getShadow(posNorm+vec4(-dt,0,0,0))){
	return shadow;
    }
    if(center!=getShadow(posNorm+vec4(+dt,0,0,0))){
	return shadow;
    }


    if(center!=getShadow(posNorm+vec4(+dt,-dt,0,0))){
	return shadow;
    }
    if(center!=getShadow(posNorm+vec4(-dt,-dt,0,0))){
	return shadow;
    }

    if(center!=getShadow(posNorm+vec4(-dt,+dt,0,0))){
	return shadow;
    }

    if(center!=getShadow(posNorm+vec4(+dt,+dt,0,0))){
	return shadow;
    }

    stencil=vec3(0);

    return vec3(center);
}


void main() {

    vec3 col = Ka+texture(KaTex,tc).rgb;

    vec3 N = normalize(normal);
    vec3 L = normalize(lightPos-position);
    vec3 A = La*col;
    vec3 D = Ld*max(dot(L,N),0)*col;
    vec3 S = vec3(0,0,0);
    if(shininess>0){
	vec3 V = normalize(cameraPos-position);
	vec3 R = reflect(-L,N);
	float spec = max(0,pow(dot(R,V),shininess));
	S = spec*Ls;
    }

    unlit = vec4(A+(D+S)*onEdge(),1);
    //unlit = vec4(onEdge(),1);
    lit = vec4(A+D+S,1);
}
