2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
18 #include "water-effect-impl.h"
25 #include <dali-toolkit/public-api/shader-effects/water-effect.h>
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
44 WaterEffect::WaterEffect( unsigned int numberOfWaves )
45 : mNumberOfWaves( numberOfWaves )
49 WaterEffect::~WaterEffect()
53 unsigned int WaterEffect::GetNumberOfWaves() const
55 return mNumberOfWaves;
59 Dali::Toolkit::WaterEffect WaterEffect::CreateShaderEffect( unsigned int numberOfWaves )
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";
65 std::string vertexShader(
66 "mediump vec4 position = vec4( aPosition, 1.0 );\n"
70 " mediump vec2 center;\n"
71 " mediump float radius;\n"
72 " mediump float amplitude;\n"
74 "uniform Drops uDrops[NUMBER_OF_DROPS];\n"
75 "varying mediump vec4 vColor;\n"
78 " position = uModelView * position;\n"
79 " mediump float refraction = 0.0;\n"
80 " for (int i=0; i<NUMBER_OF_DROPS; ++i)\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"
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"
90 vertexShaderStringStream << vertexShader;
92 std::ostringstream fragmentShaderStringStream;
94 std::string fragmentShader(
95 "varying mediump vec4 vColor;\n"
98 " gl_FragColor = texture2D( sTexture, vTexCoord)*vColor;\n"
100 fragmentShaderStringStream << fragmentShader;
102 // Create the implementation, temporarily owned on stack
103 ShaderEffect shaderEffect = ShaderEffect::New(
104 vertexShaderStringStream.str(),
105 fragmentShaderStringStream.str(),
107 ShaderEffect::HINT_GRID );
109 WaterEffect* shaderImpl = new WaterEffect( numberOfWaves );
111 Dali::Toolkit::WaterEffect handle = Dali::Toolkit::WaterEffect( shaderEffect, shaderImpl );
113 shaderImpl->Initialize( handle );
115 for ( unsigned int index = 0; index < shaderImpl->mNumberOfWaves; ++index )
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 );
125 void WaterEffect::SetAmplitude( unsigned int index, float amplitude )
127 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
128 mShaderEffect.SetUniform( GetAmplitudePropertyName( index ), amplitude );
131 void WaterEffect::SetCenter( unsigned int index, const Vector2& center )
133 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
134 mShaderEffect.SetUniform( GetCenterPropertyName( index ), center, ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION );
137 void WaterEffect::SetPropagation( unsigned int index, float radius )
139 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
140 mShaderEffect.SetUniform( GetPropagationPropertyName( index ) , radius );
143 float WaterEffect::GetAmplitude( unsigned int index ) const
145 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
146 Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetAmplitudePropertyName( index ) );
147 return mShaderEffect.GetProperty( propertyIndex ).Get<float>();
150 Vector2 WaterEffect::GetCenter( unsigned int index ) const
152 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
153 Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetCenterPropertyName( index ) );
154 return mShaderEffect.GetProperty( propertyIndex ).Get<Vector2>();
157 float WaterEffect::GetPropagation( unsigned int index ) const
159 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
160 Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetPropagationPropertyName( index ) );
161 return mShaderEffect.GetProperty( propertyIndex ).Get<float>();
164 std::string WaterEffect::GetAmplitudePropertyName( unsigned int index ) const
166 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
167 std::ostringstream oss;
168 oss << "uDrops[" << index << "].amplitude";
172 std::string WaterEffect::GetCenterPropertyName( unsigned int index ) const
174 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
175 std::ostringstream oss;
176 oss << "uDrops[" << index << "].center";
180 std::string WaterEffect::GetPropagationPropertyName( unsigned int index ) const
182 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
183 std::ostringstream oss;
184 oss << "uDrops[" << index << "].radius";
188 void WaterEffect::Initialize( Dali::ShaderEffect shaderEffect )
190 // Save a reference to the shader handle
191 mShaderEffect = shaderEffect;
194 } // namespace Internal
196 } // namespace Toolkit