Revert "License conversion from Flora to Apache 2.0"
[platform/core/uifw/dali-toolkit.git] / optional / dali-toolkit / internal / shader-effects / water-effect-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include "water-effect-impl.h"
19
20 // EXTERNAL INCLUDES
21 #include <sstream>
22 #include <iomanip>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/public-api/shader-effects/water-effect.h>
26
27 namespace Dali
28 {
29
30 namespace Toolkit
31 {
32
33 namespace Internal
34 {
35
36 namespace
37 {
38
39 static const unsigned int LIGHT_MAP_SIZE = 512; ///< Size of the bitmap created for the pre-calculated wave function
40 static const float MAX_WAVE_RADIUS = 80.0f;     ///< Maximum radius of the wave in percentage of the texture coordinates
41
42 } // namespace
43
44 WaterEffect::WaterEffect( unsigned int numberOfWaves )
45 : mNumberOfWaves( numberOfWaves )
46 {
47 }
48
49 WaterEffect::~WaterEffect()
50 {
51 }
52
53 unsigned int WaterEffect::GetNumberOfWaves() const
54 {
55   return mNumberOfWaves;
56 }
57
58
59 Dali::Toolkit::WaterEffect WaterEffect::CreateShaderEffect( unsigned int numberOfWaves )
60 {
61   std::ostringstream vertexShaderStringStream;
62   vertexShaderStringStream << "#define NUMBER_OF_DROPS " << numberOfWaves << "\n";
63   vertexShaderStringStream << "#define MAX_WAVE_RADIUS " << std::setprecision(1) << MAX_WAVE_RADIUS << "\n";
64
65   std::string vertexShader(
66       "mediump vec4 position = vec4( aPosition, 1.0 );\n"
67       "\n"
68       "struct Drops\n"
69       "{\n"
70       "  mediump vec2 center;\n"
71       "  mediump float radius;\n"
72       "  mediump float amplitude;\n"
73       "};\n"
74       "uniform Drops uDrops[NUMBER_OF_DROPS];\n"
75       "varying mediump vec4 vColor;\n"
76       "void main()\n"
77       "{\n"
78       "  position = uModelView * position;\n"
79       "  mediump float refraction = 0.0;\n"
80       "  for (int i=0; i<NUMBER_OF_DROPS; ++i)\n"
81       "  {\n"
82       "    mediump float distance = distance( uDrops[i].center, position.xy );\n"
83       "    mediump float attenuation = clamp(distance / uDrops[i].radius, 0.0, 1.0) * 1.57;\n"
84       "    refraction += uDrops[i].amplitude * cos( (distance - uDrops[i].radius) *0.075 ) * cos(attenuation);\n"
85       "  }\n"
86       "  vColor = uColor + vec4(vec3(clamp(refraction, -0.1, 1.0)), 1.0);\n"
87       "  vTexCoord = aTexCoord + vec2( sin(refraction)/MAX_WAVE_RADIUS );\n"
88       "  gl_Position = uProjection * position;\n"
89       "}\n");
90   vertexShaderStringStream << vertexShader;
91
92   std::ostringstream fragmentShaderStringStream;
93
94   std::string fragmentShader(
95       "varying mediump vec4 vColor;\n"
96       "void main()\n"
97       "{\n"
98       "  gl_FragColor = texture2D( sTexture, vTexCoord)*vColor;\n"
99       "}\n");
100   fragmentShaderStringStream << fragmentShader;
101
102   // Create the implementation, temporarily owned on stack
103   ShaderEffect shaderEffect = ShaderEffect::New(
104       vertexShaderStringStream.str(),
105       fragmentShaderStringStream.str(),
106       GEOMETRY_TYPE_IMAGE,
107       ShaderEffect::HINT_GRID );
108
109   WaterEffect* shaderImpl = new WaterEffect( numberOfWaves );
110
111   Dali::Toolkit::WaterEffect handle = Dali::Toolkit::WaterEffect( shaderEffect, shaderImpl );
112
113   shaderImpl->Initialize( handle );
114
115   for ( unsigned int index = 0; index < shaderImpl->mNumberOfWaves; ++index )
116   {
117     handle.SetUniform( shaderImpl->GetAmplitudePropertyName( index ), 0.0f );
118     handle.SetUniform( shaderImpl->GetCenterPropertyName( index ), Vector2(0.0f, 0.0f), ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION );
119     handle.SetUniform( shaderImpl->GetPropagationPropertyName( index ), 0.0f );
120   }
121
122   return handle;
123 }
124
125 void WaterEffect::SetAmplitude( unsigned int index, float amplitude )
126 {
127   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
128   mShaderEffect.SetUniform( GetAmplitudePropertyName( index ), amplitude );
129 }
130
131 void WaterEffect::SetCenter( unsigned int index, const Vector2& center )
132 {
133   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
134   mShaderEffect.SetUniform( GetCenterPropertyName( index ), center, ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION );
135 }
136
137 void WaterEffect::SetPropagation( unsigned int index, float radius )
138 {
139   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
140   mShaderEffect.SetUniform( GetPropagationPropertyName( index ) , radius );
141 }
142
143 float WaterEffect::GetAmplitude( unsigned int index ) const
144 {
145   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
146   Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetAmplitudePropertyName( index ) );
147   return mShaderEffect.GetProperty( propertyIndex ).Get<float>();
148 }
149
150 Vector2 WaterEffect::GetCenter( unsigned int index ) const
151 {
152   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
153   Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetCenterPropertyName( index ) );
154   return mShaderEffect.GetProperty( propertyIndex ).Get<Vector2>();
155 }
156
157 float WaterEffect::GetPropagation( unsigned int index ) const
158 {
159   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
160   Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetPropagationPropertyName( index ) );
161   return mShaderEffect.GetProperty( propertyIndex ).Get<float>();
162 }
163
164 std::string WaterEffect::GetAmplitudePropertyName( unsigned int index ) const
165 {
166   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
167   std::ostringstream oss;
168   oss << "uDrops[" << index << "].amplitude";
169   return oss.str();
170 }
171
172 std::string WaterEffect::GetCenterPropertyName( unsigned int index ) const
173 {
174   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
175   std::ostringstream oss;
176   oss << "uDrops[" << index << "].center";
177   return oss.str();
178 }
179
180 std::string WaterEffect::GetPropagationPropertyName( unsigned int index ) const
181 {
182   DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
183   std::ostringstream oss;
184   oss << "uDrops[" << index << "].radius";
185   return oss.str();
186 }
187
188 void WaterEffect::Initialize( Dali::ShaderEffect shaderEffect )
189 {
190   // Save a reference to the shader handle
191   mShaderEffect = shaderEffect;
192 }
193
194 } // namespace Internal
195
196 } // namespace Toolkit
197
198 } // namespace Dali