// CLASS HEADER
#include <dali/internal/event/rendering/material-impl.h> // Dali::Internal::Material
+//EXTERNAL INCLUDES
+#include <string>
+
// INTERNAL INCLUDES
#include <dali/public-api/object/type-registry.h>
#include <dali/devel-api/rendering/material.h> // Dali::Internal::Material
#include <dali/internal/event/common/property-helper.h> // DALI_PROPERTY_TABLE_BEGIN, DALI_PROPERTY, DALI_PROPERTY_TABLE_END
#include <dali/internal/update/manager/update-manager.h>
#include <dali/internal/update/rendering/scene-graph-material.h>
-#include <dali/internal/update/rendering/scene-graph-sampler.h>
namespace Dali
{
namespace
{
-/**
- * |name |type |writable|animatable|constraint-input|enum for index-checking|
- */
-DALI_PROPERTY_TABLE_BEGIN
-DALI_PROPERTY( "color", VECTOR4, true, true, true, Dali::Material::Property::COLOR )
-DALI_PROPERTY( "face-culling-mode", STRING, true, false, false, Dali::Material::Property::FACE_CULLING_MODE )
-DALI_PROPERTY( "blending-mode", STRING, true, false, false, Dali::Material::Property::BLENDING_MODE )
-DALI_PROPERTY( "blend-equation-rgb", STRING, true, false, false, Dali::Material::Property::BLEND_EQUATION_RGB )
-DALI_PROPERTY( "blend-equation-alpha", STRING, true, false, false, Dali::Material::Property::BLEND_EQUATION_ALPHA )
-DALI_PROPERTY( "source-blend-factor-rgb", STRING, true, false, false, Dali::Material::Property::BLENDING_SRC_FACTOR_RGB )
-DALI_PROPERTY( "destination-blend-factor-rgb", STRING, true, false, false, Dali::Material::Property::BLENDING_DEST_FACTOR_RGB )
-DALI_PROPERTY( "source-blend-factor-alpha", STRING, true, false, false, Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA )
-DALI_PROPERTY( "destination-blend-factor-alpha", STRING, true, false, false, Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA )
-DALI_PROPERTY( "blend-color", VECTOR4, true, true, true, Dali::Material::Property::BLEND_COLOR )
-DALI_PROPERTY_TABLE_END( DEFAULT_ACTOR_PROPERTY_START_INDEX )
-
-const ObjectImplHelper<DEFAULT_PROPERTY_COUNT> MATERIAL_IMPL = { DEFAULT_PROPERTY_DETAILS };
+const ObjectImplHelper<0> MATERIAL_IMPL = { NULL };
BaseHandle Create()
{
void Material::SetShader( Shader& shader )
{
DALI_ASSERT_DEBUG( mSceneObject )
- mShaderConnector.Set( shader, OnStage() );
+ mShader = &shader;
- const SceneGraph::Shader& sceneGraphShader = dynamic_cast<const SceneGraph::Shader&>( *shader.GetSceneObject() );
+ SceneGraph::Shader& sceneGraphShader = *shader.GetShaderSceneObject();
SceneGraph::SetShaderMessage( GetEventThreadServices(), *mSceneObject, sceneGraphShader );
}
Shader* Material::GetShader() const
{
- return mShaderConnector.Get().Get();
+ return mShader.Get();
}
-void Material::AddSampler( Sampler& sampler )
+size_t Material::AddTexture( ImagePtr image, const std::string& uniformName, SamplerPtr sampler )
{
- SamplerConnector connector;
- connector.Set( sampler, OnStage() );
- mSamplerConnectors.push_back( connector );
+ size_t index = mTextures.size();
+ mTextures.push_back( Texture( uniformName, image, sampler ) );
- const SceneGraph::Sampler& sceneGraphSampler = dynamic_cast<const SceneGraph::Sampler&>( *sampler.GetSceneObject() );
- SceneGraph::AddSamplerMessage( GetEventThreadServices(), *mSceneObject, sceneGraphSampler );
-}
+ Render::Sampler* renderSampler(0);
+ if( sampler )
+ {
+ renderSampler = sampler->GetSamplerRenderObject();
+ }
-std::size_t Material::GetNumberOfSamplers() const
-{
- return mSamplerConnectors.size();
-}
+ if( mOnStage )
+ {
+ image->Connect();
+ }
-void Material::RemoveSampler( std::size_t index )
-{
- mSamplerConnectors.erase( mSamplerConnectors.begin() + index );
+ SceneGraph::AddTextureMessage( GetEventThreadServices(), *mSceneObject, uniformName, image->GetResourceId(), renderSampler );
+ return index;
}
-Sampler* Material::GetSamplerAt( unsigned int index ) const
+void Material::RemoveTexture( size_t index )
{
- return mSamplerConnectors[index].Get().Get();
+ if( index < GetNumberOfTextures() )
+ {
+ mTextures.erase( mTextures.begin() + index );
+ SceneGraph::RemoveTextureMessage( GetEventThreadServices(), *mSceneObject, index );
+ }
}
-void Material::SetFaceCullingMode( Dali::Material::FaceCullingMode cullingMode )
+void Material::SetTextureImage( size_t index, Image* image )
{
- if( NULL != mSceneObject )
+ if( index < GetNumberOfTextures() )
{
- SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mFaceCullingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, static_cast<int>(cullingMode) );
+ if( mTextures[index].mImage && mOnStage )
+ {
+ mTextures[index].mImage->Disconnect();
+
+ if( image )
+ {
+ image->Connect();
+ }
+ }
+
+ if( image )
+ {
+ mTextures[index].mImage.Reset(image);
+ }
+ SceneGraph::SetTextureImageMessage( GetEventThreadServices(), *mSceneObject, index, mTextures[index].mImage.Get()->GetResourceId() );
}
}
-void Material::SetBlendMode( BlendingMode::Type mode )
+void Material::SetTextureSampler( size_t index, Sampler* sampler )
{
- mBlendingMode = mode;
-
- if( NULL != mSceneObject )
+ if( index < GetNumberOfTextures() )
{
- SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, static_cast<int>(mode) );
+ mTextures[index].mSampler.Reset(sampler);
+
+ Render::Sampler* renderSampler(0);
+ if( sampler )
+ {
+ renderSampler = sampler->GetSamplerRenderObject();
+ }
+ SceneGraph::SetTextureSamplerMessage( GetEventThreadServices(), *mSceneObject, index, renderSampler );
}
}
-BlendingMode::Type Material::GetBlendMode() const
+Sampler* Material::GetTextureSampler( size_t index ) const
{
- return mBlendingMode;
-}
+ if( index < GetNumberOfTextures() )
+ {
+ return mTextures[index].mSampler.Get();
+ }
-void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba )
-{
- mBlendingOptions.SetBlendFunc( srcFactorRgba, destFactorRgba, srcFactorRgba, destFactorRgba );
- SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+ return NULL;
}
-void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgb,
- BlendingFactor::Type destFactorRgb,
- BlendingFactor::Type srcFactorAlpha,
- BlendingFactor::Type destFactorAlpha )
+void Material::SetTextureUniformName( size_t index, const std::string& uniformName )
{
- mBlendingOptions.SetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+ if( index < GetNumberOfTextures() )
+ {
+ mTextures[index].mUniformName = uniformName;
+ SceneGraph::SetTextureUniformNameMessage( GetEventThreadServices(), *mSceneObject, index, uniformName );
+ }
}
-void Material::GetBlendFunc( BlendingFactor::Type& srcFactorRgb,
- BlendingFactor::Type& destFactorRgb,
- BlendingFactor::Type& srcFactorAlpha,
- BlendingFactor::Type& destFactorAlpha ) const
+int Material::GetTextureIndex( const std::string& uniformName ) const
{
- srcFactorRgb = mBlendingOptions.GetBlendSrcFactorRgb();
- destFactorRgb = mBlendingOptions.GetBlendDestFactorRgb();
- srcFactorAlpha = mBlendingOptions.GetBlendSrcFactorAlpha();
- destFactorAlpha = mBlendingOptions.GetBlendDestFactorAlpha();
-}
+ size_t textureCount(GetNumberOfTextures());
+ for( size_t i(0); i<textureCount; ++i )
+ {
+ if( uniformName.compare( mTextures[i].mUniformName ) == 0 )
+ {
+ return i;
+ }
+ }
-void Material::SetBlendEquation( BlendingEquation::Type equationRgba )
-{
- mBlendingOptions.SetBlendEquation( equationRgba, equationRgba );
- SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
+ return -1;
}
-void Material::SetBlendEquation( BlendingEquation::Type equationRgb,
- BlendingEquation::Type equationAlpha )
+Image* Material::GetTexture( const std::string& uniformName ) const
{
- mBlendingOptions.SetBlendEquation( equationRgb, equationAlpha );
- SetBlendingOptionsMessage( GetEventThreadServices(), *mSceneObject, mBlendingOptions.GetBitmask() );
-}
+ int textureId = GetTextureIndex( uniformName );
+ if( textureId != -1 )
+ {
+ return GetTexture( textureId );
+ }
-void Material::GetBlendEquation( BlendingEquation::Type& equationRgb,
- BlendingEquation::Type& equationAlpha ) const
-{
- // These are not animatable, the cached values are up-to-date.
- equationRgb = mBlendingOptions.GetBlendEquationRgb();
- equationAlpha = mBlendingOptions.GetBlendEquationAlpha();
+ return NULL;
}
-void Material::SetBlendColor( const Vector4& color )
+Image* Material::GetTexture( size_t index ) const
{
- if( mSceneObject )
+ if( index < GetNumberOfTextures() )
{
- SceneGraph::AnimatablePropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, color );
+ return mTextures[ index ].mImage.Get();
}
+
+ return NULL;
}
-const Vector4& Material::GetBlendColor() const
+size_t Material::GetNumberOfTextures() const
{
- return mSceneObject->mBlendColor[ GetEventThreadServices().GetEventBufferIndex() ];
+ return mTextures.size();
}
const SceneGraph::Material* Material::GetMaterialSceneObject() const
void Material::SetDefaultProperty( Property::Index index,
const Property::Value& propertyValue )
{
- switch( index )
- {
- case Dali::Material::Property::COLOR:
- {
- SceneGraph::AnimatablePropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
- break;
- }
- case Dali::Material::Property::FACE_CULLING_MODE:
- {
- SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mFaceCullingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
- break;
- }
- case Dali::Material::Property::BLENDING_MODE:
- {
- if( mSceneObject )
- {
- SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
- }
- break;
- }
- case Dali::Material::Property::BLEND_EQUATION_RGB:
- {
- BlendingEquation::Type alphaEquation = mBlendingOptions.GetBlendEquationAlpha();
- mBlendingOptions.SetBlendEquation( static_cast<BlendingEquation::Type>(propertyValue.Get<int>()), alphaEquation );
- break;
- }
- case Dali::Material::Property::BLEND_EQUATION_ALPHA:
- {
- BlendingEquation::Type rgbEquation = mBlendingOptions.GetBlendEquationRgb();
- mBlendingOptions.SetBlendEquation( rgbEquation, static_cast<BlendingEquation::Type>(propertyValue.Get<int>()) );
- break;
- }
- case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- SetBlendFunc( static_cast<BlendingFactor::Type>(propertyValue.Get<int>()),
- destFactorRgb,
- srcFactorAlpha,
- destFactorAlpha );
- break;
- }
- case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- SetBlendFunc( srcFactorRgb,
- static_cast<BlendingFactor::Type>(propertyValue.Get<int>()),
- srcFactorAlpha,
- destFactorAlpha );
- break;
- }
- case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- SetBlendFunc( srcFactorRgb,
- destFactorRgb,
- static_cast<BlendingFactor::Type>(propertyValue.Get<int>()),
- destFactorAlpha );
- break;
- }
- case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- SetBlendFunc( srcFactorRgb,
- destFactorRgb,
- srcFactorAlpha,
- static_cast<BlendingFactor::Type>(propertyValue.Get<int>()) );
- break;
- }
- case Dali::Material::Property::BLEND_COLOR:
- {
- SceneGraph::AnimatablePropertyMessage<Vector4>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendColor, &SceneGraph::AnimatableProperty<Vector4>::Bake, propertyValue.Get<Vector4>() );
- break;
- }
- }
}
void Material::SetSceneGraphProperty( Property::Index index,
Property::Value Material::GetDefaultProperty( Property::Index index ) const
{
- BufferIndex bufferIndex = GetEventThreadServices().GetEventBufferIndex();
Property::Value value;
-
- switch( index )
- {
- case Dali::Material::Property::COLOR:
- {
- if( mSceneObject )
- {
- value = mSceneObject->mColor[bufferIndex];
- }
- break;
- }
- case Dali::Material::Property::FACE_CULLING_MODE:
- {
- if( mSceneObject )
- {
- value = mSceneObject->mFaceCullingMode[bufferIndex];
- }
- break;
- }
- case Dali::Material::Property::BLENDING_MODE:
- {
- if( mSceneObject )
- {
- value = mSceneObject->mBlendingMode[bufferIndex];
- }
- break;
- }
- case Dali::Material::Property::BLEND_EQUATION_RGB:
- {
- value = static_cast<int>( mBlendingOptions.GetBlendEquationRgb() );
- break;
- }
- case Dali::Material::Property::BLEND_EQUATION_ALPHA:
- {
- value = static_cast<int>( mBlendingOptions.GetBlendEquationAlpha() );
- break;
- }
- case Dali::Material::Property::BLENDING_SRC_FACTOR_RGB:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- value = static_cast<int>( srcFactorRgb );
- break;
- }
- case Dali::Material::Property::BLENDING_DEST_FACTOR_RGB:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- value = static_cast<int>( destFactorRgb );
- break;
- }
- case Dali::Material::Property::BLENDING_SRC_FACTOR_ALPHA:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- value = static_cast<int>( srcFactorAlpha );
- break;
- }
- case Dali::Material::Property::BLENDING_DEST_FACTOR_ALPHA:
- {
- BlendingFactor::Type srcFactorRgb;
- BlendingFactor::Type destFactorRgb;
- BlendingFactor::Type srcFactorAlpha;
- BlendingFactor::Type destFactorAlpha;
- GetBlendFunc( srcFactorRgb, destFactorRgb, srcFactorAlpha, destFactorAlpha );
- value = static_cast<int>( destFactorAlpha );
- break;
- }
- case Dali::Material::Property::BLEND_COLOR:
- {
- if( mSceneObject )
- {
- value = mSceneObject->mBlendColor[bufferIndex];
- }
- break;
- }
- }
-
return value;
}
const SceneGraph::PropertyBase* Material::GetSceneObjectAnimatableProperty( Property::Index index ) const
{
- DALI_ASSERT_ALWAYS( IsPropertyAnimatable( index ) && "Property is not animatable" );
-
- const SceneGraph::PropertyBase* property = NULL;
-
- if( OnStage() )
- {
- property = MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
- &Material::FindAnimatableProperty,
- &Material::FindCustomProperty,
- index );
-
- if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
- {
- switch(index)
- {
- case Dali::Material::Property::COLOR:
- {
- property = &mSceneObject->mColor;
- break;
- }
- case Dali::Material::Property::BLEND_COLOR:
- {
- property = &mSceneObject->mBlendColor;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( 0 && "Property is not animatable");
- break;
- }
- }
- }
- }
-
- return property;
+ PropertyMetadata* property = index >= PROPERTY_CUSTOM_START_INDEX ? static_cast<PropertyMetadata*>(FindCustomProperty( index )) : static_cast<PropertyMetadata*>(FindAnimatableProperty( index ));
+ DALI_ASSERT_ALWAYS( property && "Property index is invalid" );
+ return property->GetSceneGraphProperty();
}
const PropertyInputImpl* Material::GetSceneObjectInputProperty( Property::Index index ) const
{
- const PropertyInputImpl* property = NULL;
-
- if( OnStage() )
- {
- const SceneGraph::PropertyBase* baseProperty =
- MATERIAL_IMPL.GetRegisteredSceneGraphProperty( this,
- &Material::FindAnimatableProperty,
- &Material::FindCustomProperty,
- index );
- property = static_cast<const PropertyInputImpl*>( baseProperty );
-
- if( property == NULL && index < DEFAULT_PROPERTY_MAX_COUNT )
- {
- switch(index)
- {
- case Dali::Material::Property::COLOR:
- {
- property = &mSceneObject->mColor;
- break;
- }
- case Dali::Material::Property::FACE_CULLING_MODE:
- {
- property = &mSceneObject->mFaceCullingMode;
- break;
- }
- case Dali::Material::Property::BLEND_COLOR:
- {
- property = &mSceneObject->mBlendColor;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( 0 && "Property cannot be a constraint input");
- break;
- }
- }
- }
- }
-
- return property;
+ return GetSceneObjectAnimatableProperty( index );
}
int Material::GetPropertyComponentIndex( Property::Index index ) const
{
- // @todo MESH_REWORK - Change this if component properties are added for color/blend-color
return Property::INVALID_COMPONENT_INDEX;
}
{
mOnStage = true;
- SamplerConnectorContainer::const_iterator end = mSamplerConnectors.end();
- for( SamplerConnectorContainer::iterator it = mSamplerConnectors.begin();
- it < end;
- ++it )
+ for( size_t i(0); i<mTextures.size(); ++i )
{
- it->OnStageConnect();
+ if( mTextures[i].mImage )
+ {
+ mTextures[i].mImage->Connect();
+ if( mTextures[i].mImage->GetResourceId() != 0 )
+ {
+ SceneGraph::SetTextureImageMessage( GetEventThreadServices(), *mSceneObject, i, mTextures[i].mImage->GetResourceId() );
+ }
+ }
}
- mShaderConnector.OnStageConnect();
}
void Material::Disconnect()
{
- mOnStage = false;
-
- SamplerConnectorContainer::const_iterator end = mSamplerConnectors.end();
- for( SamplerConnectorContainer::iterator it = mSamplerConnectors.begin();
- it < end;
- ++it )
+ for( size_t i(0); i<mTextures.size(); ++i )
{
- it->OnStageDisconnect();
+ if( mTextures[i].mImage )
+ {
+ mTextures[i].mImage->Disconnect();
+ }
}
- mShaderConnector.OnStageDisconnect();
+
+ mOnStage = false;
}
Material::Material()
: mSceneObject( NULL ),
+ mShader( NULL ),
+ mTextures(),
mOnStage( false )
{
}
EventThreadServices& eventThreadServices = GetEventThreadServices();
SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
- mSceneObject = new SceneGraph::Material();
+ mSceneObject = SceneGraph::Material::New();
AddMessage( updateManager, updateManager.GetMaterialOwner(), *mSceneObject );
eventThreadServices.RegisterObject( this );