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