2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/internal/event/rendering/material-impl.h> // Dali::Internal::Material
25 #include <dali/public-api/object/type-registry.h>
26 #include <dali/devel-api/rendering/material.h> // Dali::Internal::Material
27 #include <dali/internal/event/common/object-impl-helper.h> // Dali::Internal::ObjectHelper
28 #include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
29 #include <dali/internal/update/manager/update-manager.h>
30 #include <dali/internal/update/rendering/scene-graph-material.h>
41 * |name |type |writable|animatable|constraint-input|enum for index-checking|
43 DALI_PROPERTY_TABLE_BEGIN
44 DALI_PROPERTY( "faceCullingMode", INTEGER, true, false, false, Dali::Material::Property::FACE_CULLING_MODE )
45 DALI_PROPERTY( "blendingMode", INTEGER, true, false, false, Dali::Material::Property::BLENDING_MODE )
46 DALI_PROPERTY( "blendEquationRgb", INTEGER, true, false, false, Dali::Material::Property::BLEND_EQUATION_RGB )
47 DALI_PROPERTY( "blendEquationAlpha", INTEGER, true, false, false, Dali::Material::Property::BLEND_EQUATION_ALPHA )
48 DALI_PROPERTY( "sourceBlendFactorRgb", INTEGER, true, false, false, Dali::Material::Property::BLENDING_SRC_FACTOR_RGB )
49 DALI_PROPERTY( "destinationBlendFactorRgb", INTEGER, true, false, false, Dali::Material::Property::BLENDING_DEST_FACTOR_RGB )
50 DALI_PROPERTY( "sourceBlendFactorAlpha", INTEGER, true, false, false, Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA )
51 DALI_PROPERTY( "destinationBlendFactorAlpha", INTEGER, true, false, false, Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA )
52 DALI_PROPERTY( "blendColor", VECTOR4, true, false, false, Dali::Material::Property::BLEND_COLOR )
53 DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
55 const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> MATERIAL_IMPL = { DEFAULT_PROPERTY_DETAILS };
59 return Dali::BaseHandle();
62 TypeRegistration mType( typeid( Dali::Material ), typeid( Dali::Handle ), Create );
64 } // unnamed namespace
66 MaterialPtr Material::New()
68 MaterialPtr material( new Material() );
69 material->Initialize();
73 void Material::SetShader( Shader& shader )
75 DALI_ASSERT_DEBUG( mSceneObject )
78 SceneGraph::Shader& sceneGraphShader = *shader.GetShaderSceneObject();
79 SceneGraph::SetShaderMessage( GetEventThreadServices(), *mSceneObject, sceneGraphShader );
82 Shader* Material::GetShader() const
87 size_t Material::AddTexture( ImagePtr image, const std::string& uniformName, SamplerPtr sampler )
89 size_t index = mTextures.size();
90 mTextures.push_back( Texture( uniformName, image, sampler ) );
92 Render::Sampler* renderSampler(0);
95 renderSampler = sampler->GetSamplerRenderObject();
103 SceneGraph::AddTextureMessage( GetEventThreadServices(), *mSceneObject, uniformName, image->GetResourceId(), renderSampler );
107 void Material::RemoveTexture( size_t index )
109 if( index < GetNumberOfTextures() )
111 mTextures.erase( mTextures.begin() + index );
112 SceneGraph::RemoveTextureMessage( GetEventThreadServices(), *mSceneObject, index );
116 void Material::SetTextureImage( size_t index, Image* image )
118 if( index < GetNumberOfTextures() )
120 if( mTextures[index].mImage && mOnStage )
122 mTextures[index].mImage->Disconnect();
130 mTextures[index].mImage.Reset(image);
131 SceneGraph::SetTextureImageMessage( GetEventThreadServices(), *mSceneObject, index, mTextures[index].mImage.Get()->GetResourceId() );
135 void Material::SetTextureSampler( size_t index, Sampler* sampler )
137 if( index < GetNumberOfTextures() )
139 mTextures[index].mSampler.Reset(sampler);
141 Render::Sampler* renderSampler(0);
144 renderSampler = sampler->GetSamplerRenderObject();
146 SceneGraph::SetTextureSamplerMessage( GetEventThreadServices(), *mSceneObject, index, renderSampler );
150 Sampler* Material::GetTextureSampler( size_t index ) const
152 if( index < GetNumberOfTextures() )
154 return mTextures[index].mSampler.Get();
160 void Material::SetTextureUniformName( size_t index, const std::string& uniformName )
162 if( index < GetNumberOfTextures() )
164 mTextures[index].mUniformName = uniformName;
165 SceneGraph::SetTextureUniformNameMessage( GetEventThreadServices(), *mSceneObject, index, uniformName );
169 int Material::GetTextureIndex( const std::string& uniformName ) const
171 size_t textureCount(GetNumberOfTextures());
172 for( size_t i(0); i<textureCount; ++i )
174 if( uniformName.compare( mTextures[i].mUniformName ) == 0 )
183 Image* Material::GetTexture( const std::string& uniformName ) const
185 int textureId = GetTextureIndex( uniformName );
186 if( textureId != -1 )
188 return GetTexture( textureId );
194 Image* Material::GetTexture( size_t index ) const
196 if( index < GetNumberOfTextures() )
198 return mTextures[ index ].mImage.Get();
204 size_t Material::GetNumberOfTextures() const
206 return mTextures.size();
209 void Material::SetFaceCullingMode( Dali::Material::FaceCullingMode cullingMode )
211 if( mFaceCullingMode != cullingMode )
213 mFaceCullingMode = cullingMode;
215 SetFaceCullingModeMessage( GetEventThreadServices(), *mSceneObject, mFaceCullingMode );
219 Dali::Material::FaceCullingMode Material::GetFaceCullingMode()
221 return mFaceCullingMode;
224 void Material::SetBlendMode( BlendingMode::Type mode )
226 if( mBlendingMode != mode )
228 mBlendingMode = mode;
230 SetBlendingModeMessage( GetEventThreadServices(), *mSceneObject, mBlendingMode );
234 BlendingMode::Type Material::GetBlendMode() const
236 return mBlendingMode;
239 void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba )
241 mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
242 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
245 void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgb,
246 BlendingFactor::Type destFactorRgb,
247 BlendingFactor::Type srcFactorAlpha,
248 BlendingFactor::Type destFactorAlpha )
250 mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
251 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
254 void Material::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,
255 BlendingFactor::Type& destFactorRgb,
256 BlendingFactor::Type& srcFactorAlpha,
257 BlendingFactor::Type& destFactorAlpha ) const
259 srcFactorRgb = mBlendingOptions.GetBlendSrcFactorRgb();
260 destFactorRgb = mBlendingOptions.GetBlendDestFactorRgb();
261 srcFactorAlpha = mBlendingOptions.GetBlendSrcFactorAlpha();
262 destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
265 void Material::SetBlendEquation( BlendingEquation::Type equationRgba )
267 mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
268 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
271 void Material::SetBlendEquation( BlendingEquation::Type equationRgb,
272 BlendingEquation::Type equationAlpha )
274 mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
275 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
278 void Material::GetBlendEquation( BlendingEquation::Type& equationRgb,
279 BlendingEquation::Type& equationAlpha ) const
281 // These are not animatable, the cached values are up-to-date.
282 equationRgb = mBlendingOptions.GetBlendEquationRgb();
283 equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
286 void Material::SetBlendColor( const Vector4& color )
290 mBlendColor = new Vector4();
292 if( *mBlendColor != color )
294 *mBlendColor = color;
295 SetBlendColorMessage( GetEventThreadServices(), *mSceneObject, *mBlendColor );
299 Vector4 Material::GetBlendColor() const
305 return Color::TRANSPARENT; // GL default
308 const SceneGraph::Material* Material::GetMaterialSceneObject() const
313 unsigned int Material::GetDefaultPropertyCount() const
315 return MATERIAL_IMPL.GetDefaultPropertyCount();
318 void Material::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
320 MATERIAL_IMPL.GetDefaultPropertyIndices( indices );
323 const char* Material::GetDefaultPropertyName(Property::Index index) const
325 return MATERIAL_IMPL.GetDefaultPropertyName( index );
328 Property::Index Material::GetDefaultPropertyIndex( const std::string& name ) const
330 return MATERIAL_IMPL.GetDefaultPropertyIndex( name );
333 bool Material::IsDefaultPropertyWritable( Property::Index index ) const
335 return MATERIAL_IMPL.IsDefaultPropertyWritable( index );
338 bool Material::IsDefaultPropertyAnimatable( Property::Index index ) const
340 return MATERIAL_IMPL.IsDefaultPropertyAnimatable( index );
343 bool Material::IsDefaultPropertyAConstraintInput( Property::Index index ) const
345 return MATERIAL_IMPL.IsDefaultPropertyAConstraintInput( index );
348 Property::Type Material::GetDefaultPropertyType( Property::Index index ) const
350 return MATERIAL_IMPL.GetDefaultPropertyType( index );
353 void Material::SetDefaultProperty( Property::Index index,
354 const Property::Value& propertyValue )
358 case Dali::Material::Property::FACE_CULLING_MODE:
361 if( propertyValue.Get( faceCullingMode ) )
363 SetFaceCullingMode( Dali::Material::FaceCullingMode( faceCullingMode ) );
367 case Dali::Material::Property::BLENDING_MODE:
370 if( propertyValue.Get( blendingMode ) )
372 SetBlendMode( BlendingMode::Type( blendingMode ) );
376 case Dali::Material::Property::BLEND_EQUATION_RGB:
378 int blendingEquation;
379 if( propertyValue.Get( blendingEquation ) )
381 BlendingEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
382 mBlendingOptions.SetBlendEquation( static_cast<BlendingEquation::Type>( blendingEquation ), alphaEquation );
383 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
387 case Dali::Material::Property::BLEND_EQUATION_ALPHA:
389 int blendingEquation;
390 if( propertyValue.Get( blendingEquation ) )
392 BlendingEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
393 mBlendingOptions.SetBlendEquation( rgbEquation, static_cast<BlendingEquation::Type>( blendingEquation ) );
394 SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
398 case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
401 if( propertyValue.Get( blendingFactor ) )
403 BlendingFactor::Type srcFactorRgb;
404 BlendingFactor::Type destFactorRgb;
405 BlendingFactor::Type srcFactorAlpha;
406 BlendingFactor::Type destFactorAlpha;
407 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
408 SetBlendFunc( static_cast<BlendingFactor::Type>( blendingFactor ),
415 case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
418 if( propertyValue.Get( blendingFactor ) )
420 BlendingFactor::Type srcFactorRgb;
421 BlendingFactor::Type destFactorRgb;
422 BlendingFactor::Type srcFactorAlpha;
423 BlendingFactor::Type destFactorAlpha;
424 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
425 SetBlendFunc( srcFactorRgb,
426 static_cast<BlendingFactor::Type>( blendingFactor ),
432 case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
435 if( propertyValue.Get( blendingFactor ) )
437 BlendingFactor::Type srcFactorRgb;
438 BlendingFactor::Type destFactorRgb;
439 BlendingFactor::Type srcFactorAlpha;
440 BlendingFactor::Type destFactorAlpha;
441 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
442 SetBlendFunc( srcFactorRgb,
444 static_cast<BlendingFactor::Type>( blendingFactor ),
449 case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
452 if( propertyValue.Get( blendingFactor ) )
454 BlendingFactor::Type srcFactorRgb;
455 BlendingFactor::Type destFactorRgb;
456 BlendingFactor::Type srcFactorAlpha;
457 BlendingFactor::Type destFactorAlpha;
458 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
459 SetBlendFunc( srcFactorRgb,
462 static_cast<BlendingFactor::Type>( blendingFactor ) );
466 case Dali::Material::Property::BLEND_COLOR:
469 if( propertyValue.Get( blendColor ) )
471 SetBlendColor( blendColor );
478 void Material::SetSceneGraphProperty( Property::Index index,
479 const PropertyMetadata& entry,
480 const Property::Value& value )
482 MATERIAL_IMPL.SetSceneGraphProperty( GetEventThreadServices(), this, index, entry, value );
483 OnPropertySet(index, value);
486 Property::Value Material::GetDefaultProperty( Property::Index index ) const
488 Property::Value value;
492 case Dali::Material::Property::FACE_CULLING_MODE:
494 value = mFaceCullingMode;
497 case Dali::Material::Property::BLENDING_MODE:
499 value = mBlendingMode;
502 case Dali::Material::Property::BLEND_EQUATION_RGB:
504 value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
507 case Dali::Material::Property::BLEND_EQUATION_ALPHA:
509 value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
512 case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
514 BlendingFactor::Type srcFactorRgb;
515 BlendingFactor::Type destFactorRgb;
516 BlendingFactor::Type srcFactorAlpha;
517 BlendingFactor::Type destFactorAlpha;
518 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
519 value = static_cast<int>( srcFactorRgb );
522 case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
524 BlendingFactor::Type srcFactorRgb;
525 BlendingFactor::Type destFactorRgb;
526 BlendingFactor::Type srcFactorAlpha;
527 BlendingFactor::Type destFactorAlpha;
528 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
529 value = static_cast<int>( destFactorRgb );
532 case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
534 BlendingFactor::Type srcFactorRgb;
535 BlendingFactor::Type destFactorRgb;
536 BlendingFactor::Type srcFactorAlpha;
537 BlendingFactor::Type destFactorAlpha;
538 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
539 value = static_cast<int>( srcFactorAlpha );
542 case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
544 BlendingFactor::Type srcFactorRgb;
545 BlendingFactor::Type destFactorRgb;
546 BlendingFactor::Type srcFactorAlpha;
547 BlendingFactor::Type destFactorAlpha;
548 GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
549 value = static_cast<int>( destFactorAlpha );
552 case Dali::Material::Property::BLEND_COLOR:
562 const SceneGraph::PropertyOwner* Material::GetPropertyOwner() const
567 const SceneGraph::PropertyOwner* Material::GetSceneObject() const
572 const SceneGraph::PropertyBase* Material::GetSceneObjectAnimatableProperty( Property::Index index ) const
574 PropertyMetadata* property = index >= PROPERTY_CUSTOM_START_INDEX ? static_cast<PropertyMetadata*>(FindCustomProperty( index )) : static_cast<PropertyMetadata*>(FindAnimatableProperty( index ));
575 DALI_ASSERT_ALWAYS( property && "Property index is invalid" );
576 return property->GetSceneGraphProperty();
579 const PropertyInputImpl* Material::GetSceneObjectInputProperty( Property::Index index ) const
581 return GetSceneObjectAnimatableProperty( index );
584 int Material::GetPropertyComponentIndex( Property::Index index ) const
586 return Property::INVALID_COMPONENT_INDEX;
589 bool Material::OnStage() const
594 void Material::Connect()
598 for( size_t i(0); i<mTextures.size(); ++i )
600 if( mTextures[i].mImage )
602 mTextures[i].mImage->Connect();
603 if( mTextures[i].mImage->GetResourceId() != 0 )
605 SceneGraph::SetTextureImageMessage( GetEventThreadServices(), *mSceneObject, i, mTextures[i].mImage->GetResourceId() );
611 void Material::Disconnect()
613 for( size_t i(0); i<mTextures.size(); ++i )
615 if( mTextures[i].mImage )
617 mTextures[i].mImage->Disconnect();
625 : mSceneObject( NULL ),
628 mFaceCullingMode( Dali::Material::NONE ),
629 mBlendingMode( Dali::BlendingMode::AUTO ),
630 mBlendingOptions(), // initialises to defaults
636 void Material::Initialize()
638 EventThreadServices& eventThreadServices = GetEventThreadServices();
639 SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
641 mSceneObject = new SceneGraph::Material();
642 AddMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
644 eventThreadServices.RegisterObject( this );
647 Material::~Material()
650 if( EventThreadServices::IsCoreRunning() )
652 EventThreadServices& eventThreadServices = GetEventThreadServices();
653 SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
654 RemoveMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
656 eventThreadServices.UnregisterObject( this );
660 } // namespace Internal