Commit 5b74d885f033ea9d6763d9d6a923de86d572b5e3

Authored by Adeel Kazmi
Committed by Gerrit Code Review
2 parents ee80a447 5b7659f0

Merge "Update refraction-effect & radial-menu to use new mesh" into devel/new_mesh

examples/radial-menu/radial-menu-example.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2015 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 +#include <dali/dali.h>
  19 +#include <dali-toolkit/dali-toolkit.h>
  20 +#include "shared/view.h"
  21 +#include "radial-sweep-view.h"
  22 +#include "radial-sweep-view-impl.h"
  23 +
  24 +using namespace Dali;
  25 +using namespace Dali::Toolkit;
  26 +
  27 +namespace
  28 +{
  29 +const char* TEST_OUTER_RING_FILENAME = DALI_IMAGE_DIR "layer2.png"; // Image to be masked
  30 +const char* TEST_INNER_RING_FILENAME = DALI_IMAGE_DIR "layer1.png"; // Image to be masked
  31 +const char* TEST_MENU_FILENAME = DALI_IMAGE_DIR "layer3.png"; // Image to be masked
  32 +const char* TEST_DIAL_FILENAME = DALI_IMAGE_DIR "layer4.png"; // Image to be masked
  33 +const char* TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" ); // Background for toolbar
  34 +const char* APPLICATION_TITLE( "Radial Menu" );
  35 +const char * const PLAY_ICON( DALI_IMAGE_DIR "icon-play.png" );
  36 +const char * const STOP_ICON( DALI_IMAGE_DIR "icon-stop.png" );
  37 +}
  38 +
  39 +
  40 +/********************************************************************************
  41 + * Application controller class
  42 + */
  43 +
  44 +// This example shows how to create a mesh actor for use as a stencil buffer
  45 +class RadialMenuExample : public ConnectionTracker
  46 +{
  47 +public:
  48 + /**
  49 + * Constructor
  50 + * @param[in] app The application handle
  51 + */
  52 + RadialMenuExample(Application app);
  53 +
  54 + /**
  55 + * Destructor
  56 + */
  57 + ~RadialMenuExample();
  58 +
  59 +private:
  60 +
  61 + /**
  62 + * Initialization signal handler - all actor initialization should happen here
  63 + * @param[in] app The application handle
  64 + */
  65 + void OnInit(Application& app);
  66 +
  67 + /**
  68 + * Create a sweep view with the given image and parameters
  69 + */
  70 + RadialSweepView CreateSweepView( std::string imageName, Degree initial, Degree final );
  71 +
  72 + /**
  73 + * Start the sweep animation on the menu
  74 + */
  75 + void StartAnimation();
  76 +
  77 + /**
  78 + * Play or pause the animation when the button is clicked
  79 + */
  80 + bool OnButtonClicked( Toolkit::Button button );
  81 +
  82 + /**
  83 + * Update the state flag and change the button icon when the animation is finished
  84 + */
  85 + void OnAnimationFinished( Animation& source );
  86 +
  87 + /**
  88 + * Main key event handler
  89 + *
  90 + * @param[in] event The key event to respond to
  91 + */
  92 + void OnKeyEvent(const KeyEvent& event);
  93 +
  94 +private: // Member variables
  95 + enum AnimState
  96 + {
  97 + STOPPED,
  98 + PAUSED,
  99 + PLAYING
  100 + };
  101 +
  102 + Application mApplication; ///< The application handle
  103 + Toolkit::Control mView; ///< The toolbar view
  104 + Layer mContents; ///< The toolbar contents pane
  105 + ImageActor mImageActor; ///< Image actor shown by stencil mask
  106 + Animation mAnimation;
  107 + AnimState mAnimationState;
  108 +
  109 + Image mIconPlay;
  110 + Image mIconStop;
  111 + Toolkit::PushButton mPlayStopButton;
  112 + ImageActor mDialActor;
  113 + RadialSweepView mRadialSweepView1;
  114 + RadialSweepView mRadialSweepView2;
  115 + RadialSweepView mRadialSweepView3;
  116 +};
  117 +
  118 +RadialMenuExample::RadialMenuExample(Application app)
  119 +: mApplication( app ),
  120 + mAnimationState(STOPPED)
  121 +{
  122 + // Connect to the Application's Init signal
  123 + app.InitSignal().Connect(this, &RadialMenuExample::OnInit);
  124 +}
  125 +
  126 +RadialMenuExample::~RadialMenuExample()
  127 +{
  128 + // Nothing to do here; actor handles will clean up themselves.
  129 +}
  130 +
  131 +void RadialMenuExample::OnInit(Application& app)
  132 +{
  133 + DemoHelper::RequestThemeChange();
  134 +
  135 + Stage stage = Dali::Stage::GetCurrent();
  136 +
  137 + // The Init signal is received once (only) during the Application lifetime
  138 + stage.KeyEventSignal().Connect(this, &RadialMenuExample::OnKeyEvent);
  139 +
  140 + // Create toolbar & view
  141 + Toolkit::ToolBar toolBar;
  142 + mContents = DemoHelper::CreateView( mApplication,
  143 + mView,
  144 + toolBar,
  145 + "",
  146 + TOOLBAR_IMAGE,
  147 + APPLICATION_TITLE );
  148 +
  149 + mIconPlay = ResourceImage::New( PLAY_ICON );
  150 + mIconStop = ResourceImage::New( STOP_ICON );
  151 + mPlayStopButton = Toolkit::PushButton::New();
  152 + mPlayStopButton.SetBackgroundImage( mIconStop );
  153 +
  154 + mPlayStopButton.ClickedSignal().Connect( this, &RadialMenuExample::OnButtonClicked );
  155 +
  156 + toolBar.AddControl( mPlayStopButton,
  157 + DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
  158 + Toolkit::Alignment::HorizontalRight,
  159 + DemoHelper::DEFAULT_PLAY_PADDING );
  160 +
  161 +
  162 + const ImageDimensions intImgSize = ResourceImage::GetImageSize(TEST_OUTER_RING_FILENAME);
  163 + Vector2 imgSize = Vector2( intImgSize.GetWidth(), intImgSize.GetHeight() );
  164 + Vector2 stageSize = stage.GetSize();
  165 + float scale = stageSize.width / imgSize.width;
  166 + float availableHeight = stageSize.height - DemoHelper::DEFAULT_VIEW_STYLE.mToolBarHeight * 2.0f;
  167 + if(availableHeight <= stageSize.width)
  168 + {
  169 + scale = availableHeight / imgSize.width;
  170 + }
  171 +
  172 + mRadialSweepView1 = CreateSweepView( TEST_OUTER_RING_FILENAME, Degree(-90.0f), Degree(-90.0f));
  173 + mRadialSweepView2 = CreateSweepView( TEST_INNER_RING_FILENAME, Degree(90.0f), Degree(0.0f));
  174 + mRadialSweepView3 = CreateSweepView( TEST_MENU_FILENAME, Degree(100.0f), Degree(0.0f));
  175 + mRadialSweepView3.SetInitialActorAngle(Degree(-110));
  176 + mRadialSweepView3.SetFinalActorAngle(Degree(0));
  177 +
  178 + Image dial = ResourceImage::New( TEST_DIAL_FILENAME );
  179 + mDialActor = ImageActor::New( dial );
  180 + mDialActor.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
  181 + mDialActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
  182 + mDialActor.SetScale(scale);
  183 + Layer dialLayer = Layer::New();
  184 +
  185 + dialLayer.Add(mDialActor);
  186 + dialLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
  187 + dialLayer.SetSize(stage.GetSize());
  188 + mContents.Add(dialLayer);
  189 +
  190 + mRadialSweepView1.SetScale(scale);
  191 + mRadialSweepView2.SetScale(scale);
  192 + mRadialSweepView3.SetScale(scale);
  193 +
  194 + StartAnimation();
  195 +}
  196 +
  197 +void RadialMenuExample::StartAnimation()
  198 +{
  199 + mDialActor.SetOpacity(0.0f);
  200 + mRadialSweepView1.SetOpacity(0.0f);
  201 + mAnimation = Animation::New(6.0f);
  202 + mRadialSweepView1.Activate(mAnimation, 0.0f, 3.0f);
  203 + mRadialSweepView2.Activate(mAnimation, 1.5f, 3.0f);
  204 + mRadialSweepView3.Activate(mAnimation, 3.0f, 3.0f);
  205 + mAnimation.AnimateTo( Property( mDialActor, Actor::Property::COLOR_ALPHA ), 1.0f, AlphaFunction::EASE_IN, TimePeriod( 0.0f, 0.8f ) );
  206 + mAnimation.AnimateTo( Property( mRadialSweepView1, Actor::Property::COLOR_ALPHA ), 1.0f, AlphaFunction::EASE_IN, TimePeriod( 0.0f, 0.5f ) );
  207 + mAnimation.FinishedSignal().Connect( this, &RadialMenuExample::OnAnimationFinished );
  208 +
  209 + mAnimationState = PLAYING;
  210 + mAnimation.Play();
  211 +}
  212 +
  213 +bool RadialMenuExample::OnButtonClicked( Toolkit::Button button )
  214 +{
  215 + switch( mAnimationState )
  216 + {
  217 + case PLAYING:
  218 + {
  219 + mAnimation.Pause();
  220 + mAnimationState = PAUSED;
  221 + mPlayStopButton.SetBackgroundImage( mIconPlay );
  222 + }
  223 + break;
  224 +
  225 + case PAUSED:
  226 + {
  227 + mAnimation.Play();
  228 + mAnimationState = PLAYING;
  229 + mPlayStopButton.SetBackgroundImage( mIconStop );
  230 + }
  231 + break;
  232 +
  233 + case STOPPED:
  234 + {
  235 + mPlayStopButton.SetBackgroundImage( mIconStop );
  236 + mRadialSweepView1.Deactivate();
  237 + mRadialSweepView2.Deactivate();
  238 + mRadialSweepView3.Deactivate();
  239 + StartAnimation();
  240 + }
  241 + }
  242 + return false;
  243 +}
  244 +
  245 +void RadialMenuExample::OnAnimationFinished( Animation& source )
  246 +{
  247 + mAnimationState = STOPPED;
  248 + mPlayStopButton.SetBackgroundImage( mIconPlay );
  249 +}
  250 +
  251 +RadialSweepView RadialMenuExample::CreateSweepView( std::string imageName,
  252 + Degree initialAngle,
  253 + Degree finalAngle)
  254 +{
  255 + // Create the image
  256 + Image image = ResourceImage::New(imageName);
  257 + mImageActor = ImageActor::New(image);
  258 + mImageActor.SetParentOrigin(ParentOrigin::CENTER);
  259 + mImageActor.SetAnchorPoint(AnchorPoint::CENTER);
  260 + mImageActor.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
  261 +
  262 + // Create the stencil
  263 + const ImageDimensions imageSize = ResourceImage::GetImageSize(imageName);
  264 + float diameter = std::max(imageSize.GetWidth(), imageSize.GetHeight());
  265 + RadialSweepView radialSweepView = RadialSweepView::New();
  266 + radialSweepView.SetDiameter( diameter );
  267 + radialSweepView.SetInitialAngle( initialAngle );
  268 + radialSweepView.SetFinalAngle( finalAngle );
  269 + radialSweepView.SetInitialSector( Degree(0.0f) );
  270 + radialSweepView.SetFinalSector( Degree(359.999f) );
  271 + radialSweepView.SetSize( Stage::GetCurrent().GetSize());
  272 + radialSweepView.SetEasingFunction( Dali::AlphaFunction::EASE_IN_OUT );
  273 + radialSweepView.SetPositionInheritanceMode(USE_PARENT_POSITION);
  274 + mContents.Add(radialSweepView);
  275 + radialSweepView.Add( mImageActor );
  276 + mImageActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
  277 +
  278 + return radialSweepView;
  279 +}
  280 +
  281 +
  282 +void RadialMenuExample::OnKeyEvent(const KeyEvent& event)
  283 +{
  284 + if(event.state == KeyEvent::Down)
  285 + {
  286 + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  287 + {
  288 + mApplication.Quit();
  289 + }
  290 + }
  291 +}
  292 +
  293 +void RunTest(Application app)
  294 +{
  295 + RadialMenuExample test(app);
  296 +
  297 + app.MainLoop();
  298 +}
  299 +
  300 +// Entry point for Linux & Tizen applications
  301 +int main(int argc, char **argv)
  302 +{
  303 + Application app = Application::New(&argc, &argv);
  304 +
  305 + RunTest(app);
  306 +
  307 + return 0;
  308 +}
