6b3147a10202924392a678c6cf769870dc89e891
[platform/core/uifw/dali-core.git] / automated-tests / src / dali-internal / utc-Dali-Internal-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.c_str() ) );
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.c_str() ) );
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::ImageResourceType bitmapRequest ( Integration::ResourceImageData, 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::ImageDataPtr bitmap = Integration::NewBitmapImageData( w, h, Pixel::RGBA8888 );
184
185   // Make the bitmap non-opaque:
186   memset( bitmap->GetBuffer(), 0, w * h * 4 );
187   bitmap->SetAlphaUsed( true );
188
189   Integration::ResourcePointer resourcePtr(bitmap); // reference it
190   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
191   application.Render();           // Process LoadComplete
192   application.SendNotification(); // Process event messages
193   DALI_TEST_CHECK( ticket->GetLoadingState() == ResourceLoadingSucceeded );
194   application.GetPlatform().DiscardRequest(); // Ensure load request is discarded
195   req=NULL;
196   application.GetPlatform().ResetTrace();
197
198   return ticket;
199 }
200
201 Internal::ImagePtr LoadImage(TestApplication& application, const char* name)
202 {
203   Internal::ImagePtr image = Internal::Image::New(name);
204   application.SendNotification(); // Flush update messages
205   application.Render();           // Process resource request
206   Integration::ResourceRequest* req = application.GetPlatform().GetRequest();
207   Integration::ImageDataPtr bitmap = Integration::NewBitmapImageData( 80, 80, Pixel::RGBA8888 );
208   Integration::ResourcePointer resourcePtr(bitmap); // reference it
209
210   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
211   application.Render();           // Process LoadComplete
212   application.SendNotification(); // Process event messages
213   application.GetPlatform().DiscardRequest(); // Ensure load request is discarded
214   req=NULL;
215   application.GetPlatform().ResetTrace();
216   return image;
217 }
218
219 } // Anonymous Namespace
220
221 /********************************************************************************/
222 /********************************************************************************/
223 /********************************************************************************/
224
225 // Test new with no parameters sets up default object
226 int UtcDaliMaterialMethodNew01(void)
227 {
228   TestApplication application;
229
230   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
231   Internal::MaterialProperties props = sceneObject->GetProperties(); // copy.
232   DALI_TEST_CHECK(props.mOpacity == Dali::Material::DEFAULT_OPACITY);
233   DALI_TEST_CHECK(props.mShininess == Dali::Material::DEFAULT_SHININESS);
234   DALI_TEST_CHECK(props.mAmbientColor == Dali::Material::DEFAULT_AMBIENT_COLOR);
235   DALI_TEST_CHECK(props.mDiffuseColor == Dali::Material::DEFAULT_DIFFUSE_COLOR);
236   DALI_TEST_CHECK(props.mSpecularColor == Dali::Material::DEFAULT_SPECULAR_COLOR);
237   DALI_TEST_CHECK(props.mEmissiveColor == Dali::Material::DEFAULT_EMISSIVE_COLOR);
238
239   Internal::ResourceId textureId = sceneObject->GetDiffuseTextureId();
240   DALI_TEST_CHECK( !textureId );
241   textureId = sceneObject->GetOpacityTextureId();
242   DALI_TEST_CHECK( !textureId );
243   textureId = sceneObject->GetNormalMapId();
244   DALI_TEST_CHECK( !textureId );
245
246   DALI_TEST_CHECK(! sceneObject->HasDiffuseTexture());
247   DALI_TEST_CHECK(! sceneObject->HasOpacityTexture());
248   DALI_TEST_CHECK(! sceneObject->HasNormalMap());
249   END_TEST;
250 }
251
252 // Test new with event object sets up parameters appropriately
253 int UtcDaliMaterialMethodNew02(void)
254 {
255   TestApplication application;
256
257   Internal::Material* material = Internal::Material::New("cloth");
258   DALI_TEST_CHECK(material->GetShininess() == Dali::Material::DEFAULT_SHININESS);
259   DALI_TEST_CHECK(material->GetAmbientColor() == Dali::Material::DEFAULT_AMBIENT_COLOR);
260   material->SetOpacity(0.4f);
261   material->SetDiffuseColor(Color::MAGENTA);
262
263   // Create directly
264   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New(material);
265   Internal::MaterialProperties props = sceneObject->GetProperties(); // copy.
266   DALI_TEST_CHECK(props.mOpacity == 0.4f);
267   DALI_TEST_CHECK(props.mDiffuseColor == Color::MAGENTA);
268   DALI_TEST_CHECK(props.mShininess == Dali::Material::DEFAULT_SHININESS);
269   DALI_TEST_CHECK(props.mAmbientColor == Dali::Material::DEFAULT_AMBIENT_COLOR);
270   DALI_TEST_CHECK(props.mSpecularColor == Dali::Material::DEFAULT_SPECULAR_COLOR);
271   DALI_TEST_CHECK(props.mEmissiveColor == Dali::Material::DEFAULT_EMISSIVE_COLOR);
272
273   Internal::ResourceId textureId = sceneObject->GetDiffuseTextureId();
274   DALI_TEST_CHECK( !textureId );
275   textureId = sceneObject->GetOpacityTextureId();
276   DALI_TEST_CHECK( !textureId );
277   textureId = sceneObject->GetNormalMapId();
278   DALI_TEST_CHECK( !textureId );
279
280   DALI_TEST_CHECK(! sceneObject->HasDiffuseTexture());
281   DALI_TEST_CHECK(! sceneObject->HasOpacityTexture());
282   DALI_TEST_CHECK(! sceneObject->HasNormalMap());
283
284   // Create indirectly
285   const Internal::SceneGraph::Material* sceneObject2 = material->GetSceneObject();
286   DALI_TEST_CHECK( sceneObject2 != NULL );
287   Internal::MaterialProperties props2 = sceneObject2->GetProperties(); // copy.
288   DALI_TEST_CHECK(props2.mOpacity == 0.4f);
289   DALI_TEST_CHECK(props2.mDiffuseColor == Color::MAGENTA);
290   DALI_TEST_CHECK(props2.mShininess == Dali::Material::DEFAULT_SHININESS);
291   DALI_TEST_CHECK(props2.mAmbientColor == Dali::Material::DEFAULT_AMBIENT_COLOR);
292   DALI_TEST_CHECK(props2.mSpecularColor == Dali::Material::DEFAULT_SPECULAR_COLOR);
293   DALI_TEST_CHECK(props2.mEmissiveColor == Dali::Material::DEFAULT_EMISSIVE_COLOR);
294
295   DALI_TEST_CHECK(! sceneObject2->GetDiffuseTextureId());
296   DALI_TEST_CHECK(! sceneObject2->GetOpacityTextureId());
297   DALI_TEST_CHECK(! sceneObject2->GetNormalMapId());
298
299   DALI_TEST_CHECK(! sceneObject2->HasDiffuseTexture());
300   DALI_TEST_CHECK(! sceneObject2->HasOpacityTexture());
301   DALI_TEST_CHECK(! sceneObject2->HasNormalMap());
302   END_TEST;
303 }
304
305 // Test setting ready texture off stage
306 int UtcDaliMaterialReadyTextureOffstage(void)
307 {
308   TestApplication application;
309
310   Internal::ResourceTicketPtr ticket = CheckLoadBitmap(application, "diffuse.png", 80, 80);
311   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
312   sceneObject->SetDiffuseTextureId(ticket->GetId());
313
314   DALI_TEST_EQUALS( sceneObject->GetDiffuseTextureId(), ticket->GetId(), TEST_LOCATION );
315   END_TEST;
316 }
317
318 // Test setting unready texture offstage, becoming ready
319 int UtcDaliMaterialUnreadyTextureOffstage(void)
320 {
321   TestApplication application;
322
323   Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient();
324   ImageAttributes attr;
325   Integration::ImageResourceType bitmapRequest ( Integration::ResourceImageData, attr );
326   Internal::ResourceTicketPtr ticket = resourceClient.RequestResource( bitmapRequest, "image.png" );
327   application.SendNotification(); // Flush update messages
328   application.Render();           // Process resource request
329
330   // Ticket is valid, but no resource yet
331   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
332   Internal::ResourceId textureId = ticket->GetId();
333   sceneObject->SetDiffuseTextureId(textureId);
334   Internal::ResourceId textureId2 = sceneObject->GetDiffuseTextureId();
335   DALI_TEST_CHECK( textureId == textureId2 );
336
337   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
338   Integration::ImageDataPtr bitmap = Integration::NewBitmapImageData( 80, 80, Pixel::RGBA8888 );
339   Integration::ResourcePointer resourcePtr(bitmap); // reference it
340   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
341   application.Render();           // Process LoadComplete
342   application.SendNotification(); // Process event messages
343   DALI_TEST_CHECK( ticket->GetLoadingState() == ResourceLoadingSucceeded );
344
345   Internal::ResourceId textureId3 = sceneObject->GetDiffuseTextureId();
346   DALI_TEST_CHECK( textureId3 );
347   DALI_TEST_CHECK( textureId3 == textureId );
348   END_TEST;
349 }
350
351 // Test staging creates render material
352 int UtcDaliMaterialStaging01(void)
353 {
354   TestApplication application;
355   TestBoundTextures boundTextures(application);
356   TestProgram testProgram(application);
357
358   // Create object and set some properties
359   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
360   DALI_TEST_CHECK( sceneObject != NULL );
361   sceneObject->SetProperties(TEST_PROPS);
362
363   // Stage the object
364   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
365   AddMaterialMessage( updateManager, sceneObject );
366   application.SendNotification(); // Flush update Q
367
368   application.GetPlatform().IncrementGetTimeResult( 1 );
369   Integration::UpdateStatus status;
370   application.GetCore().Update( status );
371
372   // Check that a render object has been created
373   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
374   DALI_TEST_CHECK(renderMaterial != NULL);
375   // Not on render manager, and should have default props
376
377   Internal::SceneGraph::RenderMaterialUniforms materialUniforms;
378   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
379
380   DALI_TEST_EQUALS( testProgram.GetOpacity(),       1.0f, TEST_LOCATION );
381   DALI_TEST_EQUALS( testProgram.GetShininess(),     0.5f, TEST_LOCATION );
382   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  Vector4(0.2f, 0.2f, 0.2f, 1.0f), TEST_LOCATION);
383   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  Vector4(0.8f, 0.8f, 0.8f, 1.0f), TEST_LOCATION);
384   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
385   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
386
387   application.Render(); //Process render Q stores & processes mat
388
389   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
390   renderMaterial->BindTextures( testProgram.GetProgram() );
391   DALI_TEST_CHECK( boundTextures.GetNumBoundTextures() == 0 );
392
393   DALI_TEST_EQUALS( testProgram.GetOpacity(),       TEST_PROPS.mOpacity,       TEST_LOCATION);
394   DALI_TEST_EQUALS( testProgram.GetShininess(),     TEST_PROPS.mShininess,     TEST_LOCATION );
395   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  TEST_PROPS.mAmbientColor,  TEST_LOCATION );
396   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  TEST_PROPS.mDiffuseColor,  TEST_LOCATION );
397   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), TEST_PROPS.mSpecularColor, TEST_LOCATION );
398   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), TEST_PROPS.mEmissiveColor, TEST_LOCATION );
399   END_TEST;
400 }
401
402 // Test staging creates render material
403 int UtcDaliMaterialStaging02(void)
404 {
405   TestApplication application;
406   TestBoundTextures boundTextures(application);
407   TestProgram testProgram(application);
408
409   Internal::Material* material = Internal::Material::New("cloth");
410   material->SetOpacity(0.4f);
411   material->SetDiffuseColor(Color::MAGENTA);
412
413   // Create object and set some properties
414   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New(material);
415   DALI_TEST_CHECK( sceneObject != NULL );
416
417   // Stage the object
418   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
419   AddMaterialMessage( updateManager, sceneObject );
420   application.SendNotification(); // Flush update Q
421
422   application.GetPlatform().IncrementGetTimeResult( 1 );
423   Integration::UpdateStatus status;
424   application.GetCore().Update( status );
425
426   // Check that a render object has been created
427   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
428   DALI_TEST_CHECK(renderMaterial != NULL);
429   // Not on render manager, and should have default props
430
431   Internal::SceneGraph::RenderMaterialUniforms materialUniforms;
432   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
433
434   DALI_TEST_EQUALS( testProgram.GetOpacity(),       1.0f, TEST_LOCATION );
435   DALI_TEST_EQUALS( testProgram.GetShininess(),     0.5f, TEST_LOCATION );
436   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  Vector4(0.2f, 0.2f, 0.2f, 1.0f), TEST_LOCATION);
437   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  Vector4(0.8f, 0.8f, 0.8f, 1.0f), TEST_LOCATION);
438   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
439   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), Vector4(0.0f, 0.0f, 0.0f, 1.0f), TEST_LOCATION);
440
441   application.Render(); //Process render Q stores & processes mat
442
443   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
444   renderMaterial->BindTextures( testProgram.GetProgram() );
445
446   DALI_TEST_CHECK( boundTextures.GetNumBoundTextures() == 0 );
447   DALI_TEST_EQUALS( testProgram.GetOpacity(),       0.4f, TEST_LOCATION);
448   DALI_TEST_EQUALS( testProgram.GetShininess(),     Dali::Material::DEFAULT_SHININESS, TEST_LOCATION );
449   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  Dali::Material::DEFAULT_AMBIENT_COLOR,  TEST_LOCATION );
450   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  Color::MAGENTA, TEST_LOCATION );
451   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), Dali::Material::DEFAULT_SPECULAR_COLOR, TEST_LOCATION );
452   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), Dali::Material::DEFAULT_EMISSIVE_COLOR, TEST_LOCATION );
453   END_TEST;
454 }
455
456
457
458 // Test setting properties on stage
459 int UtcDaliMaterialSetPropsWhilstStaged(void)
460 {
461   TestApplication application;
462   TestBoundTextures boundTextures(application);
463   TestProgram testProgram(application);
464
465   // Create object with default properties
466   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
467   DALI_TEST_CHECK( sceneObject != NULL );
468
469   // Stage the object
470   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
471   AddMaterialMessage( updateManager, sceneObject );
472   application.SendNotification(); // Flush update Q
473   application.Render(); // Process update message Q then create & post to render Q
474
475   // Check that a render object has been created
476   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
477   DALI_TEST_CHECK(renderMaterial != NULL);
478   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
479
480   sceneObject->SetProperties(TEST_PROPS);
481   application.SendNotification(); // Flush update Q
482   application.Render(); // Update & Prepare material
483   application.Render(); // Process render Q
484
485   Internal::SceneGraph::RenderMaterialUniforms materialUniforms;
486   renderMaterial->SetUniforms( materialUniforms, testProgram.GetProgram(), Internal::SHADER_DEFAULT );
487   renderMaterial->BindTextures( testProgram.GetProgram() );
488
489   DALI_TEST_EQUALS( boundTextures.GetNumBoundTextures(), 0u, TEST_LOCATION );
490
491   DALI_TEST_EQUALS( testProgram.GetOpacity(),       TEST_PROPS.mOpacity,       TEST_LOCATION);
492   DALI_TEST_EQUALS( testProgram.GetShininess(),     TEST_PROPS.mShininess,     TEST_LOCATION );
493   DALI_TEST_EQUALS( testProgram.GetAmbientColor(),  TEST_PROPS.mAmbientColor,  TEST_LOCATION );
494   DALI_TEST_EQUALS( testProgram.GetDiffuseColor(),  TEST_PROPS.mDiffuseColor,  TEST_LOCATION );
495   DALI_TEST_EQUALS( testProgram.GetSpecularColor(), TEST_PROPS.mSpecularColor, TEST_LOCATION );
496   DALI_TEST_EQUALS( testProgram.GetEmissiveColor(), TEST_PROPS.mEmissiveColor, TEST_LOCATION );
497   END_TEST;
498 }
499
500 // Test setting ready texture on stage
501 int UtcDaliMaterialSetTextureWhilstStaged(void)
502 {
503   TestApplication application;
504   TestBoundTextures boundTextures(application);
505   TestProgram testProgram(application);
506
507   Internal::ResourceTicketPtr ticket = CheckLoadBitmap(application, "diffuse.png", 80, 80);
508
509   // Create object with default properties
510   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
511   DALI_TEST_CHECK( sceneObject != NULL );
512
513   // Stage the object
514   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
515   AddMaterialMessage( updateManager, sceneObject );
516   application.SendNotification(); // Flush update Q
517   application.Render(); // Process update message Q then create & post to render Q
518
519   // Check that a render object has been created
520   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
521   DALI_TEST_CHECK(renderMaterial != NULL);
522   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
523
524   sceneObject->SetDiffuseTextureId(ticket->GetId());
525   application.SendNotification(); // Flush update Q
526   application.Render(); // Update & Prepare material
527   application.Render(); // Process render Q
528
529   renderMaterial->BindTextures( testProgram.GetProgram() );
530   DALI_TEST_CHECK( boundTextures.CheckFirstTextureBound( GL_TEXTURE0 ) );
531   END_TEST;
532 }
533
534 // Test setting unready texture on stage, becoming ready
535 int UtcDaliMaterialSetUnreadyTextureWhilstStaged(void)
536 {
537   TestApplication application;
538   TestBoundTextures boundTextures(application);
539   TestProgram testProgram(application);
540
541   Internal::ResourceClient& resourceClient = Internal::ThreadLocalStorage::Get().GetResourceClient();
542   ImageAttributes attr;
543   Integration::ImageResourceType bitmapRequest ( Integration::ResourceImageData, attr );
544   Internal::ResourceTicketPtr ticket = resourceClient.RequestResource( bitmapRequest, "image.png" );
545   application.SendNotification(); // Flush update messages
546   application.Render();           // Process resource request
547
548
549   // Create object with default properties
550   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
551   DALI_TEST_CHECK( sceneObject != NULL );
552
553   // Stage the object
554   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
555   AddMaterialMessage( updateManager, sceneObject );
556   application.SendNotification(); // Flush update Q
557   application.Render(); // Process update message Q then create & post to render Q
558
559   // Check that a render object has been created
560   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
561   DALI_TEST_CHECK(renderMaterial != NULL);
562   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
563
564   sceneObject->SetDiffuseTextureId(ticket->GetId());
565   application.SendNotification(); // Flush update Q
566   application.Render(); // Update & Prepare material
567   application.Render(); // Process render Q
568
569   renderMaterial->BindTextures( testProgram.GetProgram() );
570
571   DALI_TEST_EQUALS( boundTextures.GetNumBoundTextures(), 0u, TEST_LOCATION );
572
573   Integration::ResourceRequest*   req = application.GetPlatform().GetRequest();
574   Integration::ImageDataPtr bitmap = Integration::NewBitmapImageData( 80, 80, Pixel::RGBA8888 );
575   Integration::ResourcePointer resourcePtr(bitmap); // reference it
576   application.GetPlatform().SetResourceLoaded(req->GetId(), req->GetType()->id, resourcePtr);
577   application.Render();           // Process LoadComplete
578   application.SendNotification(); // Process event messages
579
580   renderMaterial->BindTextures( testProgram.GetProgram() );
581   DALI_TEST_CHECK( boundTextures.CheckFirstTextureBound( GL_TEXTURE0 ) );
582   END_TEST;
583 }
584
585 // Test IsOpaque without texture, with unready texture, with ready texture
586
587 int UtcDaliMaterialIsOpaqueWithoutTexture(void)
588 {
589   TestApplication application;
590
591   // Create object with default properties
592   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
593   DALI_TEST_CHECK( sceneObject != NULL );
594
595   // Stage the object
596   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
597   AddMaterialMessage( updateManager, sceneObject );
598   application.SendNotification(); // Flush update Q
599   application.Render(); // Process update message Q then create & post to render Q
600
601   // Check that a render object has been created
602   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
603   DALI_TEST_CHECK(renderMaterial != NULL);
604   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
605
606   DALI_TEST_CHECK( sceneObject->IsOpaque() );
607   END_TEST;
608 }
609
610 int UtcDaliMaterialIsOpaqueWithTexture(void)
611 {
612   TestApplication application;
613
614   Internal::ResourceTicketPtr textureImageTicket = CheckLoadBitmap(application, "diffuse.png", 80, 80);
615
616   // Create object with default properties
617   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
618   DALI_TEST_CHECK( sceneObject != NULL );
619
620   // Stage the object
621   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
622   AddMaterialMessage( updateManager, sceneObject );
623   application.SendNotification(); // Flush update Q
624   application.Render(); // Process update message Q then create & post to render Q
625
626   // Check that a render object has been created
627   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
628   DALI_TEST_CHECK(renderMaterial != NULL);
629   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
630
631   DALI_TEST_CHECK( sceneObject->IsOpaque() );
632
633   sceneObject->SetDiffuseTextureId( textureImageTicket->GetId() );
634   application.SendNotification(); // Flush update Q
635   application.Render(); // Update & Prepare material
636   application.Render(); // Process render Q
637
638   DALI_TEST_CHECK( ! sceneObject->IsOpaque() );
639   END_TEST;
640 }
641
642
643 int UtcDaliMaterialIsOpaqueWithProps(void)
644 {
645   TestApplication application;
646
647   // Create object with default properties
648   Internal::SceneGraph::Material* sceneObject = Internal::SceneGraph::Material::New();
649   DALI_TEST_CHECK( sceneObject != NULL );
650
651   // Stage the object
652   Internal::SceneGraph::UpdateManager& updateManager = Internal::ThreadLocalStorage::Get().GetUpdateManager();
653   AddMaterialMessage( updateManager, sceneObject );
654   application.SendNotification(); // Flush update Q
655   application.Render(); // Process update message Q then create & post to render Q
656
657   // Check that a render object has been created
658   Internal::SceneGraph::RenderMaterial* renderMaterial = sceneObject->GetRenderMaterial();
659   DALI_TEST_CHECK(renderMaterial != NULL);
660   application.Render(); // Update & Prepare renderMat, Process render Q stores & processes mat
661
662   DALI_TEST_CHECK( sceneObject->IsOpaque() );
663
664   sceneObject->SetProperties(TEST_PROPS);
665   application.SendNotification(); // Flush update Q
666   application.Render(); // Update & Prepare material
667   application.Render(); // Process render Q
668
669   DALI_TEST_CHECK( ! sceneObject->IsOpaque() );
670   END_TEST;
671 }
672
673 int UtcDaliMaterialRender(void)
674 {
675   TestApplication application;
676   TestBoundTextures boundTextures(application);
677
678   {
679
680     MeshData meshData;
681     MeshData::VertexContainer    vertices;
682     MeshData::FaceIndices        faces;
683     BoneContainer                bones;
684     ConstructVertices(vertices, 60);
685     ConstructFaces(vertices, faces);
686     Dali::Material               material  = ConstructMaterial();
687
688     Internal::ImagePtr image = LoadImage(application, "texture.png");
689     Image imageHandle(image.Get());
690     material.SetDiffuseTexture(imageHandle);
691     meshData.SetData(vertices, faces, bones, material);
692     Mesh mesh = Mesh::New(meshData);
693
694     MeshActor actor = MeshActor::New(mesh);
695     std::string name = "AMeshActor";
696     actor.SetName(name);
697     actor.SetAffectedByLighting(false);
698     Stage::GetCurrent().Add(actor);
699
700     material.SetOpacity(TEST_PROPS.mOpacity);
701     material.SetShininess(TEST_PROPS.mShininess);
702     material.SetAmbientColor(TEST_PROPS.mAmbientColor);
703     material.SetDiffuseColor(TEST_PROPS.mDiffuseColor);
704     material.SetSpecularColor(TEST_PROPS.mSpecularColor);
705     material.SetEmissiveColor(TEST_PROPS.mEmissiveColor);
706
707     application.SendNotification();
708     application.Render();
709     application.SendNotification();
710     application.Render();
711     application.SendNotification();
712     application.Render();
713     application.SendNotification();
714
715     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mOpacity",   TEST_PROPS.mOpacity ) );
716     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mShininess", TEST_PROPS.mShininess ) );
717     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mAmbient",   TEST_PROPS.mAmbientColor ) );
718     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mDiffuse",   TEST_PROPS.mDiffuseColor ) );
719     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mSpecular",  TEST_PROPS.mSpecularColor ) );
720     DALI_TEST_CHECK(application.GetGlAbstraction().CheckUniformValue("uMaterial.mEmissive",  TEST_PROPS.mEmissiveColor ) );
721
722     DALI_TEST_CHECK(boundTextures.CheckFirstTextureBound( GL_TEXTURE0 ));
723
724     Stage::GetCurrent().Remove(actor);
725     application.SendNotification();
726     application.Render();
727     application.SendNotification();
728     application.Render();
729   }
730   application.SendNotification();
731   application.Render();
732
733   // texture should have been removed:
734   DALI_TEST_CHECK( boundTextures.CheckFirstTextureDeleted() );
735   END_TEST;
736 }