354364ffa3ed24eb417ee733de91faa8b8dfdcaa
[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* MATERIAL_SAMPLES[] =
34 {
35   DALI_IMAGE_DIR "people-medium-1.jpg",
36   DALI_IMAGE_DIR "people-medium-4.jpg",
37   DALI_IMAGE_DIR "people-medium-11.jpg",
38   DALI_IMAGE_DIR "people-small-16.jpg",
39   DALI_IMAGE_DIR "people-medium-15.jpg",
40   DALI_IMAGE_DIR "people-medium-6.jpg",
41 };
42 const unsigned int NUMBER_OF_SAMPLES(sizeof(MATERIAL_SAMPLES)/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, 4 );
102   texturedQuadVertices.SetData(texturedQuadVertexData);
103
104   // Create indices
105   unsigned int indexData[6] = { 0, 3, 1, 0, 2, 3 };
106   Property::Map indexFormat;
107   indexFormat["indices"] = Property::INTEGER;
108   PropertyBuffer indices = PropertyBuffer::New( indexFormat, 6 );
109   indices.SetData(indexData);
110
111   // Create the geometry object
112   Geometry texturedQuadGeometry = Geometry::New();
113   texturedQuadGeometry.AddVertexBuffer( texturedQuadVertices );
114   texturedQuadGeometry.SetIndexBuffer( indices );
115
116   return texturedQuadGeometry;
117 }
118
119 } // anonymous namespace
120
121 // This example shows how to use a simple mesh
122 //
123 class ExampleController : public ConnectionTracker
124 {
125 public:
126
127   /**
128    * The example controller constructor.
129    * @param[in] application The application instance
130    */
131   ExampleController( Application& application )
132   : mApplication( application ),
133     mZMode(0)
134   {
135     // Connect to the Application's Init signal
136     mApplication.InitSignal().Connect( this, &ExampleController::Create );
137     memset(mDepthIndices, 0, sizeof(mDepthIndices));
138   }
139
140   /**
141    * The example controller destructor
142    */
143   ~ExampleController()
144   {
145     // Nothing to do here;
146   }
147
148   /**
149    * Invoked upon creation of application
150    * @param[in] application The application instance
151    */
152   void Create( Application& application )
153   {
154     Stage stage = Stage::GetCurrent();
155     stage.KeyEventSignal().Connect(this, &ExampleController::OnKeyEvent);
156
157     mStageSize = stage.GetSize();
158
159     // The Init signal is received once (only) during the Application lifetime
160
161     // Hide the indicator bar
162     application.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );
163
164     mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
165     mGeometry = CreateGeometry();
166
167     Material firstMat;
168
169     for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
170     {
171       Image image = ResourceImage::New( MATERIAL_SAMPLES[i] );
172       Material material = Material::New( mShader );
173       material.AddTexture(image, "sTexture");
174       if( i==0 ) { firstMat = material; }
175
176       Renderer renderer = Renderer::New( mGeometry, material );
177       Actor meshActor = Actor::New();
178       mActors[i] = meshActor;
179       meshActor.AddRenderer( renderer );
180       meshActor.SetSize(175, 175);
181       meshActor.RegisterProperty("index", (int)i);
182
183       renderer.SetDepthIndex(0);
184       // Test with actor alpha
185       meshActor.SetParentOrigin( ParentOrigin::CENTER );
186       meshActor.SetAnchorPoint( AnchorPoint::CENTER );
187       meshActor.SetPosition( 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), i*10 );
188
189       meshActor.SetOpacity( i%2?0.7f:1.0f );
190
191       meshActor.RegisterProperty("uHue", i/(float)NUMBER_OF_SAMPLES);
192
193       meshActor.TouchedSignal().Connect(this, &ExampleController::OnTouched);
194       std::ostringstream oss;
195       oss << "Mesh Actor " << i;
196       meshActor.SetName(oss.str());
197       stage.Add( meshActor );
198     }
199
200     mActors[NUMBER_OF_SAMPLES-2].GetRendererAt(0).SetMaterial( firstMat );
201
202     stage.GetRootLayer().TouchedSignal().Connect(this, &ExampleController::OnStageTouched);
203   }
204
205   void PrintDepths()
206   {
207     switch( mZMode )
208     {
209       case 0:
210       {
211         printf("Children Z ordered back to front\n");
212         break;
213       }
214       case 1:
215       {
216         printf("All children set to same Z=0\n");
217         break;
218       }
219       case 2:
220       {
221         printf("Children Z ordered front to back\n");
222         break;
223       }
224     }
225
226     for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
227     {
228       printf("DepthIndex[%d]=%d\n", i, mDepthIndices[i]);
229     }
230     printf("\n");
231   }
232
233   bool OnTouched( Actor actor, const TouchEvent& event )
234   {
235     if( event.GetPoint(0).state == TouchPoint::Finished )
236     {
237       int index = actor.GetProperty<int>(actor.GetPropertyIndex("index"));
238
239       int newDepthIndex = (mDepthIndices[index] + 10) % 30;
240       mDepthIndices[index] = newDepthIndex;
241
242       Renderer renderer = actor.GetRendererAt(0);
243       renderer.SetDepthIndex(newDepthIndex);
244
245       PrintDepths();
246     }
247     return true;
248   }
249
250   bool OnStageTouched( Actor rootLayer, const TouchEvent& event )
251   {
252     if( event.GetPoint(0).state == TouchPoint::Finished )
253     {
254       switch( mZMode )
255       {
256         case 0:
257         {
258           mZMode = 1;
259           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
260           {
261             Actor child = rootLayer.GetChildAt(i);
262             child.SetZ( 0.0f );
263           }
264           PrintDepths();
265           break;
266         }
267         case 1:
268         {
269           mZMode = 2;
270           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
271           {
272             Actor child = rootLayer.GetChildAt(i);
273             child.SetZ( 100-i*10 );
274           }
275           PrintDepths();
276           break;
277         }
278         case 2:
279         {
280           mZMode = 0;
281           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
282           {
283             Actor child = rootLayer.GetChildAt(i);
284             child.SetZ( i*10 );
285           }
286           PrintDepths();
287           break;
288         }
289       }
290     }
291     return true;
292   }
293
294   /**
295    * Invoked whenever the quit button is clicked
296    * @param[in] button the quit button
297    */
298   bool OnQuitButtonClicked( Toolkit::Button button )
299   {
300     // quit the application
301     mApplication.Quit();
302     return true;
303   }
304
305   void OnKeyEvent(const KeyEvent& event)
306   {
307     if(event.state == KeyEvent::Down)
308     {
309       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
310       {
311         mApplication.Quit();
312       }
313     }
314   }
315
316 private:
317
318   Application&  mApplication;                             ///< Application instance
319   Vector3 mStageSize;                                     ///< The size of the stage
320
321   Shader   mShader;
322   Geometry mGeometry;
323
324   int mDepthIndices[NUMBER_OF_SAMPLES];
325   Actor mActors[NUMBER_OF_SAMPLES];
326   int mZMode;
327 };
328
329 void RunTest( Application& application )
330 {
331   ExampleController test( application );
332
333   application.MainLoop();
334 }
335
336 // Entry point for Linux & SLP applications
337 //
338 int main( int argc, char **argv )
339 {
340   Application application = Application::New( &argc, &argv );
341
342   RunTest( application );
343
344   return 0;
345 }