/****************************************************************************
**
** Copyright (C) 2014 NVIDIA Corporation.
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt 3D Studio.
**
** $QT_BEGIN_LICENSE:GPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef WIREFRAME_CM_GLSLLIB
#define WIREFRAME_CM_GLSLLIB

#ifdef GL_ES
precision highp float;
precision highp int;
#endif

#if (TESSELLATION_EVALUATION_SHADER == 1)
#define VARYING_NAME(varyingName) varyingName##TE
#else
#define VARYING_NAME(varyingName) varyingName##VX
#endif

attribute vec3 VARYING_NAME(varNormal)[];
attribute vec3 VARYING_NAME(varObjPos)[];

varying vec3 varNormal;
varying vec3 varObjPos;

#if QSSG_ENABLE_UV0
attribute vec3 VARYING_NAME(varTexCoord0)[];
varying vec3 varTexCoord0;
#endif

#if QSSG_ENABLE_TEXTAN
attribute vec3 VARYING_NAME(varTangent)[];
attribute vec3 VARYING_NAME(varObjTangent)[];
varying vec3 varTangent;
varying vec3 varObjTangent;
#endif

#if QSSG_ENABLE_BINORMAL
attribute vec3 VARYING_NAME(varBinormal)[];
attribute vec3 VARYING_NAME(varObjBinormal)[];
varying vec3 varBinormal;
varying vec3 varObjBinormal;
#endif

#if QSSG_ENABLE_WORLD_POSITION
attribute vec3 VARYING_NAME(varWorldPos)[];
varying vec3 varWorldPos;
#endif

varying vec3 varEdgeDistance;

uniform mat4 viewportMatrix;

layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

void main()
{
    // how this all work see http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf
    // project points to screen space
    vec3 p0 = vec3(viewportMatrix * (gl_in[0].gl_Position / gl_in[0].gl_Position.w));
    vec3 p1 = vec3(viewportMatrix * (gl_in[1].gl_Position / gl_in[1].gl_Position.w));
    vec3 p2 = vec3(viewportMatrix * (gl_in[2].gl_Position / gl_in[2].gl_Position.w));
    // compute triangle heights
    float e1 = length(p1 - p2);
    float e2 = length(p2 - p0);
    float e3 = length(p1 - p0);
    float alpha = acos( (e2*e2 + e3*e3 - e1*e1) / (2.0*e2*e3) );
    float beta = acos( (e1*e1 + e3*e3 - e2*e2) / (2.0*e1*e3) );
    float ha = abs( e3 * sin( beta ) );
    float hb = abs( e3 * sin( alpha ) );
    float hc = abs( e2 * sin( alpha ) );


    // vertex 0
    varEdgeDistance = vec3(ha*gl_in[0].gl_Position.w, 0.0, 0.0);
    varNormal = VARYING_NAME(varNormal)[0];
    varObjPos = VARYING_NAME(varObjPos)[0];
#if QSSG_ENABLE_UV0
        varTexCoord0 = VARYING_NAME(varTexCoord0)[0];
#endif
#if QSSG_ENABLE_TEXTAN
        varTangent = VARYING_NAME(varTangent)[0];
        varObjTangent = VARYING_NAME(varObjTangent)[0];
#endif
#if QSSG_ENABLE_BINORMAL
        varBinormal = VARYING_NAME(varBinormal)[0];
        varObjBinormal = VARYING_NAME(varObjBinormal)[0];
#endif
#if QSSG_ENABLE_WORLD_POSITION
        varWorldPos = VARYING_NAME(varWorldPos)[0];
#endif

    gl_Position = gl_in[0].gl_Position;
    EmitVertex();

    // vertex 1
    varEdgeDistance = vec3(0.0, hb*gl_in[1].gl_Position.w, 0.0);
    varNormal = VARYING_NAME(varNormal)[1];
    varObjPos = VARYING_NAME(varObjPos)[1];
#if QSSG_ENABLE_UV0
        varTexCoord0 = VARYING_NAME(varTexCoord0)[1];
#endif
#if QSSG_ENABLE_TEXTAN
        varTangent = VARYING_NAME(varTangent)[1];
        varObjTangent = VARYING_NAME(varObjTangent)[1];
#endif
#if QSSG_ENABLE_BINORMAL
        varBinormal = VARYING_NAME(varBinormal)[1];
        varObjBinormal = VARYING_NAME(varObjBinormal)[1];
#endif
#if QSSG_ENABLE_WORLD_POSITION
        varWorldPos = VARYING_NAME(varWorldPos)[1];
#endif

    gl_Position = gl_in[1].gl_Position;
    EmitVertex();

    // vertex 2
    varEdgeDistance = vec3(0.0, 0.0, hc*gl_in[2].gl_Position.w);
    varNormal = VARYING_NAME(varNormal)[2];
    varObjPos = VARYING_NAME(varObjPos)[2];
#if QSSG_ENABLE_UV0
        varTexCoord0 = VARYING_NAME(varTexCoord0)[2];
#endif
#if QSSG_ENABLE_TEXTAN
        varTangent = VARYING_NAME(varTangent)[2];
        varObjTangent = VARYING_NAME(varObjTangent)[2];
#endif
#if QSSG_ENABLE_BINORMAL
        varBinormal = VARYING_NAME(varBinormal)[2];
        varObjBinormal = VARYING_NAME(varObjBinormal)[2];
#endif
#if QSSG_ENABLE_WORLD_POSITION
        varWorldPos = VARYING_NAME(varWorldPos)[2];
#endif

    gl_Position = gl_in[2].gl_Position;
    EmitVertex();

    EndPrimitive();
}

#endif
