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