examples/radial-menu/radial-sweep-view-impl.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2015 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 +#include "radial-sweep-view-impl.h"
  19 +
  20 +#include <sstream>
  21 +
  22 +using namespace Dali;
  23 +
  24 +namespace
  25 +{
  26 +
  27 +const char* VERTEX_SHADER_PREFIX( "#define MATH_PI_2 1.570796\n#define MATH_PI_4 0.785398\n" );
  28 +
  29 +const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
  30 +attribute mediump float aAngleIndex;\n
  31 +attribute mediump vec2 aPosition1;\n
  32 +attribute mediump vec2 aPosition2;\n
  33 +uniform mediump mat4 uMvpMatrix;\n
  34 +uniform mediump float uStartAngle;\n
  35 +uniform mediump float uRotationAngle;\n
  36 +\n
  37 +void main()\n
  38 +{\n
  39 + float currentAngle = uStartAngle + uRotationAngle;\n
  40 + float angleInterval1 = MATH_PI_4 * aAngleIndex;\n
  41 + vec4 vertexPosition = vec4(0.0, 0.0, 0.0, 1.0);\n
  42 + if( currentAngle >= angleInterval1)\n
  43 + {\n
  44 + float angleInterval2 = angleInterval1 + MATH_PI_2;\n
  45 + float angle = currentAngle < angleInterval2 ? currentAngle : angleInterval2;\n
  46 + float delta;\n
  47 + if( mod( aAngleIndex+4.0, 4.0) < 2.0 )\n
  48 + {\n
  49 + delta = 0.5 - 0.5*cos(angle) / sin(angle);\n
  50 + }\n
  51 + else\n
  52 + {\n
  53 + delta = 0.5 + 0.5*sin(angle) / cos(angle);\n
  54 + }\n
  55 + vertexPosition.xy = mix( aPosition1, aPosition2, delta );\n
  56 + }\n
  57 + gl_Position = uMvpMatrix * vertexPosition;\n
  58 +}
  59 +);
  60 +
  61 +const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
  62 +uniform lowp vec4 uColor;\n
  63 +\n
  64 +void main()\n
  65 +{\n
  66 + gl_FragColor = uColor;\n
  67 +}\n
  68 +);
  69 +
  70 +float HoldZeroFastEaseInOutHoldOne(float progress)
  71 +{
  72 + if( progress < 0.2f)
  73 + {
  74 + return 0.0f;
  75 + }
  76 + else if(progress < 0.5f)
  77 + {
  78 + progress = (progress-0.2) / 0.3f;
  79 + return progress*progress*progress*0.5f;
  80 + }
  81 + else if(progress < 0.8f)
  82 + {
  83 + progress = ((progress - 0.5f) / 0.3f) - 1.0f;
  84 + return (progress*progress*progress+1.0f) * 0.5f + 0.5f;
  85 + }
  86 + else
  87 + {
  88 + return 1.0f;
  89 + }
  90 +}
  91 +
  92 +} // anonymous namespace
  93 +
  94 +
  95 +RadialSweepView RadialSweepViewImpl::New( )
  96 +{
  97 + return New( 2.0f, 100.0f, ANGLE_0, ANGLE_0, ANGLE_0, ANGLE_360 );
  98 +}
  99 +
  100 +
  101 +RadialSweepView RadialSweepViewImpl::New( float duration, float diameter, Radian initialAngle, Radian finalAngle, Radian initialSector, Radian finalSector )
  102 +{
  103 + RadialSweepViewImpl* impl= new RadialSweepViewImpl(duration, diameter, initialAngle, finalAngle, initialSector, finalSector);
  104 + RadialSweepView handle = RadialSweepView(*impl);
  105 + return handle;
  106 +}
  107 +
  108 +RadialSweepViewImpl::RadialSweepViewImpl( float duration, float diameter, Radian initialAngle, Radian finalAngle, Radian initialSector, Radian finalSector )
  109 +: Control( ControlBehaviour( ACTOR_BEHAVIOUR_NONE ) ),
  110 + mDuration(duration),
  111 + mDiameter(diameter),
  112 + mInitialAngle(initialAngle),
  113 + mFinalAngle(finalAngle),
  114 + mInitialSector(initialSector),
  115 + mFinalSector(finalSector),
  116 + mInitialActorAngle(0),
  117 + mFinalActorAngle(0),
  118 + mEasingFunction(HoldZeroFastEaseInOutHoldOne),
  119 + mStartAngleIndex(Property::INVALID_INDEX),
  120 + mRotationAngleIndex(Property::INVALID_INDEX),
  121 + mRotateActorsWithStencil(false),
  122 + mRotateActors(false)
  123 +{
  124 +}
  125 +
  126 +void RadialSweepViewImpl::SetDuration(float duration)
  127 +{
  128 + mDuration = duration;
  129 +}
  130 +
  131 +void RadialSweepViewImpl::SetEasingFunction( Dali::AlphaFunction easingFunction )
  132 +{
  133 + mEasingFunction = easingFunction;
  134 +}
  135 +
  136 +void RadialSweepViewImpl::SetDiameter(float diameter)
  137 +{
  138 + mDiameter = diameter;
  139 +}
  140 +
  141 +void RadialSweepViewImpl::SetInitialAngle( Dali::Radian initialAngle)
  142 +{
  143 + mInitialAngle = initialAngle;
  144 +}
  145 +
  146 +void RadialSweepViewImpl::SetFinalAngle( Dali::Radian finalAngle)
  147 +{
  148 + mFinalAngle = finalAngle;
  149 +}
  150 +
  151 +void RadialSweepViewImpl::SetInitialSector( Dali::Radian initialSector)
  152 +{
  153 + mInitialSector = initialSector;
  154 +}
  155 +
  156 +void RadialSweepViewImpl::SetFinalSector( Dali::Radian finalSector)
  157 +{
  158 + mFinalSector = finalSector;
  159 +}
  160 +
  161 +void RadialSweepViewImpl::SetInitialActorAngle( Dali::Radian initialAngle )
  162 +{
  163 + mInitialActorAngle = initialAngle;
  164 + mRotateActors = true;
  165 +}
  166 +
  167 +void RadialSweepViewImpl::SetFinalActorAngle( Dali::Radian finalAngle )
  168 +{
  169 + mFinalActorAngle = finalAngle;
  170 + mRotateActors = true;
  171 +}
  172 +
  173 +float RadialSweepViewImpl::GetDuration( )
  174 +{
  175 + return mDuration;
  176 +}
  177 +
  178 +float RadialSweepViewImpl::GetDiameter( )
  179 +{
  180 + return mDiameter;
  181 +}
  182 +
  183 +Dali::Radian RadialSweepViewImpl::GetInitialAngle( )
  184 +{
  185 + return mInitialAngle;
  186 +}
  187 +
  188 +Dali::Radian RadialSweepViewImpl::GetFinalAngle( )
  189 +{
  190 + return mFinalAngle;
  191 +}
  192 +
  193 +Dali::Radian RadialSweepViewImpl::GetInitialSector( )
  194 +{
  195 + return mInitialSector;
  196 +}
  197 +
  198 +Dali::Radian RadialSweepViewImpl::GetFinalSector( )
  199 +{
  200 + return mFinalSector;
  201 +}
  202 +
  203 +Dali::Radian RadialSweepViewImpl::GetInitialActorAngle( )
  204 +{
  205 + return mInitialActorAngle;
  206 +}
  207 +
  208 +Dali::Radian RadialSweepViewImpl::GetFinalActorAngle( )
  209 +{
  210 + return mFinalActorAngle;
  211 +}
  212 +
  213 +void RadialSweepViewImpl::RotateActorsWithStencil(bool rotate)
  214 +{
  215 + mRotateActorsWithStencil = rotate;
  216 +}
  217 +
  218 +void RadialSweepViewImpl::Add(Actor actor)
  219 +{
  220 + if( ! mLayer )
  221 + {
  222 + mLayer = Layer::New();
  223 + Self().Add(mLayer);
  224 + mLayer.SetSize( Stage::GetCurrent().GetSize() );
  225 + mLayer.SetPositionInheritanceMode(USE_PARENT_POSITION);
  226 + }
  227 +
  228 + mLayer.Add(actor);
  229 +}
  230 +
  231 +void RadialSweepViewImpl::Activate( Animation anim, float offsetTime, float duration )
  232 +{
  233 + bool startAnimation=false;
  234 + if( ! anim )
  235 + {
  236 + mAnim = Animation::New( mDuration );
  237 + anim = mAnim;
  238 + startAnimation = true;
  239 + }
  240 +
  241 + if( ! mStencilActor )
  242 + {
  243 + CreateStencil( mInitialSector );
  244 + mLayer.Add( mStencilActor );
  245 + mStencilActor.SetScale(mDiameter);
  246 + }
  247 +
  248 + mStencilActor.SetOrientation( mInitialAngle, Vector3::ZAXIS );
  249 + mStencilActor.SetProperty( mRotationAngleIndex, mInitialSector.radian );
  250 +
  251 + if( mRotateActors )
  252 + {
  253 + for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
  254 + {
  255 + Actor actor = mLayer.GetChildAt(i);
  256 + if( actor != mStencilActor )
  257 + {
  258 + anim.AnimateTo( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( mInitialActorAngle ), Vector3::ZAXIS ) );
  259 + }
  260 + }
  261 + }
  262 +
  263 + anim.AnimateTo( Property( mStencilActor, mRotationAngleIndex ), mFinalSector.radian, mEasingFunction, TimePeriod( offsetTime, duration ) );
  264 + anim.AnimateTo( Property( mStencilActor, Actor::Property::ORIENTATION ), Quaternion( Radian( mFinalAngle ), Vector3::ZAXIS ), mEasingFunction, TimePeriod( offsetTime, duration ) );
  265 +
  266 + if( mRotateActorsWithStencil )
  267 + {
  268 + for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
  269 + {
  270 + Actor actor = mLayer.GetChildAt(i);
  271 + if( actor != mStencilActor )
  272 + {
  273 + anim.AnimateTo( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( mFinalAngle.radian - mInitialAngle.radian ) , Vector3::ZAXIS ), mEasingFunction, TimePeriod( offsetTime, duration ) );
  274 + }
  275 + }
  276 + }
  277 + else if( mRotateActors )
  278 + {
  279 + for(unsigned int i=0, count=mLayer.GetChildCount(); i<count; i++)
  280 + {
  281 + Actor actor = mLayer.GetChildAt(i);
  282 + if( actor != mStencilActor )
  283 + {
  284 + anim.AnimateTo( Property( actor, Actor::Property::ORIENTATION ), Quaternion( Radian( mFinalActorAngle ), Vector3::ZAXIS ), mEasingFunction, TimePeriod( offsetTime, duration ) );
  285 + }
  286 + }
  287 + }
  288 +
  289 +
  290 + if( startAnimation )
  291 + {
  292 + anim.SetLooping(true);
  293 + anim.Play();
  294 + }
  295 +}
  296 +
  297 +
  298 +void RadialSweepViewImpl::Deactivate()
  299 +{
  300 + if( mAnim )
  301 + {
  302 + mAnim.Stop();
  303 + }
  304 + // mLayer.Remove( mStencilActor );
  305 + // mStencilActor.Reset();
  306 + // mMesh.Reset();
  307 + // mMaterial.Reset();
  308 +}
  309 +
  310 +void RadialSweepViewImpl::CreateStencil( Radian initialSector )
  311 +{
  312 + // Create the stencil mesh geometry
  313 + // 3-----2
  314 + // | \ / |
  315 + // | 0--1 , 6
  316 + // | / \ |
  317 + // 4-----5
  318 +
  319 + struct VertexPosition { float angleIndex; Vector2 position1; Vector2 position2; };
  320 + VertexPosition vertexData[7] = { // With X coordinate inverted to make the animation go anti clockwise from left center
  321 + { 9.f, Vector2( 0.f, 0.f ), Vector2( 0.f, 0.f ) }, // center point, keep static
  322 + { 0.f, Vector2( -0.5f, 0.f ), Vector2( -0.5f, 0.f ) }, // vertex 1, 0 degree, keep static
  323 + { -1.f, Vector2( -0.5f, 0.5f ), Vector2( -0.5f, -0.5f ) }, // -45 ~ 45 degrees ( 0 ~ 45)
  324 + { 1.f, Vector2( -0.5f, -0.5f ), Vector2( 0.5f, -0.5f ) }, // 45 ~ 135 degrees
  325 + { 3.f, Vector2( 0.5f, -0.5f ), Vector2( 0.5f, 0.5f ) }, // 135 ~ 225 degrees
  326 + { 5.f, Vector2( 0.5f, 0.5f ), Vector2( -0.5f, 0.5f ) }, // 225 ~ 315 degrees
  327 + { 7.f, Vector2( -0.5f, 0.5f ), Vector2( -0.5f, -0.5f ) } // 315 ~ 405 degrees ( 315 ~ 359.999 )
  328 + };
  329 + Property::Map vertexFormat;
  330 + vertexFormat["aAngleIndex"] = Property::FLOAT;
  331 + vertexFormat["aPosition1"] = Property::VECTOR2;
  332 + vertexFormat["aPosition2"] = Property::VECTOR2;
  333 + PropertyBuffer vertices = PropertyBuffer::New( PropertyBuffer::STATIC, vertexFormat, 7u );
  334 + vertices.SetData( vertexData );
  335 +
  336 + unsigned int indexData[15] = { 0,1,2,0,2,3,0,3,4,0,4,5,0,5,6 };
  337 + Property::Map indexFormat;
  338 + indexFormat["indices"] = Property::UNSIGNED_INTEGER;
  339 + PropertyBuffer indices = PropertyBuffer::New( PropertyBuffer::STATIC, indexFormat, 15u );
  340 + indices.SetData( indexData );
  341 +
  342 + Geometry meshGeometry = Geometry::New();
  343 + meshGeometry.AddVertexBuffer( vertices );
  344 + meshGeometry.SetIndexBuffer( indices );
  345 +
  346 + // Create material
  347 + std::ostringstream vertexShaderStringStream;
  348 + vertexShaderStringStream<<VERTEX_SHADER_PREFIX<<VERTEX_SHADER;
  349 + Shader shader = Shader::New( vertexShaderStringStream.str(), FRAGMENT_SHADER );
  350 + Material material = Material::New( shader );
  351 +
  352 + // Create renderer
  353 + Renderer renderer = Renderer::New( meshGeometry, material );
  354 +
  355 + mStencilActor = Actor::New();
  356 + mStencilActor.AddRenderer( renderer );
  357 + mStencilActor.SetSize(1.f, 1.f);
  358 +
  359 + // register properties
  360 + mStartAngleIndex = mStencilActor.RegisterProperty("start-angle", 0.f);
  361 + mStencilActor.AddUniformMapping( mStartAngleIndex, "uStartAngle " );
  362 + mRotationAngleIndex = mStencilActor.RegisterProperty("rotation-angle", initialSector.radian);
  363 + mStencilActor.AddUniformMapping( mRotationAngleIndex, "uRotationAngle" );
  364 +
  365 + mStencilActor.SetDrawMode( DrawMode::STENCIL );
  366 + mStencilActor.SetPositionInheritanceMode(USE_PARENT_POSITION);
  367 +}
