40284fa8a2388ade8bcae2f86d5a5b103176ac76
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Material.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 #include <iostream>
18
19 #include <stdlib.h>
20 #include <dali/dali.h>
21
22 #include <dali-test-suite-utils.h>
23
24 using namespace Dali;
25
26 #include <mesh-builder.h>
27
28 #include <dali/internal/event/common/thread-local-storage.h>
29 #include <dali/internal/update/resources/resource-manager.h>
30 #include <dali/internal/update/manager/update-manager.h>
31 #include <dali/internal/event/resources/resource-client.h>
32 #include <dali/internal/event/resources/resource-ticket.h>
33 #include <dali/internal/event/resources/image-ticket.h>
34 #include <dali/internal/event/resources/resource-ticket-observer.h>
35 #include <dali/internal/event/images/image-impl.h>
36 #include <dali/internal/event/modeling/model-data-impl.h>
37 #include <dali/integration-api/resource-cache.h>
38 #include <dali/internal/event/modeling/material-impl.h>
39 #include <dali/internal/update/modeling/scene-graph-material.h>
40 #include <dali/internal/render/renderers/render-material.h>
41 #include <dali/internal/render/gl-resources/context.h>
42 #include <dali/internal/render/shaders/program.h>
43
44 namespace
45 {
46 Dali::Internal::MaterialProperties TEST_PROPS;
47 }
48
49 // Called only once before first test is run.
50 void utc_dali_material_startup(void)
51 {
52   TEST_PROPS.mOpacity       = 0.4f;
53   TEST_PROPS.mShininess     = 0.27f;
54   TEST_PROPS.mDiffuseColor  = Color::MAGENTA;
55   TEST_PROPS.mAmbientColor  = Color::GREEN;
56   TEST_PROPS.mSpecularColor = Color::BLUE;
57   TEST_PROPS.mEmissiveColor = Color::RED;
58   test_return_value = TET_UNDEF;
59 }
60
61 // Called only once after last test is run
62 void utc_dali_material_cleanup(void)
63 {
64   test_return_value = TET_PASS;
65 }
66
67 namespace
68 {
69
70 class TestProgram
71 {
72 public:
73   TestProgram( TestApplication& application )
74   : app(application)
75   {
76     Internal::Context* testContext = new Internal::Context( application.GetGlAbstraction() );
77     Integration::ShaderDataPtr shaderData = new Integration::ShaderData("123", "132");
78     shaderData->AllocateBuffer(10);
79
80     Integration::ResourceId resourceId = 100;
81     program = Internal::Program::New(resourceId, shaderData.Get(), *testContext);
82     programId = app.GetGlAbstraction().GetLastProgramCreated();
83     program->Use();
84   }
85
86   virtual ~TestProgram()
87   {
88   }
89
90   Internal::Program& GetProgram()
91   {
92     return *program;
93   }
94
95   float GetUniformF(std::string uniform)
96   {
97     GLint uniformLoc = program->GetUniformLocation( program->RegisterUniform( uniform ) );
98     float value=0.0f;
99     if(app.GetGlAbstraction().GetUniformValue( programId, (GLuint) uniformLoc, value))
100     {
101       return value;
102     }
103     return 0.0f;
104   }
105
106   Vector4 GetUniformV(std::string uniform)
107   {
108     GLint uniformLoc = program->GetUniformLocation( program->RegisterUniform( uniform ) );
109     Vector4 value;
110     if(app.GetGlAbstraction().GetUniformValue( programId, (GLuint) uniformLoc, value))
111     {
112       return value;
113     }
114     return Vector4();
115   }
116
117   float GetOpacity()         { return GetUniformF("uMaterial.mOpacity"); }
118   float GetShininess()       { return GetUniformF("uMaterial.mShininess"); }
119   Vector4 GetAmbientColor()  { return GetUniformV("uMaterial.mAmbient"); }
120   Vector4 GetDiffuseColor()  { return GetUniformV("uMaterial.mDiffuse"); }
121   Vector4 GetSpecularColor() { return GetUniformV("uMaterial.mSpecular"); }
122   Vector4 GetEmissiveColor() { return GetUniformV("uMaterial.mEmissive"); }
123
124   TestApplication& app;
125   GLuint programId;
126   Internal::Program* program;
127   Integration::ShaderDataPtr shaderData;
128 };
129
130
131 class TestBoundTextures
132 {
133 public:
134   TestBoundTextures(TestApplication& application)
135   : app(application)
136   {
137     std::vector<GLuint> ids;
138     ids.push_back( 8 ); // 8 = actor1
139     ids.push_back( 9 ); // 9 = actor2
140     ids.push_back( 10 ); // 10 = actor3
141     application.GetGlAbstraction().SetNextTextureIds( ids );
142   }
143
144   std::size_t GetNumBoundTextures()
145   {
146     const std::vector<GLuint>& boundTextures = app.GetGlAbstraction().GetBoundTextures();
147     return boundTextures.size();
148   }
149
150   bool CheckFirstTextureBound( GLuint activeTextureUnit )
151   {
152     bool bound=false;
153     const std::vector<GLuint>& boundTextures = app.GetGlAbstraction().GetBoundTextures( activeTextureUnit );
154
155     if ( boundTextures.size() == 1 )
156     {
157       if( boundTextures[0] == 8u )
158       {
159         bound = true;
160       }
161     }
162     return bound;
163   }
164
165   bool CheckFirstTextureDeleted()
166   {
167     return ( app.GetGlAbstraction().CheckTextureDeleted( 8u ));
168   }
169
170   TestApplication& app;
171 };
172
173
174 Internal::ResourceTicketPtr CheckLoadBitmap(TestApplication& application, const char* name, int w, int h)
175 {
176   Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient();
177   ImageAttributes attr;
178   Integration::BitmapResourceType bitmapRequest(attr);
179   Internal::ResourceTicketPtr ticket = resourceClient.RequestResource( bitmapRequest, name );
180   application.SendNotification(); // Flush update messages
181   application.Render();           // Process resource request
182   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
183   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
184   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, w, h, w, h );
185   Integration::ResourcePointer resourcePtr(bitmap); // reference it
186   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
187   application.Render();           // Process LoadComplete
188   application.SendNotification(); // Process event messages
189   DALI_TEST_CHECK( ticket->GetLoadingState() == ResourceLoadingSucceeded );
190   application.GetPlatform().DiscardRequest(); // Ensure load request is discarded
191   req=NULL;
192   application.GetPlatform().ResetTrace();
193
194   return ticket;
195 }
196
197 Internal::ImagePtr LoadImage(TestApplication& application, const char* name)
198 {
199   Internal::ImagePtr image = Internal::Image::New(name);
200   application.SendNotification(); // Flush update messages
201   application.Render();           // Process resource request
202   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
203   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
204   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80,80,80,80 );
205   Integration::ResourcePointer resourcePtr(bitmap); // reference it
206
207   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
208   application.Render();           // Process LoadComplete
209   application.SendNotification(); // Process event messages
210   application.GetPlatform().DiscardRequest(); // Ensure load request is discarded
211   req=NULL;
212   application.GetPlatform().ResetTrace();
213   return image;
214 }
215
216 } // Anonymous Namespace
217
218 /********************************************************************************/
219 /********************************************************************************/
220 /********************************************************************************/
221
222 // Test new with no parameters sets up default object
223 int UtcDaliMaterialMethodNew01(void)
224 {
225   TestApplication application;
226
227   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
228   Internal::MaterialProperties props = sceneObject->GetProperties(); // copy.
229   DALI_TEST_CHECK(props.mOpacity == Dali::Material::DEFAULT_OPACITY);
230   DALI_TEST_CHECK(props.mShininess == Dali::Material::DEFAULT_SHININESS);
231   DALI_TEST_CHECK(props.mAmbientColor == Dali::Material::DEFAULT_AMBIENT_COLOR);
232   DALI_TEST_CHECK(props.mDiffuseColor == Dali::Material::DEFAULT_DIFFUSE_COLOR);
233   DALI_TEST_CHECK(props.mSpecularColor == Dali::Material::DEFAULT_SPECULAR_COLOR);
234   DALI_TEST_CHECK(props.mEmissiveColor == Dali::Material::DEFAULT_EMISSIVE_COLOR);
235
236   Internal::ResourceId textureId = sceneObject->GetDiffuseTextureId();
237   DALI_TEST_CHECK( !textureId );
238   textureId = sceneObject->GetOpacityTextureId();
239   DALI_TEST_CHECK( !textureId );
240   textureId = sceneObject->GetNormalMapId();
241   DALI_TEST_CHECK( !textureId );
242
243   DALI_TEST_CHECK(! sceneObject->HasDiffuseTexture());
244   DALI_TEST_CHECK(! sceneObject->HasOpacityTexture());
245   DALI_TEST_CHECK(! sceneObject->HasNormalMap());
246   END_TEST;
247 }
248
249 // Test new with event object sets up parameters appropriately
250 int UtcDaliMaterialMethodNew02(void)
251 {
252   TestApplication application;
253
254   Internal::Material* material = Internal::Material::New("cloth");
255   DALI_TEST_CHECK(material->GetShininess() == Dali::Material::DEFAULT_SHININESS);
256   DALI_TEST_CHECK(material->GetAmbientColor() == Dali::Material::DEFAULT_AMBIENT_COLOR);
257   material->SetOpacity(0.4f);
258   material->SetDiffuseColor(Color::MAGENTA);
259
260   // Create directly
261   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New(material);
262   Internal::MaterialProperties props = sceneObject->GetProperties(); // copy.
263   DALI_TEST_CHECK(props.mOpacity == 0.4f);
264   DALI_TEST_CHECK(props.mDiffuseColor == Color::MAGENTA);
265   DALI_TEST_CHECK(props.mShininess == Dali::Material::DEFAULT_SHININESS);
266   DALI_TEST_CHECK(props.mAmbientColor == Dali::Material::DEFAULT_AMBIENT_COLOR);
267   DALI_TEST_CHECK(props.mSpecularColor == Dali::Material::DEFAULT_SPECULAR_COLOR);
268   DALI_TEST_CHECK(props.mEmissiveColor == Dali::Material::DEFAULT_EMISSIVE_COLOR);
269
270   Internal::ResourceId textureId = sceneObject->GetDiffuseTextureId();
271   DALI_TEST_CHECK( !textureId );
272   textureId = sceneObject->GetOpacityTextureId();
273   DALI_TEST_CHECK( !textureId );
274   textureId = sceneObject->GetNormalMapId();
275   DALI_TEST_CHECK( !textureId );
276
277   DALI_TEST_CHECK(! sceneObject->HasDiffuseTexture());
278   DALI_TEST_CHECK(! sceneObject->HasOpacityTexture());
279   DALI_TEST_CHECK(! sceneObject->HasNormalMap());
280
281   // Create indirectly
282   const Internal::SceneGraph::Material* sceneObject2 = material->GetSceneObject();
283   DALI_TEST_CHECK( sceneObject2 != NULL );
284   Internal::MaterialProperties props2 = sceneObject2->GetProperties(); // copy.
285   DALI_TEST_CHECK(props2.mOpacity == 0.4f);
286   DALI_TEST_CHECK(props2.mDiffuseColor == Color::MAGENTA);
287   DALI_TEST_CHECK(props2.mShininess == Dali::Material::DEFAULT_SHININESS);
288   DALI_TEST_CHECK(props2.mAmbientColor == Dali::Material::DEFAULT_AMBIENT_COLOR);
289   DALI_TEST_CHECK(props2.mSpecularColor == Dali::Material::DEFAULT_SPECULAR_COLOR);
290   DALI_TEST_CHECK(props2.mEmissiveColor == Dali::Material::DEFAULT_EMISSIVE_COLOR);
291
292   DALI_TEST_CHECK(! sceneObject2->GetDiffuseTextureId());
293   DALI_TEST_CHECK(! sceneObject2->GetOpacityTextureId());
294   DALI_TEST_CHECK(! sceneObject2->GetNormalMapId());
295
296   DALI_TEST_CHECK(! sceneObject2->HasDiffuseTexture());
297   DALI_TEST_CHECK(! sceneObject2->HasOpacityTexture());
298   DALI_TEST_CHECK(! sceneObject2->HasNormalMap());
299   END_TEST;
300 }
301
302 // Test setting ready texture off stage
303 int UtcDaliMaterialReadyTextureOffstage(void)
304 {
305   TestApplication application;
306
307   Internal::ResourceTicketPtr ticket = CheckLoadBitmap(application, "diffuse.png", 80, 80);
308   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
309   sceneObject->SetDiffuseTextureId(ticket->GetId());
310
311   DALI_TEST_EQUALS( sceneObject->GetDiffuseTextureId(), ticket->GetId(), TEST_LOCATION );
312   END_TEST;
313 }
314
315 // Test setting unready texture offstage, becoming ready
316 int UtcDaliMaterialUnreadyTextureOffstage(void)
317 {
318   TestApplication application;
319
320   Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient();
321   ImageAttributes attr;
322   Integration::BitmapResourceType bitmapRequest(attr);
323   Internal::ResourceTicketPtr ticket = resourceClient.RequestResource( bitmapRequest, "image.png" );
324   application.SendNotification(); // Flush update messages
325   application.Render();           // Process resource request
326
327   // Ticket is valid, but no resource yet
328   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
329   Internal::ResourceId textureId = ticket->GetId();
330   sceneObject->SetDiffuseTextureId(textureId);
331   Internal::ResourceId textureId2 = sceneObject->GetDiffuseTextureId();
332   DALI_TEST_CHECK( textureId == textureId2 );
333
334   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
335   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
336   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
337   Integration::ResourcePointer resourcePtr(bitmap); // reference it
338   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
339   application.Render();           // Process LoadComplete
340   application.SendNotification(); // Process event messages
341   DALI_TEST_CHECK( ticket->GetLoadingState() == ResourceLoadingSucceeded );
342
343   Internal::ResourceId textureId3 = sceneObject->GetDiffuseTextureId();
344   DALI_TEST_CHECK( textureId3 );
345   DALI_TEST_CHECK( textureId3 == textureId );
346   END_TEST;
347 }
348
349 // Test staging creates render material
350 int UtcDaliMaterialStaging01(void)
351 {
352   TestApplication application;
353   TestBoundTextures boundTextures(application);
354   TestProgram testProgram(application);
355
356   // Create object and set some properties
357   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
358   DALI_TEST_CHECK( sceneObject != NULL );
359   sceneObject->SetProperties(TEST_PROPS);
360
361   // Stage the object
362   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
363   AddMaterialMessage( updateManager, sceneObject );
364   application.SendNotification(); // Flush update Q
365
366   application.GetPlatform().IncrementGetTimeResult( 1 );
367   Integration::UpdateStatus status;
368   application.GetCore().Update( status );
369
370   // Check that a render object has been created
371   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
372   DALI_TEST_CHECK(renderMaterial != NULL);
373   // Not on render manager, and should have default props
374
375   Internal::SceneGraph::RenderMaterialUniforms materialUniforms;
376   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
377
378   DALI_TEST_EQUALS( testProgram.GetOpacity(),       1.0f, TEST_LOCATION );
379   DALI_TEST_EQUALS( testProgram.GetShininess(),     0.5f, TEST_LOCATION );
380   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  Vector4(0.2f, 0.2f, 0.2f, 1.0f), TEST_LOCATION);
381   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  Vector4(0.8f, 0.8f, 0.8f, 1.0f), TEST_LOCATION);
382   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
383   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
384
385   application.Render(); //Process render Q stores & processes mat
386
387   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
388   renderMaterial->BindTextures( testProgram.GetProgram() );
389   DALI_TEST_CHECK( boundTextures.GetNumBoundTextures() == 0 );
390
391   DALI_TEST_EQUALS( testProgram.GetOpacity(),       TEST_PROPS.mOpacity,       TEST_LOCATION);
392   DALI_TEST_EQUALS( testProgram.GetShininess(),     TEST_PROPS.mShininess,     TEST_LOCATION );
393   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  TEST_PROPS.mAmbientColor,  TEST_LOCATION );
394   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  TEST_PROPS.mDiffuseColor,  TEST_LOCATION );
395   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), TEST_PROPS.mSpecularColor, TEST_LOCATION );
396   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), TEST_PROPS.mEmissiveColor, TEST_LOCATION );
397   END_TEST;
398 }
399
400 // Test staging creates render material
401 int UtcDaliMaterialStaging02(void)
402 {
403   TestApplication application;
404   TestBoundTextures boundTextures(application);
405   TestProgram testProgram(application);
406
407   Internal::Material* material = Internal::Material::New("cloth");
408   material->SetOpacity(0.4f);
409   material->SetDiffuseColor(Color::MAGENTA);
410
411   // Create object and set some properties
412   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New(material);
413   DALI_TEST_CHECK( sceneObject != NULL );
414
415   // Stage the object
416   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
417   AddMaterialMessage( updateManager, sceneObject );
418   application.SendNotification(); // Flush update Q
419
420   application.GetPlatform().IncrementGetTimeResult( 1 );
421   Integration::UpdateStatus status;
422   application.GetCore().Update( status );
423
424   // Check that a render object has been created
425   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
426   DALI_TEST_CHECK(renderMaterial != NULL);
427   // Not on render manager, and should have default props
428
429   Internal::SceneGraph::RenderMaterialUniforms materialUniforms;
430   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
431
432   DALI_TEST_EQUALS( testProgram.GetOpacity(),       1.0f, TEST_LOCATION );
433   DALI_TEST_EQUALS( testProgram.GetShininess(),     0.5f, TEST_LOCATION );
434   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  Vector4(0.2f, 0.2f, 0.2f, 1.0f), TEST_LOCATION);
435   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  Vector4(0.8f, 0.8f, 0.8f, 1.0f), TEST_LOCATION);
436   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
437   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
438
439   application.Render(); //Process render Q stores & processes mat
440
441   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
442   renderMaterial->BindTextures( testProgram.GetProgram() );
443
444   DALI_TEST_CHECK( boundTextures.GetNumBoundTextures() == 0 );
445   DALI_TEST_EQUALS( testProgram.GetOpacity(),       0.4f, TEST_LOCATION);
446   DALI_TEST_EQUALS( testProgram.GetShininess(),     Dali::Material::DEFAULT_SHININESS, TEST_LOCATION );
447   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  Dali::Material::DEFAULT_AMBIENT_COLOR,  TEST_LOCATION );
448   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  Color::MAGENTA, TEST_LOCATION );
449   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), Dali::Material::DEFAULT_SPECULAR_COLOR, TEST_LOCATION );
450   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), Dali::Material::DEFAULT_EMISSIVE_COLOR, TEST_LOCATION );
451   END_TEST;
452 }
453
454
455
456 // Test setting properties on stage
457 int UtcDaliMaterialSetPropsWhilstStaged(void)
458 {
459   TestApplication application;
460   TestBoundTextures boundTextures(application);
461   TestProgram testProgram(application);
462
463   // Create object with default properties
464   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
465   DALI_TEST_CHECK( sceneObject != NULL );
466
467   // Stage the object
468   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
469   AddMaterialMessage( updateManager, sceneObject );
470   application.SendNotification(); // Flush update Q
471   application.Render(); // Process update message Q then create & post to render Q
472
473   // Check that a render object has been created
474   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
475   DALI_TEST_CHECK(renderMaterial != NULL);
476   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
477
478   sceneObject->SetProperties(TEST_PROPS);
479   application.SendNotification(); // Flush update Q
480   application.Render(); // Update & Prepare material
481   application.Render(); // Process render Q
482
483   Internal::SceneGraph::RenderMaterialUniforms materialUniforms;
484   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
485   renderMaterial->BindTextures( testProgram.GetProgram() );
486
487   DALI_TEST_EQUALS( boundTextures.GetNumBoundTextures(), 0u, TEST_LOCATION );
488
489   DALI_TEST_EQUALS( testProgram.GetOpacity(),       TEST_PROPS.mOpacity,       TEST_LOCATION);
490   DALI_TEST_EQUALS( testProgram.GetShininess(),     TEST_PROPS.mShininess,     TEST_LOCATION );
491   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  TEST_PROPS.mAmbientColor,  TEST_LOCATION );
492   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  TEST_PROPS.mDiffuseColor,  TEST_LOCATION );
493   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), TEST_PROPS.mSpecularColor, TEST_LOCATION );
494   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), TEST_PROPS.mEmissiveColor, TEST_LOCATION );
495   END_TEST;
496 }
497
498 // Test setting ready texture on stage
499 int UtcDaliMaterialSetTextureWhilstStaged(void)
500 {
501   TestApplication application;
502   TestBoundTextures boundTextures(application);
503   TestProgram testProgram(application);
504
505   Internal::ResourceTicketPtr ticket = CheckLoadBitmap(application, "diffuse.png", 80, 80);
506
507   // Create object with default properties
508   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
509   DALI_TEST_CHECK( sceneObject != NULL );
510
511   // Stage the object
512   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
513   AddMaterialMessage( updateManager, sceneObject );
514   application.SendNotification(); // Flush update Q
515   application.Render(); // Process update message Q then create & post to render Q
516
517   // Check that a render object has been created
518   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
519   DALI_TEST_CHECK(renderMaterial != NULL);
520   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
521
522   sceneObject->SetDiffuseTextureId(ticket->GetId());
523   application.SendNotification(); // Flush update Q
524   application.Render(); // Update & Prepare material
525   application.Render(); // Process render Q
526
527   renderMaterial->BindTextures( testProgram.GetProgram() );
528   DALI_TEST_CHECK( boundTextures.CheckFirstTextureBound( GL_TEXTURE0 ) );
529   END_TEST;
530 }
531
532 // Test setting unready texture on stage, becoming ready
533 int UtcDaliMaterialSetUnreadyTextureWhilstStaged(void)
534 {
535   TestApplication application;
536   TestBoundTextures boundTextures(application);
537   TestProgram testProgram(application);
538
539   Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient();
540   ImageAttributes attr;
541   Integration::BitmapResourceType bitmapRequest(attr);
542   Internal::ResourceTicketPtr ticket = resourceClient.RequestResource( bitmapRequest, "image.png" );
543   application.SendNotification(); // Flush update messages
544   application.Render();           // Process resource request
545
546
547   // Create object with default properties
548   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
549   DALI_TEST_CHECK( sceneObject != NULL );
550
551   // Stage the object
552   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
553   AddMaterialMessage( updateManager, sceneObject );
554   application.SendNotification(); // Flush update Q
555   application.Render(); // Process update message Q then create & post to render Q
556
557   // Check that a render object has been created
558   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
559   DALI_TEST_CHECK(renderMaterial != NULL);
560   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
561
562   sceneObject->SetDiffuseTextureId(ticket->GetId());
563   application.SendNotification(); // Flush update Q
564   application.Render(); // Update & Prepare material
565   application.Render(); // Process render Q
566
567   renderMaterial->BindTextures( testProgram.GetProgram() );
568
569   DALI_TEST_EQUALS( boundTextures.GetNumBoundTextures(), 0u, TEST_LOCATION );
570
571   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
572   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, false );
573   bitmap->GetPackedPixelsProfile()->ReserveBuffer( Pixel::RGBA8888, 80, 80, 80, 80 );
574   Integration::ResourcePointer resourcePtr(bitmap); // reference it
575   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
576   application.Render();           // Process LoadComplete
577   application.SendNotification(); // Process event messages
578
579   renderMaterial->BindTextures( testProgram.GetProgram() );
580   DALI_TEST_CHECK( boundTextures.CheckFirstTextureBound( GL_TEXTURE0 ) );
581   END_TEST;
582 }
583
584 // Test IsOpaque without texture, with unready texture, with ready texture
585
586 int UtcDaliMaterialIsOpaqueWithoutTexture(void)
587 {
588   TestApplication application;
589
590   // Create object with default properties
591   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
592   DALI_TEST_CHECK( sceneObject != NULL );
593
594   // Stage the object
595   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
596   AddMaterialMessage( updateManager, sceneObject );
597   application.SendNotification(); // Flush update Q
598   application.Render(); // Process update message Q then create & post to render Q
599
600   // Check that a render object has been created
601   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
602   DALI_TEST_CHECK(renderMaterial != NULL);
603   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
604
605   DALI_TEST_CHECK( sceneObject->IsOpaque() );
606   END_TEST;
607 }
608
609 int UtcDaliMaterialIsOpaqueWithTexture(void)
610 {
611   TestApplication application;
612
613   Internal::ResourceTicketPtr ticket = CheckLoadBitmap(application, "diffuse.png", 80, 80);
614
615   // Create object with default properties
616   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
617   DALI_TEST_CHECK( sceneObject != NULL );
618
619   // Stage the object
620   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
621   AddMaterialMessage( updateManager, sceneObject );
622   application.SendNotification(); // Flush update Q
623   application.Render(); // Process update message Q then create & post to render Q
624
625   // Check that a render object has been created
626   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
627   DALI_TEST_CHECK(renderMaterial != NULL);
628   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
629
630   DALI_TEST_CHECK( sceneObject->IsOpaque() );
631
632   sceneObject->SetDiffuseTextureId(ticket->GetId());
633   application.SendNotification(); // Flush update Q
634   application.Render(); // Update & Prepare material
635   application.Render(); // Process render Q
636
637   DALI_TEST_CHECK( ! sceneObject->IsOpaque() );
638   END_TEST;
639 }
640
641
642 int UtcDaliMaterialIsOpaqueWithProps(void)
643 {
644   TestApplication application;
645
646   // Create object with default properties
647   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
648   DALI_TEST_CHECK( sceneObject != NULL );
649
650   // Stage the object
651   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
652   AddMaterialMessage( updateManager, sceneObject );
653   application.SendNotification(); // Flush update Q
654   application.Render(); // Process update message Q then create & post to render Q
655
656   // Check that a render object has been created
657   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
658   DALI_TEST_CHECK(renderMaterial != NULL);
659   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
660
661   DALI_TEST_CHECK( sceneObject->IsOpaque() );
662
663   sceneObject->SetProperties(TEST_PROPS);
664   application.SendNotification(); // Flush update Q
665   application.Render(); // Update & Prepare material
666   application.Render(); // Process render Q
667
668   DALI_TEST_CHECK( ! sceneObject->IsOpaque() );
669   END_TEST;
670 }
671
672 int UtcDaliMaterialRender(void)
673 {
674   TestApplication application;
675   TestBoundTextures boundTextures(application);
676
677   {
678
679     MeshData meshData;
680     MeshData::VertexContainer    vertices;
681     MeshData::FaceIndices        faces;
682     BoneContainer                bones;
683     ConstructVertices(vertices, 60);
684     ConstructFaces(vertices, faces);
685     Dali::Material               material  = ConstructMaterial();
686
687     Internal::ImagePtr image = LoadImage(application, "texture.png");
688     Image imageHandle(image.Get());
689     material.SetDiffuseTexture(imageHandle);
690     meshData.SetData(vertices, faces, bones, material);
691     Mesh mesh = Mesh::New(meshData);
692
693     MeshActor actor = MeshActor::New(mesh);
694     std::string name = "AMeshActor";
695     actor.SetName(name);
696     actor.SetAffectedByLighting(false);
697     Stage::GetCurrent().Add(actor);
698
699     material.SetOpacity(TEST_PROPS.mOpacity);
700     material.SetShininess(TEST_PROPS.mShininess);
701     material.SetAmbientColor(TEST_PROPS.mAmbientColor);
702     material.SetDiffuseColor(TEST_PROPS.mDiffuseColor);
703     material.SetSpecularColor(TEST_PROPS.mSpecularColor);
704     material.SetEmissiveColor(TEST_PROPS.mEmissiveColor);
705
706     application.SendNotification();
707     application.Render();
708     application.SendNotification();
709     application.Render();
710     application.SendNotification();
711     application.Render();
712     application.SendNotification();
713
714     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mOpacity",   TEST_PROPS.mOpacity ) );
715     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mShininess", TEST_PROPS.mShininess ) );
716     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mAmbient",   TEST_PROPS.mAmbientColor ) );
717     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mDiffuse",   TEST_PROPS.mDiffuseColor ) );
718     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mSpecular",  TEST_PROPS.mSpecularColor ) );
719     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mEmissive",  TEST_PROPS.mEmissiveColor ) );
720
721     DALI_TEST_CHECK(boundTextures.CheckFirstTextureBound( GL_TEXTURE0 ));
722
723     Stage::GetCurrent().Remove(actor);
724     application.SendNotification();
725     application.Render();
726     application.SendNotification();
727     application.Render();
728   }
729   application.SendNotification();
730   application.Render();
731
732   // texture should have been removed:
733   DALI_TEST_CHECK( boundTextures.CheckFirstTextureDeleted() );
734   END_TEST;
735 }