License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / event / modeling / material-impl.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 // CLASS HEADER
19 #include <dali/internal/event/modeling/material-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/constants.h>
23 #include <dali/internal/update/modeling/scene-graph-material.h>
24 #include <dali/internal/common/event-to-update.h>
25 #include <dali/internal/event/images/image-impl.h>
26 #include <dali/internal/event/common/stage-impl.h>
27 #include <dali/internal/event/common/thread-local-storage.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 MaterialProperties::MaterialProperties()
36   : mOpacity           (Dali::Material::DEFAULT_OPACITY),
37     mShininess         (Dali::Material::DEFAULT_SHININESS),
38     mAmbientColor      (Dali::Material::DEFAULT_AMBIENT_COLOR),
39     mDiffuseColor      (Dali::Material::DEFAULT_DIFFUSE_COLOR),
40     mSpecularColor     (Dali::Material::DEFAULT_SPECULAR_COLOR),
41     mEmissiveColor     (Dali::Material::DEFAULT_EMISSIVE_COLOR),
42     mMapU              (Dali::Material::DEFAULT_MAPPING_MODE),
43     mMapV              (Dali::Material::DEFAULT_MAPPING_MODE),
44     mDiffuseUVIndex    (Dali::Material::DEFAULT_DIFFUSE_UV_INDEX),
45     mOpacityUVIndex    (Dali::Material::DEFAULT_OPACITY_UV_INDEX),
46     mNormalUVIndex     (Dali::Material::DEFAULT_NORMAL_UV_INDEX),
47     mHasHeightMap      (Dali::Material::DEFAULT_HAS_HEIGHT_MAP)
48 {
49 }
50
51 MaterialProperties::MaterialProperties(const MaterialProperties& rhs)
52   : mOpacity(rhs.mOpacity),
53     mShininess(rhs.mShininess),
54     mAmbientColor(rhs.mAmbientColor),
55     mDiffuseColor(rhs.mDiffuseColor),
56     mSpecularColor(rhs.mSpecularColor),
57     mEmissiveColor(rhs.mEmissiveColor),
58     mMapU(rhs.mMapU),
59     mMapV(rhs.mMapV),
60     mDiffuseUVIndex(rhs.mDiffuseUVIndex),
61     mOpacityUVIndex(rhs.mOpacityUVIndex),
62     mNormalUVIndex(rhs.mNormalUVIndex),
63     mHasHeightMap(rhs.mHasHeightMap)
64 {
65 }
66
67 MaterialProperties& MaterialProperties::operator=(const MaterialProperties& rhs)
68 {
69   mOpacity           = rhs.mOpacity;
70   mShininess         = rhs.mShininess;
71   mAmbientColor      = rhs.mAmbientColor;
72   mDiffuseColor      = rhs.mDiffuseColor;
73   mSpecularColor     = rhs.mSpecularColor;
74   mEmissiveColor     = rhs.mEmissiveColor;
75   mMapU              = rhs.mMapU;
76   mMapV              = rhs.mMapV;
77   mDiffuseUVIndex    = rhs.mDiffuseUVIndex;
78   mOpacityUVIndex    = rhs.mOpacityUVIndex;
79   mNormalUVIndex     = rhs.mNormalUVIndex;
80   mHasHeightMap      = rhs.mHasHeightMap;
81
82   return *this;
83 }
84
85
86 Material* Material::New(const std::string& name)
87 {
88   return new Material(name);
89 }
90
91 Material::Material(const std::string& name)
92   : mName(name),
93     mProperties(),
94     mSceneObject(NULL),
95     mEventToUpdate(NULL),
96     mUpdateManager(NULL),
97     mConnectionCount(0)
98 {
99 }
100
101 Material::~Material()
102 {
103   if ( mSceneObject &&
104        Stage::IsInstalled()/*Guard to allow handle destruction after Core has been destroyed*/ )
105   {
106     RemoveMaterialMessage( *mUpdateManager, mSceneObject );
107   }
108 }
109
110 SceneGraph::Material* Material::CreateSceneObject()
111 {
112   DALI_ASSERT_DEBUG( mSceneObject == NULL );
113
114   if(mEventToUpdate == NULL)
115   {
116     EventToUpdate& eventToUpdate = ThreadLocalStorage::Get().GetEventToUpdate();
117     mEventToUpdate = &eventToUpdate;
118   }
119
120   if(mUpdateManager == NULL)
121   {
122     SceneGraph::UpdateManager& updateManager = ThreadLocalStorage::Get().GetUpdateManager();
123     mUpdateManager = &updateManager;
124   }
125
126   mSceneObject = SceneGraph::Material::New(this);
127   if( mDiffuseImage )
128   {
129     mSceneObject->SetDiffuseTextureId( GetImplementation(mDiffuseImage).GetResourceId() );
130   }
131   if( mOpacityImage )
132   {
133     mSceneObject->SetOpacityTextureId( GetImplementation(mOpacityImage).GetResourceId() );
134   }
135   if( mNormalMap )
136   {
137     mSceneObject->SetNormalMapId( GetImplementation(mNormalMap).GetResourceId() );
138   }
139   AddMaterialMessage( *mUpdateManager, mSceneObject );
140
141   return mSceneObject;
142 }
143
144 // Used for staging material
145 const SceneGraph::Material* Material::GetSceneObject()
146 {
147   if( mSceneObject == NULL )
148   {
149     mSceneObject = CreateSceneObject();
150   }
151   return mSceneObject;
152 }
153
154 void Material::Connect()
155 {
156   if(mConnectionCount == 0)
157   {
158     if( mSceneObject == NULL )
159     {
160       mSceneObject = CreateSceneObject();
161     }
162
163     if (mDiffuseImage)
164     {
165       GetImplementation(mDiffuseImage).Connect();
166       SendDiffuseImageToSceneObject(mDiffuseImage);
167     }
168     if (mOpacityImage)
169     {
170       GetImplementation(mOpacityImage).Connect();
171       SendOpacityImageToSceneObject(mOpacityImage);
172     }
173     if (mNormalMap)
174     {
175       GetImplementation(mNormalMap).Connect();
176       SendNormalMapToSceneObject(mNormalMap);
177     }
178   }
179   else
180   {
181     DALI_ASSERT_DEBUG(mSceneObject);
182   }
183   mConnectionCount++;
184 }
185
186 void Material::Disconnect()
187 {
188   if(mConnectionCount > 0)
189   {
190     DALI_ASSERT_DEBUG(mSceneObject);
191     mConnectionCount--;
192   }
193
194   if(mConnectionCount <= 0)
195   {
196     if (mDiffuseImage)
197     {
198       GetImplementation(mDiffuseImage).Disconnect();
199     }
200     if (mOpacityImage)
201     {
202       GetImplementation(mOpacityImage).Disconnect();
203     }
204     if (mNormalMap)
205     {
206       GetImplementation(mNormalMap).Disconnect();
207     }
208   }
209 }
210
211 void Material::SendPropertiesToSceneObject()
212 {
213   if( mSceneObject != NULL )
214   {
215     DALI_ASSERT_DEBUG( mEventToUpdate != NULL );
216     if( mEventToUpdate != NULL )
217     {
218       SetPropertiesMessage( *mEventToUpdate, *mSceneObject, mProperties );
219     }
220   }
221 }
222
223 void Material::SendDiffuseImageToSceneObject(Dali::Image image)
224 {
225   if( image && mSceneObject != NULL && mEventToUpdate != NULL )
226   {
227     ResourceId id = GetImplementation(image).GetResourceId();
228     SetDiffuseTextureMessage( *mEventToUpdate, *mSceneObject, id );
229   }
230 }
231
232 void Material::SendOpacityImageToSceneObject(Dali::Image image)
233 {
234   if( image && mSceneObject != NULL && mEventToUpdate != NULL )
235   {
236     ResourceId id = GetImplementation(image).GetResourceId();
237     SetOpacityTextureMessage( *mEventToUpdate, *mSceneObject, id );
238   }
239 }
240
241 void Material::SendNormalMapToSceneObject(Dali::Image image)
242 {
243   if( image && mSceneObject != NULL && mEventToUpdate != NULL )
244   {
245     ResourceId id = GetImplementation(image).GetResourceId();
246     SetNormalMapMessage( *mEventToUpdate, *mSceneObject, id );
247   }
248 }
249
250 void Material::SetOpacity(const float opacity)
251 {
252   mProperties.mOpacity = opacity;
253   SendPropertiesToSceneObject();
254 }
255
256 float Material::GetOpacity() const
257 {
258   return mProperties.mOpacity;
259 }
260
261 void Material::SetShininess(const float shininess)
262 {
263   mProperties.mShininess = shininess;
264   SendPropertiesToSceneObject();
265 }
266
267 float Material::GetShininess() const
268 {
269   return mProperties.mShininess;
270 }
271
272 void Material::SetAmbientColor(const Vector4& color)
273 {
274   mProperties.mAmbientColor = color;
275   SendPropertiesToSceneObject();
276 }
277
278 const Vector4& Material::GetAmbientColor() const
279 {
280   return mProperties.mAmbientColor;
281 }
282
283 void Material::SetDiffuseColor(const Vector4& color)
284 {
285   mProperties.mDiffuseColor = color;
286   SendPropertiesToSceneObject();
287 }
288
289 const Vector4& Material::GetDiffuseColor() const
290 {
291   return mProperties.mDiffuseColor;
292 }
293
294 void Material::SetSpecularColor(const Vector4& color)
295 {
296   mProperties.mSpecularColor = color;
297   SendPropertiesToSceneObject();
298 }
299
300 const Vector4& Material::GetSpecularColor() const
301 {
302   return mProperties.mSpecularColor;
303 }
304
305 void Material::SetEmissiveColor(const Vector4& color)
306 {
307   mProperties.mEmissiveColor = color;
308   SendPropertiesToSceneObject();
309 }
310
311 const Vector4& Material::GetEmissiveColor() const
312 {
313   return mProperties.mEmissiveColor;
314 }
315
316 void Material::SetDiffuseTexture(Dali::Image image)
317 {
318   if( mDiffuseImage == image )
319   {
320     return;
321   }
322
323   if( mDiffuseImage && mConnectionCount > 0 )
324   {
325     GetImplementation(mDiffuseImage).Disconnect();
326   }
327
328   mDiffuseImage = image;
329
330   if( image && mConnectionCount > 0 )
331   {
332     GetImplementation(image).Connect();
333   }
334
335   /// @todo currently there is a bug in material rendering if image is not loaded at this point (Trac issue #475)
336   SendDiffuseImageToSceneObject(image);
337 }
338
339 void Material::SetDiffuseTextureFileName(const std::string filename)
340 {
341   mDiffuseName = filename;
342 }
343
344 Dali::Image Material::GetDiffuseTexture() const
345 {
346   return mDiffuseImage;
347 }
348
349 const std::string& Material::GetDiffuseTextureFileName() const
350 {
351   return mDiffuseName;
352 }
353
354 void Material::SetOpacityTexture(Dali::Image image)
355 {
356   if (mOpacityImage == image)
357   {
358     return;
359   }
360
361   if (mOpacityImage && mConnectionCount > 0)
362   {
363     GetImplementation(mOpacityImage).Disconnect();
364   }
365
366   mOpacityImage = image;
367
368   if (image && mConnectionCount > 0)
369   {
370     GetImplementation(image).Connect();
371   }
372
373   /// @todo currently there is a bug in material rendering if image is not loaded at this point (Trac issue #475)
374   SendOpacityImageToSceneObject(image);
375 }
376
377 void Material::SetOpacityTextureFileName(const std::string filename)
378 {
379   mOpacityName = filename;
380 }
381
382 Dali::Image Material::GetOpacityTexture() const
383 {
384   return mOpacityImage;
385 }
386
387 const std::string& Material::GetOpacityTextureFileName() const
388 {
389   return mOpacityName;
390 }
391
392 void Material::SetNormalMap(Dali::Image image)
393 {
394   if (mNormalMap == image)
395   {
396     return;
397   }
398
399   if (mNormalMap && mConnectionCount > 0)
400   {
401     GetImplementation(mNormalMap).Disconnect();
402   }
403
404   mNormalMap = image;
405
406   if (image && mConnectionCount > 0)
407   {
408     GetImplementation(image).Connect();
409   }
410
411   /// @todo currently there is a bug in material rendering if image is not loaded at this point (Trac issue #475)
412   SendNormalMapToSceneObject(image);
413 }
414
415 void Material::SetNormalMapFileName(const std::string filename)
416 {
417   mNormalMapName = filename;
418 }
419
420 Dali::Image Material::GetNormalMap() const
421 {
422   return mNormalMap;
423 }
424
425 const std::string&  Material::GetNormalMapFileName() const
426 {
427   return mNormalMapName;
428 }
429
430 void Material::SetMapU(const unsigned int map)
431 {
432   mProperties.mMapU = map;
433   SendPropertiesToSceneObject();
434 }
435
436 const unsigned int Material::GetMapU() const
437 {
438   return mProperties.mMapU;
439 }
440
441 void Material::SetMapV(const unsigned int map)
442 {
443   mProperties.mMapV = map;
444   SendPropertiesToSceneObject();
445 }
446
447 const unsigned int Material::GetMapV() const
448 {
449   return mProperties.mMapV;
450 }
451
452 void Material::SetDiffuseUVIndex(const int index)
453 {
454   mProperties.mDiffuseUVIndex = index;
455   SendPropertiesToSceneObject();
456 }
457
458 const unsigned int Material::GetDiffuseUVIndex() const
459 {
460   return mProperties.mDiffuseUVIndex;
461 }
462
463 void Material::SetOpacityUVIndex(const int index)
464 {
465   mProperties.mOpacityUVIndex = index;
466   SendPropertiesToSceneObject();
467 }
468
469 const unsigned int Material::GetOpacityUVIndex() const
470 {
471   return mProperties.mOpacityUVIndex;
472 }
473
474 void Material::SetNormalUVIndex(const int index)
475 {
476   mProperties.mNormalUVIndex = index;
477   SendPropertiesToSceneObject();
478 }
479
480 const unsigned int Material::GetNormalUVIndex() const
481 {
482   return mProperties.mNormalUVIndex;
483 }
484
485 void Material::SetHasHeightMap(const bool flag)
486 {
487   mProperties.mHasHeightMap = true;
488   SendPropertiesToSceneObject();
489 }
490
491 const bool Material::GetHasHeightMap() const
492 {
493   return mProperties.mHasHeightMap;
494 }
495
496
497
498 } // namespace Internal
499
500 } // namespace Dali