Changes after TouchedSignal changes
[platform/core/uifw/dali-demo.git] / examples / ray-marching / ray-marching-example.cpp
1 /*
2  * Copyright (c) 2020 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-toolkit/dali-toolkit.h>
19 #include <dali-toolkit/devel-api/controls/tool-bar/tool-bar.h>
20 #include "shared/view.h"
21 #include "shared/utility.h"
22 #include <stdio.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/devel-api/adaptor-framework/file-stream.h>
25
26 using namespace Dali;
27 using Dali::Toolkit::TextLabel;
28 using Dali::Toolkit::Control;
29 using Dali::Toolkit::ToolBar;
30
31 const char* BACKGROUND_IMAGE( "" );
32 const char* TOOLBAR_IMAGE( DEMO_IMAGE_DIR "top-bar.png" );
33 const char* APPLICATION_TITLE( "Ray Marching" );
34 const char* SHADER_NAME("raymarch_sphere_shaded");
35
36 /**
37  * @brief LoadShaderCode
38  * @param filename
39  * @param output
40  * @return
41  */
42 bool LoadShaderCode( const char* path, const char* filename, std::vector<char>& output )
43 {
44   std::string fullpath( path );
45   fullpath += filename;
46
47   Dali::FileStream fileStream( fullpath, Dali::FileStream::READ | Dali::FileStream::BINARY );
48   FILE* file = fileStream.GetFile();
49   if( !file )
50   {
51     return false;
52   }
53
54   bool retValue = false;
55   if( !fseek( file, 0, SEEK_END ) )
56   {
57     long int size = ftell( file );
58
59     if( ( size != -1L ) &&
60         ( ! fseek( file, 0, SEEK_SET ) ) )
61     {
62       output.resize( size + 1 );
63       std::fill( output.begin(), output.end(), 0 );
64       ssize_t result = fread( output.data(), size, 1, file );
65
66       retValue = ( result >= 0 );
67     }
68   }
69
70   return retValue;
71 }
72
73 /**
74  * @brief LoadShaders
75  * @param shaderName
76  * @return
77  */
78 Shader LoadShaders( const std::string& shaderName )
79 {
80   std::vector<char> bufV, bufF;
81   std::string shaderVSH( shaderName );
82   std::string shaderFSH( shaderName );
83   shaderVSH += ".vsh";
84   shaderFSH += ".fsh";
85
86   Shader shader;
87   if( LoadShaderCode( DEMO_SHADER_DIR, shaderVSH.c_str(), bufV ) &&
88       LoadShaderCode( DEMO_SHADER_DIR, shaderFSH.c_str(), bufF ) )
89   {
90     shader = Shader::New( bufV.data(), bufF.data() );
91   }
92   return shader;
93 }
94
95 // This example shows how to create a Ray Marching using a shader
96 //
97 class RayMarchingExample : public ConnectionTracker
98 {
99 public:
100
101   RayMarchingExample( Application& application )
102   : mApplication( application )
103   {
104     // Connect to the Application's Init signal
105     mApplication.InitSignal().Connect( this, &RayMarchingExample::Create );
106   }
107
108   ~RayMarchingExample()
109   {
110     // Nothing to do here;
111   }
112
113   // The Init signal is received once (only) during the Application lifetime
114   void Create( Application& application )
115   {
116     // Get a handle to the window
117     Window window = application.GetWindow();
118
119     window.GetRootLayer().TouchedSignal().Connect( this, &RayMarchingExample::OnTouch );
120
121     window.KeyEventSignal().Connect(this, &RayMarchingExample::OnKeyEvent);
122
123     window.SetBackgroundColor( Color::YELLOW );
124
125     // Creates a default view with a default tool bar.
126     // The view is added to the window.
127     mContentLayer = DemoHelper::CreateView( application,
128                                             mView,
129                                             mToolBar,
130                                             BACKGROUND_IMAGE,
131                                             TOOLBAR_IMAGE,
132                                             APPLICATION_TITLE );
133
134     // Add an extra space on the right to center the title text.
135     mToolBar.AddControl( Actor::New(), DemoHelper::DEFAULT_VIEW_STYLE.mToolBarButtonPercentage, Toolkit::Alignment::HORIZONTAL_RIGHT );
136
137     AddContentLayer();
138
139   }
140   bool OnTouch( Actor actor, const TouchEvent& touch )
141   {
142     // quit the application
143     mApplication.Quit();
144     return true;
145   }
146
147   /**
148    * Main key event handler
149    */
150   void OnKeyEvent(const KeyEvent& event)
151   {
152     if(event.GetState() == KeyEvent::DOWN)
153     {
154       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
155       {
156         mApplication.Quit();
157       }
158     }
159   }
160
161   /**
162    * Creates quad renderer
163    */
164   Renderer CreateQuadRenderer()
165   {
166     // Create shader & geometry needed by Renderer
167     Shader shader = LoadShaders( SHADER_NAME );
168
169     Property::Map vertexFormat;
170     vertexFormat["aPosition"] = Property::VECTOR2;
171     VertexBuffer vertexBuffer = VertexBuffer::New( vertexFormat );
172
173     const float P( 0.5f );
174     const Vector2 vertices[] = {
175       Vector2( -P, -P ),
176       Vector2( +P, -P ),
177       Vector2( -P, +P ),
178       Vector2( +P, +P )
179     };
180
181     vertexBuffer.SetData( vertices, 4 );
182
183     // Instantiate quad geometry
184     Geometry geometry = Geometry::New();
185     geometry.AddVertexBuffer( vertexBuffer );
186     geometry.SetType( Geometry::TRIANGLE_STRIP );
187
188     // Create renderer
189     Renderer renderer = Renderer::New( geometry, shader );
190
191     renderer.RegisterProperty("uRadius", 0.0f );
192     renderer.RegisterProperty("uAdjuster", -4.0f );
193
194     //  Animate the sphere radius uniform and a generic uAdjust uniform currently used to move the light around
195     Animation animation = Animation::New(8.0f);
196     animation.AnimateTo( Property(renderer,"uRadius"), 1.2f, AlphaFunction::BOUNCE);
197     animation.AnimateTo( Property(renderer,"uAdjuster"), 4.0f, AlphaFunction::BOUNCE);
198     animation.SetLooping( true );
199     animation.Play();
200
201     return renderer;
202   }
203
204   void AddContentLayer()
205   {
206     Window window = mApplication.GetWindow();
207
208      //Create all the renderers
209     Renderer renderer = CreateQuadRenderer();
210
211     Actor actor = Actor::New();
212     actor.AddRenderer( renderer );
213
214     actor.SetProperty( Actor::Property::ANCHOR_POINT, Dali::AnchorPoint::CENTER );
215     actor.SetProperty( Actor::Property::PARENT_ORIGIN, Dali::ParentOrigin::CENTER );
216     actor.SetResizePolicy( Dali::ResizePolicy::FILL_TO_PARENT, Dali::Dimension::ALL_DIMENSIONS );
217
218     mContentLayer.Add( actor );
219   }
220
221 private:
222   Application&  mApplication;
223   Control mView;
224   Layer mContentLayer;
225   ToolBar mToolBar;
226 };
227
228 int DALI_EXPORT_API main( int argc, char **argv )
229 {
230   Application application = Application::New( &argc, &argv );
231   RayMarchingExample test( application );
232   application.MainLoop();
233   return 0;
234 }