#version 120
//  Copyright © 2013-2017  B. Clausius <barcc@gmx.de>
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifdef GL_OES_standard_derivatives
    #extension GL_OES_standard_derivatives : enable
#endif
#ifdef GL_ES
precision mediump float;
#endif

uniform sampler2D tex;
varying vec4 position;
varying vec3 normal;
varying vec3 color;
varying vec2 texcoord;
varying vec3 barycentric;

#ifndef GL_ES
const
#endif
vec3 bevel_color = vec3(pow(15./255., 2.2));
const vec3 pointlight = vec3(0., 0., 0.);
// diffuse+ambient+specular is the maxintensity
const float diffuse = 0.5;
const float ambient = 1.2;
const float shininess = 15.;
const float attenuation = 0.001;
const vec3 specular = vec3(.3);
const vec3 invgamma = vec3(1./2.2);

vec3 lighting(vec3 col_face)
{
    vec3 norm = normalize(normal);
    vec3 lightvector = pointlight - position.xyz;
    vec3 dirtolight = normalize(lightvector);
    float cos_angle = dot(norm, dirtolight);
    cos_angle = clamp(cos_angle, 0., 1.);
    
    // attenuation
    float light_distance_sqr = dot(lightvector, lightvector);
    float attenfactor = 1. / (1.0 + attenuation * light_distance_sqr);
    
    // combine color components
    vec3 col = ambient * col_face;
    col += specular * attenfactor * pow(cos_angle, shininess);
    col += diffuse * col_face * cos_angle;
    return col;
}

void main()
{
    vec3 col;
    vec4 col_tex = texture2D(tex, texcoord);
    float bary_min = min(min(barycentric.x, barycentric.y), barycentric.z);
    #ifdef GL_OES_standard_derivatives
    float bary_width = fwidth(bary_min);
    #endif
    if (barycentric == vec3(0.)) {
        // unlabeled part
        col = bevel_color;
    } else if (bary_min <= 0.02) {
        // frame around the label
        col = bevel_color;
    } else {
        // the label
        col = mix(color.rgb, col_tex.rgb, col_tex.a);
        #ifdef GL_OES_standard_derivatives
        bary_min = (bary_min - 0.02) / 1.1;
        if (bary_min < bary_width) {
            // smooth at the frame
            col = mix(bevel_color, col, bary_min / bary_width);
        }
        #endif
    }
    
    col = lighting(col);
    
    gl_FragColor = vec4(pow(col, invgamma), 1.);
}

