diff --git a/demo/dali-demo.cpp b/demo/dali-demo.cpp index 379758f..70da658 100644 --- a/demo/dali-demo.cpp +++ b/demo/dali-demo.cpp @@ -44,6 +44,8 @@ int DALI_EXPORT_API main(int argc, char **argv) demo.AddExample(Example("fpp-game.example", DALI_DEMO_STR_TITLE_FPP_GAME)); demo.AddExample(Example("item-view.example", DALI_DEMO_STR_TITLE_ITEM_VIEW)); demo.AddExample(Example("mesh-visual.example", DALI_DEMO_STR_TITLE_MESH_VISUAL)); + demo.AddExample(Example("metaball-explosion.example", DALI_DEMO_STR_TITLE_METABALL_EXPLOSION)); + demo.AddExample(Example("metaball-refrac.example", DALI_DEMO_STR_TITLE_METABALL_REFRAC)); demo.AddExample(Example("motion-blur.example", DALI_DEMO_STR_TITLE_MOTION_BLUR)); demo.AddExample(Example("refraction-effect.example", DALI_DEMO_STR_TITLE_REFRACTION)); demo.AddExample(Example("renderer-stencil.example", DALI_DEMO_STR_TITLE_RENDERER_STENCIL)); diff --git a/examples/image-view-url/image-view-url-example.cpp b/examples/image-view-url/image-view-url-example.cpp index 59ebda9..624709e 100644 --- a/examples/image-view-url/image-view-url-example.cpp +++ b/examples/image-view-url/image-view-url-example.cpp @@ -139,7 +139,7 @@ private: Pixel::RGB888, unsigned(TARGET_SIZE.width), unsigned(TARGET_SIZE.height)); - auto framebuffer = FrameBuffer::New(TARGET_SIZE.width, TARGET_SIZE.height, Pixel::RGB888); + auto framebuffer = FrameBuffer::New(TARGET_SIZE.width, TARGET_SIZE.height, FrameBuffer::Attachment::NONE ); framebuffer.AttachColorTexture(mOutputTexture); renderTask.SetFrameBuffer(framebuffer); diff --git a/examples/layouting/animation-example.cpp b/examples/layouting/animation-example.cpp index a3f2dac..3b2c0a9 100644 --- a/examples/layouting/animation-example.cpp +++ b/examples/layouting/animation-example.cpp @@ -17,6 +17,7 @@ #include #include "animation-example.h" +#include #include #include #include @@ -65,15 +66,17 @@ void CreateChild( ImageView& child, int index, Size size ) { child = ImageView::New(); Property::Map imagePropertyMap; - imagePropertyMap[ Toolkit::Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; - imagePropertyMap[ Toolkit::ImageVisual::Property::URL ] = IMAGE_PATH[ index ]; + imagePropertyMap[ Visual::Property::TYPE ] = Toolkit::Visual::IMAGE; + imagePropertyMap[ ImageVisual::Property::URL ] = IMAGE_PATH[ index ]; imagePropertyMap[ ImageVisual::Property::DESIRED_WIDTH ] = size.width; imagePropertyMap[ ImageVisual::Property::DESIRED_HEIGHT ] = size.height; + imagePropertyMap[ ImageVisual::Property::FITTING_MODE ] = FittingMode::SCALE_TO_FILL; child.SetProperty( Toolkit::ImageView::Property::IMAGE, imagePropertyMap ); std::string name = "ImageView"; name.append( 1, '0' + index ); child.SetName( name ); - child.SetAnchorPoint( AnchorPoint::TOP_LEFT ); + child.SetAnchorPoint( AnchorPoint::CENTER ); + child.SetProperty( DevelActor::Property::POSITION_USES_ANCHOR_POINT, false ); } // Create set layout transition. A parent opacity increases 'ease in out' from semi-transparent to fully opaque and children pulse in order @@ -93,6 +96,19 @@ LayoutTransitionData CreateOnSetLayoutTransition( Control& container ) // Apply to parent only layoutTransitionData.AddPropertyAnimator( container, map ); + // Reset scale after possible focus animation + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + + // Children pulses in/out for( size_t i = 0; i < container.GetChildCount(); i++ ) { Property::Map map; @@ -106,6 +122,18 @@ LayoutTransitionData CreateOnSetLayoutTransition( Control& container ) layoutTransitionData.AddPropertyAnimator( container.GetChildAt( i ), map ); } + // Children move + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + return layoutTransitionData; } @@ -124,13 +152,25 @@ LayoutTransitionData CreateOnChildAddTransition( Control& parent ) .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); layoutTransitionData.AddPropertyAnimator( parent, map ); + // Reset scale after possible focus animation + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + // New child is growing { Property::Map map; map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_ADD; - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; - map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3( 0.0f, 0.0f, 0 ); - map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f, 100.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::INITIAL_VALUE ] = Vector3::ZERO; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE; map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR ) .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() @@ -152,6 +192,18 @@ LayoutTransitionData CreateOnChildAddTransition( Control& parent ) layoutTransitionData.AddPropertyAnimator( Actor(), map ); } + // Other just move + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + return layoutTransitionData; } @@ -160,56 +212,112 @@ LayoutTransitionData CreateOnChildRemoveTransition( Control& container ) { auto layoutTransitionData = LayoutTransitionData::New(); - // Apply animation to remaining children - Property::Map map; - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; - map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() - .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::SIN ) - .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() - .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) - .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); - layoutTransitionData.AddPropertyAnimator( Actor(), map ); + // Reset scale after possible focus animation + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + + // Apply animation to remaining children - sin shaking + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::SIN ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + + // Add a linear to reduce a linear to half + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::ALPHA_FUNCTION, AlphaFunction::LINEAR ) + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f)); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } return layoutTransitionData; } -// Create child focus transition. A focus gained child grows 115% and focus lost child gets its original size back -LayoutTransitionData CreateOnChildFocusTransition( Control& parent ) +// Create child focus transition. A focus gained child grows 120% and focus lost child gets its original size back +LayoutTransitionData CreateOnChildFocusTransition( Control& parent, bool affectsSiblings ) { auto layoutTransitionData = LayoutTransitionData::New(); + // Focus gain child animation { Property::Map map; map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_FOCUS_GAINED; - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; - map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 115.0f, 115.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS ] = affectsSiblings; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 1.2f, 1.2f, 1.0f ); map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, LayoutTransitionData::Animator::ANIMATE_TO ) .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); layoutTransitionData.AddPropertyAnimator( Actor(), map ); } + // Focus lost child animation { Property::Map map; map[ LayoutTransitionData::AnimatorKey::CONDITION ] = LayoutTransitionData::Condition::ON_FOCUS_LOST; - map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; - map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 100.0f, 100.0f, 0 ); + map[ LayoutTransitionData::AnimatorKey::AFFECTS_SIBLINGS ] = affectsSiblings; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3( 1.0f, 1.0f, 1.0f ); map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TYPE, LayoutTransitionData::Animator::ANIMATE_TO ) .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); layoutTransitionData.AddPropertyAnimator( Actor(), map ); } + // Linear children positioning + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Property::Value(); + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); + layoutTransitionData.AddPropertyAnimator( Actor(), map ); + } + return layoutTransitionData; } // An example of custom default transition, ease in for position animation, ease out for size animation -LayoutTransitionData CreateCustomDefaultTransition( Control& parent ) +LayoutTransitionData CreateCustomDefaultTransition( Control& control ) { auto layoutTransitionData = LayoutTransitionData::New(); + // Resets control scale after possible focus animation + { + Property::Map map; + map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SCALE; + map[ LayoutTransitionData::AnimatorKey::TARGET_VALUE ] = Vector3::ONE; + map[ LayoutTransitionData::AnimatorKey::ANIMATOR ] = Property::Map() + .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() + .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) + .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.0f ) ); + layoutTransitionData.AddPropertyAnimator( control, map ); + } + // Moves control ease in { Property::Map map; map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::POSITION; @@ -218,9 +326,10 @@ LayoutTransitionData CreateCustomDefaultTransition( Control& parent ) .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); - layoutTransitionData.AddPropertyAnimator( parent, map ); + layoutTransitionData.AddPropertyAnimator( control, map ); } + // Sizes control ease out { Property::Map map; map[ LayoutTransitionData::AnimatorKey::PROPERTY ] = Actor::Property::SIZE; @@ -229,7 +338,7 @@ LayoutTransitionData CreateCustomDefaultTransition( Control& parent ) .Add( LayoutTransitionData::AnimatorKey::TIME_PERIOD, Property::Map() .Add( LayoutTransitionData::AnimatorKey::DELAY, 0.0f ) .Add( LayoutTransitionData::AnimatorKey::DURATION, 0.5f ) ); - layoutTransitionData.AddPropertyAnimator( parent, map ); + layoutTransitionData.AddPropertyAnimator( control, map ); } return layoutTransitionData; @@ -318,16 +427,16 @@ void AnimationExample::Create() mHorizontalLayout.SetOrientation( LinearLayout::Orientation::HORIZONTAL ); mHorizontalLayout.SetAlignment( LinearLayout::Alignment::CENTER_HORIZONTAL | LinearLayout::Alignment::CENTER_VERTICAL ); mHorizontalLayout.SetAnimateLayout(true); - mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer ) ); + mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer, true ) ); mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, CreateOnChildRemoveTransition( mAnimationContainer ) ); mHorizontalLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, CreateOnChildAddTransition( mAnimationContainer ) ); DevelControl::SetLayout( mAnimationContainer, mHorizontalLayout ); mGridLayout = Grid::New(); - mGridLayout.SetAnimateLayout(true); - mGridLayout.SetNumberOfColumns(2); - mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer ) ); + mGridLayout.SetAnimateLayout( true ); + mGridLayout.SetNumberOfColumns( 2 ); + mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer, false ) ); mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_REMOVE, CreateOnChildRemoveTransition( mAnimationContainer ) ); mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_ADD, CreateOnChildAddTransition( mAnimationContainer ) ); @@ -335,8 +444,7 @@ void AnimationExample::Create() stage.Add( mAnimationContainer ); } -// Remove controls added by this example from stage mGridLayout.SetTransitionData( LayoutTransitionData::ON_CHILD_FOCUS, CreateOnChildFocusTransition( mAnimationContainer ) ); - +// Remove controls added by this example from stage void AnimationExample::Remove() { if ( mAnimationContainer ) diff --git a/examples/metaball-explosion/metaball-explosion-example.cpp b/examples/metaball-explosion/metaball-explosion-example.cpp new file mode 100644 index 0000000..a7fdd82 --- /dev/null +++ b/examples/metaball-explosion/metaball-explosion-example.cpp @@ -0,0 +1,697 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include // uint32_t, uint16_t etc + +#include +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include "shared/utility.h" // DemoHelper::LoadTexture + +using namespace Dali; + +namespace // unnamed namespace for constants +{ +// background image +const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" ); + +// number of metaballs +constexpr uint32_t METABALL_NUMBER = 6; + +/** + * Vertex shader code for metaball + */ +const char* const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER ( + attribute mediump vec2 aPosition;\n + attribute mediump vec2 aTexture;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform lowp vec4 uColor;\n + varying mediump vec2 vTexCoord;\n + + void main()\n + {\n + vTexCoord = aTexture;\n + mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n + gl_Position = uMvpMatrix * vertexPosition;\n + }\n +); + +/** + * Fragment shader code for metaball + */ +const char* const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER ( + precision mediump float;\n + varying vec2 vTexCoord;\n + uniform vec2 uPositionMetaball;\n + uniform vec2 uPositionVar;\n + uniform vec2 uGravityVector;\n + uniform float uRadius;\n + uniform float uRadiusVar;\n + void main()\n + {\n + vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n + vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n + \n + float finalRadius = uRadius + uRadiusVar;\n + vec2 distanceVec = adjustedCoords - finalMetaballPosition;\n + float result = dot(distanceVec, distanceVec);\n + float color = inversesqrt(result) * finalRadius;\n + \n + gl_FragColor = vec4(color,color,color,1.0);\n + }\n +); + +/** + * Fragment shader code for metaball and background composition with refraction effect + */ +const char* const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER ( + precision highp float;\n + varying vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform sampler2D sEffect;\n + uniform vec2 uPositionMetaball;\n + void main()\n + {\n + vec2 zoomCoords;\n + vec3 normal = vec3(0.0,0.0,1.0);\n + vec2 fakePos = vec2(0.0,0.0);\n + vec3 color = vec3(1.0, 1.0, 1.0); + float ambient = 0.2; + \n + vec4 metaColor = texture2D(sEffect, vTexCoord);\n + \n + vec2 adjustedCoords = vTexCoord.xy * vec2(2.0) - vec2(1.0);\n + fakePos = adjustedCoords.xy - vec2(uPositionMetaball.x, -uPositionMetaball.y); + float len = length(fakePos) + 0.01;\n + vec3 colorPos = vec3(0,0,1); + \n + if (metaColor.r > 0.85)\n + {\n + zoomCoords = ((vTexCoord - 0.5) * 0.9);\n + zoomCoords = zoomCoords + 0.5;\n + \n + float interpNormal = mix(0.7, 1.0, (metaColor.r - 0.85) * 4.);\n + normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n + normal.xyz = normalize(normal.xyz);\n + color = vec3(0.65, 1.0, 0);\n + colorPos = vec3(fakePos.x,fakePos.y,0); + }\n + else if (metaColor.r > 0.75)\n + {\n + float interpolation = mix(0.9, 1.15, (0.85 - metaColor.r) * 10.0);\n + zoomCoords = ((vTexCoord - 0.5) * interpolation);\n + zoomCoords = zoomCoords + 0.5;\n + \n + float interpNormal = mix(0.7, 0.0, (0.85 - metaColor.r) * 10.0);\n + normal.xyz = vec3(fakePos.x * (1.0 - interpNormal) / len, fakePos.y * (1.0 - interpNormal) / len, interpNormal);\n + normal.xyz = normalize(normal.xyz);\n + color = vec3(0.65, 1.0, 0);\n + colorPos = vec3(fakePos.x,fakePos.y,0); + }\n + else\n + {\n + zoomCoords = vTexCoord;\n + normal = vec3(0,0,0);\n + ambient = 0.5;\n + }\n + \n + vec3 lightPosition = vec3(-750.0,-1000.0,2000.0);\n + vec3 vertex = vec3(adjustedCoords.x,adjustedCoords.y,0.0);\n + \n + vec3 vecToLight = normalize( lightPosition - vertex );\n + \n + float lightDiffuse = dot( vecToLight, normal );\n + lightDiffuse = max(0.0,lightDiffuse);\n + lightDiffuse = lightDiffuse * 0.5 + 0.5; + \n + vec3 vertexToEye = vec3(0,0,1) - vertex;\n + vertexToEye = normalize(vertexToEye); + vec3 lightReflect = normalize(reflect(-vecToLight, normal));\n + float specularFactor = max(0.0,dot(vertexToEye, lightReflect));\n + specularFactor = pow(specularFactor, 32.0) * 0.7; + \n + vec4 texColor = texture2D(sTexture, zoomCoords);\n + gl_FragColor.rgb = texColor.rgb * ambient + color.rgb * texColor.rgb * lightDiffuse + vec3(specularFactor);\n + gl_FragColor.a = 1.0; + }\n + ); + +/** + * Metadata for each ball + */ +struct MetaballInfo +{ + Actor actor; + Vector2 position; + float radius; + float initRadius; + + //new shader stuff + Property::Index positionIndex; + Property::Index positionVarIndex; +}; + +} // unnamed namespace + +/** + * Demo using Metaballs + * + * When the metaball is clicked it explodes to smaller balls + */ +class MetaballExplosionController : public ConnectionTracker +{ +public: + + /** + * Constructor + * @param application + */ + MetaballExplosionController( Application& application ); + + /** + * Destructor + */ + virtual ~MetaballExplosionController(); + + /** + * Creates the metaballs and initializes the scene + */ + void Create( Application& app ); + + /** + * Touch event handler to center metaballs at touch position + * and start explosion animation on release + */ + bool OnTouch( Actor actor, const TouchData& touch ); + + /** + * Key event handler to quit application on escape or back key + */ + void OnKeyEvent(const KeyEvent& event); + +private: // Data + + Application& mApplication; + Vector2 mScreenSize; + + Texture mBackgroundTexture; + FrameBuffer mMetaballFBO; + Texture mMetaballFBOTexture; + + Actor mMetaballRoot; + MetaballInfo mMetaballs[METABALL_NUMBER]; + + Property::Index mPositionIndex; + Actor mCompositionActor; + + //Motion + Vector2 mCurrentTouchPosition; + Vector2 mMetaballPosVariation; + Vector2 mMetaballPosVariationFrom; + Vector2 mMetaballPosVariationTo; + Vector2 mMetaballCenter; + + //Animations + Animation mPositionVarAnimation[METABALL_NUMBER]; + + uint32_t mDispersion; + Animation mDispersionAnimation[METABALL_NUMBER]; + + Timer mTimerDispersion; + + float mTimeMultiplier; + + // Private helper functions + + /** + * Create a mesh data with the geometry for the metaball rendering + * @param aspectMappedTexture whether texture coords should be mapped based on aspect ratio + */ + Geometry CreateGeometry( bool aspectMappedTexture = true ); + + /** + * Create a actors and renderers for the metaballs + */ + void CreateMetaballActors(); + + /** + * Create the render task and FBO to render the metaballs into a texture + */ + void CreateMetaballImage(); + + /** + * Create the the final composition + */ + void CreateComposition(); + + /** + * Function to create animations for the small variations of position inside the metaball + */ + void CreateAnimations(); + + /** + * Function to reset metaball state + */ + void ResetMetaballs( bool resetAnims ); + + /** + * Function to create disperse each of the ball that compose the metaball when exploding + */ + void DisperseBallAnimation( uint32_t ball ); + + /** + * Function to make metaballs come back to reset position + */ + void LaunchResetMetaballPosition( Animation& source ); + + /** + * Function to set things at the end of the animation + */ + void EndDisperseAnimation( Animation& source ); + + /** + * Function to init dispersion of the metaballs one by one using a timer + * (so not all the balls begin moving at the same time) + */ + bool OnTimerDispersionTick(); + + /** + * Function to set the actual position of the metaballs when the user clicks the screen + */ + void SetPositionToMetaballs( const Vector2& metaballCenter ); +}; + +/** + * Implementation + */ + +MetaballExplosionController::MetaballExplosionController( Application& application ) +: mApplication( application ), + mScreenSize(), + mBackgroundTexture(), + mMetaballFBO(), + mMetaballFBOTexture(), + mMetaballRoot(), + mMetaballs(), + mPositionIndex(), + mCompositionActor(), + mCurrentTouchPosition(), + mMetaballPosVariation(), + mMetaballPosVariationFrom(), + mMetaballPosVariationTo(), + mMetaballCenter(), + mPositionVarAnimation(), + mDispersion( 0 ), + mDispersionAnimation(), + mTimerDispersion(), + mTimeMultiplier( 1.0f ) +{ + // Connect to the Application's Init signal + mApplication.InitSignal().Connect( this, &MetaballExplosionController::Create ); +} + +MetaballExplosionController::~MetaballExplosionController() +{ + // Nothing to do here; +} + +void MetaballExplosionController::Create( Application& app ) +{ + Stage stage = Stage::GetCurrent(); + + stage.KeyEventSignal().Connect( this, &MetaballExplosionController::OnKeyEvent ); + + mScreenSize = stage.GetSize(); + + mTimeMultiplier = 1.0f; + + stage.SetBackgroundColor(Color::BLACK); + + // Load background texture + mBackgroundTexture = DemoHelper::LoadTexture( BACKGROUND_IMAGE ); + + srand( static_cast( time(0) ) ); + + //Create internal data + CreateMetaballActors(); + CreateMetaballImage(); + CreateComposition(); + + CreateAnimations(); + + mDispersion = 0; + mTimerDispersion = Timer::New( 150 ); + mTimerDispersion.TickSignal().Connect( this, &MetaballExplosionController::OnTimerDispersionTick ); + + // Connect the callback to the touch signal on the mesh actor + stage.GetRootLayer().TouchSignal().Connect( this, &MetaballExplosionController::OnTouch ); +} + +Geometry MetaballExplosionController::CreateGeometry( bool aspectMappedTexture ) +{ + const float aspect = mScreenSize.y / mScreenSize.x; + + // Create vertices and specify their color + const float xsize = mScreenSize.x * 0.5; + + // Create the meshdata for the metaballs + struct VertexPosition { Vector2 position; }; + struct VertexTexture { Vector2 texture; }; + + VertexPosition vertices[] = + { + { Vector2( -xsize, -xsize * aspect ) }, + { Vector2( xsize, -xsize * aspect ) }, + { Vector2( -xsize, xsize * aspect ) }, + { Vector2( xsize, xsize * aspect ) } + }; + + const float textureAspect = (aspectMappedTexture) ? aspect : 1.0f; + VertexTexture textures[] = + { + { Vector2( 0.0f, 0.0f ) }, + { Vector2( 1.0f, 0.0f ) }, + { Vector2( 0.0f, 1.0f * textureAspect ) }, + { Vector2( 1.0f, 1.0f * textureAspect ) } + }; + + uint32_t numberOfVertices = sizeof(vertices)/sizeof(VertexPosition); + + // Vertices + Property::Map positionVertexFormat; + positionVertexFormat["aPosition"] = Property::VECTOR2; + PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat ); + positionVertices.SetData( vertices, numberOfVertices ); + + // Textures + Property::Map textureVertexFormat; + textureVertexFormat["aTexture"] = Property::VECTOR2; + PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat ); + textureVertices.SetData( textures, numberOfVertices ); + + // Indices + const uint16_t indices[] = { 0, 3, 1, 0, 2, 3 }; + + // Create the geometry object + Geometry texturedQuadGeometry = Geometry::New(); + texturedQuadGeometry.AddVertexBuffer( positionVertices ); + texturedQuadGeometry.AddVertexBuffer( textureVertices ); + + texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) ); + + return texturedQuadGeometry; +} + +void MetaballExplosionController::CreateMetaballActors() +{ + // Create the shader for the metaballs, tell DALi that shader modifies geometry so we dont need to set a meaningless size + Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER, Shader::Hint::MODIFIES_GEOMETRY ); + + Geometry metaballGeom = CreateGeometry(); + // Reuse same renderer for each actor + Renderer renderer = Renderer::New( metaballGeom, shader ); + renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE ); + + //Initialization of each of the metaballs + for( uint32_t i = 0; i < METABALL_NUMBER; i++ ) + { + mMetaballs[i].position = Vector2(0.0f, 0.0f); + mMetaballs[i].radius = mMetaballs[i].initRadius = Random::Range(0.05f,0.07f); + + mMetaballs[i].actor = Actor::New( ); + mMetaballs[i].actor.SetName( "Metaball" ); + mMetaballs[i].actor.SetScale( 1.0f ); + mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER ); + mMetaballs[i].actor.AddRenderer( renderer ); + + mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position ); + + mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) ); + + mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(Random::Range(-0.2,0.2),Random::Range(-0.2,0.2)) ); + mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius ); + mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f ); + } + + // Root creation + mMetaballRoot = Actor::New(); + mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER ); + for( uint32_t i = 0; i < METABALL_NUMBER; i++ ) + { + mMetaballRoot.Add( mMetaballs[i].actor ); + } + +} + +void MetaballExplosionController::CreateMetaballImage() +{ + // Create an FBO and a render task to create to render the metaballs with a fragment shader + Stage stage = Stage::GetCurrent(); + + mMetaballFBO = FrameBuffer::New( mScreenSize.x, mScreenSize.y, FrameBuffer::Attachment::NONE ); + mMetaballFBOTexture = Texture::New( Dali::TextureType::TEXTURE_2D, + Pixel::RGB888, + mScreenSize.x, mScreenSize.y ); + mMetaballFBO.AttachColorTexture( mMetaballFBOTexture ); + + stage.Add(mMetaballRoot); + + // Create the render task used to render the metaballs + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); + RenderTask task = taskList.CreateTask(); + task.SetRefreshRate( RenderTask::REFRESH_ALWAYS ); + task.SetSourceActor( mMetaballRoot ); + task.SetExclusive( true ); + task.SetClearColor( Color::BLACK ); + task.SetClearEnabled( true ); + task.SetFrameBuffer( mMetaballFBO ); +} + +void MetaballExplosionController::CreateComposition() +{ + //Create new shader + Shader shader = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER ); + + // Create new texture set + auto textureSet = TextureSet::New(); + textureSet.SetTexture( 0u, mBackgroundTexture ); + textureSet.SetTexture( 1u, mMetaballFBOTexture ); + + // Create geometry + Geometry metaballGeom = CreateGeometry( false ); + + Renderer mRenderer = Renderer::New( metaballGeom, shader ); + mRenderer.SetTextures( textureSet ); + + // Create actor + mCompositionActor = Actor::New( ); + mCompositionActor.SetParentOrigin(ParentOrigin::CENTER); + mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f)); + mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y); + mCompositionActor.AddRenderer( mRenderer ); + + Vector2 metaballCenter(0.0,0); + metaballCenter.x = metaballCenter.x * 0.5; + metaballCenter.y = metaballCenter.y * 0.5; + mPositionIndex = mCompositionActor.RegisterProperty( "uPositionMetaball", metaballCenter ); + + SetPositionToMetaballs( metaballCenter ); + + mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y); + + Stage stage = Stage::GetCurrent(); + stage.Add( mCompositionActor ); +} + +void MetaballExplosionController::CreateAnimations() +{ + Vector2 direction; + + for( uint32_t i = 0; i < METABALL_NUMBER; i++ ) + { + KeyFrames keySinCosVariation = KeyFrames::New(); + Vector2 sinCosVariation( 0,0 ); + + direction.x = Random::Range( -100.f,100.f ); + direction.y = Random::Range( -100.f,100.f ); + + direction.Normalize(); + direction *= 0.1f; + + for( uint32_t j = 0; j < 360; j++ ) + { + sinCosVariation.x = sinf( j * Math::PI/180.f ) * direction.x; + sinCosVariation.y = cosf( j * Math::PI/180.f ) * direction.y; + float key = j/360.f; + keySinCosVariation.Add( key, sinCosVariation ); + } + + mPositionVarAnimation[i] = Animation::New( 3.f ); + mPositionVarAnimation[i].AnimateBetween( Property( mMetaballs[i].actor, mMetaballs[i].positionVarIndex ), keySinCosVariation ); + mPositionVarAnimation[i].SetLooping( true ); + mPositionVarAnimation[i].Play(); + } +} + +void MetaballExplosionController::ResetMetaballs( bool resetAnims ) +{ + for( uint32_t i = 0; i < METABALL_NUMBER; i++ ) + { + if( mDispersionAnimation[i] ) + { + mDispersionAnimation[i].Clear(); + } + + mMetaballs[i].position = Vector2( 0.0f, 0.0f ); + mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position ); + } + mTimerDispersion.Stop(); + mDispersion = 0; + + mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) ); +} + +void MetaballExplosionController::DisperseBallAnimation( uint32_t ball ) +{ + Vector2 position; + position.x = Random::Range(-1.5f,1.5f); + position.y = Random::Range(-1.5f,1.5f); + + mDispersionAnimation[ball] = Animation::New(2.0f * mTimeMultiplier); + mDispersionAnimation[ball].AnimateTo( Property(mMetaballs[ball].actor, mMetaballs[ball].positionIndex), position); + mDispersionAnimation[ball].Play(); + + if( ball == METABALL_NUMBER - 1 ) + { + mDispersionAnimation[ball].FinishedSignal().Connect( this, &MetaballExplosionController::LaunchResetMetaballPosition ); + } +} + +void MetaballExplosionController::LaunchResetMetaballPosition( Animation& source ) +{ + for( uint32_t i = 0; i < METABALL_NUMBER; i++ ) + { + mDispersionAnimation[i] = Animation::New( 1.5f + i * 0.25f * mTimeMultiplier ); + mDispersionAnimation[i].AnimateTo(Property( mMetaballs[i].actor, mMetaballs[i].positionIndex), Vector2(0,0) ); + mDispersionAnimation[i].Play(); + + if( i == METABALL_NUMBER - 1 ) + { + mDispersionAnimation[i].FinishedSignal().Connect( this, &MetaballExplosionController::EndDisperseAnimation ); + } + } +} + +void MetaballExplosionController::EndDisperseAnimation( Animation& source ) +{ + mCompositionActor.SetProperty( mPositionIndex, Vector2(0,0) ); +} + +bool MetaballExplosionController::OnTimerDispersionTick() +{ + if( mDispersion < METABALL_NUMBER ) + { + DisperseBallAnimation( mDispersion ); + mDispersion++; + } + return true; +} + +void MetaballExplosionController::SetPositionToMetaballs( const Vector2& metaballCenter ) +{ + //We set the position for the metaballs based on click position + for( uint32_t i = 0; i < METABALL_NUMBER; i++ ) + { + mMetaballs[i].position = metaballCenter; + mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position ); + } + + mCompositionActor.SetProperty( mPositionIndex, metaballCenter ); +} + +bool MetaballExplosionController::OnTouch( Actor actor, const TouchData& touch ) +{ + float aspectR = mScreenSize.y / mScreenSize.x; + + switch( touch.GetState( 0 ) ) + { + case PointState::DOWN: + { + ResetMetaballs(true); + + const Vector2 screen = touch.GetScreenPosition( 0 ); + Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f ) * 2.0f; + SetPositionToMetaballs(metaballCenter); + + break; + } + case PointState::MOTION: + { + const Vector2 screen = touch.GetScreenPosition( 0 ); + Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f, (aspectR * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f ) * 2.0f; + SetPositionToMetaballs(metaballCenter); + break; + } + case PointState::UP: + case PointState::LEAVE: + case PointState::INTERRUPTED: + { + mTimerDispersion.Start(); + break; + } + default: + break; + } + return true; +} + +void MetaballExplosionController::OnKeyEvent(const KeyEvent& event) +{ + if(event.state == KeyEvent::Down) + { + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) ) + { + mApplication.Quit(); + } + } +} + +/** + * Main entry point + */ +int32_t DALI_EXPORT_API main( int argc, char **argv ) +{ + Application application = Application::New( &argc, &argv ); + + MetaballExplosionController test( application ); + + application.MainLoop(); + + return 0; +} diff --git a/examples/metaball-refrac/metaball-refrac-example.cpp b/examples/metaball-refrac/metaball-refrac-example.cpp new file mode 100644 index 0000000..8d1def8 --- /dev/null +++ b/examples/metaball-refrac/metaball-refrac-example.cpp @@ -0,0 +1,787 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// EXTERNAL INCLUDES +#include +#include +#include // uint32_t, uint16_t etc + +#include +#include +#include +#include + +// INTERNAL INCLUDES +#include "shared/utility.h" // DemoHelper::LoadTexture + +using namespace Dali; + +namespace // unnamed namespace for constants +{ +const char * const BACKGROUND_IMAGE( DEMO_IMAGE_DIR "background-2.jpg" ); +const float GRAVITY_X(0); +const float GRAVITY_Y(-0.09); + +// number of metaballs +constexpr uint32_t METABALL_NUMBER = 6; + +/** + * Vertex shader for metaballs + */ +const char* const METABALL_VERTEX_SHADER = DALI_COMPOSE_SHADER ( + attribute mediump vec2 aPosition;\n + attribute mediump vec2 aTexture;\n + uniform mediump mat4 uMvpMatrix;\n + uniform mediump vec3 uSize;\n + uniform lowp vec4 uColor;\n + varying mediump vec2 vTexCoord;\n + + void main()\n + {\n + mediump vec4 vertexPosition = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n + vertexPosition = uMvpMatrix * vertexPosition;\n + gl_Position = vertexPosition;\n + vTexCoord = aTexture;\n + }\n +); + +/** + * Fragment shader for metaballs + */ +const char* const METABALL_FRAG_SHADER = DALI_COMPOSE_SHADER ( + precision mediump float;\n + varying vec2 vTexCoord;\n + uniform vec2 uPositionMetaball;\n + uniform vec2 uPositionVar;\n + uniform vec2 uGravityVector;\n + uniform float uRadius;\n + uniform float uRadiusVar;\n + uniform float uAspect;\n + void main()\n + {\n + vec2 adjustedCoords = vTexCoord * 2.0 - 1.0;\n + vec2 finalMetaballPosition = uPositionMetaball + uGravityVector + uPositionVar;\n + + float distance = (adjustedCoords.x - finalMetaballPosition.x) * (adjustedCoords.x - finalMetaballPosition.x) + + (adjustedCoords.y - finalMetaballPosition.y) * (adjustedCoords.y - finalMetaballPosition.y);\n + float finalRadius = uRadius + uRadiusVar;\n + float color = finalRadius / sqrt( distance );\n + vec2 bordercolor = vec2(0.0,0.0);\n + if (vTexCoord.x < 0.1)\n + {\n + bordercolor.x = (0.1 - vTexCoord.x) * 0.8;\n + }\n + if (vTexCoord.x > 0.9)\n + {\n + bordercolor.x = (vTexCoord.x - 0.9) * 0.8;\n + }\n + if (vTexCoord.y < 0.1)\n + {\n + bordercolor.y = (0.1 - vTexCoord.y) * 0.8;\n + }\n + if (vTexCoord.y > (0.9 * uAspect))\n + {\n + bordercolor.y = (vTexCoord.y - (0.9 * uAspect)) * 0.8;\n + }\n + float border = (bordercolor.x + bordercolor.y) * 0.5;\n + gl_FragColor = vec4(color + border,color + border,color + border,1.0);\n + }\n +); + +/** + * Fragment shader code for metaball and background composition with refraction effect + */ +const char* const REFRACTION_FRAG_SHADER = DALI_COMPOSE_SHADER ( + precision mediump float;\n + varying vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + uniform sampler2D sEffect;\n + void main()\n + {\n + vec4 metaColor = texture2D(sEffect, vTexCoord);\n + vec2 zoomCoords;\n + float bright = 1.0;\n + if (metaColor.r > 0.85)\n + {\n + zoomCoords = ((vTexCoord - 0.5) * 0.95) + 0.5;\n + }\n + else if (metaColor.r > 0.78)\n + {\n + float interpolation = mix(0.95, 1.05, (0.85 - metaColor.r) * 50.0);\n + zoomCoords = ((vTexCoord - 0.5) * interpolation) + 0.5;\n + bright = 1.2;\n + }\n + else\n + {\n + zoomCoords = vTexCoord;\n + }\n + + gl_FragColor = texture2D(sTexture, zoomCoords) * bright;\n + }\n + ); + +/** + * Fragment shader code when there's no effect + */ +const char* const FRAG_SHADER = DALI_COMPOSE_SHADER ( + precision mediump float;\n + varying vec2 vTexCoord;\n + uniform sampler2D sTexture;\n + void main()\n + {\n + gl_FragColor = texture2D(sTexture, vTexCoord);\n + }\n +); + +/** + * Metadata for each ball + */ +struct MetaballInfo +{ + Actor actor; + Vector2 position; + float radius; + float initRadius; + + //Properties needed for animations + Property::Index positionIndex; + Property::Index positionVarIndex; + Property::Index gravityIndex; + Property::Index radiusIndex; + Property::Index radiusVarIndex; + Property::Index aspectIndex; +}; + +} // unnamed namespace + +/** + * Demo using Metaballs + * + * When the metaball is clicked it starts to grow and fuses into the closest edge of screen + */ +class MetaballRefracController : public ConnectionTracker +{ +public: + + /** + * Constructor + * @param application + */ + MetaballRefracController( Application& application ); + + /** + * Destructor + */ + virtual ~MetaballRefracController(); + + /** + * Creates the metaballs and initializes the scene + */ + void Create( Application& app ); + + /** + * Touch handler, start the grow animation and creates additional metaballs + */ + bool OnTouch( Actor actor, const TouchData& touch ); + + /** + * Key event callback to quit the application on escape or back key + */ + void OnKeyEvent( const KeyEvent& event ); + +private: // Data + + Application& mApplication; + Vector2 mScreenSize; + + Texture mBackgroundTexture; + FrameBuffer mMetaballFBO; + Texture mMetaballFBOTexture; + + Actor mMetaballRoot; + MetaballInfo mMetaballs[METABALL_NUMBER]; + + Actor mCompositionActor; + + //Motion + Vector2 mCurrentTouchPosition; + Vector2 mMetaballPosVariation; + Vector2 mMetaballPosVariationFrom; + Vector2 mMetaballPosVariationTo; + Vector2 mMetaballCenter; + + Vector2 mGravity; + Vector2 mGravityVar; + + Renderer mRendererRefraction; + TextureSet mTextureSetRefraction; + Shader mShaderRefraction; + TextureSet mTextureSetNormal; + Shader mShaderNormal; + + // Animations + Animation mGravityAnimation[METABALL_NUMBER]; + Animation mRadiusDecAnimation[METABALL_NUMBER]; + Animation mRadiusIncFastAnimation[METABALL_NUMBER]; + Animation mRadiusIncSlowAnimation[METABALL_NUMBER]; + Animation mRadiusVarAnimation[METABALL_NUMBER]; + Animation mPositionVarAnimation[METABALL_NUMBER]; + + // Private Helper functions + + /** + * Create a mesh data with the geometry for the metaball rendering + * @param aspectMappedTexture whether texture coords should be mapped based on aspect ratio + */ + Geometry CreateGeometry( bool aspectMappedTexture = true ); + + /** + * Create a actor for the metaballs + */ + void CreateMetaballActors(); + + /** + * Create the render task and FBO to render the metaballs into a texture + */ + void CreateMetaballImage(); + + /** + * Create the the final composition + */ + void CreateComposition(); + + /** + * Create all the metaballs animations (gravity, movement, size, etc.) + */ + void CreateAnimations(); + + /** + * Function to launch the grow slow radius for the metaballs, and also the small variations for metaball[2] and [3] + */ + void LaunchRadiusIncSlowAnimations( Animation& source ); + + /** + * Function to launch the animation to get the metaball[1] back to the center + */ + void LaunchGetBackToPositionAnimation( Animation& source ); + + /** + * Function to stop all animations related to the click of the user in the screen + */ + void StopClickAnimations(); + + /** + * Function to stop all animations related to the after click of the user in the screen + */ + void StopAfterClickAnimations(); + + /** + * Function that resets the sate of the different Metaballs + */ + void ResetMetaballsState(); + + /** + * Function to set the actual position of the metaballs when the user clicks the screen + */ + void SetPositionToMetaballs( const Vector2& metaballCenter ); + +}; + +/** + * Implementation + */ + +MetaballRefracController::MetaballRefracController( Application& application ) + : mApplication( application ) +{ + // Connect to the Application's Init signal + mApplication.InitSignal().Connect( this, &MetaballRefracController::Create ); +} + +MetaballRefracController::~MetaballRefracController() +{ + // Nothing to do here; +} + +void MetaballRefracController::Create( Application& app ) +{ + Stage stage = Stage::GetCurrent(); + + stage.KeyEventSignal().Connect( this, &MetaballRefracController::OnKeyEvent ); + + mScreenSize = stage.GetSize(); + + stage.SetBackgroundColor(Color::BLACK); + + // Load background texture + mBackgroundTexture = DemoHelper::LoadTexture( BACKGROUND_IMAGE ); + + mGravity = Vector2(GRAVITY_X,GRAVITY_Y); + mGravityVar = Vector2(0,0); + + CreateMetaballActors(); + CreateMetaballImage(); + CreateComposition(); + CreateAnimations(); + + // Connect the callback to the touch signal on the mesh actor + stage.GetRootLayer().TouchSignal().Connect( this, &MetaballRefracController::OnTouch ); +} + +Geometry MetaballRefracController::CreateGeometry( bool aspectMappedTexture ) +{ + const float aspect = mScreenSize.y / mScreenSize.x; + + // Create vertices and specify their color + const float xsize = mScreenSize.x * 0.5; + + // Create the meshdata for the metaballs + struct VertexPosition { Vector2 position; }; + struct VertexTexture { Vector2 texture; }; + + VertexPosition vertices[] = + { + { Vector2( -xsize, -xsize * aspect ) }, + { Vector2( xsize, -xsize * aspect ) }, + { Vector2( -xsize, xsize * aspect ) }, + { Vector2( xsize, xsize * aspect ) } + }; + + const float textureAspect = (aspectMappedTexture) ? aspect : 1.0f; + VertexTexture textures[] = + { + { Vector2( 0.0f, 0.0f ) }, + { Vector2( 1.0f, 0.0f ) }, + { Vector2( 0.0f, 1.0f * textureAspect ) }, + { Vector2( 1.0f, 1.0f * textureAspect ) } + }; + + uint32_t numberOfVertices = sizeof(vertices)/sizeof(VertexPosition); + + // Vertices + Property::Map positionVertexFormat; + positionVertexFormat["aPosition"] = Property::VECTOR2; + PropertyBuffer positionVertices = PropertyBuffer::New( positionVertexFormat ); + positionVertices.SetData( vertices, numberOfVertices ); + + // Textures + Property::Map textureVertexFormat; + textureVertexFormat["aTexture"] = Property::VECTOR2; + PropertyBuffer textureVertices = PropertyBuffer::New( textureVertexFormat ); + textureVertices.SetData( textures, numberOfVertices ); + + // Indices + const uint16_t indices[] = { 0, 3, 1, 0, 2, 3 }; + + // Create the geometry object + Geometry texturedQuadGeometry = Geometry::New(); + texturedQuadGeometry.AddVertexBuffer( positionVertices ); + texturedQuadGeometry.AddVertexBuffer( textureVertices ); + + texturedQuadGeometry.SetIndexBuffer ( &indices[0], sizeof( indices )/ sizeof( indices[0] ) ); + + return texturedQuadGeometry; +} + +void MetaballRefracController::CreateMetaballActors() +{ + const float aspect = mScreenSize.y / mScreenSize.x; + + // Create the renderer for the metaballs + Shader shader = Shader::New( METABALL_VERTEX_SHADER, METABALL_FRAG_SHADER, Shader::Hint::MODIFIES_GEOMETRY ); + Geometry metaballGeometry = CreateGeometry(); + Renderer renderer = Renderer::New( metaballGeometry, shader ); + renderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_RGB, BlendFactor::ONE ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_RGB, BlendFactor::ONE ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_SRC_ALPHA, BlendFactor::ONE ); + renderer.SetProperty( Renderer::Property::BLEND_FACTOR_DEST_ALPHA, BlendFactor::ONE ); + + // Each metaball has a different radius + mMetaballs[0].radius = mMetaballs[0].initRadius = 0.0145f; + mMetaballs[1].radius = mMetaballs[1].initRadius = 0.012f; + mMetaballs[2].radius = mMetaballs[2].initRadius = 0.0135f; + mMetaballs[3].radius = mMetaballs[3].initRadius = 0.0135f; + + // Initialization of each of the metaballs + for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ ) + { + mMetaballs[i].position = Vector2(0.0f, 0.0f); + + mMetaballs[i].actor = Actor::New(); + mMetaballs[i].actor.SetName( "Metaball" ); + mMetaballs[i].actor.SetScale( 1.0f ); + mMetaballs[i].actor.SetParentOrigin( ParentOrigin::CENTER ); + + + mMetaballs[i].actor.AddRenderer( renderer ); + + mMetaballs[i].positionIndex = mMetaballs[i].actor.RegisterProperty( "uPositionMetaball", mMetaballs[i].position ); + mMetaballs[i].positionVarIndex = mMetaballs[i].actor.RegisterProperty( "uPositionVar", Vector2(0.f,0.f) ); + mMetaballs[i].gravityIndex = mMetaballs[i].actor.RegisterProperty( "uGravityVector", Vector2(0.f,0.f) ); + mMetaballs[i].radiusIndex = mMetaballs[i].actor.RegisterProperty( "uRadius", mMetaballs[i].radius ); + mMetaballs[i].radiusVarIndex = mMetaballs[i].actor.RegisterProperty( "uRadiusVar", 0.f ); + mMetaballs[i].aspectIndex = mMetaballs[i].actor.RegisterProperty( "uAspect", aspect ); + } + + //Root creation + mMetaballRoot = Actor::New(); + mMetaballRoot.SetParentOrigin( ParentOrigin::CENTER ); + for( uint32_t i = 0 ; i < METABALL_NUMBER ; i++ ) + { + mMetaballRoot.Add( mMetaballs[i].actor ); + } +} + +void MetaballRefracController::CreateMetaballImage() +{ + // Create an FBO and a render task to create to render the metaballs with a fragment shader + Stage stage = Stage::GetCurrent(); + mMetaballFBO = FrameBuffer::New( mScreenSize.x, mScreenSize.y, FrameBuffer::Attachment::NONE ); + mMetaballFBOTexture = Texture::New( Dali::TextureType::TEXTURE_2D, + Pixel::RGB888, + mScreenSize.x, mScreenSize.y ); + mMetaballFBO.AttachColorTexture( mMetaballFBOTexture ); + + stage.Add(mMetaballRoot); + + //Creation of the render task used to render the metaballs + RenderTaskList taskList = Stage::GetCurrent().GetRenderTaskList(); + RenderTask task = taskList.CreateTask(); + task.SetRefreshRate( RenderTask::REFRESH_ALWAYS ); + task.SetSourceActor( mMetaballRoot ); + task.SetExclusive( true ); + task.SetClearColor( Color::BLACK ); + task.SetClearEnabled( true ); + task.SetFrameBuffer( mMetaballFBO ); +} + +void MetaballRefracController::CreateComposition() +{ + // Create Refraction shader and renderer + mShaderRefraction = Shader::New( METABALL_VERTEX_SHADER, REFRACTION_FRAG_SHADER ); + + // Create new texture set + mTextureSetRefraction = TextureSet::New(); + mTextureSetRefraction.SetTexture( 0u, mBackgroundTexture ); + mTextureSetRefraction.SetTexture( 1u, mMetaballFBOTexture ); + + // Create normal shader + mShaderNormal = Shader::New( METABALL_VERTEX_SHADER, FRAG_SHADER ); + + // Create new texture set + mTextureSetNormal = TextureSet::New(); + mTextureSetNormal.SetTexture( 0u, mBackgroundTexture ); + + // Create actor + mCompositionActor = Actor::New( ); + mCompositionActor.SetParentOrigin(ParentOrigin::CENTER); + mCompositionActor.SetPosition(Vector3(0.0f, 0.0f, 0.0f)); + mCompositionActor.SetSize(mScreenSize.x, mScreenSize.y); + + // Create geometry + Geometry metaballGeometry = CreateGeometry( false ); + mRendererRefraction = Renderer::New( metaballGeometry, mShaderNormal ); + mRendererRefraction.SetTextures( mTextureSetNormal ); + mCompositionActor.AddRenderer( mRendererRefraction ); + + Stage stage = Stage::GetCurrent(); + stage.Add( mCompositionActor ); +} + +void MetaballRefracController::CreateAnimations() +{ + uint32_t i = 0; + float key; + + mPositionVarAnimation[1] = Animation::New( 2.f ); + mPositionVarAnimation[1].SetLooping( false ); + mPositionVarAnimation[1].Pause(); + mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation ); + + KeyFrames keySinCosVariation = KeyFrames::New(); + Vector2 sinCosVariation(0,0); + for( i = 0 ; i < 360; i++ ) + { + sinCosVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) ); + sinCosVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) ); + key = i/360.f; + keySinCosVariation.Add(key, sinCosVariation); + } + + mPositionVarAnimation[2] = Animation::New(6.f); + mPositionVarAnimation[2].AnimateBetween(Property( mMetaballs[2].actor, mMetaballs[2].positionVarIndex ), keySinCosVariation); + mPositionVarAnimation[2].SetLooping( true ); + mPositionVarAnimation[2].Pause(); + + KeyFrames keyCosSinVariation = KeyFrames::New(); + Vector2 cosSinVariation(0,0); + for( i = 0 ; i < 360; i++ ) + { + cosSinVariation.x = 0.05f * ( -sinf(i * Math::PI_OVER_180) - cosf(i * Math::PI_OVER_180) ); + cosSinVariation.y = 0.05f * ( sinf(i * Math::PI_OVER_180) + cosf(i * Math::PI_OVER_180) ); + key = i/360.f; + keyCosSinVariation.Add(key, cosSinVariation); + } + + mPositionVarAnimation[3] = Animation::New(6.f); + mPositionVarAnimation[3].AnimateBetween(Property( mMetaballs[3].actor, mMetaballs[3].positionVarIndex ), keyCosSinVariation); + mPositionVarAnimation[3].SetLooping( true ); + mPositionVarAnimation[3].Pause(); + + //Animations for gravity + for( i = 0 ; i < METABALL_NUMBER; i++ ) + { + mGravityAnimation[i] = Animation::New( 25.f ); + mGravityAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].gravityIndex ), mGravity * 25.f * 3.f ); + mGravityAnimation[i].SetLooping( false ); + mGravityAnimation[i].Pause(); + } + + //Animation to decrease size of metaballs when there is no click + for( i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusDecAnimation[i] = Animation::New( 25.f ); + mRadiusDecAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), -0.004f * 25.f * 3.f ); + mRadiusDecAnimation[i].SetLooping( false ); + mRadiusDecAnimation[i].Pause(); + } + + // Animation to grow the size of the metaballs the first second of the click + for( i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusIncFastAnimation[i] = Animation::New( 0.3f ); + mRadiusIncFastAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.06f ); + mRadiusIncFastAnimation[i].SetLooping( false ); + mRadiusIncFastAnimation[i].Pause(); + } + mRadiusIncFastAnimation[0].FinishedSignal().Connect( this, &MetaballRefracController::LaunchRadiusIncSlowAnimations ); + + // Animation to grow the size of the metaballs afterwards + for( i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusIncSlowAnimation[i] = Animation::New( 20.f ); + mRadiusIncSlowAnimation[i].AnimateBy( Property( mMetaballs[i].actor, mMetaballs[i].radiusIndex ), 0.04f ); + mRadiusIncSlowAnimation[i].SetLooping( false ); + mRadiusIncSlowAnimation[i].Pause(); + } + + // Keyframes of a sin function + KeyFrames keySin = KeyFrames::New(); + float val; + for( i = 0 ; i < 360; i++ ) + { + val = 0.01f * sin(i * Math::PI/180.f); + key = i/360.f; + keySin.Add(key, val); + } + + //Animation to change the size of the metaball + mRadiusVarAnimation[2] = Animation::New( 8.f ); + mRadiusVarAnimation[2].AnimateBetween( Property( mMetaballs[2].actor, mMetaballs[2].radiusVarIndex ), keySin ); + mRadiusVarAnimation[2].SetLooping( true ); + + // Keyframes of a cos function + KeyFrames keyCos = KeyFrames::New(); + for( i = 0 ; i < 360; i++ ) + { + val = 0.01f * cos(i * Math::PI/180.f); + key = i/360.f; + keyCos.Add(key, val); + } + + //Animation to change the size of the metaball + mRadiusVarAnimation[3] = Animation::New( 8.f ); + mRadiusVarAnimation[3].AnimateBetween( Property( mMetaballs[3].actor, mMetaballs[3].radiusVarIndex ), keyCos ); + mRadiusVarAnimation[3].SetLooping( true ); +} + +void MetaballRefracController::LaunchGetBackToPositionAnimation( Animation& source ) +{ + mMetaballPosVariationTo = Vector2(0,0); + + mPositionVarAnimation[1] = Animation::New( 1.f ); + mPositionVarAnimation[1].SetLooping( false ); + mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), Vector2(0,0) ); + mPositionVarAnimation[1].Play(); +} + +void MetaballRefracController::LaunchRadiusIncSlowAnimations( Animation& source ) +{ + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusIncSlowAnimation[i].Play(); + } + mPositionVarAnimation[2].Play(); + mPositionVarAnimation[3].Play(); +} + +void MetaballRefracController::StopClickAnimations() +{ + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusIncSlowAnimation[i].Stop(); + mRadiusIncFastAnimation[i].Stop(); + } + mPositionVarAnimation[1].Stop(); + mPositionVarAnimation[2].Stop(); + mPositionVarAnimation[3].Stop(); +} + +void MetaballRefracController::StopAfterClickAnimations() +{ + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mGravityAnimation[i].Stop(); + mRadiusDecAnimation[i].Stop(); + + mMetaballs[i].radius = mMetaballs[i].initRadius; + + mMetaballs[i].actor.SetProperty( mMetaballs[i].gravityIndex, Vector2(0,0) ); + mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusIndex, mMetaballs[i].radius ); + mMetaballs[i].actor.SetProperty( mMetaballs[i].radiusVarIndex, 0.f ); + } + mRadiusVarAnimation[2].Stop(); + mRadiusVarAnimation[3].Stop(); +} + +void MetaballRefracController::ResetMetaballsState() +{ + mRendererRefraction.SetTextures( mTextureSetNormal ); + mRendererRefraction.SetShader( mShaderNormal ); + + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mMetaballs[i].radius = mMetaballs[i].initRadius; + } + + mMetaballPosVariationTo = Vector2(0,0); + mMetaballPosVariationFrom = Vector2(0,0); + mMetaballPosVariation = Vector2(0,0); + mGravityVar = Vector2(0,0); +} + +void MetaballRefracController::SetPositionToMetaballs( const Vector2& metaballCenter ) +{ + //We set the position for the metaballs based on click position + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mMetaballs[i].position = metaballCenter; + mMetaballs[i].actor.SetProperty( mMetaballs[i].positionIndex, mMetaballs[i].position ); + } +} + +bool MetaballRefracController::OnTouch( Actor actor, const TouchData& touch ) +{ + const float aspect = mScreenSize.y / mScreenSize.x; + switch( touch.GetState( 0 ) ) + { + case PointState::DOWN: + { + StopAfterClickAnimations(); + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusIncFastAnimation[i].Play(); + } + mRadiusVarAnimation[2].Play(); + mRadiusVarAnimation[3].Play(); + + //We draw with the refraction-composition shader + mRendererRefraction.SetTextures( mTextureSetRefraction ); + mRendererRefraction.SetShader( mShaderRefraction ); + mCurrentTouchPosition = touch.GetScreenPosition( 0 ); + + //we use the click position for the metaballs + Vector2 metaballCenter = Vector2( (mCurrentTouchPosition.x / mScreenSize.x) - 0.5f, + (aspect * (mScreenSize.y - mCurrentTouchPosition.y) / mScreenSize.y) - 0.5f ) * 2.0f; + SetPositionToMetaballs(metaballCenter); + break; + } + case PointState::MOTION: + { + Vector2 screen = touch.GetScreenPosition( 0 ); + Vector2 displacement = screen - mCurrentTouchPosition; + mCurrentTouchPosition = screen; + + mMetaballPosVariationTo.x += ( displacement.x / mScreenSize.x ) * 2.2f; + mMetaballPosVariationTo.y += (-displacement.y / mScreenSize.y ) * 2.2f; + + if (mPositionVarAnimation[1]) + { + mPositionVarAnimation[1].FinishedSignal().Disconnect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation ); + mPositionVarAnimation[1].Stop(); + } + mPositionVarAnimation[1] = Animation::New( 1.f ); + mPositionVarAnimation[1].SetLooping( false ); + mPositionVarAnimation[1].AnimateTo(Property( mMetaballs[1].actor, mMetaballs[1].positionVarIndex ), mMetaballPosVariationTo ); + mPositionVarAnimation[1].FinishedSignal().Connect( this, &MetaballRefracController::LaunchGetBackToPositionAnimation ); + mPositionVarAnimation[1].Play(); + + //we use the click position for the metaballs + Vector2 metaballCenter = Vector2( (screen.x / mScreenSize.x) - 0.5f, + (aspect * (mScreenSize.y - screen.y) / mScreenSize.y) - 0.5f) * 2.0f; + SetPositionToMetaballs(metaballCenter); + break; + } + case PointState::UP: + case PointState::LEAVE: + case PointState::INTERRUPTED: + { + //Stop click animations + StopClickAnimations(); + + //Launch out of screen animations + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mGravityAnimation[i].Play(); + } + + for( uint32_t i = 0 ; i < METABALL_NUMBER; i++ ) + { + mRadiusDecAnimation[i].Play(); + } + break; + } + default: + break; + } + return true; +} + +void MetaballRefracController::OnKeyEvent(const KeyEvent& event) +{ + if( event.state == KeyEvent::Down ) + { + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) ) + { + mApplication.Quit(); + } + } +} + +/** + * Main entry point + */ +int32_t DALI_EXPORT_API main( int argc, char **argv ) +{ + Application application = Application::New( &argc, &argv ); + + MetaballRefracController test( application ); + application.MainLoop(); + + return 0; +} diff --git a/packaging/com.samsung.dali-demo.spec b/packaging/com.samsung.dali-demo.spec index ad4568a..22ec3f6 100755 --- a/packaging/com.samsung.dali-demo.spec +++ b/packaging/com.samsung.dali-demo.spec @@ -2,7 +2,7 @@ Name: com.samsung.dali-demo Summary: The OpenGLES Canvas Core Demo -Version: 1.3.51 +Version: 1.3.52 Release: 1 Group: System/Libraries License: Apache-2.0 diff --git a/resources/po/as.po b/resources/po/as.po index 54b478d..bab37b3 100755 --- a/resources/po/as.po +++ b/resources/po/as.po @@ -76,6 +76,12 @@ msgstr "মেশ অঙ্কুৰিত" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "3D অনুগামী" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "মেটাবল মহা-বিস্ফোৰণবাদ" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "মেটাবল প্ৰতিসৰিত" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "অস্পষ্ট" diff --git a/resources/po/de.po b/resources/po/de.po index f0aad71..6190e2a 100755 --- a/resources/po/de.po +++ b/resources/po/de.po @@ -76,6 +76,12 @@ msgstr "Mesh Veränderung" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "3D-Modelle" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "Metaball Explosion" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "Metaball Brechung" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "Bewegungsunschärfe" diff --git a/resources/po/en_GB.po b/resources/po/en_GB.po index b6339ab..342d10d 100755 --- a/resources/po/en_GB.po +++ b/resources/po/en_GB.po @@ -112,6 +112,12 @@ msgstr "Mesh Morph" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "Mesh Visual" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "Metaball Explosion" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "Metaball Refraction" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "Motion Blur" diff --git a/resources/po/en_US.po b/resources/po/en_US.po index d3d6215..50460ee 100755 --- a/resources/po/en_US.po +++ b/resources/po/en_US.po @@ -115,6 +115,12 @@ msgstr "Mesh Morph" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "Mesh Visual" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "Metaball Explosion" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "Metaball Refraction" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "Motion Blur" diff --git a/resources/po/es.po b/resources/po/es.po index 4d5ae43..6b4458b 100755 --- a/resources/po/es.po +++ b/resources/po/es.po @@ -76,6 +76,12 @@ msgstr "Transformacion de geometrias" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "Gemeotria 3D" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "Explosion de metabolas" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "Refraccion de metabolas" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "Desenfoque de movimiento" diff --git a/resources/po/fi.po b/resources/po/fi.po index b56ef25..5e7552e 100755 --- a/resources/po/fi.po +++ b/resources/po/fi.po @@ -76,6 +76,12 @@ msgstr "Polygoniverkon Muodonmuutos" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "Polygoniverkkovisuaali" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "Metaball Räjähdys" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "Metaball Valon Taittumisella" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "Liikesumennus" diff --git a/resources/po/ko.po b/resources/po/ko.po index 0ea0613..51f1239 100755 --- a/resources/po/ko.po +++ b/resources/po/ko.po @@ -85,6 +85,12 @@ msgstr "메쉬 형태" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "메쉬 비주얼" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "메타볼 폭발" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "메타볼 굴절" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "모션 블러" diff --git a/resources/po/ml.po b/resources/po/ml.po index a1f7e83..8873d62 100755 --- a/resources/po/ml.po +++ b/resources/po/ml.po @@ -76,6 +76,12 @@ msgstr "മോർഫ് mesh" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "3D മോഡലിങ്" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "മെറ്റാ പന്ത് സ്ഫോടനം" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "മെറ്റാ പന്ത് അപവർത്തനം" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "അവ്യക്തമാക്കല്" diff --git a/resources/po/ur.po b/resources/po/ur.po index 5b41075..512bd10 100755 --- a/resources/po/ur.po +++ b/resources/po/ur.po @@ -79,6 +79,12 @@ msgstr "میش کی تبدیلی" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "3D میش" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "میٹابال دھماکہ" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "میٹابال اپورتن" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "دھندلانے کی حرکت" diff --git a/resources/po/zn_CH.po b/resources/po/zn_CH.po index f5aafe8..5897486 100755 --- a/resources/po/zn_CH.po +++ b/resources/po/zn_CH.po @@ -76,6 +76,12 @@ msgstr "网格变形" msgid "DALI_DEMO_STR_TITLE_MESH_VISUAL" msgstr "3D模型" +msgid "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION" +msgstr "元球爆炸" + +msgid "DALI_DEMO_STR_TITLE_METABALL_REFRAC" +msgstr "元球折射" + msgid "DALI_DEMO_STR_TITLE_MOTION_BLUR" msgstr "动作模糊" diff --git a/shared/dali-demo-strings.h b/shared/dali-demo-strings.h index 92f08e8..e0fcb42 100644 --- a/shared/dali-demo-strings.h +++ b/shared/dali-demo-strings.h @@ -73,6 +73,8 @@ extern "C" #define DALI_DEMO_STR_TITLE_MAGNIFIER dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MAGNIFIER") #define DALI_DEMO_STR_TITLE_MESH_MORPH dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MESH_MORPH") #define DALI_DEMO_STR_TITLE_MESH_VISUAL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MESH_VISUAL") +#define DALI_DEMO_STR_TITLE_METABALL_EXPLOSION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_METABALL_EXPLOSION") +#define DALI_DEMO_STR_TITLE_METABALL_REFRAC dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_METABALL_REFRAC") #define DALI_DEMO_STR_TITLE_MOTION_BLUR dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MOTION_BLUR") #define DALI_DEMO_STR_TITLE_MOTION_STRETCH dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_MOTION_STRETCH") #define DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE") @@ -159,6 +161,8 @@ extern "C" #define DALI_DEMO_STR_TITLE_MAGNIFIER "Magnifier" #define DALI_DEMO_STR_TITLE_MESH_MORPH "Mesh Morph" #define DALI_DEMO_STR_TITLE_MESH_VISUAL "Mesh Visual" +#define DALI_DEMO_STR_TITLE_METABALL_EXPLOSION "Metaball Explosion" +#define DALI_DEMO_STR_TITLE_METABALL_REFRAC "Metaball Refractions" #define DALI_DEMO_STR_TITLE_MOTION_BLUR "Motion Blur" #define DALI_DEMO_STR_TITLE_MOTION_STRETCH "Motion Stretch" #define DALI_DEMO_STR_TITLE_NATIVE_IMAGE_SOURCE "Native Image Source"