Merge "Simple TextEditor demo." into devel/master
[platform/core/uifw/dali-demo.git] / examples / mesh-sorting / mesh-sorting-example.cpp
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 // EXTERNAL INCLUDES
19 #include <dali/devel-api/rendering/renderer.h>
20 #include <dali-toolkit/dali-toolkit.h>
21 #include <stdio.h>
22 #include <sstream>
23 #include <cstring>
24
25 // INTERNAL INCLUDES
26 #include "shared/view.h"
27
28 using namespace Dali;
29
30 namespace
31 {
32
33 const char* IMAGES[] =
34 {
35   DEMO_IMAGE_DIR "people-medium-1.jpg",
36   DEMO_IMAGE_DIR "people-medium-4.jpg",
37   DEMO_IMAGE_DIR "people-medium-11.jpg",
38   DEMO_IMAGE_DIR "people-small-16.jpg",
39   DEMO_IMAGE_DIR "people-medium-15.jpg",
40   DEMO_IMAGE_DIR "people-medium-6.jpg",
41 };
42 const unsigned int NUMBER_OF_SAMPLES(sizeof(IMAGES)/sizeof(const char*));
43
44
45 #define MAKE_SHADER(A)#A
46
47 const char* VERTEX_SHADER = MAKE_SHADER(
48 uniform   highp   float   uHue;
49 attribute mediump vec2    aPosition;
50 attribute highp   vec2    aTexCoord;
51 varying   mediump vec2    vTexCoord;
52 uniform   mediump mat4    uMvpMatrix;
53 uniform   mediump vec3    uSize;
54 varying   mediump vec3    vGlobColor;
55
56 vec3 hsv2rgb(vec3 c)
57 {
58   vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
59   vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
60   return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
61 }
62
63 void main()
64 {
65   mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
66   vertexPosition.xyz *= uSize;
67   vertexPosition = uMvpMatrix * vertexPosition;
68   vGlobColor = hsv2rgb( vec3( clamp(uHue, 0.0, 1.0), 1.0, 1.0 ) );
69
70   vTexCoord = aTexCoord;
71   gl_Position = vertexPosition;
72 }
73 );
74
75 const char* FRAGMENT_SHADER = MAKE_SHADER(
76 varying mediump vec2  vTexCoord;
77 varying mediump vec3  vGlobColor;
78 uniform lowp    vec4  uColor;
79 uniform sampler2D     sTexture;
80
81 void main()
82 {
83   gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor * vec4(vGlobColor, 1.0) ;
84 }
85 );
86
87 Geometry CreateGeometry()
88 {
89   // Create vertices
90   const float halfQuadSize = .5f;
91   struct TexturedQuadVertex { Vector2 position; Vector2 textureCoordinates; };
92   TexturedQuadVertex texturedQuadVertexData[4] = {
93     { Vector2(-halfQuadSize, -halfQuadSize), Vector2(0.f, 0.f) },
94     { Vector2( halfQuadSize, -halfQuadSize), Vector2(1.f, 0.f) },
95     { Vector2(-halfQuadSize,  halfQuadSize), Vector2(0.f, 1.f) },
96     { Vector2( halfQuadSize,  halfQuadSize), Vector2(1.f, 1.f) } };
97
98   Property::Map texturedQuadVertexFormat;
99   texturedQuadVertexFormat["aPosition"] = Property::VECTOR2;
100   texturedQuadVertexFormat["aTexCoord"] = Property::VECTOR2;
101   PropertyBuffer texturedQuadVertices = PropertyBuffer::New( texturedQuadVertexFormat );
102   texturedQuadVertices.SetData( texturedQuadVertexData, 4 );
103
104   // Create indices
105   unsigned short indexData[6] = { 0, 3, 1, 0, 2, 3 };
106
107   // Create the geometry object
108   Geometry texturedQuadGeometry = Geometry::New();
109   texturedQuadGeometry.AddVertexBuffer( texturedQuadVertices );
110   texturedQuadGeometry.SetIndexBuffer( &indexData[0], sizeof(indexData)/sizeof(unsigned short) );
111
112   return texturedQuadGeometry;
113 }
114
115 } // anonymous namespace
116
117 // This example shows how to use a simple mesh
118 //
119 class ExampleController : public ConnectionTracker
120 {
121 public:
122
123   /**
124    * The example controller constructor.
125    * @param[in] application The application instance
126    */
127   ExampleController( Application& application )
128   : mApplication( application ),
129     mZMode(0)
130   {
131     // Connect to the Application's Init signal
132     mApplication.InitSignal().Connect( this, &ExampleController::Create );
133     memset(mDepthIndices, 0, sizeof(mDepthIndices));
134   }
135
136   /**
137    * The example controller destructor
138    */
139   ~ExampleController()
140   {
141     // Nothing to do here;
142   }
143
144   /**
145    * Invoked upon creation of application
146    * @param[in] application The application instance
147    */
148   void Create( Application& application )
149   {
150     Stage stage = Stage::GetCurrent();
151     stage.KeyEventSignal().Connect(this, &ExampleController::OnKeyEvent);
152
153     mStageSize = stage.GetSize();
154
155     // The Init signal is received once (only) during the Application lifetime
156
157     // Hide the indicator bar
158     application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
159
160     mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
161     mGeometry = CreateGeometry();
162
163     TextureSet firstTextureSet;
164
165     for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
166     {
167       Image image = ResourceImage::New( IMAGES[i] );
168       TextureSet textureSet = TextureSet::New();
169       textureSet.SetImage( 0u, image );
170       if( i==0 ) { firstTextureSet = textureSet; }
171
172       Renderer renderer = Renderer::New( mGeometry, mShader );
173       renderer.SetTextures( textureSet );
174       Actor meshActor = Actor::New();
175       mActors[i] = meshActor;
176       meshActor.AddRenderer( renderer );
177       meshActor.SetSize(175, 175);
178       meshActor.RegisterProperty("index", (int)i);
179
180       renderer.SetProperty( Renderer::Property::DEPTH_INDEX, 0 );
181       // Test with actor alpha
182       meshActor.SetParentOrigin( ParentOrigin::CENTER );
183       meshActor.SetAnchorPoint( AnchorPoint::CENTER );
184       meshActor.SetPosition( 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), i*10 );
185
186       meshActor.SetOpacity( i%2?0.7f:1.0f );
187
188       meshActor.RegisterProperty("uHue", i/(float)NUMBER_OF_SAMPLES);
189
190       meshActor.TouchSignal().Connect(this, &ExampleController::OnTouched);
191       std::ostringstream oss;
192       oss << "Mesh Actor " << i;
193       meshActor.SetName(oss.str());
194       stage.Add( meshActor );
195     }
196
197     mActors[NUMBER_OF_SAMPLES-2].GetRendererAt(0).SetTextures( firstTextureSet );
198
199     stage.GetRootLayer().TouchSignal().Connect(this, &ExampleController::OnStageTouched);
200   }
201
202   void PrintDepths()
203   {
204     switch( mZMode )
205     {
206       case 0:
207       {
208         printf("Children Z ordered back to front\n");
209         break;
210       }
211       case 1:
212       {
213         printf("All children set to same Z=0\n");
214         break;
215       }
216       case 2:
217       {
218         printf("Children Z ordered front to back\n");
219         break;
220       }
221     }
222
223     for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
224     {
225       printf("DepthIndex[%d]=%d\n", i, mDepthIndices[i]);
226     }
227     printf("\n");
228   }
229
230   bool OnTouched( Actor actor, const TouchData& event )
231   {
232     if( event.GetState( 0 ) == PointState::UP )
233     {
234       int index = actor.GetProperty<int>(actor.GetPropertyIndex("index"));
235
236       int newDepthIndex = (mDepthIndices[index] + 10) % 30;
237       mDepthIndices[index] = newDepthIndex;
238
239       Renderer renderer = actor.GetRendererAt(0);
240       renderer.SetProperty( Renderer::Property::DEPTH_INDEX, newDepthIndex);
241
242       PrintDepths();
243     }
244     return true;
245   }
246
247   bool OnStageTouched( Actor rootLayer, const TouchData& event )
248   {
249     if( event.GetState( 0 ) == PointState::UP )
250     {
251       switch( mZMode )
252       {
253         case 0:
254         {
255           mZMode = 1;
256           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
257           {
258             Actor child = rootLayer.GetChildAt(i);
259             child.SetZ( 0.0f );
260           }
261           PrintDepths();
262           break;
263         }
264         case 1:
265         {
266           mZMode = 2;
267           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
268           {
269             Actor child = rootLayer.GetChildAt(i);
270             child.SetZ( 100-i*10 );
271           }
272           PrintDepths();
273           break;
274         }
275         case 2:
276         {
277           mZMode = 0;
278           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
279           {
280             Actor child = rootLayer.GetChildAt(i);
281             child.SetZ( i*10 );
282           }
283           PrintDepths();
284           break;
285         }
286       }
287     }
288     return true;
289   }
290
291   /**
292    * Invoked whenever the quit button is clicked
293    * @param[in] button the quit button
294    */
295   bool OnQuitButtonClicked( Toolkit::Button button )
296   {
297     // quit the application
298     mApplication.Quit();
299     return true;
300   }
301
302   void OnKeyEvent(const KeyEvent& event)
303   {
304     if(event.state == KeyEvent::Down)
305     {
306       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
307       {
308         mApplication.Quit();
309       }
310     }
311   }
312
313 private:
314
315   Application&  mApplication;                             ///< Application instance
316   Vector3 mStageSize;                                     ///< The size of the stage
317
318   Shader   mShader;
319   Geometry mGeometry;
320
321   int mDepthIndices[NUMBER_OF_SAMPLES];
322   Actor mActors[NUMBER_OF_SAMPLES];
323   int mZMode;
324 };
325
326 void RunTest( Application& application )
327 {
328   ExampleController test( application );
329
330   application.MainLoop();
331 }
332
333 // Entry point for Linux & SLP applications
334 //
335 int DALI_EXPORT_API main( int argc, char **argv )
336 {
337   Application application = Application::New( &argc, &argv );
338
339   RunTest( application );
340
341   return 0;
342 }