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