Fixes for removal of animatable property-buffer.
[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
20 // INTERNAL INCLUDES
21 #include "shared/view.h"
22
23 #include <dali-toolkit/dali-toolkit.h>
24 #include <stdio.h>
25 #include <sstream>
26 #include <cstring>
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::UNSIGNED_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       Sampler sampler = Sampler::New(image, "sTexture");
173       Material material = Material::New( mShader );
174       material.AddSampler( sampler );
175       if( i==0 ) { firstMat = material; }
176
177       Renderer renderer = Renderer::New( mGeometry, material );
178       Actor meshActor = Actor::New();
179       mActors[i] = meshActor;
180       meshActor.AddRenderer( renderer );
181       meshActor.SetSize(175, 175);
182       meshActor.RegisterProperty("index", (int)i);
183
184       renderer.SetDepthIndex(0);
185       // Test with actor alpha
186       meshActor.SetParentOrigin( ParentOrigin::CENTER );
187       meshActor.SetAnchorPoint( AnchorPoint::CENTER );
188       meshActor.SetPosition( 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), 40.0f*(i-(NUMBER_OF_SAMPLES*0.5f)), i*10 );
189
190       meshActor.SetOpacity( i%2?0.7f:1.0f );
191
192       Property::Index index=meshActor.RegisterProperty("hue", i/(float)NUMBER_OF_SAMPLES);
193       meshActor.AddUniformMapping( index, "uHue" );
194
195       meshActor.TouchedSignal().Connect(this, &ExampleController::OnTouched);
196       std::ostringstream oss;
197       oss << "Mesh Actor " << i;
198       meshActor.SetName(oss.str());
199       stage.Add( meshActor );
200     }
201
202     mActors[NUMBER_OF_SAMPLES-2].GetRendererAt(0).SetMaterial( firstMat );
203
204     stage.GetRootLayer().TouchedSignal().Connect(this, &ExampleController::OnStageTouched);
205   }
206
207   void PrintDepths()
208   {
209     switch( mZMode )
210     {
211       case 0:
212       {
213         printf("Children Z ordered back to front\n");
214         break;
215       }
216       case 1:
217       {
218         printf("All children set to same Z=0\n");
219         break;
220       }
221       case 2:
222       {
223         printf("Children Z ordered front to back\n");
224         break;
225       }
226     }
227
228     for( unsigned i=0; i<NUMBER_OF_SAMPLES; ++i)
229     {
230       printf("DepthIndex[%d]=%d\n", i, mDepthIndices[i]);
231     }
232     printf("\n");
233   }
234
235   bool OnTouched( Actor actor, const TouchEvent& event )
236   {
237     if( event.GetPoint(0).state == TouchPoint::Finished )
238     {
239       int index = actor.GetProperty<int>(actor.GetPropertyIndex("index"));
240
241       int newDepthIndex = (mDepthIndices[index] + 10) % 30;
242       mDepthIndices[index] = newDepthIndex;
243
244       Renderer renderer = actor.GetRendererAt(0);
245       renderer.SetDepthIndex(newDepthIndex);
246
247       PrintDepths();
248     }
249     return true;
250   }
251
252   bool OnStageTouched( Actor rootLayer, const TouchEvent& event )
253   {
254     if( event.GetPoint(0).state == TouchPoint::Finished )
255     {
256       switch( mZMode )
257       {
258         case 0:
259         {
260           mZMode = 1;
261           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
262           {
263             Actor child = rootLayer.GetChildAt(i);
264             child.SetZ( 0.0f );
265           }
266           PrintDepths();
267           break;
268         }
269         case 1:
270         {
271           mZMode = 2;
272           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
273           {
274             Actor child = rootLayer.GetChildAt(i);
275             child.SetZ( 100-i*10 );
276           }
277           PrintDepths();
278           break;
279         }
280         case 2:
281         {
282           mZMode = 0;
283           for(unsigned int i=1; i < rootLayer.GetChildCount(); ++i)
284           {
285             Actor child = rootLayer.GetChildAt(i);
286             child.SetZ( i*10 );
287           }
288           PrintDepths();
289           break;
290         }
291       }
292     }
293     return true;
294   }
295
296   /**
297    * Invoked whenever the quit button is clicked
298    * @param[in] button the quit button
299    */
300   bool OnQuitButtonClicked( Toolkit::Button button )
301   {
302     // quit the application
303     mApplication.Quit();
304     return true;
305   }
306
307   void OnKeyEvent(const KeyEvent& event)
308   {
309     if(event.state == KeyEvent::Down)
310     {
311       if( IsKey( event, Dali::DALI_KEY_ESCAPE) || IsKey( event, Dali::DALI_KEY_BACK) )
312       {
313         mApplication.Quit();
314       }
315     }
316   }
317
318 private:
319
320   Application&  mApplication;                             ///< Application instance
321   Vector3 mStageSize;                                     ///< The size of the stage
322
323   Shader   mShader;
324   Geometry mGeometry;
325
326   int mDepthIndices[NUMBER_OF_SAMPLES];
327   Actor mActors[NUMBER_OF_SAMPLES];
328   int mZMode;
329 };
330
331 void RunTest( Application& application )
332 {
333   ExampleController test( application );
334
335   application.MainLoop();
336 }
337
338 // Entry point for Linux & SLP applications
339 //
340 int main( int argc, char **argv )
341 {
342   Application application = Application::New( &argc, &argv );
343
344   RunTest( application );
345
346   return 0;
347 }