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 "water-effect-impl.h"
26 #include <dali-toolkit/devel-api/shader-effects/water-effect.h>
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
45 WaterEffect::WaterEffect( unsigned int numberOfWaves )
46 : mNumberOfWaves( numberOfWaves )
50 WaterEffect::~WaterEffect()
54 unsigned int WaterEffect::GetNumberOfWaves() const
56 return mNumberOfWaves;
60 Dali::Toolkit::WaterEffect WaterEffect::CreateShaderEffect( unsigned int numberOfWaves )
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";
66 std::string vertexShader(
67 "mediump vec4 position = vec4( aPosition, 1.0 );\n"
71 " mediump vec2 center;\n"
72 " mediump float radius;\n"
73 " mediump float amplitude;\n"
75 "uniform Drops uDrops[NUMBER_OF_DROPS];\n"
76 "varying mediump vec4 vColor;\n"
79 " position = uModelView * position;\n"
80 " mediump float refraction = 0.0;\n"
81 " for (int i=0; i<NUMBER_OF_DROPS; ++i)\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"
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"
91 vertexShaderStringStream << vertexShader;
93 std::ostringstream fragmentShaderStringStream;
95 std::string fragmentShader(
96 "varying mediump vec4 vColor;\n"
99 " gl_FragColor = texture2D( sTexture, vTexCoord)*vColor;\n"
101 fragmentShaderStringStream << fragmentShader;
103 // Create the implementation, temporarily owned on stack
104 ShaderEffect shaderEffect = ShaderEffect::New(
105 vertexShaderStringStream.str(),
106 fragmentShaderStringStream.str(),
108 ShaderEffect::HINT_GRID );
110 WaterEffect* shaderImpl = new WaterEffect( numberOfWaves );
112 Dali::Toolkit::WaterEffect handle = Dali::Toolkit::WaterEffect( shaderEffect, shaderImpl );
114 shaderImpl->Initialize( handle );
116 for ( unsigned int index = 0; index < shaderImpl->mNumberOfWaves; ++index )
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 );
126 void WaterEffect::SetAmplitude( unsigned int index, float amplitude )
128 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
129 mShaderEffect.SetUniform( GetAmplitudePropertyName( index ), amplitude );
132 void WaterEffect::SetCenter( unsigned int index, const Vector2& center )
134 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
135 mShaderEffect.SetUniform( GetCenterPropertyName( index ), center, ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION );
138 void WaterEffect::SetPropagation( unsigned int index, float radius )
140 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
141 mShaderEffect.SetUniform( GetPropagationPropertyName( index ) , radius );
144 float WaterEffect::GetAmplitude( unsigned int index ) const
146 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
147 Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetAmplitudePropertyName( index ) );
148 return mShaderEffect.GetProperty( propertyIndex ).Get<float>();
151 Vector2 WaterEffect::GetCenter( unsigned int index ) const
153 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
154 Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetCenterPropertyName( index ) );
155 return mShaderEffect.GetProperty( propertyIndex ).Get<Vector2>();
158 float WaterEffect::GetPropagation( unsigned int index ) const
160 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
161 Property::Index propertyIndex = mShaderEffect.GetPropertyIndex( GetPropagationPropertyName( index ) );
162 return mShaderEffect.GetProperty( propertyIndex ).Get<float>();
165 std::string WaterEffect::GetAmplitudePropertyName( unsigned int index ) const
167 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
168 std::ostringstream oss;
169 oss << "uDrops[" << index << "].amplitude";
173 std::string WaterEffect::GetCenterPropertyName( unsigned int index ) const
175 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
176 std::ostringstream oss;
177 oss << "uDrops[" << index << "].center";
181 std::string WaterEffect::GetPropagationPropertyName( unsigned int index ) const
183 DALI_ASSERT_ALWAYS( index < mNumberOfWaves );
184 std::ostringstream oss;
185 oss << "uDrops[" << index << "].radius";
189 void WaterEffect::Initialize( Dali::ShaderEffect shaderEffect )
191 // Save a reference to the shader handle
192 mShaderEffect = shaderEffect;
195 } // namespace Internal
197 } // namespace Toolkit