Merge "Fixes the change of style when the text-field grabs the keyboard focus." into...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / shader-effects / distance-field-effect.h
1 #ifndef __DALI_TOOLKIT_SHADER_EFFECT_DISTANCEFIELD_H__
2 #define __DALI_TOOLKIT_SHADER_EFFECT_DISTANCEFIELD_H__
3
4 /*
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/shader-effects/shader-effect.h>
23
24 namespace Dali
25 {
26
27 namespace Toolkit
28 {
29
30 /**
31  * Creates a new DistanceFieldEffect
32  *
33  * DistanceFieldEffect is a custom shader effect to achieve distance field on Image actors
34  *
35  * Animatable/Constrainable uniforms:
36  *
37  *  "uSmoothing"    - Soft edge smoothing. Specify the distance field value for the center of the edge.
38
39  *  "uDoGlow"       - The glow state. If true, glow is enabled
40  *  "uGlowBoundary" - The glow boundary factor
41  *  "uGlowColor"    - The glow color multiplier
42
43  *  "uDoShadow"     - The shadow state. If true, shadows is enabled. Cannot be used with glow/and or outline
44  *  "uShadowColor"  - The shadow color multiplier
45  *  "uShadowOffset" - The shadow offset
46
47  *  "uDoOutline"    - The outline state. If true, outline is enabled
48  *  "uOutlineColor" - The outline color multiplier
49  *  "uOutlineParams"- Thickness of outline. The outline thickness is determined by two values.
50  *                    First value [0-1] Specifies the distance field value for the center of the outline.
51  *                    Second value [0-1] Specifies the softness/width/anti-aliasing of the outlines inner edge.
52  *
53  * @return A handle to a newly allocated ShaderEffect
54  */
55 inline ShaderEffect CreateDistanceFieldEffect()
56 {
57   std::string fragmentShaderPrefix(
58       "#extension GL_OES_standard_derivatives : enable\n"
59       "\n"
60   );
61
62   std::string fragmentShader(
63       "uniform mediump float uSmoothing;\n"
64       "uniform mediump float uGlowBoundary;\n"
65       "uniform mediump vec2  uOutlineParams;\n"
66       "uniform lowp    vec4  uOutlineColor;\n"
67       "uniform lowp    vec4  uShadowColor;\n"
68       "uniform mediump vec2  uShadowOffset;\n"
69       "uniform lowp    vec4  uGlowColor;\n"
70       "uniform lowp    float uDoOutline;\n"
71       "uniform lowp    float uDoShadow;\n"
72       "uniform lowp    float uDoGlow;\n"
73       "\n"
74       "void main()\n"
75       "{\n"
76       "  // sample distance field\n"
77       "  mediump float distance = texture2D(sTexture, vTexCoord).a;\n"
78       "  mediump float smoothWidth = fwidth(distance);\n"
79       "  mediump float alphaFactor = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);\n"
80       "  lowp    vec4  color;\n"
81       "  if (uDoShadow == 0.0)\n"
82       "  {\n"
83       "    mediump float alpha = uColor.a * alphaFactor;\n"
84       "    lowp    vec4  rgb = uColor;\n"
85       "\n"
86       "    if (uDoOutline > 0.0)\n"
87       "    {\n"
88       "      mediump float outlineWidth = uOutlineParams[1] + smoothWidth;\n"
89       "      mediump float outlineBlend = smoothstep(uOutlineParams[0] - outlineWidth, uOutlineParams[0] + outlineWidth, distance);\n"
90       "      alpha = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);\n"
91       "      rgb = mix(uOutlineColor, uColor, outlineBlend);\n"
92       "    }\n"
93       "\n"
94       "    if (uDoGlow > 0.0)\n"
95       "    {\n"
96       "      rgb = mix(uGlowColor, rgb, alphaFactor);\n"
97       "      alpha = smoothstep(uGlowBoundary, uSmoothing, distance);\n"
98       "    }\n"
99       "\n"
100       "    // set fragment color\n"
101       "    color = vec4(rgb.rgb, alpha);\n"
102       "  }\n"
103       "\n"
104       "  else // (uDoShadow > 0.0)\n"
105       "  {\n"
106       "    mediump float shadowDistance = texture2D(sTexture, vTexCoord - uShadowOffset).a;\n"
107       "    mediump float inText = alphaFactor;\n"
108       "    mediump float inShadow = smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, shadowDistance);\n"
109       "\n"
110       "    // inside object, outside shadow\n"
111       "    if (inText == 1.0)\n"
112       "    {\n"
113       "      color = uColor;\n"
114       "    }\n"
115       "    // inside object, outside shadow\n"
116       "    else if ((inText != 0.0) && (inShadow == 0.0))\n"
117       "    {\n"
118       "      color = uColor;\n"
119       "      color.a *= inText;\n"
120       "    }\n"
121       "    // outside object, completely inside shadow\n"
122       "    else if ((inText == 0.0) && (inShadow == 1.0))\n"
123       "    {\n"
124       "      color = uShadowColor;\n"
125       "    }\n"
126       "    // inside object, completely inside shadow\n"
127       "    else if ((inText != 0.0) && (inShadow == 1.0))\n"
128       "    {\n"
129       "      color = mix(uShadowColor, uColor, inText);\n"
130       "      color.a = uShadowColor.a;\n"
131       "    }\n"
132       "    // inside object, inside shadow's border\n"
133       "    else if ((inText != 0.0) && (inShadow != 0.0))\n"
134       "    {\n"
135       "      color = mix(uShadowColor, uColor, inText);\n"
136       "      color.a *= max(inText, inShadow);\n"
137       "    }\n"
138       "    // inside shadow's border\n"
139       "    else if (inShadow != 0.0)\n"
140       "    {\n"
141       "      color = uShadowColor;\n"
142       "      color.a *= inShadow;\n"
143       "    }\n"
144       "    // outside shadow and object\n"
145       "    else \n"
146       "    {\n"
147       "      color.a = 0.0;\n"
148       "    }\n"
149       "\n"
150       "  }\n"
151       "\n"
152       "  gl_FragColor = color;\n"
153       "\n"
154       "}\n"
155   );
156
157   // Create the implementation, temporarily owned on stack
158   Dali::ShaderEffect shaderEffect =  Dali::ShaderEffect::NewWithPrefix(
159       "", "",
160       fragmentShaderPrefix, fragmentShader,
161       ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING));
162
163   shaderEffect.SetUniform("uSmoothing",0.5f);
164   shaderEffect.SetUniform("uOutlineColor",Color::BLACK);
165   shaderEffect.SetUniform("uOutlineParams",Vector2(0.51f, 0.0f));
166   shaderEffect.SetUniform("uGlowBoundary",0.4f);
167   shaderEffect.SetUniform("uGlowColor",Color::GREEN);
168   shaderEffect.SetUniform("uShadowColor",Vector4(0.0f, 0.0f, 0.0f, 0.4f));
169
170   // TODO: find a way to set the shadow offset in texel coordinates instead of UVs.
171   shaderEffect.SetUniform("uShadowOffset",Vector2(0.05f, 0.05f));
172
173   // Default:
174   shaderEffect.SetUniform("uDoOutline",false);
175   shaderEffect.SetUniform("uDoGlow",false);
176   shaderEffect.SetUniform("uDoShadow",false);
177
178   return shaderEffect;
179 }
180
181
182 } // namespace Toolkit
183
184 } // namespace Dali
185
186 #endif // __DALI_TOOLKIT_SHADER_EFFECT_SPOT_H__