2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <dali-toolkit/dali-toolkit.h>
18 #include "../shared/view.h"
21 using namespace Dali::Toolkit;
23 class NewWindowController;
27 const char * gModelFile = DALI_MODEL_DIR "AlbumCute.dali-bin";
28 const char * const BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-2.jpg" );
29 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
30 const char * const LOSE_CONTEXT_IMAGE( DALI_IMAGE_DIR "icon-cluster-wobble.png" );
31 const char * const BASE_IMAGE( DALI_IMAGE_DIR "gallery-large-14.jpg" );
32 const char * const EFFECT_IMAGE( DALI_IMAGE_DIR "gallery-large-18.jpg" );
34 const float EXPLOSION_DURATION(1.2f);
35 const unsigned int EMIT_INTERVAL_IN_MS(80);
36 const float TRACK_DURATION_IN_MS(970);
38 Application gApplication;
39 NewWindowController* gNewWindowController(NULL);
41 const char*const FRAG_SHADER=
42 "uniform mediump float alpha;\n"
46 " mediump vec4 fragColor = texture2D(sTexture, vTexCoord);\n"
47 " mediump vec4 fxColor = texture2D(sEffect, vTexCoord);\n"
48 " gl_FragColor = mix(fragColor,fxColor, alpha);\n"
51 }; // anonymous namespace
54 class NewWindowController : public ConnectionTracker
57 NewWindowController( Application& app );
58 void Create( Application& app );
59 void Destroy( Application& app );
60 void OnKeyEvent(const KeyEvent& event);
61 bool OnLoseContextButtonClicked( Toolkit::Button button );
62 static void NewWindow(void);
65 void OnContextRegained();
66 void CreateMeshActor();
67 Mesh CreateMesh(bool, Material);
68 void CreateBubbles(Vector2 stageSize);
69 void CreateBlending();
72 void OnModelLoaded(Model model);
73 bool OnTrackTimerTick();
74 bool OnExplodeTimerTick();
75 void SetUpAnimation( Vector2 emitPosition, Vector2 direction );
76 FrameBufferImage CreateMirrorImage(const char* imageName);
77 ImageActor CreateBlurredMirrorImage(const char* imageName);
78 FrameBufferImage CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect);
82 Application mApplication;
83 Animation mModelAnimation;
87 ImageActor mImageActor;
88 ImageActor mBlendActor;
91 LightActor mKeyLightActor;
93 MeshActor mAnimatedMeshActor;
96 Toolkit::View mView; ///< The View instance.
97 Toolkit::ToolBar mToolBar; ///< The View's Toolbar.
98 TextView mTitleActor; ///< The Toolbar's Title.
99 Layer mContentLayer; ///< Content layer (scrolling cluster content)
100 Toolkit::PushButton mLoseContextButton;
102 Toolkit::BubbleEmitter mEmitter;
104 Timer mEmitTrackTimer;
106 bool mNeedNewAnimation;
108 unsigned int mAnimateComponentCount;
109 Animation mEmitAnimation;
113 NewWindowController::NewWindowController( Application& application )
114 : mApplication(application),
115 mHSVDelta(0.5f, 0.0f, 0.5f),
116 mNeedNewAnimation(true)
118 mApplication.InitSignal().Connect(this, &NewWindowController::Create);
119 mApplication.TerminateSignal().Connect(this, &NewWindowController::Destroy);
122 void NewWindowController::Create( Application& app )
124 Stage stage = Stage::GetCurrent();
125 stage.SetBackgroundColor(Color::YELLOW);
127 stage.KeyEventSignal().Connect(this, &NewWindowController::OnKeyEvent);
129 // The Init signal is received once (only) during the Application lifetime
131 // Hide the indicator bar
132 mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
134 mContentLayer = DemoHelper::CreateView( app,
139 "Context recovery" );
141 // Point the default render task at the view
142 RenderTaskList taskList = stage.GetRenderTaskList();
143 RenderTask defaultTask = taskList.GetTask( 0u );
146 defaultTask.SetSourceActor( mView );
149 mLoseContextButton = Toolkit::PushButton::New();
150 mLoseContextButton.SetBackgroundImage( Image::New( LOSE_CONTEXT_IMAGE ) );
151 mLoseContextButton.ClickedSignal().Connect( this, &NewWindowController::OnLoseContextButtonClicked );
152 mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
155 Actor logoLayoutActor = Actor::New();
156 logoLayoutActor.SetParentOrigin(ParentOrigin::CENTER);
157 logoLayoutActor.SetPosition(0.0f, -200.0f, 0.0f);
158 logoLayoutActor.SetScale(0.5f);
159 mContentLayer.Add(logoLayoutActor);
161 Image image = Image::New(DALI_IMAGE_DIR "dali-logo.png");
162 mImageActor = ImageActor::New(image);
163 mImageActor.SetName("dali-logo");
164 mImageActor.SetParentOrigin(ParentOrigin::CENTER);
165 mImageActor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
166 logoLayoutActor.Add(mImageActor);
168 ImageActor mirrorImageActor = CreateBlurredMirrorImage(DALI_IMAGE_DIR "dali-logo.png");
169 mirrorImageActor.SetParentOrigin(ParentOrigin::CENTER);
170 mirrorImageActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
171 logoLayoutActor.Add(mirrorImageActor);
173 CreateBubbles(stage.GetSize());
179 stage.ContextLostSignal().Connect(this, &NewWindowController::OnContextLost);
180 stage.ContextRegainedSignal().Connect(this, &NewWindowController::OnContextRegained);
183 void NewWindowController::Destroy( Application& app )
185 UnparentAndReset(mTextActor);
188 bool NewWindowController::OnLoseContextButtonClicked( Toolkit::Button button )
190 // Add as an idle callback to avoid ProcessEvents being recursively called.
191 mApplication.AddIdle(NewWindowController::NewWindow);
195 void NewWindowController::CreateMeshActor()
197 mEffectImage = Image::New(EFFECT_IMAGE);
199 Material baseMaterial = Material::New( "Material1" );
200 Dali::MeshActor meshActor = MeshActor::New( CreateMesh(true, baseMaterial) );
201 meshActor.SetScale( 100.0f );
202 meshActor.SetParentOrigin( ParentOrigin::CENTER );
203 meshActor.SetPosition(Vector3( -150.0f, 200.0f, 0.0f ));
204 meshActor.SetAffectedByLighting( false );
205 meshActor.SetName("MeshActor");
206 mContentLayer.Add( meshActor );
208 Material orchidMaterial = Material::New( "Material2" );
209 orchidMaterial.SetDiffuseTexture(mEffectImage);
211 Dali::MeshActor meshActor2 = MeshActor::New( CreateMesh(false, orchidMaterial) );
212 meshActor2.SetScale( 100.0f );
213 meshActor2.SetParentOrigin( ParentOrigin::CENTER );
214 meshActor2.SetPosition(Vector3( -150.0f, 310.0f, 0.0f ));
215 meshActor2.SetAffectedByLighting( false );
216 meshActor2.SetName("MeshActor");
217 mContentLayer.Add( meshActor2 );
220 FrameBufferImage NewWindowController::CreateMirrorImage(const char* imageName)
222 FrameBufferImage fbo;
223 Image image = Image::New(imageName);
224 fbo = CreateFrameBufferForImage(imageName, image, ShaderEffect());
228 ImageActor NewWindowController::CreateBlurredMirrorImage(const char* imageName)
230 FrameBufferImage fbo;
231 Image image = Image::New( imageName );
232 Vector2 FBOSize = Image::GetImageSize(imageName);
233 fbo = FrameBufferImage::New( FBOSize.width, FBOSize.height, Pixel::RGBA8888);
234 GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true);
235 gbv.SetBackgroundColor(Color::TRANSPARENT);
236 gbv.SetUserImageAndOutputRenderTarget( image, fbo );
237 gbv.SetSize(FBOSize);
238 Stage::GetCurrent().Add(gbv);
241 ImageActor blurredActor = ImageActor::New(fbo);
242 blurredActor.SetSize(FBOSize);
243 blurredActor.SetScale(1.0f, -1.0f, 1.0f);
247 FrameBufferImage NewWindowController::CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect)
249 Stage stage = Stage::GetCurrent();
250 Vector2 FBOSize = Image::GetImageSize(imageName);
252 FrameBufferImage framebuffer = FrameBufferImage::New(FBOSize.x, FBOSize.y );
254 RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
256 ImageActor imageActor = ImageActor::New(image);
257 imageActor.SetName("Source image actor");
260 imageActor.SetShaderEffect(shaderEffect);
262 imageActor.SetParentOrigin(ParentOrigin::CENTER);
263 imageActor.SetAnchorPoint(AnchorPoint::CENTER);
264 imageActor.SetScale(1.0f, -1.0f, 1.0f);
265 stage.Add(imageActor); // Not in default image view
267 CameraActor cameraActor = CameraActor::New(FBOSize);
268 cameraActor.SetParentOrigin(ParentOrigin::CENTER);
269 cameraActor.SetFieldOfView(Math::PI*0.25f);
270 cameraActor.SetNearClippingPlane(1.0f);
271 cameraActor.SetAspectRatio(FBOSize.width / FBOSize.height);
272 cameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
273 cameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
274 cameraActor.SetPosition(0.0f, 0.0f, ((FBOSize.height * 0.5f) / tanf(Math::PI * 0.125f)));
275 stage.Add(cameraActor);
277 renderTask.SetSourceActor(imageActor);
278 renderTask.SetInputEnabled(false);
279 renderTask.SetTargetFrameBuffer(framebuffer);
280 renderTask.SetCameraActor( cameraActor );
281 renderTask.SetClearColor( Color::TRANSPARENT );
282 renderTask.SetClearEnabled( true );
283 renderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
288 void NewWindowController::CreateBubbles(Vector2 stageSize)
290 mEmitter = Toolkit::BubbleEmitter::New( stageSize,
291 Image::New( DALI_IMAGE_DIR "bubble-ball.png" ),
292 1000, Vector2( 5.0f, 5.0f ) );
294 Image background = Image::New(BACKGROUND_IMAGE);
295 mEmitter.SetBackground( background, mHSVDelta );
296 Actor bubbleRoot = mEmitter.GetRootActor();
297 mContentLayer.Add( bubbleRoot );
298 bubbleRoot.SetParentOrigin(ParentOrigin::CENTER);
299 bubbleRoot.SetZ(0.1f);
301 mEmitTrackTimer = Timer::New( EMIT_INTERVAL_IN_MS );
302 mEmitTrackTimer.TickSignal().Connect(this, &NewWindowController::OnTrackTimerTick);
303 mEmitTrackTimer.Start();
305 //mExplodeTimer = Timer::New( Random::Range(4000.f, 8000.f) );
306 //mExplodeTimer.TickSignal().Connect(this, &NewWindowController::OnExplodeTimerTick);
307 //mExplodeTimer.Start();
310 bool NewWindowController::OnExplodeTimerTick()
312 mEmitter.StartExplosion( EXPLOSION_DURATION, 5.0f );
314 mExplodeTimer = Timer::New( Random::Range(4.f, 8.f) );
315 mExplodeTimer.TickSignal().Connect(this, &NewWindowController::OnExplodeTimerTick);
319 void NewWindowController::SetUpAnimation( Vector2 emitPosition, Vector2 direction )
321 if( mNeedNewAnimation )
323 float duration = Random::Range(1.f, 1.5f);
324 mEmitAnimation = Animation::New( duration );
325 mNeedNewAnimation = false;
326 mAnimateComponentCount = 0;
329 mEmitter.EmitBubble( mEmitAnimation, emitPosition, direction, Vector2(1, 1) );
331 mAnimateComponentCount++;
333 if( mAnimateComponentCount % 20 ==0 )
335 mEmitAnimation.Play();
336 mNeedNewAnimation = true;
340 bool NewWindowController::OnTrackTimerTick()
343 const float radius(250.0f);
345 time += EMIT_INTERVAL_IN_MS;
346 float modTime = time / TRACK_DURATION_IN_MS;
347 float angle = 2.0f*Math::PI*modTime;
349 Vector2 position(radius*cosf(angle), radius*-sinf(angle));
350 Vector2 aimPos(radius*2*sinf(angle), radius*2*-cosf(angle));
351 Vector2 direction = aimPos-position;
352 Vector2 stageSize = Stage::GetCurrent().GetSize();
354 for(int i=0; i<20; i++)
356 SetUpAnimation( stageSize*0.5f+position, direction );
363 void NewWindowController::CreateBlending()
365 Toolkit::ColorAdjuster colorAdjuster = ColorAdjuster::New(mHSVDelta);
366 FrameBufferImage fb2 = CreateFrameBufferForImage( EFFECT_IMAGE, mEffectImage, colorAdjuster );
368 ImageActor tmpActor = ImageActor::New(fb2);
369 mContentLayer.Add(tmpActor);
370 tmpActor.SetParentOrigin(ParentOrigin::BOTTOM_RIGHT);
371 tmpActor.SetAnchorPoint(AnchorPoint::BOTTOM_RIGHT);
372 tmpActor.SetScale(0.25f);
374 // create blending shader effect
375 ShaderEffect blendShader = ShaderEffect::New( "", FRAG_SHADER );
376 blendShader.SetEffectImage( fb2 );
377 blendShader.SetUniform("alpha", 0.5f);
379 mBaseImage = Image::New(BASE_IMAGE);
380 mBlendActor = ImageActor::New( mBaseImage );
381 mBlendActor.SetParentOrigin(ParentOrigin::CENTER);
382 mBlendActor.SetPosition(Vector3(150.0f, 200.0f, 0.0f));
383 mBlendActor.SetSize(140, 140);
384 mBlendActor.SetShaderEffect( blendShader );
385 mContentLayer.Add(mBlendActor);
388 void NewWindowController::CreateText()
390 mTextActor = TextActor::New("Some text");
391 mTextActor.SetParentOrigin(ParentOrigin::CENTER);
392 mTextActor.SetColor(Color::RED);
393 mTextActor.SetName("PushMe text");
394 mContentLayer.Add( mTextActor );
397 Mesh NewWindowController::CreateMesh(bool hasColor, Material material)
399 // Create vertices and specify their color
400 MeshData::VertexContainer vertices(4);
401 vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2(0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f) );
402 vertices[ 1 ] = MeshData::Vertex( Vector3( 0.5f, -0.5f, 0.0f ), Vector2(1.0f, 0.0f), Vector3(1.0f, 1.0f, 0.0f) );
403 vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f, 0.5f, 0.0f ), Vector2(0.0f, 1.0f), Vector3(0.0f,1.0f,0.0f) );
404 vertices[ 3 ] = MeshData::Vertex( Vector3( 0.5f, 0.5f, 0.0f ), Vector2(1.0f, 1.0f), Vector3(0.0f,0.0f,1.0f) );
406 // Specify all the faces
407 MeshData::FaceIndices faces;
408 faces.reserve( 6 ); // 2 triangles in Quad
409 faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
410 faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
412 // Create the mesh data from the vertices and faces
414 meshData.SetHasColor( hasColor );
415 meshData.SetMaterial( material );
416 meshData.SetVertices( vertices );
417 meshData.SetFaceIndices( faces );
419 // Create a mesh from the data
420 Dali::Mesh mesh = Mesh::New( meshData );
424 void NewWindowController::CreateModel()
426 mModel = Model::New(gModelFile);
427 mModel.LoadingFinishedSignal().Connect(this, &NewWindowController::OnModelLoaded);
430 Light keylight = Light::New("KeyLight");
431 keylight.SetFallOff(Vector2(10000.0f, 10000.0f));
433 mCastingLight = Actor::New();
434 mCastingLight.SetParentOrigin(ParentOrigin::CENTER);
435 mCastingLight.SetAnchorPoint(AnchorPoint::CENTER);
436 mCastingLight.SetPosition( Vector3( 0.0f, 0.0f, 800.0f ) );
437 mContentLayer.Add( mCastingLight );
439 mKeyLightActor = LightActor::New();
440 mKeyLightActor.SetParentOrigin(ParentOrigin::CENTER);
441 mKeyLightActor.SetName(keylight.GetName());
443 //Add all the actors to the stage
444 mCastingLight.Add(mKeyLightActor);
445 mKeyLightActor.SetLight(keylight);
448 void NewWindowController::OnModelLoaded( Model model )
450 if( model.GetLoadingState() == ResourceLoadingSucceeded )
452 std::cout << "Succeeded loading model" << std::endl;
453 mModelActor = ModelActorFactory::BuildActorTree(mModel, ""); // Gets root actor
454 mModelActor.SetSize(250.0f, 250.0f);
455 mModelActor.SetPosition(0.0f, 200.0f, 70.0f);
456 mModelActor.SetScale(0.5f);
457 mModelActor.SetRotation(Radian(Math::PI*0.25f), Vector3(1.0, 0.7, 0.0));
459 mContentLayer.Add( mModelActor );
461 if (mModel.NumberOfAnimations())
463 mModelAnimation = ModelActorFactory::BuildAnimation(mModel, mModelActor, 0);
464 mModelAnimation.SetDuration(4.0f);
465 mModelAnimation.SetLooping(true);
466 mModelAnimation.Play();
471 std::cout << "Failed loading model" << std::endl;
476 void NewWindowController::NewWindow(void)
478 PositionSize posSize(0, 0, 720, 1280);
479 gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window
482 void NewWindowController::OnKeyEvent(const KeyEvent& event)
484 if(event.state == KeyEvent::Down)
486 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
493 void NewWindowController::OnContextLost()
495 printf("Stage reporting context loss\n");
498 void NewWindowController::OnContextRegained()
500 printf("Stage reporting context regain\n");
506 void RunTest(Application& app)
508 gNewWindowController = new NewWindowController(app);
509 app.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
512 // Entry point for Linux & SLP applications
515 int main(int argc, char **argv)
517 gApplication = Application::New(&argc, &argv);
518 RunTest(gApplication);