examples/radial-menu/radial-sweep-view-impl.h 0 → 100644
  1 +#ifndef DALI_DEMO_RADIAL_SWEEP_VIEW_IMPL_H
  2 +#define DALI_DEMO_RADIAL_SWEEP_VIEW_IMPL_H
  3 +
  4 +/*
  5 + * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +#include <dali-toolkit/dali-toolkit.h>
  22 +#include "radial-sweep-view.h"
  23 +
  24 +
  25 +/********************************************************************************
  26 + * Class to implement a layer with a radial sweep stencil mask and an actor tree
  27 + */
  28 +class RadialSweepViewImpl : public Dali::Toolkit::Internal::Control
  29 +{
  30 +public:
  31 + static RadialSweepView New();
  32 +
  33 + static RadialSweepView New( float duration,
  34 + float diameter,
  35 + Dali::Radian initialAngle,
  36 + Dali::Radian finalAngle,
  37 + Dali::Radian initialSector,
  38 + Dali::Radian finalSector );
  39 +
  40 + RadialSweepViewImpl( float duration,
  41 + float diameter,
  42 + Dali::Radian initialAngle,
  43 + Dali::Radian finalAngle,
  44 + Dali::Radian initialSector,
  45 + Dali::Radian finalSector );
  46 +
  47 + void SetDuration(float duration);
  48 + void SetEasingFunction( Dali::AlphaFunction easingFunction );
  49 +
  50 + void SetDiameter(float diameter);
  51 + void SetInitialAngle( Dali::Radian initialAngle);
  52 + void SetFinalAngle( Dali::Radian finalAngle);
  53 + void SetInitialSector( Dali::Radian initialSector);
  54 + void SetFinalSector( Dali::Radian finalSector);
  55 + void SetInitialActorAngle( Dali::Radian initialAngle );
  56 + void SetFinalActorAngle( Dali::Radian finalAngle );
  57 +
  58 + float GetDuration( );
  59 + float GetDiameter( );
  60 + Dali::Radian GetInitialAngle( );
  61 + Dali::Radian GetFinalAngle( );
  62 + Dali::Radian GetInitialSector( );
  63 + Dali::Radian GetFinalSector( );
  64 + Dali::Radian GetInitialActorAngle( );
  65 + Dali::Radian GetFinalActorAngle( );
  66 +
  67 + void RotateActorsWithStencil(bool rotate);
  68 +
  69 + void Add( Dali::Actor actor );
  70 +
  71 + void Activate( Dali::Animation anim = Dali::Animation(), float offsetTime=0, float duration=2.0f );
  72 +
  73 + void Deactivate();
  74 +
  75 +private:
  76 +
  77 + /**
  78 + * Create the stencil mask
  79 + */
  80 + void CreateStencil(Dali::Radian initialSector );
  81 +
  82 +private:
  83 + Dali::Layer mLayer;
  84 + Dali::Animation mAnim;
  85 + float mDuration;
  86 + float mDiameter;
  87 + Dali::Radian mInitialAngle;
  88 + Dali::Radian mFinalAngle;
  89 + Dali::Radian mInitialSector;
  90 + Dali::Radian mFinalSector;
  91 + Dali::Radian mInitialActorAngle;
  92 + Dali::Radian mFinalActorAngle;
  93 + Dali::AlphaFunction mEasingFunction;
  94 + Dali::Actor mStencilActor; ///< Stencil actor which generates mask
  95 + Dali::Property::Index mStartAngleIndex; ///< Index of start-angle property
  96 + Dali::Property::Index mRotationAngleIndex; ///< Index of rotation-angle property
  97 + bool mRotateActorsWithStencil:1;
  98 + bool mRotateActors;
  99 +};
  100 +
  101 +
  102 +inline RadialSweepViewImpl& GetImpl( RadialSweepView& obj )
  103 +{
  104 + DALI_ASSERT_ALWAYS(obj);
  105 + Dali::RefObject& handle = obj.GetImplementation();
  106 + return static_cast<RadialSweepViewImpl&>(handle);
  107 +}
  108 +
  109 +inline const RadialSweepViewImpl& GetImpl( const RadialSweepView& obj )
  110 +{
  111 + DALI_ASSERT_ALWAYS(obj);
  112 + const Dali::RefObject& handle = obj.GetImplementation();
  113 + return static_cast<const RadialSweepViewImpl&>(handle);
  114 +}
  115 +
  116 +
  117 +
  118 +#endif // DALI_DEMO_RADIAL_SWEEP_VIEW_IMPL_H
