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"
23 using namespace Dali::Toolkit;
25 class NewWindowController;
29 const char * const BACKGROUND_IMAGE( DALI_IMAGE_DIR "background-2.jpg" );
30 const char * const TOOLBAR_IMAGE( DALI_IMAGE_DIR "top-bar.png" );
31 const char * const LOSE_CONTEXT_IMAGE( DALI_IMAGE_DIR "icon-cluster-wobble.png" );
32 const char * const BASE_IMAGE( DALI_IMAGE_DIR "gallery-large-14.jpg" );
33 const char * const EFFECT_IMAGE( DALI_IMAGE_DIR "gallery-large-18.jpg" );
35 const float EXPLOSION_DURATION(1.2f);
36 const unsigned int EMIT_INTERVAL_IN_MS(80);
37 const float TRACK_DURATION_IN_MS(970);
39 Application gApplication;
40 NewWindowController* gNewWindowController(NULL);
42 const char*const FRAG_SHADER=
43 "uniform mediump float alpha;\n"
47 " mediump vec4 fragColor = texture2D(sTexture, vTexCoord);\n"
48 " mediump vec4 fxColor = texture2D(sEffect, vTexCoord);\n"
49 " gl_FragColor = mix(fragColor,fxColor, alpha);\n"
52 }; // anonymous namespace
55 class NewWindowController : public ConnectionTracker
58 NewWindowController( Application& app );
59 void Create( Application& app );
60 void Destroy( Application& app );
61 void OnKeyEvent(const KeyEvent& event);
62 bool OnLoseContextButtonClicked( Toolkit::Button button );
63 static void NewWindow(void);
66 void OnContextRegained();
67 void CreateMeshActor();
68 Mesh CreateMesh(bool, Material);
69 void CreateBubbles(Vector2 stageSize);
70 void CreateBlending();
72 bool OnTrackTimerTick();
73 bool OnExplodeTimerTick();
74 void SetUpAnimation( Vector2 emitPosition, Vector2 direction );
75 FrameBufferImage CreateMirrorImage(const char* imageName);
76 ImageActor CreateBlurredMirrorImage(const char* imageName);
77 FrameBufferImage CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect);
81 Application mApplication;
84 ImageActor mImageActor;
85 ImageActor mBlendActor;
89 MeshActor mAnimatedMeshActor;
91 Toolkit::View mView; ///< The View instance.
92 Toolkit::ToolBar mToolBar; ///< The View's Toolbar.
93 TextView mTitleActor; ///< The Toolbar's Title.
94 Layer mContentLayer; ///< Content layer (scrolling cluster content)
95 Toolkit::PushButton mLoseContextButton;
97 Toolkit::BubbleEmitter mEmitter;
99 Timer mEmitTrackTimer;
101 bool mNeedNewAnimation;
103 unsigned int mAnimateComponentCount;
104 Animation mEmitAnimation;
108 NewWindowController::NewWindowController( Application& application )
109 : mApplication(application),
110 mHSVDelta(0.5f, 0.0f, 0.5f),
111 mNeedNewAnimation(true)
113 mApplication.InitSignal().Connect(this, &NewWindowController::Create);
114 mApplication.TerminateSignal().Connect(this, &NewWindowController::Destroy);
117 void NewWindowController::Create( Application& app )
119 Stage stage = Stage::GetCurrent();
120 stage.SetBackgroundColor(Color::YELLOW);
122 stage.KeyEventSignal().Connect(this, &NewWindowController::OnKeyEvent);
124 // The Init signal is received once (only) during the Application lifetime
126 // Hide the indicator bar
127 mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
129 mContentLayer = DemoHelper::CreateView( app,
134 "Context recovery" );
136 // Point the default render task at the view
137 RenderTaskList taskList = stage.GetRenderTaskList();
138 RenderTask defaultTask = taskList.GetTask( 0u );
141 defaultTask.SetSourceActor( mView );
144 mLoseContextButton = Toolkit::PushButton::New();
145 mLoseContextButton.SetBackgroundImage( ResourceImage::New( LOSE_CONTEXT_IMAGE ) );
146 mLoseContextButton.ClickedSignal().Connect( this, &NewWindowController::OnLoseContextButtonClicked );
147 mToolBar.AddControl( mLoseContextButton, DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HorizontalRight, DemoHelper::DEFAULT_MODE_SWITCH_PADDING );
150 Actor logoLayoutActor = Actor::New();
151 logoLayoutActor.SetParentOrigin(ParentOrigin::CENTER);
152 logoLayoutActor.SetPosition(0.0f, -200.0f, 0.0f);
153 logoLayoutActor.SetScale(0.5f);
154 mContentLayer.Add(logoLayoutActor);
156 Image image = ResourceImage::New(DALI_IMAGE_DIR "dali-logo.png");
157 mImageActor = ImageActor::New(image);
158 mImageActor.SetName("dali-logo");
159 mImageActor.SetParentOrigin(ParentOrigin::CENTER);
160 mImageActor.SetAnchorPoint(AnchorPoint::BOTTOM_CENTER);
161 logoLayoutActor.Add(mImageActor);
163 ImageActor mirrorImageActor = CreateBlurredMirrorImage(DALI_IMAGE_DIR "dali-logo.png");
164 mirrorImageActor.SetParentOrigin(ParentOrigin::CENTER);
165 mirrorImageActor.SetAnchorPoint(AnchorPoint::TOP_CENTER);
166 logoLayoutActor.Add(mirrorImageActor);
168 CreateBubbles(stage.GetSize());
173 stage.ContextLostSignal().Connect(this, &NewWindowController::OnContextLost);
174 stage.ContextRegainedSignal().Connect(this, &NewWindowController::OnContextRegained);
177 void NewWindowController::Destroy( Application& app )
179 UnparentAndReset(mTextActor);
182 bool NewWindowController::OnLoseContextButtonClicked( Toolkit::Button button )
184 // Add as an idle callback to avoid ProcessEvents being recursively called.
185 mApplication.AddIdle( MakeCallback( NewWindowController::NewWindow ) );
189 void NewWindowController::CreateMeshActor()
191 mEffectImage = ResourceImage::New(EFFECT_IMAGE);
193 Material baseMaterial = Material::New( "Material1" );
194 Dali::MeshActor meshActor = MeshActor::New( CreateMesh(true, baseMaterial) );
195 meshActor.SetScale( 100.0f );
196 meshActor.SetParentOrigin( ParentOrigin::CENTER );
197 meshActor.SetPosition(Vector3( -150.0f, 200.0f, 0.0f ));
198 meshActor.SetName("MeshActor");
199 mContentLayer.Add( meshActor );
201 Material orchidMaterial = Material::New( "Material2" );
202 orchidMaterial.SetDiffuseTexture(mEffectImage);
204 Dali::MeshActor meshActor2 = MeshActor::New( CreateMesh(false, orchidMaterial) );
205 meshActor2.SetScale( 100.0f );
206 meshActor2.SetParentOrigin( ParentOrigin::CENTER );
207 meshActor2.SetPosition(Vector3( -150.0f, 310.0f, 0.0f ));
208 meshActor2.SetName("MeshActor");
209 mContentLayer.Add( meshActor2 );
212 FrameBufferImage NewWindowController::CreateMirrorImage(const char* imageName)
214 FrameBufferImage fbo;
215 Image image = ResourceImage::New(imageName);
216 fbo = CreateFrameBufferForImage(imageName, image, ShaderEffect());
220 ImageActor NewWindowController::CreateBlurredMirrorImage(const char* imageName)
222 FrameBufferImage fbo;
223 Image image = ResourceImage::New( imageName );
224 Vector2 FBOSize = ResourceImage::GetImageSize(imageName);
225 fbo = FrameBufferImage::New( FBOSize.width, FBOSize.height, Pixel::RGBA8888);
226 GaussianBlurView gbv = GaussianBlurView::New(5, 2.0f, Pixel::RGBA8888, 0.5f, 0.5f, true);
227 gbv.SetBackgroundColor(Color::TRANSPARENT);
228 gbv.SetUserImageAndOutputRenderTarget( image, fbo );
229 gbv.SetSize(FBOSize);
230 Stage::GetCurrent().Add(gbv);
233 ImageActor blurredActor = ImageActor::New(fbo);
234 blurredActor.SetSize(FBOSize);
235 blurredActor.SetScale(1.0f, -1.0f, 1.0f);
239 FrameBufferImage NewWindowController::CreateFrameBufferForImage(const char* imageName, Image image, ShaderEffect shaderEffect)
241 Stage stage = Stage::GetCurrent();
242 Vector2 FBOSize = ResourceImage::GetImageSize(imageName);
244 FrameBufferImage framebuffer = FrameBufferImage::New(FBOSize.x, FBOSize.y );
246 RenderTask renderTask = stage.GetRenderTaskList().CreateTask();
248 ImageActor imageActor = ImageActor::New(image);
249 imageActor.SetName("Source image actor");
252 imageActor.SetShaderEffect(shaderEffect);
254 imageActor.SetParentOrigin(ParentOrigin::CENTER);
255 imageActor.SetAnchorPoint(AnchorPoint::CENTER);
256 imageActor.SetScale(1.0f, -1.0f, 1.0f);
257 stage.Add(imageActor); // Not in default image view
259 CameraActor cameraActor = CameraActor::New(FBOSize);
260 cameraActor.SetParentOrigin(ParentOrigin::CENTER);
261 cameraActor.SetFieldOfView(Math::PI*0.25f);
262 cameraActor.SetNearClippingPlane(1.0f);
263 cameraActor.SetAspectRatio(FBOSize.width / FBOSize.height);
264 cameraActor.SetType(Dali::Camera::FREE_LOOK); // camera orientation based solely on actor
265 cameraActor.SetRotation(Quaternion(M_PI, Vector3::YAXIS));
266 cameraActor.SetPosition(0.0f, 0.0f, ((FBOSize.height * 0.5f) / tanf(Math::PI * 0.125f)));
267 stage.Add(cameraActor);
269 renderTask.SetSourceActor(imageActor);
270 renderTask.SetInputEnabled(false);
271 renderTask.SetTargetFrameBuffer(framebuffer);
272 renderTask.SetCameraActor( cameraActor );
273 renderTask.SetClearColor( Color::TRANSPARENT );
274 renderTask.SetClearEnabled( true );
275 renderTask.SetRefreshRate(RenderTask::REFRESH_ONCE);
280 void NewWindowController::CreateBubbles(Vector2 stageSize)
282 mEmitter = Toolkit::BubbleEmitter::New( stageSize,
283 ResourceImage::New( DALI_IMAGE_DIR "bubble-ball.png" ),
284 1000, Vector2( 5.0f, 5.0f ) );
286 Image background = ResourceImage::New(BACKGROUND_IMAGE);
287 mEmitter.SetBackground( background, mHSVDelta );
288 Actor bubbleRoot = mEmitter.GetRootActor();
289 mContentLayer.Add( bubbleRoot );
290 bubbleRoot.SetParentOrigin(ParentOrigin::CENTER);
291 bubbleRoot.SetZ(0.1f);
293 mEmitTrackTimer = Timer::New( EMIT_INTERVAL_IN_MS );
294 mEmitTrackTimer.TickSignal().Connect(this, &NewWindowController::OnTrackTimerTick);
295 mEmitTrackTimer.Start();
297 //mExplodeTimer = Timer::New( Random::Range(4000.f, 8000.f) );
298 //mExplodeTimer.TickSignal().Connect(this, &NewWindowController::OnExplodeTimerTick);
299 //mExplodeTimer.Start();
302 bool NewWindowController::OnExplodeTimerTick()
304 mEmitter.StartExplosion( EXPLOSION_DURATION, 5.0f );
306 mExplodeTimer = Timer::New( Random::Range(4.f, 8.f) );
307 mExplodeTimer.TickSignal().Connect(this, &NewWindowController::OnExplodeTimerTick);
311 void NewWindowController::SetUpAnimation( Vector2 emitPosition, Vector2 direction )
313 if( mNeedNewAnimation )
315 float duration = Random::Range(1.f, 1.5f);
316 mEmitAnimation = Animation::New( duration );
317 mNeedNewAnimation = false;
318 mAnimateComponentCount = 0;
321 mEmitter.EmitBubble( mEmitAnimation, emitPosition, direction, Vector2(1, 1) );
323 mAnimateComponentCount++;
325 if( mAnimateComponentCount % 20 ==0 )
327 mEmitAnimation.Play();
328 mNeedNewAnimation = true;
332 bool NewWindowController::OnTrackTimerTick()
335 const float radius(250.0f);
337 time += EMIT_INTERVAL_IN_MS;
338 float modTime = time / TRACK_DURATION_IN_MS;
339 float angle = 2.0f*Math::PI*modTime;
341 Vector2 position(radius*cosf(angle), radius*-sinf(angle));
342 Vector2 aimPos(radius*2*sinf(angle), radius*2*-cosf(angle));
343 Vector2 direction = aimPos-position;
344 Vector2 stageSize = Stage::GetCurrent().GetSize();
346 for(int i=0; i<20; i++)
348 SetUpAnimation( stageSize*0.5f+position, direction );
355 void NewWindowController::CreateBlending()
357 Toolkit::ColorAdjuster colorAdjuster = ColorAdjuster::New(mHSVDelta);
358 FrameBufferImage fb2 = CreateFrameBufferForImage( EFFECT_IMAGE, mEffectImage, colorAdjuster );
360 ImageActor tmpActor = ImageActor::New(fb2);
361 mContentLayer.Add(tmpActor);
362 tmpActor.SetParentOrigin(ParentOrigin::BOTTOM_RIGHT);
363 tmpActor.SetAnchorPoint(AnchorPoint::BOTTOM_RIGHT);
364 tmpActor.SetScale(0.25f);
366 // create blending shader effect
367 ShaderEffect blendShader = ShaderEffect::New( "", FRAG_SHADER );
368 blendShader.SetEffectImage( fb2 );
369 blendShader.SetUniform("alpha", 0.5f);
371 mBaseImage = ResourceImage::New(BASE_IMAGE);
372 mBlendActor = ImageActor::New( mBaseImage );
373 mBlendActor.SetParentOrigin(ParentOrigin::CENTER);
374 mBlendActor.SetPosition(Vector3(150.0f, 200.0f, 0.0f));
375 mBlendActor.SetSize(140, 140);
376 mBlendActor.SetShaderEffect( blendShader );
377 mContentLayer.Add(mBlendActor);
380 void NewWindowController::CreateText()
382 mTextActor = TextActor::New("Some text");
383 mTextActor.SetParentOrigin(ParentOrigin::CENTER);
384 mTextActor.SetColor(Color::RED);
385 mTextActor.SetName("PushMe text");
386 mContentLayer.Add( mTextActor );
389 Mesh NewWindowController::CreateMesh(bool hasColor, Material material)
391 // Create vertices and specify their color
392 MeshData::VertexContainer vertices(4);
393 vertices[ 0 ] = MeshData::Vertex( Vector3( -0.5f, -0.5f, 0.0f ), Vector2(0.0f, 0.0f), Vector3(1.0f, 0.0f, 0.0f) );
394 vertices[ 1 ] = MeshData::Vertex( Vector3( 0.5f, -0.5f, 0.0f ), Vector2(1.0f, 0.0f), Vector3(1.0f, 1.0f, 0.0f) );
395 vertices[ 2 ] = MeshData::Vertex( Vector3( -0.5f, 0.5f, 0.0f ), Vector2(0.0f, 1.0f), Vector3(0.0f,1.0f,0.0f) );
396 vertices[ 3 ] = MeshData::Vertex( Vector3( 0.5f, 0.5f, 0.0f ), Vector2(1.0f, 1.0f), Vector3(0.0f,0.0f,1.0f) );
398 // Specify all the faces
399 MeshData::FaceIndices faces;
400 faces.reserve( 6 ); // 2 triangles in Quad
401 faces.push_back( 0 ); faces.push_back( 3 ); faces.push_back( 1 );
402 faces.push_back( 0 ); faces.push_back( 2 ); faces.push_back( 3 );
404 // Create the mesh data from the vertices and faces
406 meshData.SetHasColor( hasColor );
407 meshData.SetMaterial( material );
408 meshData.SetVertices( vertices );
409 meshData.SetFaceIndices( faces );
411 // Create a mesh from the data
412 Dali::Mesh mesh = Mesh::New( meshData );
416 void NewWindowController::NewWindow(void)
418 PositionSize posSize(0, 0, 720, 1280);
419 gApplication.ReplaceWindow(posSize, "NewWindow"); // Generates a new window
422 void NewWindowController::OnKeyEvent(const KeyEvent& event)
424 if(event.state == KeyEvent::Down)
426 if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
433 void NewWindowController::OnContextLost()
435 printf("Stage reporting context loss\n");
438 void NewWindowController::OnContextRegained()
440 printf("Stage reporting context regain\n");
446 void RunTest(Application& app)
448 gNewWindowController = new NewWindowController(app);
449 app.MainLoop(Configuration::APPLICATION_DOES_NOT_HANDLE_CONTEXT_LOSS);
452 // Entry point for Linux & Tizen applications
455 int main(int argc, char **argv)
457 gApplication = Application::New(&argc, &argv);
458 RunTest(gApplication);