(StyleManager) Stop throwing an exception if style-sheet not found
[platform/core/uifw/dali-toolkit.git] / optional / dali-toolkit / public-api / shader-effects / bubble-effect / bubble-effect.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "bubble-effect.h"
20
21 // EXTERNAL HEADERS
22 #include <sstream>
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/images/image.h>
25
26 namespace Dali
27 {
28
29 namespace Toolkit
30 {
31
32 namespace
33 {
34
35 const std::string MAGNIFICATIOB_PROPERTY_NAME( "uMagnification" );
36 const float EACH_WIDTH_PER_SHAPE(32.0f);
37
38 } // namespace
39
40 BubbleEffect::BubbleEffect()
41 : mNumberOfBubbles(0)
42 {
43 }
44
45 BubbleEffect::BubbleEffect( ShaderEffect handle )
46 : ShaderEffect( handle ),
47   mNumberOfBubbles(0)
48 {
49 }
50
51 BubbleEffect::~BubbleEffect()
52 {
53 }
54
55 BubbleEffect BubbleEffect::New( unsigned int numberOfBubble, const std::string& shapeImagePath)
56 {
57   std::ostringstream vertexShaderStringStream;
58   vertexShaderStringStream << "#define NUMBER_OF_BUBBLE "<< numberOfBubble << "\n";
59   std::string vertexShader(
60     // the gravity applied to the y direction
61     "  uniform float uGravity; \n"
62     // Width of the texture in pixels
63     "  uniform float uShapeWidth; \n"
64     // xy: the emit position of the bubble; zw: the destinationof the bubble.
65     // The bubble is moving from (xy) to (zw plus the y drop influenced by gravity).
66     "  uniform vec4 uStartAndEndPos[NUMBER_OF_BUBBLE];\n"
67     // The undergoing percentage of the bubble movement. 0.0: start from emit position, 1.0: reach the destination
68     "  uniform float uPercentage[NUMBER_OF_BUBBLE];\n"
69     "  uniform vec2 uInvertedMovementArea; \n"
70     // The bubble number is restricted by the available uniform num.
71     // To increase the displayed bubble, every uStartAndEndPos and uPercentage uniform is applied to a small bunch of bubbles (9 here)
72     // The offset defines the random offset between bubbles within the bunch.
73     "  uniform vec2 offset[9]; \n"
74     // This uniform is specially for increase part of the bubble size and spread the bubble to the whole screen when unlock to home screen
75     "  uniform float uMagnification; \n"
76     // This uniform is used to change the bubble size during running time
77     "  uniform float uDynamicScale; \n"
78     "  varying float vPercentage;\n"
79     "  varying vec2  vEffectTexCoord;\n"
80     "  void main()\n"
81     "  {\n"
82     "    mediump vec4 position = vec4( aPosition.xy, 0.0, 1.0 );\n"
83     // The Z coordinate is used to record the bubble index within current mesh actor
84     "    int zCoord = int(aPosition.z); \n"
85     // for some i between 0 ~ NUMBER_OF_BUBBLE-1: i,i+NUMBER_OF_BUBBLE, i+NUMBER_OF_BUBBLE*2, ... (up to i+NUMBER_OF_BUBBLE*8) belongs to the same bunch.
86     "    int groupIdx = zCoord / NUMBER_OF_BUBBLE;\n"
87     // The bubbles within the same bunch applies the same uniforms uStartAndEndPos[idx] & uPercentage[idx]
88     "    int idx = zCoord - groupIdx*NUMBER_OF_BUBBLE;\n"
89     // early out if uPercentage is (zero || one) setting position to zero (zero sized triangles)
90     "    if( uPercentage[idx] <= 0.0 || uPercentage[idx] >= 1.0 )\n"
91     "    {\n"
92     "      gl_Position = vec4(0.0);\n"
93     "      return;\n"
94     "    }\n"
95     "    vec4 startAndEnd = uStartAndEndPos[idx]; \n"
96     // The final position is added up different offset for bubbles
97     "    startAndEnd.zw += offset[groupIdx];\n"
98     // Notice: Only animate the uMagnification for unlock (bubble explosion animation)!
99     // In other cases, uMagnification = 1.0!
100     // Increase the Size of part of bubbles and increase the speed of movement for unlock.
101     // Performance acceptable: Branch on a uniform variable.
102     "    if( uMagnification > 1.0)\n"
103     "    {\n"
104     "      if(mod(aPosition.z,24.0) < 1.0 )\n"
105     "      {\n"
106     "        position.xy *= uMagnification;\n"
107     "      }\n"
108     "    }\n"
109     "    float percentage = uPercentage[idx]*min(uMagnification,2.5);\n"
110     "\n"
111     // increase the bubble size from 0% to 100% during the first 1/5 of movement & apply the dynamic scale
112     // the new xy value containes both the new scale and new bubble position
113     "    position.xy *= uDynamicScale*min(percentage*5.0, 1.0);\n"
114     "    position.xy += mix(startAndEnd.xy, startAndEnd.zw, percentage*uMagnification);\n"
115     // The gravity is g*t*t on the y direction
116     "    position.y += uGravity * pow(percentage, 2.0);\n"
117     "    gl_Position = uMvpMatrix * position;\n"
118     "\n"
119     // Add multiple bubble shapes in the effect
120     "    mediump float texCoordX = floor( mod(startAndEnd.z, uShapeWidth) );\n "
121     "    mediump float texCoordY = floor( mod(startAndEnd.w, uShapeWidth) );\n "
122     "    vTexCoord = vec2( (texCoordX + aTexCoord.x)/ uShapeWidth,(texCoordY + aTexCoord.y)/ uShapeWidth );\n"
123     "    vPercentage = percentage;\n"
124     // Use the emit position color for the bubble
125     "    vEffectTexCoord = startAndEnd.xy * uInvertedMovementArea;\n"
126     "  }\n" );
127   vertexShaderStringStream << vertexShader;
128
129   std::string fragmentShader(
130     "  varying float vPercentage;\n"
131     "  varying vec2  vEffectTexCoord;\n"
132     "\n"
133     "  void main()\n"
134     "  {\n"
135     // Get the emit pisition color, and Mix with the actor color
136     "    vec4 fragColor = texture2D(sEffect, vEffectTexCoord)*uColor;\n"
137     // Apply the shape defined by the texture contained in the material
138     // And make the opacity being 0.7, and animate from 0.7 to 0 during the last 1/5 of movement
139     "    fragColor.a  *= texture2D(sTexture, vTexCoord).a * ( 3.5 - max( vPercentage*3.5, 2.8 ) );\n"
140     "    gl_FragColor = fragColor;\n"
141     "  }\n");
142
143   ShaderEffect shaderEffect = ShaderEffect::New( vertexShaderStringStream.str(), fragmentShader,
144                                                  GeometryType( GEOMETRY_TYPE_TEXTURED_MESH),
145                                                  ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING ) );
146   BubbleEffect handle( shaderEffect );
147
148   handle.mNumberOfBubbles = numberOfBubble;
149   handle.SetMovementArea( Stage::GetCurrent().GetSize() );
150
151
152   handle.SetUniform( "uGravity", 50.f );
153   handle.SetUniform( "uMagnification", 1.f );
154   handle.SetUniform( "uDynamicScale", 1.f );
155
156   //Get pixel width of the shape
157   float width = Image::GetImageSize(shapeImagePath).width;
158   handle.SetUniform( "uShapeWidth", (width/EACH_WIDTH_PER_SHAPE) );
159
160   Vector4 zeroVector;
161   for( unsigned int i=0; i<numberOfBubble; i++ )
162   {
163     handle.SetPercentage( i, 0.f);
164     handle.SetStartAndEndPosition( i, zeroVector );
165   }
166
167   return handle;
168 }
169
170 void BubbleEffect::SetMovementArea( const Vector2& movementArea )
171 {
172   if( movementArea == mMovementArea )
173   {
174     return;
175   }
176
177   mMovementArea = movementArea;
178   SetUniform( "uInvertedMovementArea", Vector2(1.f,1.f) / mMovementArea );
179
180   srand(time(NULL));
181   int offset = mMovementArea.Length() / 10.f;
182   SetUniform("offset[0]", Vector2(0.f,0.f));
183   SetUniform("offset[1]", Vector2(rand()%offset,rand()%offset) );
184   SetUniform("offset[2]", Vector2(rand()%offset,-rand()%offset) );
185   SetUniform("offset[3]", Vector2(-rand()%offset,rand()%offset) );
186   SetUniform("offset[4]", Vector2(-rand()%offset,-rand()%offset) );
187   SetUniform("offset[5]", Vector2(rand()%offset,0.f));
188   SetUniform("offset[6]", Vector2(-rand()%offset,0.f));
189   SetUniform("offset[7]", Vector2(0.f,rand()%offset));
190   SetUniform("offset[8]", Vector2(0.f,-rand()%offset));
191 }
192
193 void BubbleEffect::SetStartAndEndPosition( unsigned int index, const Vector4& startAndEndPosition )
194 {
195   DALI_ASSERT_ALWAYS( index < mNumberOfBubbles );
196   std::ostringstream oss;
197   oss<< "uStartAndEndPos["<< index << "]";
198   SetUniform( oss.str(), startAndEndPosition );
199 }
200
201 void BubbleEffect::SetPercentage( unsigned int index, float percentage )
202 {
203   DALI_ASSERT_ALWAYS( index < mNumberOfBubbles );
204   SetUniform( GetPercentagePropertyName(index), percentage );
205 }
206
207 void BubbleEffect::SetGravity( float gravity )
208 {
209   SetUniform( "uGravity", gravity );
210 }
211
212 void BubbleEffect::SetShapeImageWidth( float imageWidth )
213 {
214   SetUniform( "uShapeWidth", (imageWidth/EACH_WIDTH_PER_SHAPE) );
215 }
216
217 void BubbleEffect::SetDynamicScale( float scale )
218 {
219   SetUniform( "uDynamicScale", scale );
220 }
221
222 void BubbleEffect::SetMagnification( float magnification )
223 {
224   SetUniform( MAGNIFICATIOB_PROPERTY_NAME, magnification );
225 }
226
227 std::string BubbleEffect::GetPercentagePropertyName( unsigned int index ) const
228 {
229   DALI_ASSERT_ALWAYS( index < mNumberOfBubbles );
230   std::ostringstream oss;
231   oss<< "uPercentage["<< index << "]";
232   return oss.str();
233 }
234
235 std::string BubbleEffect::GetMagnificationPropertyName() const
236 {
237   return MAGNIFICATIOB_PROPERTY_NAME;
238 }
239
240 void BubbleEffect::ResetParameters()
241 {
242   SetMagnification( 1.f );
243   Vector4 zeroVector;
244   for( unsigned int i=0; i<mNumberOfBubbles; i++ )
245   {
246     SetPercentage( i, 1.f);
247     SetStartAndEndPosition( i, zeroVector );
248   }
249 }
250
251
252 } // namespace Toolkit
253
254 } // namespace Dali