examples/radial-menu/radial-sweep-view.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2015 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 +#include "radial-sweep-view.h"
  19 +#include "radial-sweep-view-impl.h"
  20 +
  21 +using namespace Dali;
  22 +
  23 +RadialSweepView::RadialSweepView()
  24 +{
  25 +}
  26 +
  27 +RadialSweepView::RadialSweepView(const RadialSweepView& handle)
  28 +: Control(handle)
  29 +{
  30 +}
  31 +
  32 +RadialSweepView& RadialSweepView::operator=(const RadialSweepView& rhs)
  33 +{
  34 + if( &rhs != this )
  35 + {
  36 + Control::operator=(rhs);
  37 + }
  38 + return *this;
  39 +}
  40 +
  41 +RadialSweepView::~RadialSweepView()
  42 +{
  43 +}
  44 +
  45 +RadialSweepView RadialSweepView::DownCast( BaseHandle handle )
  46 +{
  47 + return Control::DownCast<RadialSweepView, RadialSweepViewImpl>(handle);
  48 +}
  49 +
  50 +RadialSweepView RadialSweepView::New( )
  51 +{
  52 + return RadialSweepViewImpl::New();
  53 +}
  54 +
  55 +RadialSweepView RadialSweepView::New( float duration,
  56 + float diameter,
  57 + Radian initialAngle,
  58 + Radian finalAngle,
  59 + Radian initialSector,
  60 + Radian finalSector )
  61 +{
  62 + return RadialSweepViewImpl::New(duration, diameter, initialAngle, finalAngle, initialSector, finalSector );
  63 +}
  64 +
  65 +RadialSweepView::RadialSweepView( RadialSweepViewImpl& impl )
  66 +: Control( impl )
  67 +{
  68 +}
  69 +
  70 +RadialSweepView::RadialSweepView( Dali::Internal::CustomActor* impl )
  71 +: Control( impl )
  72 +{
  73 + VerifyCustomActorPointer<RadialSweepViewImpl>(impl);
  74 +}
  75 +
  76 +void RadialSweepView::SetDuration(float duration)
  77 +{
  78 + GetImpl(*this).SetDuration(duration);
  79 +}
  80 +
  81 +void RadialSweepView::SetEasingFunction( Dali::AlphaFunction easingFunction )
  82 +{
  83 + GetImpl(*this).SetEasingFunction( easingFunction );
  84 +}
  85 +
  86 +void RadialSweepView::SetDiameter(float diameter)
  87 +{
  88 + GetImpl(*this).SetDiameter(diameter);
  89 +}
  90 +
  91 +void RadialSweepView::SetInitialAngle( Dali::Radian initialAngle)
  92 +{
  93 + GetImpl(*this).SetInitialAngle(initialAngle);
  94 +}
  95 +
  96 +void RadialSweepView::SetFinalAngle( Dali::Radian finalAngle)
  97 +{
  98 + GetImpl(*this).SetFinalAngle(finalAngle);
  99 +}
  100 +
  101 +void RadialSweepView::SetInitialSector( Dali::Radian initialSector)
  102 +{
  103 + GetImpl(*this).SetInitialSector(initialSector);
  104 +}
  105 +
  106 +void RadialSweepView::SetFinalSector( Dali::Radian finalSector)
  107 +{
  108 + GetImpl(*this).SetFinalSector(finalSector);
  109 +}
  110 +
  111 +void RadialSweepView::SetInitialActorAngle( Dali::Radian initialAngle )
  112 +{
  113 + GetImpl(*this).SetInitialActorAngle(initialAngle);
  114 +}
  115 +
  116 +void RadialSweepView::SetFinalActorAngle( Dali::Radian finalAngle )
  117 +{
  118 + GetImpl(*this).SetFinalActorAngle(finalAngle);
  119 +}
  120 +
  121 +float RadialSweepView::GetDuration( )
  122 +{
  123 + return GetImpl(*this).GetDuration();
  124 +}
  125 +
  126 +float RadialSweepView::GetDiameter( )
  127 +{
  128 + return GetImpl(*this).GetDiameter();
  129 +}
  130 +
  131 +Dali::Radian RadialSweepView::GetInitialAngle( )
  132 +{
  133 + return GetImpl(*this).GetInitialAngle();
  134 +}
  135 +
  136 +Dali::Radian RadialSweepView::GetFinalAngle( )
  137 +{
  138 + return GetImpl(*this).GetFinalAngle();
  139 +}
  140 +
  141 +Dali::Radian RadialSweepView::GetInitialSector( )
  142 +{
  143 + return GetImpl(*this).GetInitialSector();
  144 +}
  145 +
  146 +Dali::Radian RadialSweepView::GetFinalSector( )
  147 +{
  148 + return GetImpl(*this).GetFinalSector();
  149 +}
  150 +
  151 +Dali::Radian RadialSweepView::GetInitialActorAngle( )
  152 +{
  153 + return GetImpl(*this).GetInitialActorAngle();
  154 +}
  155 +
  156 +Dali::Radian RadialSweepView::GetFinalActorAngle( )
  157 +{
  158 + return GetImpl(*this).GetFinalActorAngle();
  159 +}
  160 +
  161 +void RadialSweepView::RotateActorsWithStencil(bool rotate)
  162 +{
  163 + GetImpl(*this).RotateActorsWithStencil(rotate);
  164 +}
  165 +
  166 +void RadialSweepView::Add(Actor actor)
  167 +{
  168 + GetImpl(*this).Add(actor);
  169 +}
  170 +
  171 +void RadialSweepView::Activate()
  172 +{
  173 + GetImpl(*this).Activate();
  174 +}
  175 +
  176 +void RadialSweepView::Activate( Dali::Animation anim, float offsetTime, float duration )
  177 +{
  178 + GetImpl(*this).Activate(anim, offsetTime, duration);
  179 +}
  180 +
  181 +void RadialSweepView::Deactivate()
  182 +{
  183 + GetImpl(*this).Deactivate();
  184 +}
