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