2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "bubble-effect.h"
23 #include <dali/public-api/common/stage.h>
24 #include <dali/public-api/images/image.h>
35 const std::string MAGNIFICATIOB_PROPERTY_NAME( "uMagnification" );
36 const float EACH_WIDTH_PER_SHAPE(32.0f);
40 BubbleEffect::BubbleEffect()
45 BubbleEffect::BubbleEffect( ShaderEffect handle )
46 : ShaderEffect( handle ),
51 BubbleEffect::~BubbleEffect()
55 BubbleEffect BubbleEffect::New( unsigned int numberOfBubble, const std::string& shapeImagePath)
57 std::ostringstream vertexShaderStringStream;
58 vertexShaderStringStream << "#define NUMBER_OF_BUBBLE "<< numberOfBubble << "\n";
59 std::string vertexShader(
60 " precision mediump float;\n"
61 // the gravity applied to the y direction
62 " uniform float uGravity; \n"
63 // Width of the texture in pixels
64 " uniform float uShapeWidth; \n"
65 // xy: the emit position of the bubble; zw: the destinationof the bubble.
66 // The bubble is moving from (xy) to (zw plus the y drop influenced by gravity).
67 " uniform vec4 uStartAndEndPos[NUMBER_OF_BUBBLE];\n"
68 // The undergoing percentage of the bubble movement. 0.0: start from emit position, 1.0: reach the destination
69 " uniform float uPercentage[NUMBER_OF_BUBBLE];\n"
70 " uniform vec2 uInvertedMovementArea; \n"
71 // The bubble number is restricted by the available uniform num.
72 // To increase the displayed bubble, every uStartAndEndPos and uPercentage uniform is applied to a small bunch of bubbles (9 here)
73 // The offset defines the random offset between bubbles within the bunch.
74 " uniform vec2 offset[9]; \n"
75 // This uniform is specially for increase part of the bubble size and spread the bubble to the whole screen when unlock to home screen
76 " uniform float uMagnification; \n"
77 // This uniform is used to change the bubble size during running time
78 " uniform float uDynamicScale; \n"
79 " varying float vPercentage;\n"
80 " varying vec2 vEffectTexCoord;\n"
83 " mediump vec4 position = vec4( aPosition.xy, 0.0, 1.0 );\n"
84 // The Z coordinate is used to record the bubble index within current mesh actor
85 " int zCoord = int(aPosition.z); \n"
86 // 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.
87 " int groupIdx = zCoord / NUMBER_OF_BUBBLE;\n"
88 // The bubbles within the same bunch applies the same uniforms uStartAndEndPos[idx] & uPercentage[idx]
89 " int idx = zCoord - groupIdx*NUMBER_OF_BUBBLE;\n"
90 // early out if uPercentage is (zero || one) setting position to zero (zero sized triangles)
91 " if( uPercentage[idx] <= 0.0 || uPercentage[idx] >= 1.0 )\n"
93 " gl_Position = vec4(0.0);\n"
96 " vec4 startAndEnd = uStartAndEndPos[idx]; \n"
97 // The final position is added up different offset for bubbles
98 " startAndEnd.zw += offset[groupIdx];\n"
99 // Notice: Only animate the uMagnification for unlock (bubble explosion animation)!
100 // In other cases, uMagnification = 1.0!
101 // Increase the Size of part of bubbles and increase the speed of movement for unlock.
102 // Performance acceptable: Branch on a uniform variable.
103 " if( uMagnification > 1.0)\n"
105 " if(mod(aPosition.z,24.0) < 1.0 )\n"
107 " position.xy *= uMagnification;\n"
110 " float percentage = uPercentage[idx]*min(uMagnification,2.5);\n"
112 // increase the bubble size from 0% to 100% during the first 1/5 of movement & apply the dynamic scale
113 // the new xy value containes both the new scale and new bubble position
114 " position.xy *= uDynamicScale*min(percentage*5.0, 1.0);\n"
115 " position.xy += mix(startAndEnd.xy, startAndEnd.zw, percentage*uMagnification);\n"
116 // The gravity is g*t*t on the y direction
117 " position.y += uGravity * pow(percentage, 2.0);\n"
118 " gl_Position = uMvpMatrix * position;\n"
120 // Add multiple bubble shapes in the effect
121 " mediump float texCoordX = floor( mod(startAndEnd.z, uShapeWidth) );\n "
122 " mediump float texCoordY = floor( mod(startAndEnd.w, uShapeWidth) );\n "
123 " vTexCoord = vec2( (texCoordX + aTexCoord.x)/ uShapeWidth,(texCoordY + aTexCoord.y)/ uShapeWidth );\n"
124 " vPercentage = percentage;\n"
125 // Use the emit position color for the bubble
126 " vEffectTexCoord = startAndEnd.xy * uInvertedMovementArea;\n"
128 vertexShaderStringStream << vertexShader;
130 std::string fragmentShader(
131 " precision mediump float;\n"
132 " varying float vPercentage;\n"
133 " varying vec2 vEffectTexCoord;\n"
137 // Get the emit pisition color, and Mix with the actor color
138 " vec4 fragColor = texture2D(sEffect, vEffectTexCoord)*uColor;\n"
139 // Apply the shape defined by the texture contained in the material
140 // And make the opacity being 0.7, and animate from 0.7 to 0 during the last 1/5 of movement
141 " fragColor.a *= texture2D(sTexture, vTexCoord).a * ( 3.5 - max( vPercentage*3.5, 2.8 ) );\n"
142 " gl_FragColor = fragColor;\n"
145 ShaderEffect shaderEffect = ShaderEffect::New(
146 vertexShaderStringStream.str(),
148 GeometryType( GEOMETRY_TYPE_TEXTURED_MESH),
149 ShaderEffect::GeometryHints( ShaderEffect::HINT_BLENDING ) );
151 BubbleEffect handle( shaderEffect );
153 handle.mNumberOfBubbles = numberOfBubble;
154 handle.SetMovementArea( Stage::GetCurrent().GetSize() );
156 handle.SetUniform( "uGravity", 50.f );
157 handle.SetUniform( "uMagnification", 1.f );
158 handle.SetUniform( "uDynamicScale", 1.f );
160 //Get pixel width of the shape
161 float width = Image::GetImageSize(shapeImagePath).width;
162 handle.SetUniform( "uShapeWidth", (width/EACH_WIDTH_PER_SHAPE) );
165 for( unsigned int i=0; i<numberOfBubble; i++ )
167 handle.SetPercentage( i, 0.f);
168 handle.SetStartAndEndPosition( i, zeroVector );
174 void BubbleEffect::SetMovementArea( const Vector2& movementArea )
176 if( movementArea == mMovementArea )
181 mMovementArea = movementArea;
182 SetUniform( "uInvertedMovementArea", Vector2(1.f,1.f) / mMovementArea );
185 int offset = mMovementArea.Length() / 10.f;
186 SetUniform("offset[0]", Vector2(0.f,0.f));
187 SetUniform("offset[1]", Vector2(rand()%offset,rand()%offset) );
188 SetUniform("offset[2]", Vector2(rand()%offset,-rand()%offset) );
189 SetUniform("offset[3]", Vector2(-rand()%offset,rand()%offset) );
190 SetUniform("offset[4]", Vector2(-rand()%offset,-rand()%offset) );
191 SetUniform("offset[5]", Vector2(rand()%offset,0.f));
192 SetUniform("offset[6]", Vector2(-rand()%offset,0.f));
193 SetUniform("offset[7]", Vector2(0.f,rand()%offset));
194 SetUniform("offset[8]", Vector2(0.f,-rand()%offset));
197 void BubbleEffect::SetStartAndEndPosition( unsigned int index, const Vector4& startAndEndPosition )
199 DALI_ASSERT_ALWAYS( index < mNumberOfBubbles );
200 std::ostringstream oss;
201 oss<< "uStartAndEndPos["<< index << "]";
202 SetUniform( oss.str(), startAndEndPosition );
205 void BubbleEffect::SetPercentage( unsigned int index, float percentage )
207 DALI_ASSERT_ALWAYS( index < mNumberOfBubbles );
208 SetUniform( GetPercentagePropertyName(index), percentage );
211 void BubbleEffect::SetGravity( float gravity )
213 SetUniform( "uGravity", gravity );
216 void BubbleEffect::SetShapeImageWidth( float imageWidth )
218 SetUniform( "uShapeWidth", (imageWidth/EACH_WIDTH_PER_SHAPE) );
221 void BubbleEffect::SetDynamicScale( float scale )
223 SetUniform( "uDynamicScale", scale );
226 void BubbleEffect::SetMagnification( float magnification )
228 SetUniform( MAGNIFICATIOB_PROPERTY_NAME, magnification );
231 std::string BubbleEffect::GetPercentagePropertyName( unsigned int index ) const
233 DALI_ASSERT_ALWAYS( index < mNumberOfBubbles );
234 std::ostringstream oss;
235 oss<< "uPercentage["<< index << "]";
239 std::string BubbleEffect::GetMagnificationPropertyName() const
241 return MAGNIFICATIOB_PROPERTY_NAME;
244 void BubbleEffect::ResetParameters()
246 SetMagnification( 1.f );
248 for( unsigned int i=0; i<mNumberOfBubbles; i++ )
250 SetPercentage( i, 1.f);
251 SetStartAndEndPosition( i, zeroVector );
256 } // namespace Toolkit