examples/radial-menu/radial-sweep-view.h 0 → 100644
  1 +#ifndef DALI_DEMO_RADIAL_SWEEP_VIEW_H
  2 +#define DALI_DEMO_RADIAL_SWEEP_VIEW_H
  3 +
  4 +/*
  5 + * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  6 + *
  7 + * Licensed under the Apache License, Version 2.0 (the "License");
  8 + * you may not use this file except in compliance with the License.
  9 + * You may obtain a copy of the License at
  10 + *
  11 + * http://www.apache.org/licenses/LICENSE-2.0
  12 + *
  13 + * Unless required by applicable law or agreed to in writing, software
  14 + * distributed under the License is distributed on an "AS IS" BASIS,
  15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16 + * See the License for the specific language governing permissions and
  17 + * limitations under the License.
  18 + *
  19 + */
  20 +
  21 +#include <dali-toolkit/dali-toolkit.h>
  22 +
  23 +class RadialSweepViewImpl;
  24 +
  25 +
  26 +/********************************************************************************
  27 + * Handle to RadialSweepView implementation
  28 + */
  29 +class RadialSweepView : public Dali::Toolkit::Control
  30 +{
  31 +public:
  32 + /**
  33 + * Create a new RadialSweepView with default parameters (2 second animation,
  34 + * no rotation, sweeping out a full circle).
  35 + */
  36 + static RadialSweepView New( );
  37 +
  38 + /**
  39 + * Create a new RadialSweepView.
  40 + * @param[in] duration The duration of the sweep animation
  41 + * @param[in] diameter The diameter of the stencil mask
  42 + * @param[in] initialAngle The initial angle of the anticlockwise line of the sweep sector
  43 + * @param[in] finalAngle The final angle of the anticlockwise line of the sweep sector
  44 + * @param[in] initialSector The angle of the starting sector
  45 + * @param[in] finalSector The angle of the sector at the end of the animation.
  46 + * Note, to cover the entire circle, use a value of 359.9999 degrees, not zero or 360 degrees.
  47 + *
  48 + * initial sector
  49 + * \ | .
  50 + * \ | .
  51 + * initialAngle \ | . final sector
  52 + * \| _|
  53 + * .________
  54 + */
  55 + static RadialSweepView New( float duration,
  56 + float diameter,
  57 + Dali::Radian initialAngle,
  58 + Dali::Radian finalAngle,
  59 + Dali::Radian initialSector,
  60 + Dali::Radian finalSector );
  61 +
  62 + void SetDuration(float duration);
  63 +
  64 + void SetEasingFunction( Dali::AlphaFunction easingFunction );
  65 +
  66 + void SetDiameter(float diameter);
  67 +
  68 + void SetInitialAngle( Dali::Radian initialAngle);
  69 +
  70 + void SetFinalAngle( Dali::Radian finalAngle);
  71 +
  72 + void SetInitialSector( Dali::Radian initialSector);
  73 +
  74 + void SetFinalSector( Dali::Radian finalSector);
  75 +
  76 + void SetInitialActorAngle( Dali::Radian initialAngle );
  77 +
  78 + void SetFinalActorAngle( Dali::Radian finalAngle );
  79 +
  80 + float GetDuration( );
  81 +
  82 + float GetDiameter( );
  83 +
  84 + Dali::Radian GetInitialAngle( );
  85 +
  86 + Dali::Radian GetFinalAngle( );
  87 +
  88 + Dali::Radian GetInitialSector( );
  89 +
  90 + Dali::Radian GetFinalSector( );
  91 +
  92 + Dali::Radian GetInitialActorAngle( );
  93 +
  94 + Dali::Radian GetFinalActorAngle( );
  95 +
  96 + /**
  97 + * @param[in] rotate True if the actors should rotate with the stencil
  98 + */
  99 + void RotateActorsWithStencil(bool rotate);
  100 +
  101 + /**
  102 + * Add actors to the view
  103 + */
  104 + void Add(Actor actor);
  105 +
  106 + /**
  107 + * Activate the sweep animation
  108 + */
  109 + void Activate( );
  110 +
  111 + void Activate( Dali::Animation anim, float offsetTime, float duration );
  112 +
  113 + /**
  114 + * Deactivate the sweep animation
  115 + */
  116 + void Deactivate();
  117 +
  118 + /**
  119 + * Default constructor. Create an uninitialized handle.
  120 + */
  121 + RadialSweepView();
  122 +
  123 + /**
  124 + * Copy constructor
  125 + */
  126 + RadialSweepView(const RadialSweepView& handle);
  127 +
  128 + /**
  129 + * Assignment operator
  130 + */
  131 + RadialSweepView& operator=(const RadialSweepView& rhs);
  132 +
  133 + /**
  134 + * Destructor
  135 + */
  136 + ~RadialSweepView();
  137 +
  138 + /**
  139 + * Downcast method
  140 + */
  141 + static RadialSweepView DownCast( BaseHandle handle );
  142 +
  143 +public: // Not for use by application developers
  144 +
  145 + RadialSweepView( RadialSweepViewImpl& impl );
  146 +
  147 + RadialSweepView( Dali::Internal::CustomActor* impl );
  148 +};
  149 +
  150 +#endif
