xref: /OK3568_Linux_fs/app/forlinx/flapp/src/plugins/imxwayland/qmlvideofx/shaders/pagecurl.fsh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd and/or its subsidiary(-ies).
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Mobility Components.
7**
8** $QT_BEGIN_LICENSE:LGPL21$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 2.1 or version 3 as published by the Free
20** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22** following information to ensure the GNU Lesser General Public License
23** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25**
26** As a special exception, The Qt Company gives you certain additional
27** rights. These rights are described in The Qt Company LGPL Exception
28** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29**
30** $QT_END_LICENSE$
31**
32****************************************************************************/
33
34// Based on http://rectalogic.github.com/webvfx/examples_2transition-shader-pagecurl_8html-example.html
35
36uniform float dividerValue;
37uniform float curlExtent;
38uniform sampler2D source;
39uniform lowp float qt_Opacity;
40varying vec2 qt_TexCoord0;
41
42const float minAmount = -0.16;
43const float maxAmount = 1.3;
44const float PI = 3.141592653589793;
45const float scale = 512.0;
46const float sharpness = 3.0;
47const vec4 bgColor = vec4(1.0, 1.0, 0.8, 1.0);
48
49float amount = curlExtent * (maxAmount - minAmount) + minAmount;
50float cylinderCenter = amount;
51// 360 degrees * amount
52float cylinderAngle = 2.0 * PI * amount;
53const float cylinderRadius = 1.0 / PI / 2.0;
54
55vec3 hitPoint(float hitAngle, float yc, vec3 point, mat3 rrotation)
56{
57    float hitPoint = hitAngle / (2.0 * PI);
58    point.y = hitPoint;
59    return rrotation * point;
60}
61
62vec4 antiAlias(vec4 color1, vec4 color2, float distance)
63{
64    distance *= scale;
65    if (distance < 0.0) return color2;
66    if (distance > 2.0) return color1;
67    float dd = pow(1.0 - distance / 2.0, sharpness);
68    return ((color2 - color1) * dd) + color1;
69}
70
71float distanceToEdge(vec3 point)
72{
73    float dx = abs(point.x > 0.5 ? 1.0 - point.x : point.x);
74    float dy = abs(point.y > 0.5 ? 1.0 - point.y : point.y);
75    if (point.x < 0.0) dx = -point.x;
76    if (point.x > 1.0) dx = point.x - 1.0;
77    if (point.y < 0.0) dy = -point.y;
78    if (point.y > 1.0) dy = point.y - 1.0;
79    if ((point.x < 0.0 || point.x > 1.0) && (point.y < 0.0 || point.y > 1.0)) return sqrt(dx * dx + dy * dy);
80    return min(dx, dy);
81}
82
83vec4 seeThrough(float yc, vec2 p, mat3 rotation, mat3 rrotation)
84{
85    float hitAngle = PI - (acos(yc / cylinderRadius) - cylinderAngle);
86    vec3 point = hitPoint(hitAngle, yc, rotation * vec3(p, 1.0), rrotation);
87    if (yc <= 0.0 && (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0))
88        return bgColor;
89    if (yc > 0.0)
90        return texture2D(source, p);
91    vec4 color = texture2D(source, point.xy);
92    vec4 tcolor = vec4(0.0);
93    return antiAlias(color, tcolor, distanceToEdge(point));
94}
95
96vec4 seeThroughWithShadow(float yc, vec2 p, vec3 point, mat3 rotation, mat3 rrotation)
97{
98    float shadow = distanceToEdge(point) * 30.0;
99    shadow = (1.0 - shadow) / 3.0;
100    if (shadow < 0.0)
101        shadow = 0.0;
102    else
103        shadow *= amount;
104    vec4 shadowColor = seeThrough(yc, p, rotation, rrotation);
105    shadowColor.r -= shadow;
106    shadowColor.g -= shadow;
107    shadowColor.b -= shadow;
108    return shadowColor;
109}
110
111vec4 backside(float yc, vec3 point)
112{
113    vec4 color = texture2D(source, point.xy);
114    float gray = (color.r + color.b + color.g) / 15.0;
115    gray += (8.0 / 10.0) * (pow(1.0 - abs(yc / cylinderRadius), 2.0 / 10.0) / 2.0 + (5.0 / 10.0));
116    color.rgb = vec3(gray);
117    return color;
118}
119
120void main(void)
121{
122    const float angle = 30.0 * PI / 180.0;
123    float c = cos(-angle);
124    float s = sin(-angle);
125    mat3 rotation = mat3(
126        c, s, 0,
127        -s, c, 0,
128        0.12, 0.258, 1
129    );
130    c = cos(angle);
131    s = sin(angle);
132    mat3 rrotation = mat3(
133        c, s, 0,
134        -s, c, 0,
135        0.15, -0.5, 1
136    );
137    vec3 point = rotation * vec3(qt_TexCoord0, 1.0);
138    float yc = point.y - cylinderCenter;
139    vec4 color = vec4(1.0, 0.0, 0.0, 1.0);
140    if (yc < -cylinderRadius) {
141        // See through to background
142        color = bgColor;
143    } else if (yc > cylinderRadius) {
144        // Flat surface
145        color = texture2D(source, qt_TexCoord0);
146    } else {
147        float hitAngle = (acos(yc / cylinderRadius) + cylinderAngle) - PI;
148        float hitAngleMod = mod(hitAngle, 2.0 * PI);
149        if ((hitAngleMod > PI && amount < 0.5) || (hitAngleMod > PI/2.0 && amount < 0.0)) {
150            color = seeThrough(yc, qt_TexCoord0, rotation, rrotation);
151        } else {
152            point = hitPoint(hitAngle, yc, point, rrotation);
153            if (point.x < 0.0 || point.y < 0.0 || point.x > 1.0 || point.y > 1.0) {
154                color = seeThroughWithShadow(yc, qt_TexCoord0, point, rotation, rrotation);
155            } else {
156                color = backside(yc, point);
157                vec4 otherColor;
158                if (yc < 0.0) {
159                    float shado = 1.0 - (sqrt(pow(point.x - 0.5, 2.0) + pow(point.y - 0.5, 2.0)) / 0.71);
160                    shado *= pow(-yc / cylinderRadius, 3.0);
161                    shado *= 0.5;
162                    otherColor = vec4(0.0, 0.0, 0.0, shado);
163                } else {
164                    otherColor = texture2D(source, qt_TexCoord0);
165                }
166                color = antiAlias(color, otherColor, cylinderRadius - abs(yc));
167
168                // This second antialiasing step causes the shader to fail to render, on
169                // Symbian devices (tested so far using IVE3.5).  Running out of scratch
170                // memory?
171            }
172        }
173    }
174    gl_FragColor = qt_Opacity * color;
175}
176