examples/refraction-effect/refraction-effect-example.cpp 0 → 100644
  1 +/*
  2 + * Copyright (c) 2015 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 +#include <dali/dali.h>
  19 +#include <dali-toolkit/dali-toolkit.h>
  20 +#include "shared/view.h"
  21 +
  22 +#include <fstream>
  23 +#include <sstream>
  24 +#include <limits>
  25 +
  26 +using namespace Dali;
  27 +
  28 +namespace
  29 +{
  30 +const char * const APPLICATION_TITLE( "Refraction Effect" );
  31 +const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
  32 +const char * const CHANGE_TEXTURE_ICON( DALI_IMAGE_DIR "icon-change.png" );
  33 +const char * const CHANGE_MESH_ICON( DALI_IMAGE_DIR "icon-replace.png" );
  34 +
  35 +const char* MESH_FILES[] =
  36 +{
  37 + DALI_MODEL_DIR "surface_pattern_v01.obj",
  38 + DALI_MODEL_DIR "surface_pattern_v02.obj"
  39 +};
  40 +const unsigned int NUM_MESH_FILES( sizeof( MESH_FILES ) / sizeof( MESH_FILES[0] ) );
  41 +
  42 +const char* TEXTURE_IMAGES[]=
  43 +{
  44 + DALI_IMAGE_DIR "background-1.jpg",
  45 + DALI_IMAGE_DIR "background-2.jpg",
  46 + DALI_IMAGE_DIR "background-3.jpg",
  47 + DALI_IMAGE_DIR "background-4.jpg"
  48 +};
  49 +const unsigned int NUM_TEXTURE_IMAGES( sizeof( TEXTURE_IMAGES ) / sizeof( TEXTURE_IMAGES[0] ) );
  50 +
  51 +struct LightOffsetConstraint
  52 +{
  53 + LightOffsetConstraint( float radius )
  54 + : mRadius( radius )
  55 + {
  56 + }
  57 +
  58 + void operator()( Vector2& current, const PropertyInputContainer& inputs )
  59 + {
  60 + float spinAngle = inputs[0]->GetFloat();
  61 + current.x = cos( spinAngle );
  62 + current.y = sin( spinAngle );
  63 +
  64 + current *= mRadius;
  65 + }
  66 +
  67 + float mRadius;
  68 +};
  69 +
  70 +/**
  71 + * @brief Load an image, scaled-down to no more than the stage dimensions.
  72 + *
  73 + * Uses image scaling mode SCALE_TO_FILL to resize the image at
  74 + * load time to cover the entire stage with pixels with no borders,
  75 + * and filter mode BOX_THEN_LINEAR to sample the image with maximum quality.
  76 + */
  77 +ResourceImage LoadStageFillingImage( const char * const imagePath )
  78 +{
  79 + Size stageSize = Stage::GetCurrent().GetSize();
  80 + return ResourceImage::New( imagePath, ImageDimensions( stageSize.x, stageSize.y ), Dali::FittingMode::SCALE_TO_FILL, Dali::SamplingMode::BOX_THEN_LINEAR );
  81 +}
  82 +
  83 +/**
  84 + * structure of the vertex in the mesh
  85 + */
  86 +struct Vertex
  87 +{
  88 + Vector3 position;
  89 + Vector3 normal;
  90 + Vector2 textureCoord;
  91 +
  92 + Vertex()
  93 + {}
  94 +
  95 + Vertex( const Vector3& position, const Vector3& normal, const Vector2& textureCoord )
  96 + : position( position ), normal( normal ), textureCoord( textureCoord )
  97 + {}
  98 +};
  99 +
  100 +/************************************************************************************************
  101 + *** The shader source is used when the MeshActor is not touched***
  102 + ************************************************************************************************/
  103 +const char* VERTEX_SHADER_FLAT = DALI_COMPOSE_SHADER(
  104 +attribute mediump vec3 aPosition;\n
  105 +attribute mediump vec3 aNormal;\n
  106 +attribute highp vec2 aTexCoord;\n
  107 +uniform mediump mat4 uMvpMatrix;\n
  108 +varying mediump vec2 vTexCoord;\n
  109 +void main()\n
  110 +{\n
  111 + gl_Position = uMvpMatrix * vec4( aPosition.xy, 0.0, 1.0 );\n
  112 + vTexCoord = aTexCoord.xy;\n
  113 +}\n
  114 +);
  115 +
  116 +const char* FRAGMENT_SHADER_FLAT = DALI_COMPOSE_SHADER(
  117 +uniform lowp vec4 uColor;\n
  118 +uniform sampler2D sTexture;\n
  119 +varying mediump vec2 vTexCoord;\n
  120 +void main()\n
  121 +{\n
  122 + gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n
  123 +}\n
  124 +);
  125 +
  126 +/************************************************************
  127 + ** Custom refraction effect shader***************************
  128 + ************************************************************/
  129 +const char* VERTEX_SHADER_REFRACTION = DALI_COMPOSE_SHADER(
  130 +attribute mediump vec3 aPosition;\n
  131 +attribute mediump vec3 aNormal;\n
  132 +attribute highp vec2 aTexCoord;\n
  133 +uniform mediump mat4 uMvpMatrix;\n
  134 +varying mediump vec4 vVertex;\n
  135 +varying mediump vec3 vNormal;\n
  136 +varying mediump vec2 vTexCoord;\n
  137 +varying mediump vec2 vTextureOffset;\n
  138 +void main()\n
  139 +{\n
  140 + gl_Position = uMvpMatrix * vec4( aPosition.xy, 0.0, 1.0 );\n
  141 + vTexCoord = aTexCoord.xy;\n
  142 +
  143 + vNormal = aNormal;\n
  144 + vVertex = vec4( aPosition, 1.0 );\n
  145 + float length = max(0.01, length(aNormal.xy)) * 40.0;\n
  146 + vTextureOffset = aNormal.xy / length;\n
  147 +}\n
  148 +);
  149 +
  150 +const char* FRAGMENT_SHADER_REFRACTION = DALI_COMPOSE_SHADER(
  151 +precision mediump float;\n
  152 +uniform mediump float uEffectStrength;\n
  153 +uniform mediump vec3 uLightPosition;\n
  154 +uniform mediump vec2 uLightXYOffset;\n
  155 +uniform mediump vec2 uLightSpinOffset;\n
  156 +uniform mediump float uLightIntensity;\n
  157 +uniform lowp vec4 uColor;\n
  158 +uniform sampler2D sTexture;\n
  159 +varying mediump vec4 vVertex;\n
  160 +varying mediump vec3 vNormal;\n
  161 +varying mediump vec2 vTexCoord;\n
  162 +varying mediump vec2 vTextureOffset;\n
  163 +
  164 +vec3 rgb2hsl(vec3 rgb)\n
  165 +{\n
  166 + float epsilon = 1.0e-10;\n
  167 + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);\n
  168 + vec4 P = mix(vec4(rgb.bg, K.wz), vec4(rgb.gb, K.xy), step(rgb.b, rgb.g));\n
  169 + vec4 Q = mix(vec4(P.xyw, rgb.r), vec4(rgb.r, P.yzx), step(P.x, rgb.r));\n
  170 + \n
  171 + // RGB -> HCV
  172 + float value = Q.x;\n
  173 + float chroma = Q.x - min(Q.w, Q.y);\n
  174 + float hue = abs(Q.z + (Q.w-Q.y) / (6.0*chroma+epsilon));\n
  175 + // HCV -> HSL
  176 + float lightness = value - chroma*0.5;\n
  177 + return vec3( hue, chroma/max( 1.0-abs(lightness*2.0-1.0), 1.0e-1 ), lightness );\n
  178 +}\n
  179 +
  180 +vec3 hsl2rgb( vec3 hsl )\n
  181 +{\n
  182 + // pure hue->RGB
  183 + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);\n
  184 + vec3 p = abs(fract(hsl.xxx + K.xyz) * 6.0 - K.www);\n
  185 + vec3 RGB = clamp(p - K.xxx, 0.0, 1.0);\n
  186 + \n
  187 + float chroma = ( 1.0 - abs( hsl.z*2.0-1.0 ) ) * hsl.y;\n
  188 + return ( RGB - 0.5 ) * chroma + hsl.z;\n
  189 +}\n
  190 +
  191 +void main()\n
  192 +{\n
  193 + vec3 normal = normalize( vNormal);\n
  194 +
  195 + vec3 lightPosition = uLightPosition + vec3(uLightXYOffset+uLightSpinOffset, 0.0);\n
  196 + mediump vec3 vecToLight = normalize( (lightPosition - vVertex.xyz) * 0.01 );\n
  197 + mediump float spotEffect = pow( max(0.05, vecToLight.z ) - 0.05, 8.0);\n
  198 +
  199 + spotEffect = spotEffect * uEffectStrength;\n
  200 + mediump float lightDiffuse = ( ( dot( vecToLight, normal )-0.75 ) *uLightIntensity ) * spotEffect;\n
  201 +
  202 + lowp vec4 color = texture2D( sTexture, vTexCoord + vTextureOffset * spotEffect );\n
  203 + vec3 lightedColor = hsl2rgb( rgb2hsl(color.rgb) + vec3(0.0,0.0,lightDiffuse) );\n
  204 +
  205 + gl_FragColor = vec4( lightedColor, color.a ) * uColor;\n
  206 +}\n
  207 +);
  208 +
  209 +} // namespace
  210 +
  211 +
  212 +/*************************************************/
  213 +/*Demo using RefractionEffect*****************/
  214 +/*************************************************/
  215 +class RefractionEffectExample : public ConnectionTracker
  216 +{
  217 +public:
  218 + RefractionEffectExample( Application &application )
  219 + : mApplication( application ),
  220 + mCurrentTextureId( 1 ),
  221 + mCurrentMeshId( 0 )
  222 + {
  223 + // Connect to the Application's Init signal
  224 + application.InitSignal().Connect(this, &RefractionEffectExample::Create);
  225 + }
  226 +
  227 + ~RefractionEffectExample()
  228 + {
  229 + }
  230 +
  231 +private:
  232 +
  233 + // The Init signal is received once (only) during the Application lifetime
  234 + void Create(Application& application)
  235 + {
  236 + DemoHelper::RequestThemeChange();
  237 +
  238 + Stage stage = Stage::GetCurrent();
  239 + Vector2 stageSize = stage.GetSize();
  240 +
  241 + stage.KeyEventSignal().Connect(this, &RefractionEffectExample::OnKeyEvent);
  242 +
  243 + // Creates a default view with a default tool bar.
  244 + // The view is added to the stage.
  245 + Toolkit::ToolBar toolBar;
  246 + Toolkit::Control view;
  247 + mContent = DemoHelper::CreateView( application,
  248 + view,
  249 + toolBar,
  250 + "",
  251 + TOOLBAR_IMAGE,
  252 + APPLICATION_TITLE );
  253 +
  254 + // Add a button to change background. (right of toolbar)
  255 + mChangeTextureButton = Toolkit::PushButton::New();
  256 + mChangeTextureButton.SetBackgroundImage( ResourceImage::New( CHANGE_TEXTURE_ICON ) );
  257 + mChangeTextureButton.ClickedSignal().Connect( this, &RefractionEffectExample::OnChangeTexture );
  258 + toolBar.AddControl( mChangeTextureButton,
  259 + DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
  260 + Toolkit::Alignment::HorizontalRight,
  261 + DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
  262 + // Add a button to change mesh pattern. ( left of bar )
  263 + mChangeMeshButton = Toolkit::PushButton::New();
  264 + mChangeMeshButton.SetBackgroundImage( ResourceImage::New( CHANGE_MESH_ICON ) );
  265 + mChangeMeshButton.ClickedSignal().Connect( this, &RefractionEffectExample::OnChangeMesh );
  266 + toolBar.AddControl( mChangeMeshButton,
  267 + DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage,
  268 + Toolkit::Alignment::HorizontalLeft,
  269 + DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
  270 +
  271 +
  272 +
  273 + // shader used when the screen is not touched, render a flat surface
  274 + mShaderFlat = Shader::New( VERTEX_SHADER_FLAT, FRAGMENT_SHADER_FLAT );
  275 + mGeometry = CreateGeometry( MESH_FILES[mCurrentMeshId] );
  276 +
  277 + Image texture = LoadStageFillingImage( TEXTURE_IMAGES[mCurrentTextureId] );
  278 + mSampler = Sampler::New( texture, "sTexture" );
  279 + mMaterial = Material::New( mShaderFlat );
  280 + mMaterial.AddSampler( mSampler );
  281 +
  282 + mRenderer = Renderer::New( mGeometry, mMaterial );
  283 +
  284 + mMeshActor = Actor::New();
  285 + mMeshActor.AddRenderer( mRenderer );
  286 + mMeshActor.SetSize( stageSize );
  287 + mMeshActor.SetParentOrigin(ParentOrigin::CENTER);
  288 + mContent.Add( mMeshActor );
  289 +
  290 + // Connect the callback to the touch signal on the mesh actor
  291 + mContent.TouchedSignal().Connect( this, &RefractionEffectExample::OnTouch );
  292 +
  293 + // shader used when the finger is touching the screen. render refraction effect
  294 + mShaderRefraction = Shader::New( VERTEX_SHADER_REFRACTION, FRAGMENT_SHADER_REFRACTION );
  295 +
  296 + // register uniforms
  297 + mLightXYOffsetIndex = mMeshActor.RegisterProperty( "light-XY-offset", Vector2::ZERO );
  298 + mMeshActor.AddUniformMapping( mLightXYOffsetIndex, "uLightXYOffset" );
  299 +
  300 + mLightIntensityIndex = mMeshActor.RegisterProperty( "light-intensity", 2.5f );
  301 + mMeshActor.AddUniformMapping( mLightIntensityIndex, "uLightIntensity" );
  302 +
  303 + mEffectStrengthIndex = mMeshActor.RegisterProperty( "effect-strength", 0.f );
  304 + mMeshActor.AddUniformMapping( mEffectStrengthIndex, "uEffectStrength" );
  305 +
  306 + Vector3 lightPosition( -stageSize.x*0.5f, -stageSize.y*0.5f, stageSize.x*0.5f ); // top_left
  307 + Property::Index lightPositionIndex = mMeshActor.RegisterProperty( "light-position", lightPosition );
  308 + mMeshActor.AddUniformMapping( lightPositionIndex, "uLightPosition");
  309 +
  310 + Property::Index lightSpinOffsetIndex = mMeshActor.RegisterProperty( "light-spin-offset", Vector2::ZERO );
  311 + mMeshActor.AddUniformMapping( lightSpinOffsetIndex, "uLightSpinOffset" );
  312 +
  313 + mSpinAngleIndex = mMeshActor.RegisterProperty("spin-angle", 0.f );
  314 + Constraint constraint = Constraint::New<Vector2>( mMeshActor, lightSpinOffsetIndex, LightOffsetConstraint(stageSize.x*0.1f) );
  315 + constraint.AddSource( LocalSource(mSpinAngleIndex) );
  316 + constraint.Apply();
  317 +
  318 + // the animation which spin the light around the finger touch position
  319 + mLightAnimation = Animation::New(2.f);
  320 + mLightAnimation.AnimateTo( Property( mMeshActor, mSpinAngleIndex ), Math::PI*2.f );
  321 + mLightAnimation.SetLooping( true );
  322 + mLightAnimation.Pause();
  323 + }
  324 +
  325 + void SetLightXYOffset( const Vector2& offset )
  326 + {
  327 + mMeshActor.SetProperty( mLightXYOffsetIndex, offset );
  328 + }
  329 +
  330 + /**
  331 + * Create a mesh actor with different geometry to replace the current one
  332 + */
  333 + bool OnChangeMesh( Toolkit::Button button )
  334 + {
  335 + mCurrentMeshId = ( mCurrentMeshId + 1 ) % NUM_MESH_FILES;
  336 + mGeometry = CreateGeometry( MESH_FILES[mCurrentMeshId] );
  337 + mRenderer.SetGeometry( mGeometry );
  338 +
  339 + return true;
  340 + }
  341 +
  342 + bool OnChangeTexture( Toolkit::Button button )
  343 + {
  344 + mCurrentTextureId = ( mCurrentTextureId + 1 ) % NUM_TEXTURE_IMAGES;
  345 + Image texture = LoadStageFillingImage( TEXTURE_IMAGES[mCurrentTextureId] );
  346 + mSampler.SetImage( texture );
  347 + return true;
  348 + }
  349 +
  350 + bool OnTouch( Actor actor , const TouchEvent& event )
  351 + {
  352 + const TouchPoint &point = event.GetPoint(0);
  353 + switch(point.state)
  354 + {
  355 + case TouchPoint::Down:
  356 + {
  357 + mMaterial.SetShader( mShaderRefraction );
  358 +
  359 + SetLightXYOffset( point.screen );
  360 +
  361 + mLightAnimation.Play();
  362 +
  363 + if( mStrenghAnimation )
  364 + {
  365 + mStrenghAnimation.Clear();
  366 + }
  367 +
  368 + mStrenghAnimation= Animation::New(0.5f);
  369 + mStrenghAnimation.AnimateTo( Property( mMeshActor, mEffectStrengthIndex ), 1.f );
  370 + mStrenghAnimation.Play();
  371 +
  372 + break;
  373 + }
  374 + case TouchPoint::Motion:
  375 + {
  376 + // make the light position following the finger movement
  377 + SetLightXYOffset( point.screen );
  378 + break;
  379 + }
  380 + case TouchPoint::Up:
  381 + case TouchPoint::Leave:
  382 + case TouchPoint::Interrupted:
  383 + {
  384 + mLightAnimation.Pause();
  385 +
  386 + if( mStrenghAnimation )
  387 + {
  388 + mStrenghAnimation.Clear();
  389 + }
  390 + mStrenghAnimation = Animation::New(0.5f);
  391 + mStrenghAnimation.AnimateTo( Property( mMeshActor, mEffectStrengthIndex ), 0.f );
  392 + mStrenghAnimation.FinishedSignal().Connect( this, &RefractionEffectExample::OnTouchFinished );
  393 + mStrenghAnimation.Play();
  394 + break;
  395 + }
  396 + case TouchPoint::Stationary:
  397 + case TouchPoint::Last:
  398 + default:
  399 + {
  400 + break;
  401 + }
  402 + }
  403 +
  404 + return true;
  405 + }
  406 +
  407 + void OnTouchFinished( Animation& source )
  408 + {
  409 + mMaterial.SetShader( mShaderFlat );
  410 + SetLightXYOffset( Vector2::ZERO );
  411 + }
  412 +
  413 + Geometry CreateGeometry(const std::string& objFileName)
  414 + {
  415 + std::vector<Vector3> vertexPositions;
  416 + Vector<unsigned int> faceIndices;
  417 + Vector<float> boundingBox;
  418 + // read the vertice and faces from the .obj file, and record the bounding box
  419 + ReadObjFile( objFileName, boundingBox, vertexPositions, faceIndices );
  420 +
  421 + std::vector<Vector2> textureCoordinates;
  422 + // align the mesh, scale it to fit the screen size, and calculate the texture coordinate for each vertex
  423 + ShapeResizeAndTexureCoordinateCalculation( boundingBox, vertexPositions, textureCoordinates );
  424 +
  425 + // re-organize the mesh, the vertices are duplicated, each vertex only belongs to one triangle.
  426 + // Without sharing vertex between triangle, so we can manipulate the texture offset on each triangle conveniently.
  427 + std::vector<Vertex> vertices;
  428 +
  429 + std::size_t size = faceIndices.Size();
  430 + vertices.reserve( size );
  431 +
  432 + for( std::size_t i=0; i<size; i=i+3 )
  433 + {
  434 + Vector3 edge1 = vertexPositions[ faceIndices[i+2] ] - vertexPositions[ faceIndices[i] ];
  435 + Vector3 edge2 = vertexPositions[ faceIndices[i+1] ] - vertexPositions[ faceIndices[i] ];
  436 + Vector3 normal = edge1.Cross(edge2);
  437 + normal.Normalize();
  438 +
  439 + // make sure all the faces are front-facing
  440 + if( normal.z > 0 )
  441 + {
  442 + vertices.push_back( Vertex( vertexPositions[ faceIndices[i] ], normal, textureCoordinates[ faceIndices[i] ] ) );
  443 + vertices.push_back( Vertex( vertexPositions[ faceIndices[i+1] ], normal, textureCoordinates[ faceIndices[i+1] ] ) );
  444 + vertices.push_back( Vertex( vertexPositions[ faceIndices[i+2] ], normal, textureCoordinates[ faceIndices[i+2] ] ) );
  445 + }
  446 + else
  447 + {
  448 + normal *= -1.f;
  449 + vertices.push_back( Vertex( vertexPositions[ faceIndices[i] ], normal, textureCoordinates[ faceIndices[i] ] ) );
  450 + vertices.push_back( Vertex( vertexPositions[ faceIndices[i+2] ], normal, textureCoordinates[ faceIndices[i+2] ] ) );
  451 + vertices.push_back( Vertex( vertexPositions[ faceIndices[i+1] ], normal, textureCoordinates[ faceIndices[i+1] ] ) );
  452 + }
  453 + }
  454 +
  455 + Property::Map vertexFormat;
  456 + vertexFormat["aPosition"] = Property::VECTOR3;
  457 + vertexFormat["aNormal"] = Property::VECTOR3;
  458 + vertexFormat["aTexCoord"] = Property::VECTOR2;
  459 + PropertyBuffer surfaceVertices = PropertyBuffer::New( PropertyBuffer::STATIC, vertexFormat, vertices.size() );
  460 + surfaceVertices.SetData( &vertices[0] );
  461 +
  462 + Geometry surface = Geometry::New();
  463 + surface.AddVertexBuffer( surfaceVertices );
  464 +
  465 + return surface;
  466 + }
  467 +
  468 + void ReadObjFile( const std::string& objFileName,
  469 + Vector<float>& boundingBox,
  470 + std::vector<Vector3>& vertexPositions,
  471 + Vector<unsigned int>& faceIndices)
  472 + {
  473 + std::ifstream ifs( objFileName.c_str(), std::ios::in );
  474 +
  475 + boundingBox.Resize( 6 );
  476 + boundingBox[0]=boundingBox[2]=boundingBox[4] = std::numeric_limits<float>::max();
  477 + boundingBox[1]=boundingBox[3]=boundingBox[5] = -std::numeric_limits<float>::max();
  478 +
  479 + std::string line;
  480 + while( std::getline( ifs, line ) )
  481 + {
  482 + if( line[0] == 'v' && std::isspace(line[1])) // vertex
  483 + {
  484 + std::istringstream iss(line.substr(2), std::istringstream::in);
  485 + unsigned int i = 0;
  486 + Vector3 vertex;
  487 + while( iss >> vertex[i++] && i < 3);
  488 + if( vertex.x < boundingBox[0] ) boundingBox[0] = vertex.x;
  489 + if( vertex.x > boundingBox[1] ) boundingBox[1] = vertex.x;
  490 + if( vertex.y < boundingBox[2] ) boundingBox[2] = vertex.y;
  491 + if( vertex.y > boundingBox[3] ) boundingBox[3] = vertex.y;
  492 + if( vertex.z < boundingBox[4] ) boundingBox[4] = vertex.z;
  493 + if( vertex.z > boundingBox[5] ) boundingBox[5] = vertex.z;
  494 + vertexPositions.push_back( vertex );
  495 + }
  496 + else if( line[0] == 'f' ) //face
  497 + {
  498 + unsigned int numOfInt = 3;
  499 + while( true )
  500 + {
  501 + std::size_t found = line.find('/');
  502 + if( found == std::string::npos )
  503 + {
  504 + break;
  505 + }
  506 + line[found] = ' ';
  507 + numOfInt++;
  508 + }
  509 +
  510 + std::istringstream iss(line.substr(2), std::istringstream::in);
  511 + unsigned int indices[ numOfInt ];
  512 + unsigned int i=0;
  513 + while( iss >> indices[i++] && i < numOfInt);
  514 + unsigned int step = (i+1) / 3;
  515 + faceIndices.PushBack( indices[0]-1 );
  516 + faceIndices.PushBack( indices[step]-1 );
  517 + faceIndices.PushBack( indices[2*step]-1 );
  518 + }
  519 + }
  520 +
  521 + ifs.close();
  522 + }
  523 +
  524 + void ShapeResizeAndTexureCoordinateCalculation( const Vector<float>& boundingBox,
  525 + std::vector<Vector3>& vertexPositions,
  526 + std::vector<Vector2>& textureCoordinates)
  527 + {
  528 + Vector3 bBoxSize( boundingBox[1] - boundingBox[0], boundingBox[3] - boundingBox[2], boundingBox[5] - boundingBox[4]);
  529 + Vector3 bBoxMinCorner( boundingBox[0], boundingBox[2], boundingBox[4] );
  530 +
  531 + Vector2 stageSize = Stage::GetCurrent().GetSize();
  532 + Vector3 scale( stageSize.x / bBoxSize.x, stageSize.y / bBoxSize.y, 1.f );
  533 + scale.z = (scale.x + scale.y)/2.f;
  534 +
  535 + textureCoordinates.reserve(vertexPositions.size());
  536 +
  537 + for( std::vector<Vector3>::iterator iter = vertexPositions.begin(); iter != vertexPositions.end(); iter++ )
  538 + {
  539 + Vector3 newPosition( (*iter) - bBoxMinCorner ) ;
  540 +
  541 + textureCoordinates.push_back( Vector2( newPosition.x / bBoxSize.x, newPosition.y / bBoxSize.y ) );
  542 +
  543 + newPosition -= bBoxSize * 0.5f;
  544 + (*iter) = newPosition * scale;
  545 + }
  546 + }
  547 +
  548 + /**
  549 + * Main key event handler
  550 + */
  551 + void OnKeyEvent(const KeyEvent& event)
  552 + {
  553 + if(event.state == KeyEvent::Down)
  554 + {
  555 + if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
  556 + {
  557 + mApplication.Quit();
  558 + }
  559 + }
  560 + }
  561 +
  562 +private:
  563 +
  564 + Application& mApplication;
  565 + Layer mContent;
  566 +
  567 + Sampler mSampler;
  568 + Material mMaterial;
  569 + Geometry mGeometry;
  570 + Renderer mRenderer;
  571 + Actor mMeshActor;
  572 +
  573 + Shader mShaderFlat;
  574 + Shader mShaderRefraction;
  575 +
  576 + Animation mLightAnimation;
  577 + Animation mStrenghAnimation;
  578 +
  579 + Property::Index mLightXYOffsetIndex;
  580 + Property::Index mSpinAngleIndex;
  581 + Property::Index mLightIntensityIndex;
  582 + Property::Index mEffectStrengthIndex;
  583 +
  584 + Toolkit::PushButton mChangeTextureButton;
  585 + Toolkit::PushButton mChangeMeshButton;
  586 + unsigned int mCurrentTextureId;
  587 + unsigned int mCurrentMeshId;
  588 +};
  589 +
  590 +/*****************************************************************************/
  591 +
  592 +static void
  593 +RunTest(Application& app)
  594 +{
  595 + RefractionEffectExample theApp(app);
  596 + app.MainLoop();
  597 +}
  598 +
  599 +/*****************************************************************************/
  600 +
  601 +int
  602 +main(int argc, char **argv)
  603 +{
  604 + Application app = Application::New(&argc, &argv);
  605 +
  606 + RunTest(app);
  607 +
  608 + return 0;
  609 +}