namespace
{
-const char* vertexSource =
-"void main()\n"
-"{\n"
-" gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);\n"
-" vTexCoord = aTexCoord;\n"
-"}\n";
-
-const char* fragmentSource =
-"void main()\n"
-"{\n"
-" gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n"
-"}\n";
-
bool gTouchCallBackCalled=false;
bool gTouchCallBack2Called=false;
END_TEST;
}
-int UtcDaliActorSetInheritShaderEffect(void)
-{
- TestApplication application;
-
- Actor actor = Actor::New();
-
- actor.SetInheritShaderEffect(false);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
- DALI_TEST_CHECK(actor.GetInheritShaderEffect() == false);
-
- actor.SetInheritShaderEffect(true);
- // flush the queue and render once
- application.SendNotification();
- application.Render();
- DALI_TEST_CHECK(actor.GetInheritShaderEffect() == true);
- END_TEST;
-}
-
-int UtcDaliActorGetInheritShaderEffect(void)
-{
- TestApplication application;
-
- Actor actor = Actor::New();
-
- DALI_TEST_CHECK(actor.GetInheritShaderEffect() == true);
- END_TEST;
-}
-
-int UtcDaliActorSetShaderEffect(void)
-{
- TestApplication application;
- Actor actor = Actor::New();
-
- ShaderEffect effect = ShaderEffect::New(vertexSource, fragmentSource);
-
- DALI_TEST_CHECK(effect != actor.GetShaderEffect());
-
- actor.SetShaderEffect(effect);
-
- DALI_TEST_CHECK(effect == actor.GetShaderEffect());
- END_TEST;
-}
-
-int UtcDaliActorGetShaderEffect(void)
-{
- TestApplication application;
- Actor actor = Actor::New();
-
- ShaderEffect effect = ShaderEffect::New(vertexSource, fragmentSource);
- actor.SetShaderEffect(effect);
-
- DALI_TEST_CHECK(effect == actor.GetShaderEffect());
- END_TEST;
-}
-
-int UtcDaliActorRemoveShaderEffect01(void)
-{
- TestApplication application;
- Actor actor = Actor::New();
-
- ShaderEffect defaultEffect = actor.GetShaderEffect();
-
- ShaderEffect effect = ShaderEffect::New(vertexSource, fragmentSource);
- actor.SetShaderEffect(effect);
-
- DALI_TEST_CHECK(effect == actor.GetShaderEffect());
-
- actor.RemoveShaderEffect();
-
- DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
- END_TEST;
-}
-
-int UtcDaliActorRemoveShaderEffect02(void)
-{
- TestApplication application;
- Actor actor = Actor::New();
-
- ShaderEffect defaultEffect = actor.GetShaderEffect();
-
- actor.RemoveShaderEffect();
-
- DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
- END_TEST;
-}
-
int UtcDaliActorSetColor(void)
{
TestApplication application;
{ "name", Actor::NAME, Property::STRING },
{ "sensitive", Actor::SENSITIVE, Property::BOOLEAN },
{ "leave-required", Actor::LEAVE_REQUIRED, Property::BOOLEAN },
- { "inherit-shader-effect", Actor::INHERIT_SHADER_EFFECT, Property::BOOLEAN },
{ "inherit-rotation", Actor::INHERIT_ROTATION, Property::BOOLEAN },
{ "inherit-scale", Actor::INHERIT_SCALE, Property::BOOLEAN },
{ "color-mode", Actor::COLOR_MODE, Property::STRING },
DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::NAME ) );
DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::SENSITIVE ) );
DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::LEAVE_REQUIRED ) );
- DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::INHERIT_SHADER_EFFECT ) );
DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::INHERIT_ROTATION ) );
DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::INHERIT_SCALE ) );
DALI_TEST_CHECK( false == actor.IsPropertyAConstraintInput( Actor::COLOR_MODE ) );
END_TEST;
}
+
+int UtcDaliRenderableActorSetShaderEffect(void)
+{
+ TestApplication application;
+ BitmapImage img = BitmapImage::New( 1,1 );
+ ImageActor actor = ImageActor::New( img );
+ Stage::GetCurrent().Add( actor );
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+ GLuint lastShaderCompiledBefore = application.GetGlAbstraction().GetLastShaderCompiled();
+
+ application.GetGlAbstraction().EnableShaderCallTrace( true );
+
+ const std::string vertexShader = "UtcDaliRenderableActorSetShaderEffect-VertexSource";
+ const std::string fragmentShader = "UtcDaliRenderableActorSetShaderEffect-FragmentSource";
+ ShaderEffect effect = ShaderEffect::New(vertexShader, fragmentShader );
+ DALI_TEST_CHECK( effect != actor.GetShaderEffect() );
+
+ actor.SetShaderEffect( effect );
+ DALI_TEST_CHECK( effect == actor.GetShaderEffect() );
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ GLuint lastShaderCompiledAfter = application.GetGlAbstraction().GetLastShaderCompiled();
+ DALI_TEST_EQUALS( lastShaderCompiledAfter, lastShaderCompiledBefore + 2, TEST_LOCATION );
+
+ std::string actualVertexShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 1 );
+ DALI_TEST_EQUALS( vertexShader,
+ actualVertexShader.substr( actualVertexShader.length() - vertexShader.length() ), TEST_LOCATION );
+ std::string actualFragmentShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 2 );
+ DALI_TEST_EQUALS( fragmentShader,
+ actualFragmentShader.substr( actualFragmentShader.length() - fragmentShader.length() ), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliRenderableActorGetShaderEffect(void)
+{
+ TestApplication application;
+ TextActor actor = TextActor::New();
+
+ ShaderEffect effect = ShaderEffect::New("UtcDaliRenderableActorGetShaderEffect-VertexSource", "UtcDaliRenderableActorGetShaderEffect-FragmentSource" );
+ actor.SetShaderEffect(effect);
+
+ DALI_TEST_CHECK(effect == actor.GetShaderEffect());
+ END_TEST;
+}
+
+int UtcDaliRenderableActorRemoveShaderEffect01(void)
+{
+ TestApplication application;
+ TextActor actor = TextActor::New();
+
+ ShaderEffect defaultEffect = actor.GetShaderEffect();
+
+ ShaderEffect effect = ShaderEffect::New("UtcDaliRenderableActorRemoveShaderEffect-VertexSource", "UtcDaliRenderableActorRemoveShaderEffect-FragmentSource" );
+ actor.SetShaderEffect(effect);
+
+ DALI_TEST_CHECK(effect == actor.GetShaderEffect());
+
+ actor.RemoveShaderEffect();
+
+ DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
+ END_TEST;
+}
+
+int UtcDaliRenderableActorRemoveShaderEffect02(void)
+{
+ TestApplication application;
+ TextActor actor = TextActor::New();
+
+ ShaderEffect defaultEffect = actor.GetShaderEffect();
+
+ actor.RemoveShaderEffect();
+
+ DALI_TEST_CHECK(defaultEffect == actor.GetShaderEffect());
+ END_TEST;
+}
+
+int UtcDaliSetShaderEffectRecursively(void)
+{
+ TestApplication application;
+ /**
+ * create a tree
+ * actor1
+ * actor2 actor4
+ * actor3 textactor
+ * imageactor
+ */
+ BitmapImage img = BitmapImage::New( 1,1 );
+ ImageActor actor1 = ImageActor::New( img );
+ Actor actor2 = Actor::New();
+ actor1.Add( actor2 );
+ Actor actor3 = Actor::New();
+ actor2.Add( actor3 );
+ TextActor textactor = TextActor::New( "Foo" );
+ actor2.Add( textactor );
+ ImageActor imageactor = ImageActor::New( img );
+ actor3.Add( imageactor );
+ Actor actor4 = Actor::New();
+ actor1.Add( actor4 );
+ Stage::GetCurrent().Add( actor1 );
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+ GLuint lastShaderCompiledBefore = application.GetGlAbstraction().GetLastShaderCompiled();
+
+ application.GetGlAbstraction().EnableShaderCallTrace( true );
+
+ const std::string vertexShader = "UtcDaliRenderableActorSetShaderEffect-VertexSource";
+ const std::string fragmentShader = "UtcDaliRenderableActorSetShaderEffect-FragmentSource";
+ // test with empty effect
+ ShaderEffect effect;
+ SetShaderEffectRecursively( actor1, effect );
+
+ effect = ShaderEffect::New(vertexShader, fragmentShader );
+
+ DALI_TEST_CHECK( effect != actor1.GetShaderEffect() );
+ DALI_TEST_CHECK( effect != textactor.GetShaderEffect() );
+ DALI_TEST_CHECK( effect != imageactor.GetShaderEffect() );
+
+ SetShaderEffectRecursively( actor1, effect );
+ DALI_TEST_CHECK( effect == textactor.GetShaderEffect() );
+ DALI_TEST_CHECK( effect == imageactor.GetShaderEffect() );
+
+ // flush the queue and render once
+ application.SendNotification();
+ application.Render();
+
+ GLuint lastShaderCompiledAfter = application.GetGlAbstraction().GetLastShaderCompiled();
+ DALI_TEST_EQUALS( lastShaderCompiledAfter, lastShaderCompiledBefore + 2, TEST_LOCATION );
+
+ std::string actualVertexShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 1 );
+ DALI_TEST_EQUALS( vertexShader,
+ actualVertexShader.substr( actualVertexShader.length() - vertexShader.length() ), TEST_LOCATION );
+ std::string actualFragmentShader = application.GetGlAbstraction().GetShaderSource( lastShaderCompiledBefore + 2 );
+ DALI_TEST_EQUALS( fragmentShader,
+ actualFragmentShader.substr( actualFragmentShader.length() - fragmentShader.length() ), TEST_LOCATION );
+
+ // remove from one that does not have shader
+ RemoveShaderEffectRecursively( actor4 );
+
+ // remove partially
+ RemoveShaderEffectRecursively( actor3 );
+ DALI_TEST_CHECK( effect == textactor.GetShaderEffect() );
+ DALI_TEST_CHECK( effect != imageactor.GetShaderEffect() );
+
+ // test with empty actor just to check it does not crash
+ Actor empty;
+ SetShaderEffectRecursively( empty, effect );
+ RemoveShaderEffectRecursively( empty );
+
+ // test with actor with no children just to check it does not crash
+ Actor loner = Actor::New();
+ Stage::GetCurrent().Add( loner );
+ SetShaderEffectRecursively( loner, effect );
+ DALI_TEST_CHECK( effect != loner.GetShaderEffect() ); // base actor does not have shader effects
+ RemoveShaderEffectRecursively( loner );
+
+ END_TEST;
+}
+
};
+/**
+ * Templated message which calls a member function of an object.
+ * This overload passes just the buffer index to the method, no parameters.
+ */
+template< typename T >
+class MessageDoubleBuffered0 : public MessageBase
+{
+public:
+
+ typedef void(T::*MemberFunction)( BufferIndex );
+
+ /**
+ * Create a message.
+ * @note The object is expected to be const in the thread which sends this message.
+ * However it can be modified when Process() is called in a different thread.
+ * @param[in] obj The object.
+ * @param[in] member The member function of the object.
+ */
+ MessageDoubleBuffered0( const T* obj, MemberFunction member )
+ : MessageBase(),
+ object( const_cast< T* >( obj ) ),
+ memberFunction( member )
+ {
+ }
+
+ /**
+ * Virtual destructor
+ */
+ virtual ~MessageDoubleBuffered0()
+ {
+ }
+
+ /**
+ * @copydoc MessageBase::Process
+ */
+ virtual void Process( BufferIndex bufferIndex )
+ {
+ DALI_ASSERT_DEBUG( object && "Message does not have an object" );
+ (object->*memberFunction)( bufferIndex );
+ }
+
+private:
+
+ T* object;
+ MemberFunction memberFunction;
+
+};
+
+
/**
* Templated message which calls a member function of an object.
* This overload passes a value-type to set a double-buffered property.
// INTERNAL INCLUDES
#include <dali/internal/event/common/stage-impl.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
#include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
-#include <dali/internal/render/renderers/scene-graph-renderer.h>
+
+using Dali::Internal::SceneGraph::Shader;
namespace Dali
{
RenderableAttachment::RenderableAttachment( Stage& stage )
: ActorAttachment( stage ),
+ mShaderEffect(),
+ mBlendingOptions(),
+ mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) ),
mSortModifier( 0.0f ),
mCullFaceMode( CullNone ),
- mBlendingMode( BlendingMode::AUTO ),
- mSamplerBitfield( ImageSampler::PackBitfield( FilterMode::DEFAULT, FilterMode::DEFAULT ) )
+ mBlendingMode( BlendingMode::AUTO )
{
}
magFilter = ImageSampler::GetMagnifyFilterMode( mSamplerBitfield );
}
+void RenderableAttachment::SetShaderEffect(ShaderEffect& effect)
+{
+ if ( OnStage() )
+ {
+ if ( mShaderEffect )
+ {
+ mShaderEffect->Disconnect();
+ }
+
+ mShaderEffect.Reset( &effect );
+
+ const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
+
+ ApplyShaderMessage( mStage->GetUpdateInterface(), GetSceneObject(), shader );
+
+ mShaderEffect->Connect();
+ }
+ else
+ {
+ mShaderEffect = ShaderEffectPtr(&effect);
+ }
+ // Effects can only be applied when the Node is connected to scene-graph
+}
+
+ShaderEffectPtr RenderableAttachment::GetShaderEffect() const
+{
+ return mShaderEffect;
+}
+
+void RenderableAttachment::RemoveShaderEffect()
+{
+ if ( OnStage() )
+ {
+ RemoveShaderMessage( mStage->GetUpdateInterface(), GetSceneObject() );
+
+ // Notify shader effect
+ if (mShaderEffect)
+ {
+ mShaderEffect->Disconnect();
+ }
+ }
+
+ mShaderEffect.Reset();
+}
void RenderableAttachment::OnStageConnection()
{
+ if ( mShaderEffect )
+ {
+ const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
+
+ ApplyShaderMessage( mStage->GetUpdateInterface(), GetSceneObject(), shader );
+
+ // Notify shader effect
+ mShaderEffect->Connect();
+ }
+
// For derived classes
OnStageConnection2();
}
void RenderableAttachment::OnStageDisconnection()
{
+ // Notify shader effect
+ if ( mShaderEffect )
+ {
+ mShaderEffect->Disconnect();
+ }
+
// For derived classes
OnStageDisconnection2();
}
{
class RenderableAttachment;
}
+class ShaderEffect;
+typedef IntrusivePtr<ShaderEffect> ShaderEffectPtr;
/**
* An base class for renderable actor attachments
*/
void GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter ) const;
+ /**
+ * @copydoc Dali::RenderableActor::SetShaderEffect
+ */
+ void SetShaderEffect(ShaderEffect& effect);
+
+ /**
+ * @copydoc Dali::RenderableActor::GetShaderEffect
+ */
+ ShaderEffectPtr GetShaderEffect() const;
+
+ /**
+ * @copydoc Dali::RenderableActor::RemoveShaderEffect
+ */
+ void RemoveShaderEffect();
+
protected:
/**
*/
virtual const SceneGraph::RenderableAttachment& GetSceneObject() const = 0;
-private:
+private: // Data, cached for actor-thread getters
- // Cached for actor-thread getters
- float mSortModifier;
- CullFaceMode mCullFaceMode;
- BlendingMode::Type mBlendingMode;
+ ShaderEffectPtr mShaderEffect; ///< Optional referenced shader effect
BlendingOptions mBlendingOptions;
unsigned int mSamplerBitfield;
+ float mSortModifier;
+ CullFaceMode mCullFaceMode:3; ///< cullface mode, 3 bits enough for 4 values
+ BlendingMode::Type mBlendingMode:2; ///< blending mode, 2 bits enough for 3 values
+
+
};
} // namespace Internal
#include <dali/internal/event/actor-attachments/actor-attachment-impl.h>
#include <dali/internal/event/animation/constraint-impl.h>
#include <dali/internal/event/common/projection.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
#include <dali/internal/update/common/animatable-property.h>
#include <dali/internal/update/common/property-owner-messages.h>
#include <dali/internal/update/nodes/node-messages.h>
#include <dali/internal/update/nodes/node-declarations.h>
#include <dali/internal/update/animation/scene-graph-constraint.h>
-#include <dali/internal/event/effects/shader-effect-impl.h>
#include <dali/internal/event/events/actor-gesture-data.h>
#include <dali/internal/common/message.h>
#include <dali/integration-api/debug.h>
using Dali::Internal::SceneGraph::Node;
using Dali::Internal::SceneGraph::AnimatableProperty;
using Dali::Internal::SceneGraph::PropertyBase;
-using Dali::Internal::SceneGraph::Shader;
using namespace std;
const Property::Index Actor::NAME = 35;
const Property::Index Actor::SENSITIVE = 36;
const Property::Index Actor::LEAVE_REQUIRED = 37;
-const Property::Index Actor::INHERIT_SHADER_EFFECT = 38;
-const Property::Index Actor::INHERIT_ROTATION = 39;
-const Property::Index Actor::INHERIT_SCALE = 40;
-const Property::Index Actor::COLOR_MODE = 41;
-const Property::Index Actor::POSITION_INHERITANCE = 42;
-const Property::Index Actor::DRAW_MODE = 43;
+const Property::Index Actor::INHERIT_ROTATION = 38;
+const Property::Index Actor::INHERIT_SCALE = 39;
+const Property::Index Actor::COLOR_MODE = 40;
+const Property::Index Actor::POSITION_INHERITANCE = 41;
+const Property::Index Actor::DRAW_MODE = 42;
namespace // unnamed namespace
{
{ "name", Property::STRING, true, false, false }, // NAME
{ "sensitive", Property::BOOLEAN, true, false, false }, // SENSITIVE
{ "leave-required", Property::BOOLEAN, true, false, false }, // LEAVE_REQUIRED
- { "inherit-shader-effect", Property::BOOLEAN, true, false, false }, // INHERIT_SHADER_EFFECT
{ "inherit-rotation", Property::BOOLEAN, true, false, false }, // INHERIT_ROTATION
{ "inherit-scale", Property::BOOLEAN, true, false, false }, // INHERIT_SCALE
{ "color-mode", Property::STRING, true, false, false }, // COLOR_MODE
return Vector3::ZERO;
}
-void Actor::SetInheritShaderEffect(bool inherit)
-{
- if( NULL != mNode )
- {
- // mNode is being used in a separate thread; queue a message to set the value
- SetInheritShaderMessage( mStage->GetUpdateInterface(), *mNode, inherit );
- }
-}
-
-bool Actor::GetInheritShaderEffect() const
-{
- if( NULL != mNode )
- {
- // mNode is being used in a separate thread; copy the value from the previous update
- return mNode->GetInheritShader();
- }
-
- return true;
-}
-
void Actor::SetShaderEffect(ShaderEffect& effect)
{
- if ( OnStage() )
- {
- if (mShaderEffect)
- {
- mShaderEffect->Disconnect();
- }
-
- mShaderEffect = ShaderEffectPtr(&effect);
-
- const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
-
- if( NULL != mNode )
- {
- // mNode is being used in a separate thread; queue a message to apply shader
- ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
- }
-
- mShaderEffect->Connect();
- }
- else
- {
- mShaderEffect = ShaderEffectPtr(&effect);
- }
- // Effects can only be applied when the Node is connected to scene-graph
+ // no-op on an Actor
}
ShaderEffectPtr Actor::GetShaderEffect() const
{
- return mShaderEffect;
+ return ShaderEffectPtr();
}
void Actor::RemoveShaderEffect()
{
- if ( OnStage() )
- {
- if( NULL != mNode )
- {
- // mNode is being used in a separate thread; queue a message to remove shader
- RemoveShaderMessage( mStage->GetUpdateInterface(), *mNode );
- }
-
- // Notify shader effect
- if (mShaderEffect)
- {
- mShaderEffect->Disconnect();
- }
- }
-
- mShaderEffect.Reset();
}
#ifdef DYNAMICS_SUPPORT
#endif
mGestureData( NULL ),
mAttachment(),
- mShaderEffect(),
mName(),
mId( ++mActorCounter ), // actor ID is initialised to start from 1, and 0 is reserved
mIsRoot( ROOT_LAYER == derivedType ),
ConnectNodeMessage( mStage->GetUpdateManager(), *(mParent->mNode), *mNode );
}
- if (mShaderEffect)
- {
- const Shader& shader = dynamic_cast<const Shader&>( *mShaderEffect->GetSceneObject() );
-
- if( NULL != mNode )
- {
- // Effects can only be applied when the node is on-stage
- ApplyShaderMessage( mStage->GetUpdateInterface(), *mNode, shader );
- }
-
- // Notify shader effect
- mShaderEffect->Connect();
- }
-
// Notify attachment
if (mAttachment)
{
// Notification for ProxyObject::Observers
OnSceneObjectRemove();
- // Notify shader effect
- if (mShaderEffect)
- {
- mShaderEffect->Disconnect();
- }
-
// Notify attachment
if (mAttachment)
{
break;
}
- case Dali::Actor::INHERIT_SHADER_EFFECT:
- {
- SetInheritShaderEffect( property.Get<bool>() );
- break;
- }
-
case Dali::Actor::INHERIT_ROTATION:
{
SetInheritRotation( property.Get<bool>() );
break;
}
- case Dali::Actor::INHERIT_SHADER_EFFECT:
- {
- value = GetInheritShaderEffect();
- break;
- }
-
case Dali::Actor::INHERIT_ROTATION:
{
value = IsRotationInherited();
class ActorGestureData;
class RenderTask;
class ShaderEffect;
+typedef IntrusivePtr<ShaderEffect> ShaderEffectPtr;
struct DynamicsData;
typedef IntrusivePtr<Actor> ActorPtr;
-typedef IntrusivePtr<ShaderEffect> ShaderEffectPtr;
typedef Dali::ActorContainer ActorContainer; // Store handles to return via public-api
typedef ActorContainer::iterator ActorIter;
typedef ActorContainer::const_iterator ActorConstIter;
return mSensitive;
}
- /**
- * Set whether the actor inherits a shader effect from its parent.
- * The inherited effect can be overridden using SetShaderEffect()
- * @param [in] inherit True if the parent effect is inherited.
- */
- void SetInheritShaderEffect(bool inherit);
-
- /**
- * Query whether the actor inherits a shader effect from its parent.
- * @return True if the parent effect is inherited.
- */
- bool GetInheritShaderEffect() const;
+ // Shader effects, these are virtual so that RenderableActor can override the behaviour.
+ // Default actor behaviour is to do nothing, but the API is kept in Actor for convenience.
/**
+ * @todo remove when API is cleaned up
* Sets the shader effect for the Actor.
* Shader effects provide special effects like rippling and bending.
* Setting a shader effect removes any shader effect previously set by SetShaderEffect.
* @param [in] effect The shader effect.
*/
- void SetShaderEffect(ShaderEffect& effect);
+ virtual void SetShaderEffect(ShaderEffect& effect);
/**
+ * @todo remove when API is cleaned up
* Retrieve the shader effect for the Actor.
* @return The shader effect
*/
- ShaderEffectPtr GetShaderEffect() const;
+ virtual ShaderEffectPtr GetShaderEffect() const;
/**
+ * @todo remove when API is cleaned up
* Removes the current shader effect.
*/
- void RemoveShaderEffect();
+ virtual void RemoveShaderEffect();
/**
* @copydoc Dali::Actor::SetDrawMode
DynamicsData* mDynamicsData; ///< optional physics data
#endif
- ActorGestureData* mGestureData; /// Optional Gesture data. Only created when actor requires gestures
+ ActorGestureData* mGestureData; /// Optional Gesture data. Only created when actor requires gestures
ActorAttachmentPtr mAttachment; ///< Optional referenced attachment
- ShaderEffectPtr mShaderEffect; ///< Optional referenced shader effect
// Signals
Dali::Actor::TouchSignalV2 mTouchedSignalV2;
// INTERNAL INCLUDES
#include <dali/public-api/object/type-registry.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
#include <dali/internal/event/actor-attachments/renderable-attachment-impl.h>
namespace // unnamed namespace
{
}
+void RenderableActor::SetShaderEffect(ShaderEffect& effect)
+{
+ GetRenderableAttachment().SetShaderEffect( effect );
+}
+
+ShaderEffectPtr RenderableActor::GetShaderEffect() const
+{
+ return GetRenderableAttachment().GetShaderEffect();
+}
+
+void RenderableActor::RemoveShaderEffect()
+{
+ return GetRenderableAttachment().RemoveShaderEffect();
+}
+
} // namespace Internal
} // namespace Dali
*/
virtual ~RenderableActor();
+public: // from Actor, in future not virtual. Accessible also from RenderableActor
+
+ /**
+ * @copydoc Actor::SetShaderEffect
+ */
+ virtual void SetShaderEffect(ShaderEffect& effect);
+
+ /**
+ * @copydoc Actor::GetShaderEffect
+ */
+ virtual ShaderEffectPtr GetShaderEffect() const;
+
+ /**
+ * @copydoc Actor::RemoveShaderEffect
+ */
+ virtual void RemoveShaderEffect();
+
private:
/**
RenderableActor(const RenderableActor&);
// Undefined
RenderableActor& operator=(const RenderableActor& rhs);
+
};
} // namespace Internal
RenderQueue& renderQueue,
DiscardQueue& discardQueue,
TextureCache& textureCache,
- CompleteStatusManager& completeStatusManager )
+ CompleteStatusManager& completeStatusManager,
+ Shader*& defaultShader )
: mRenderMessageDispatcher( renderMessageDispatcher ),
mRenderQueue( renderQueue ),
mDiscardQueue( discardQueue ),
mTextureCache( textureCache ),
- mCompleteStatusManager( completeStatusManager )
+ mCompleteStatusManager( completeStatusManager ),
+ mDefaultShader( defaultShader )
{
mLightController = new LightControllerImpl;
}
* @param[in] renderQueue The renderQueue
* @param[in] discardQueue The discardQueue
* @param[in] completeStatusTracker The resource complete status tracker
+ * @param[in] defaultShader to use for renderable attachments
*/
- SceneControllerImpl( RenderMessageDispatcher& renderMessageDispatcher, RenderQueue& renderQueue, DiscardQueue& discardQueue, TextureCache& textureCache, CompleteStatusManager& completeStatusManager );
+ SceneControllerImpl( RenderMessageDispatcher& renderMessageDispatcher,
+ RenderQueue& renderQueue,
+ DiscardQueue& discardQueue,
+ TextureCache& textureCache,
+ CompleteStatusManager& completeStatusManager,
+ Shader*& defaultShader );
/**
* Destructor
*/
virtual ~SceneControllerImpl();
-public: // for scene controller interface
+public: // from SceneController
/**
- * Get the light controller
- * @return reference to a light controller
+ * @copydoc SceneController::GetLightController()
*/
virtual LightController& GetLightController() { return *mLightController; }
/**
- * Return the renderer dispatcher
- * @return A reference to the renderer dispatcher
+ * @copydoc SceneController::GetRenderMessageDispatcher()
*/
virtual RenderMessageDispatcher& GetRenderMessageDispatcher() { return mRenderMessageDispatcher; }
/**
- * Return the render queue
- * @return A reference to the render queue
+ * @copydoc SceneController::GetRenderQueue()
*/
virtual RenderQueue& GetRenderQueue() { return mRenderQueue; }
/**
- * Return the discard queue
- * @return A reference to the discard queue
+ * @copydoc SceneController::GetDiscardQueue()
*/
virtual DiscardQueue& GetDiscardQueue() { return mDiscardQueue; }
/**
- * Return the texture cache
- * @note USE ONLY IN RENDER THREAD OBJECTS
- * @return The texture cache
+ * @copydoc SceneController::GetTextureCache()
*/
virtual TextureCache& GetTextureCache() { return mTextureCache; }
/**
- * @return the complete status tracker
+ * @copydoc SceneController::GetCompleteStatusManager()
*/
virtual CompleteStatusManager& GetCompleteStatusManager() { return mCompleteStatusManager; }
+ /**
+ * @copydoc SceneController::GetDefaultShader()
+ */
+ virtual Shader* GetDefaultShader() { return mDefaultShader; }
+
private:
// Undefined copy constructor.
private:
- LightController* mLightController; ///< light controller
+ LightController* mLightController; ///< light controller
RenderMessageDispatcher& mRenderMessageDispatcher; ///< Used for passing messages to the render-thread
- RenderQueue& mRenderQueue; ///< render queue
- DiscardQueue& mDiscardQueue; ///< discard queue
- TextureCache& mTextureCache; ///< texture cache
- CompleteStatusManager& mCompleteStatusManager; ///< Complete Status manager
+ RenderQueue& mRenderQueue; ///< render queue
+ DiscardQueue& mDiscardQueue; ///< discard queue
+ TextureCache& mTextureCache; ///< texture cache
+ CompleteStatusManager& mCompleteStatusManager; ///< Complete Status manager
+ Shader*& mDefaultShader; ///< default shader, reference to a pointer as it will be setup later
+
};
} // namespace SceneGraph
class RenderQueue;
class DiscardQueue;
class TextureCache;
+class Shader;
/**
* Abstract interface for the scene controller
*/
virtual CompleteStatusManager& GetCompleteStatusManager() = 0;
+ /**
+ * Return the default shader
+ * @return pointer to the default shader
+ */
+ virtual Shader* GetDefaultShader() = 0;
+
private:
// Undefined copy constructor.
#include <dali/internal/update/node-attachments/scene-graph-renderable-attachment.h>
#include <dali/internal/update/animation/scene-graph-constraint-base.h>
#include <dali/internal/update/nodes/scene-graph-layer.h>
-#include <dali/internal/render/shaders/shader.h>
#include <dali/internal/render/renderers/scene-graph-renderer.h>
#include <dali/integration-api/debug.h>
************************** Update node hierarchy *****************************
******************************************************************************/
-inline void UpdateRootNodeShader( Layer& rootNode, int nodeDirtyFlags, Shader* defaultShader )
-{
- if ( nodeDirtyFlags & ShaderFlag )
- {
- rootNode.SetInheritedShader( defaultShader );
- }
-}
-
-inline void UpdateNodeShader( Node& node, int nodeDirtyFlags, Shader* defaultShader )
-{
- // If shader needs to be re-inherited
- if ( nodeDirtyFlags & ShaderFlag )
- {
- // It will use the default if the nodes mInheritShader is set to false
- node.InheritShader( defaultShader );
- }
-}
-
inline void UpdateRootNodeOpacity( Layer& rootNode, int nodeDirtyFlags, BufferIndex updateBufferIndex )
{
if ( nodeDirtyFlags & ColorFlag )
renderable->SizeChanged( updateBufferIndex );
}
- // Notify renderables when shader has changed
- if( nodeDirtyFlags & ShaderFlag )
- {
- renderable->ShaderChanged( updateBufferIndex );
- }
-
// check if node is visible
if( renderable->ResolveVisibility( updateBufferIndex ) )
{
ResourceManager& resourceManager,
RenderQueue& renderQueue,
Layer& currentLayer,
- Shader* defaultShader,
int inheritedDrawMode )
{
Layer* layer = ¤tLayer;
// Some dirty flags are inherited from parent
int nodeDirtyFlags( node.GetDirtyFlags() | ( parentFlags & InheritedDirtyFlags ) );
- if ( node.GetInheritedShader() == NULL )
- {
- nodeDirtyFlags |= ShaderFlag;
- }
-
int cumulativeDirtyFlags = nodeDirtyFlags;
if ( node.IsLayer() )
}
DALI_ASSERT_DEBUG( NULL != layer );
- UpdateNodeShader( node, nodeDirtyFlags, defaultShader );
-
UpdateNodeOpacity( node, nodeDirtyFlags, updateBufferIndex );
UpdateNodeGeometry( node, nodeDirtyFlags, updateBufferIndex );
resourceManager,
renderQueue,
*layer,
- defaultShader,
inheritedDrawMode );
}
int UpdateNodesAndAttachments( Layer& rootNode,
BufferIndex updateBufferIndex,
ResourceManager& resourceManager,
- RenderQueue& renderQueue,
- Shader* defaultShader )
+ RenderQueue& renderQueue )
{
DALI_ASSERT_DEBUG( rootNode.IsRoot() );
int nodeDirtyFlags( rootNode.GetDirtyFlags() );
- if ( rootNode.GetInheritedShader() == NULL )
- {
- nodeDirtyFlags |= ShaderFlag;
- }
-
int cumulativeDirtyFlags = nodeDirtyFlags;
- UpdateRootNodeShader( rootNode, nodeDirtyFlags, defaultShader );
-
UpdateRootNodeOpacity( rootNode, nodeDirtyFlags, updateBufferIndex );
UpdateRootNodeTransformValues( rootNode, nodeDirtyFlags, updateBufferIndex );
resourceManager,
renderQueue,
rootNode,
- defaultShader,
drawMode );
}
class Node;
class PropertyOwner;
class RenderQueue;
-class Shader;
/**
* Recursively apply the constraints on the nodes.
* @param[in] updateBufferIndex The current update buffer index.
* @param[in] resourceManager The resource manager.
* @param[in] renderQueue Used to query messages for the next Render.
- * @param[in] defaultShader The default shader.
* @return The cumulative (ORed) dirty flags for the updated nodes
*/
int UpdateNodesAndAttachments( Layer& rootNode,
BufferIndex updateBufferIndex,
ResourceManager& resourceManager,
- RenderQueue& renderQueue,
- Shader* defaultShader );
+ RenderQueue& renderQueue );
} // namespace SceneGraph
renderTaskList( NULL ),
renderTaskWaiting( false )
{
- sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager );
+ sceneController = new SceneControllerImpl( renderMessageDispatcher, renderQueue, discardQueue, textureCache, completeStatusManager, defaultShader );
}
~Impl()
PERF_MONITOR_START( PerformanceMonitor::UPDATE_NODES );
- Shader* defaultShader = GetDefaultShader();
+ // Prepare resources, update shaders, update attachments, for each node
+ // And add the renderers to the sorted layers. Start from root, which is also a layer
+ mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
+ mSceneGraphBuffers.GetUpdateBufferIndex(),
+ mImpl->resourceManager,
+ mImpl->renderQueue );
- if ( NULL != defaultShader )
+ if ( mImpl->systemLevelRoot )
{
- // Prepare resources, update shaders, update attachments, for each node
- // And add the renderers to the sorted layers. Start from root, which is also a layer
- mImpl->nodeDirtyFlags = UpdateNodesAndAttachments( *( mImpl->root ),
- mSceneGraphBuffers.GetUpdateBufferIndex(),
- mImpl->resourceManager,
- mImpl->renderQueue,
- defaultShader );
-
- if ( mImpl->systemLevelRoot )
- {
- mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
- mSceneGraphBuffers.GetUpdateBufferIndex(),
- mImpl->resourceManager,
- mImpl->renderQueue,
- defaultShader );
- }
+ mImpl->nodeDirtyFlags |= UpdateNodesAndAttachments( *( mImpl->systemLevelRoot ),
+ mSceneGraphBuffers.GetUpdateBufferIndex(),
+ mImpl->resourceManager,
+ mImpl->renderQueue );
}
PERF_MONITOR_END( PerformanceMonitor::UPDATE_NODES );
void ImageAttachment::ShaderChanged( BufferIndex updateBufferIndex )
{
- Shader* shader = GetParent().GetInheritedShader();
- DALI_ASSERT_DEBUG( shader != NULL );
+ DALI_ASSERT_DEBUG( mShader != NULL );
DALI_ASSERT_DEBUG( mSceneController );
- // Use the Node's inherited shader in the next render
- {
- typedef MessageValue1< Renderer, Shader* > DerivedType;
-
- // Reserve some memory inside the render queue
- unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
-
- // Construct message in the render queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( mImageRenderer, &Renderer::SetShader, shader );
- }
-
- int hints = shader->GetGeometryHints();
+ int hints = mShader->GetGeometryHints();
if ( hints != mPreviousRefreshHints )
{
* Fully opaque when...
* 1) not using the alpha channel from the image data
* 2) the inherited color is not transparent nor semi-transparent
- * 3) the shader doesn't require it
+ * 3) the shader doesn't require blending
*/
bool opaque = mBitmapMetadata.IsFullyOpaque();
{
opaque = ( mParent->GetWorldColor(updateBufferIndex).a >= FULLY_OPAQUE );
- if ( opaque && mParent->GetInheritedShader() != NULL )
+ if ( opaque && mShader != NULL )
{
opaque = !PreviousHintEnabled( Dali::ShaderEffect::HINT_BLENDING );
}
void MeshAttachment::ShaderChanged( BufferIndex updateBufferIndex )
{
DALI_ASSERT_DEBUG(mSceneController);
- Shader* shader = GetParent().GetInheritedShader();
- {
- typedef MessageValue1< Renderer, Shader* > DerivedType;
+ typedef Message< MeshRenderer > DerivedType;
- // Reserve some memory inside the render queue
- unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+ // Reserve some memory inside the render queue
+ unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
- // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( mRenderer, &Renderer::SetShader, shader );
- }
-
- {
- typedef Message< MeshRenderer > DerivedType;
-
- // Reserve some memory inside the render queue
- unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
-
- // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( mRenderer, &MeshRenderer::ResetCustomUniforms );
- }
+ // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
+ new (slot) DerivedType( mRenderer, &MeshRenderer::ResetCustomUniforms );
}
void MeshAttachment::SizeChanged( BufferIndex updateBufferIndex )
if ( fullyOpaque )
{
- Shader* shader = mParent->GetInheritedShader();
- if( shader != NULL )
+ if( mShader != NULL )
{
- fullyOpaque = (shader->GetGeometryHints() != Dali::ShaderEffect::HINT_BLENDING );
+ fullyOpaque = (mShader->GetGeometryHints() != Dali::ShaderEffect::HINT_BLENDING );
}
}
}
mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
mTrackedResources.Clear(); // Resource trackers are only needed if not yet completea
- if( Shader* shader = mParent->GetAppliedShader() )
+ if( mShader )
{
- Integration::ResourceId id = shader->GetEffectTextureResourceId();
+ Integration::ResourceId id = mShader->GetEffectTextureResourceId();
if( id != 0 )
{
mScaleForSizeDirty = false;
}
+void RenderableAttachment::ApplyShader( BufferIndex updateBufferIndex, Shader* shader )
+{
+ mShader = shader;
+
+ // send the message to renderer
+ SendShaderChangeMessage( updateBufferIndex );
+
+ // tell derived class to do something
+ ShaderChanged( updateBufferIndex );
+}
+
+void RenderableAttachment::RemoveShader( BufferIndex updateBufferIndex )
+{
+ // return to default shader
+ mShader = mSceneController->GetDefaultShader();
+
+ // send the message to renderer
+ SendShaderChangeMessage( updateBufferIndex );
+
+ // tell derived class to do something
+ ShaderChanged( updateBufferIndex );
+}
+
void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
{
scaling = Vector3::ONE;
RenderableAttachment::RenderableAttachment( bool usesGeometryScaling )
: mSceneController(NULL),
+ mShader( NULL ),
+ mTrackedResources(),
+ mSortModifier( 0.0f ),
mBlendingMode( Dali::RenderableActor::DEFAULT_BLENDING_MODE ),
mUsesGeometryScaling( usesGeometryScaling ),
mScaleForSizeDirty( true ),
mResourcesReady( false ),
mFinishedResourceAcquisition( false ),
mHasUntrackedResources( false ),
- mCullFaceMode( CullNone ),
- mSortModifier( 0.0f )
+ mCullFaceMode( CullNone )
{
}
void RenderableAttachment::ConnectToSceneGraph( SceneController& sceneController, BufferIndex updateBufferIndex )
{
mSceneController = &sceneController;
+ // get the default shader
+ mShader = mSceneController->GetDefaultShader();
// Chain to derived attachments
ConnectToSceneGraph2( updateBufferIndex );
// After derived classes have (potentially) created their renderer
- GetRenderer().SetCullFace( mCullFaceMode );
+ Renderer& renderer = GetRenderer();
+ renderer.SetCullFace( mCullFaceMode );
+
+ // set the default shader here as well
+ renderer.SetShader( mShader );
}
void RenderableAttachment::OnDestroy()
return this;
}
+void RenderableAttachment::SendShaderChangeMessage( BufferIndex updateBufferIndex )
+{
+ typedef MessageValue1< Renderer, Shader* > DerivedType;
+ // Reserve memory inside the render queue
+ unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
+ // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
+ new (slot) DerivedType( &GetRenderer(), &Renderer::SetShader, mShader );
+}
} // namespace SceneGraph
namespace SceneGraph
{
class Renderer;
+class Shader;
/**
* RenderableAttachments are responsible for preparing textures, meshes, matrices etc. during the Update.
*/
void GetScaleForSize( const Vector3& nodeSize, Vector3& scaling );
+ /**
+ * Apply a shader on the renderable
+ * @param[in] updateBufferIndex The current update buffer index.
+ * @param[in] shader to apply.
+ */
+ void ApplyShader( BufferIndex updateBufferIndex, Shader* shader );
+
+ /**
+ * Remove the shader from the renderable
+ * @param[in] updateBufferIndex The current update buffer index.
+ */
+ void RemoveShader( BufferIndex updateBufferIndex );
+
public: // For use during in the update algorithm only
/**
*/
virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0;
+ /**
+ * Sends the shader to the renderer
+ * @param updateBufferIndex for the message buffer
+ */
+ void SendShaderChangeMessage( BufferIndex updateBufferIndex );
+
// Undefined
RenderableAttachment( const RenderableAttachment& );
protected:
SceneController* mSceneController; ///< Used for initializing renderers whilst attached
+ Shader* mShader; ///< A pointer to the shader
- BlendingMode::Type mBlendingMode:2; ///< Whether blending is used to render the renderable attachment. 2 bits is enough for 3 values
+ Dali::Vector< Integration::ResourceId > mTrackedResources; ///< Filled during PrepareResources if there are uncomplete, tracked resources.
+
+ float mSortModifier;
+
+ BlendingMode::Type mBlendingMode:2; ///< Whether blending is used to render the renderable attachment. 2 bits is enough for 3 values
bool mUsesGeometryScaling:1; ///< True if the derived renderer uses scaling.
bool mScaleForSizeDirty:1; ///< True if mScaleForSize has changed in the current frame.
bool mHasUntrackedResources:1; ///< Set during PrepareResources, true if have tried to follow untracked resources
CullFaceMode mCullFaceMode:3; ///< Cullface mode, 3 bits is enough for 4 values
- float mSortModifier;
-
- Dali::Vector< Integration::ResourceId > mTrackedResources; ///< Filled during PrepareResources if there are uncomplete, tracked resources.
};
// Messages for RenderableAttachment
new (slot) LocalType( &attachment, &RenderableAttachment::SetSampler, samplerBitfield );
}
+inline void ApplyShaderMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment, const Shader& constShader )
+{
+ // Update thread can edit the object
+ Shader& shader = const_cast< Shader& >( constShader );
+
+ typedef MessageDoubleBuffered1< RenderableAttachment, Shader* > LocalType;
+
+ // Reserve some memory inside the message queue
+ unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new (slot) LocalType( &attachment, &RenderableAttachment::ApplyShader, &shader );
+}
+
+inline void RemoveShaderMessage( EventToUpdate& eventToUpdate, const RenderableAttachment& attachment )
+{
+ typedef MessageDoubleBuffered0< RenderableAttachment > LocalType;
+
+ // Reserve some memory inside the message queue
+ unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
+
+ // Construct message in the message queue memory; note that delete should not be called on the return value
+ new (slot) LocalType( &attachment, &RenderableAttachment::RemoveShader );
+}
+
} // namespace SceneGraph
} // namespace Internal
void TextAttachment::ShaderChanged( BufferIndex updateBufferIndex )
{
- {
- Shader* shader = GetParent().GetInheritedShader();
-
- typedef MessageValue1< Renderer, Shader* > DerivedType;
-
- // Reserve some memory inside the render queue
- unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
-
- // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
- new (slot) DerivedType( mTextRenderer, &Renderer::SetShader, shader );
- }
+ // nothing to do
}
void TextAttachment::SizeChanged( BufferIndex updateBufferIndex )
// INTERNAL INCLUDES
#include <dali/internal/update/node-attachments/node-attachment.h>
#include <dali/internal/update/common/discard-queue.h>
-#include <dali/internal/render/shaders/shader.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/public-api/common/constants.h>
mWorldMatrix( Matrix::IDENTITY ),
mWorldColor( Color::WHITE ),
mParent( NULL ),
- mAppliedShader( NULL ),
- mInheritedShader( NULL ),
mExclusiveRenderTask( NULL ),
mAttachment( NULL ),
mChildren(),
mInitialVolume( Vector3::ONE ),
mDirtyFlags(AllFlags),
mIsRoot( false ),
- mInheritShader( true ),
mInheritRotation( true ),
mInheritScale( true ),
mTransmitGeometryScaling( false ),
found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
}
-void Node::ApplyShader( Shader* shader )
-{
- DALI_ASSERT_DEBUG( shader && "null shader passed to node" );
-
- mAppliedShader = shader;
-
- SetDirtyFlag(ShaderFlag);
-}
-
-void Node::RemoveShader()
-{
- mAppliedShader = NULL; // Wait until InheritShader to grab default shader
-
- SetDirtyFlag(ShaderFlag);
-}
-
-Shader* Node::GetAppliedShader() const
-{
- return mAppliedShader;
-}
-
-void Node::SetInheritedShader(Shader* shader)
-{
- mInheritedShader = shader;
-}
-
-Shader* Node::GetInheritedShader() const
-{
- return mInheritedShader;
-}
-
-void Node::InheritShader(Shader* defaultShader)
-{
- DALI_ASSERT_DEBUG(mParent != NULL);
-
- // If we have a custom shader for this node, then use it
- if ( mAppliedShader != NULL )
- {
- mInheritedShader = mAppliedShader;
- }
- else
- {
- // Otherwise we either inherit a shader, or fall-back to the default
- if (mInheritShader)
- {
- mInheritedShader = mParent->GetInheritedShader();
- }
- else
- {
- mInheritedShader = defaultShader;
- }
- }
- DALI_ASSERT_DEBUG( mInheritedShader != NULL );
-}
-
int Node::GetDirtyFlags() const
{
// get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
// Animators, Constraints etc. should be disconnected from the child's properties.
PropertyOwner::DisconnectFromSceneGraph();
- // Remove effects
- mAppliedShader = NULL;
- mInheritedShader = NULL;
-
// Remove back-pointer to parent
mParent = NULL;
class DiscardQueue;
class Layer;
-class Shader;
class NodeAttachment;
class RenderTask;
class UpdateManager;
VisibleFlag = 0x002,
ColorFlag = 0x004,
SizeFlag = 0x008,
- ShaderFlag = 0x010,
- OverlayFlag = 0x020,
- SortModifierFlag = 0x040,
- ChildDeletedFlag = 0x080
+ OverlayFlag = 0x010,
+ SortModifierFlag = 0x020,
+ ChildDeletedFlag = 0x040
};
static const int AllFlags = ( ChildDeletedFlag << 1 ) - 1; // all the flags
* Size is not inherited.
* VisibleFlag is inherited so that attachments can be synchronized with nodes after they become visible
*/
-static const int InheritedDirtyFlags = TransformFlag | VisibleFlag | ColorFlag | ShaderFlag | OverlayFlag;
+static const int InheritedDirtyFlags = TransformFlag | VisibleFlag | ColorFlag | OverlayFlag;
// Flags which require the scene renderable lists to be updated
static const int RenderableUpdateFlags = TransformFlag | SortModifierFlag | ChildDeletedFlag;
return mChildren;
}
- // Shaders
-
- /**
- * Set whether the node inherits a shader effect from its parent.
- * The inherited effect can be overriden using ApplyShader()
- * @param [in] inherit True if the parent effect is inherited.
- */
- void SetInheritShader(bool inherit)
- {
- if (inherit != mInheritShader)
- {
- mInheritShader = inherit;
-
- SetDirtyFlag(ShaderFlag);
- }
- }
-
- /**
- * Query whether the node inherits a shader from its parent.
- * @return True if the parent effect is inherited.
- */
- bool GetInheritShader() const
- {
- return mInheritShader;
- }
-
- /**
- * Apply a shader object to this Node.
- * Shader effects are weakly referenced, potentially by multiple nodes & node attachments.
- * @param[in] shader The shader to apply.
- */
- void ApplyShader( Shader* shader );
-
- /**
- * Remove the shader object from this Node (if any).
- */
- void RemoveShader();
-
- /**
- * Retrieve the applied shader.
- * @return The applied shader.
- */
- Shader* GetAppliedShader() const;
-
- /**
- * Sets the inherited shader of the node.
- * @param[in] shader The new inherited shader.
- */
- void SetInheritedShader(Shader* shader);
-
- /**
- * Retrieve the inherited shader.
- * @return The inherited shader.
- */
- Shader* GetInheritedShader() const;
-
- /**
- * Inherit a shader (if any) applied to the parent node.
- * This method should only be called when the parents inherited shader is up-to-date.
- * @param defaultShader pointer to the default shader, used if inherit shader is set to false
- * @pre The node has a parent.
- */
- void InheritShader(Shader* defaultShader);
-
// Update methods
/**
protected:
Node* mParent; ///< Pointer to parent node (a child is owned by its parent)
- Shader* mAppliedShader; ///< A pointer to an applied shader
- Shader* mInheritedShader; ///< A pointer to an inherited shader
RenderTask* mExclusiveRenderTask; ///< Nodes can be marked as exclusive to a single RenderTask
NodeAttachmentOwner mAttachment; ///< Optional owned attachment
int mDirtyFlags:10; ///< A composite set of flags for each of the Node properties
bool mIsRoot:1; ///< True if the node cannot have a parent
- bool mInheritShader:1; ///< Whether the parent's shader should be inherited.
bool mInheritRotation:1; ///< Whether the parent's rotation should be inherited.
bool mInheritScale:1; ///< Whether the parent's scale should be inherited.
bool mTransmitGeometryScaling:1; ///< Whether geometry scaling should be applied to world transform.
// Messages for Node
-inline void SetInheritShaderMessage( EventToUpdate& eventToUpdate, const Node& node, bool inherit )
-{
- typedef MessageValue1< Node, bool > LocalType;
-
- // Reserve some memory inside the message queue
- unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
-
- // Construct message in the message queue memory; note that delete should not be called on the return value
- new (slot) LocalType( &node, &Node::SetInheritShader, inherit );
-}
-
inline void SetInheritRotationMessage( EventToUpdate& eventToUpdate, const Node& node, bool inherit )
{
typedef MessageValue1< Node, bool > LocalType;
new (slot) LocalType( &node, &Node::SetTransmitGeometryScaling, transmitGeometryScaling );
}
-inline void ApplyShaderMessage( EventToUpdate& eventToUpdate, const Node& node, const Shader& constShader )
-{
- // Update thread can edit the object
- Shader& shader = const_cast< Shader& >( constShader );
-
- typedef MessageValue1< Node, Shader* > LocalType;
-
- // Reserve some memory inside the message queue
- unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
-
- // Construct message in the message queue memory; note that delete should not be called on the return value
- new (slot) LocalType( &node, &Node::ApplyShader, &shader );
-}
-
-inline void RemoveShaderMessage( EventToUpdate& eventToUpdate, const Node& node )
-{
- typedef Message< Node > LocalType;
-
- // Reserve some memory inside the message queue
- unsigned int* slot = eventToUpdate.ReserveMessageSlot( sizeof( LocalType ) );
-
- // Construct message in the message queue memory; note that delete should not be called on the return value
- new (slot) LocalType( &node, &Node::RemoveShader );
-}
-
inline void SetParentOriginMessage( EventToUpdate& eventToUpdate, const Node& node, const Vector3& origin )
{
typedef MessageValue1< Node, Vector3 > LocalType;
void Actor::SetInheritShaderEffect(bool inherit)
{
- GetImplementation(*this).SetInheritShaderEffect(inherit);
+ // TODO remove this API
+ // @deprecated
}
bool Actor::GetInheritShaderEffect() const
{
- return GetImplementation(*this).GetInheritShaderEffect();
+ // TODO remove this API
+ // @deprecated
+ return false;
}
void Actor::SetShaderEffect(ShaderEffect effect)
{
+ // TODO remove this API
GetImplementation(*this).SetShaderEffect(GetImplementation(effect));
}
ShaderEffect Actor::GetShaderEffect() const
{
- Internal::ShaderEffectPtr internal = GetImplementation(*this).GetShaderEffect();
-
- return ShaderEffect(internal.Get());
+ // TODO remove this API
+ return ShaderEffect();
}
void Actor::RemoveShaderEffect()
{
+ // TODO remove this API
GetImplementation(*this).RemoveShaderEffect();
}
static const Property::Index NAME; ///< name "name", type STRING
static const Property::Index SENSITIVE; ///< name "sensitive", type BOOLEAN
static const Property::Index LEAVE_REQUIRED; ///< name "leave-required", type BOOLEAN
- static const Property::Index INHERIT_SHADER_EFFECT; ///< name "inherit-shader-effect", type BOOLEAN
static const Property::Index INHERIT_ROTATION; ///< name "inherit-rotation", type BOOLEAN
static const Property::Index INHERIT_SCALE; ///< name "inherit-scale", type BOOLEAN
static const Property::Index COLOR_MODE; ///< name "color-mode", type STRING
* @brief Adds a child Actor to this Actor.
*
* NOTE! if the child already has a parent, it will be removed from old parent
- * and reparented to this actor. This may change childs position, color, shader effect,
+ * and reparented to this actor. This may change childs position, color,
* scale etc as it now inherits them from this actor
* @pre This Actor (the parent) has been initialized.
* @pre The child actor has been initialized.
// Shader Effects
/**
- * @brief Set whether the actor inherits a shader effect from its parent; it does inherit by default.
+ * @deprecated call Set/RemoveShaderEffectRecursively if you want to apply the same shader for a tree of actors
*
- * The inherited effect can still be overriden using SetShaderEffect().
- * @pre The Actor has been initialized.
- * @param [in] inherit True if the parent effect is inherited.
+ * @param [in] ignored
*/
- void SetInheritShaderEffect(bool inherit);
+ void SetInheritShaderEffect(bool ignored);
/**
- * @brief Query whether the actor inherits a shader effect from its parent.
+ * @deprecated functionality no longer supported
*
- * @pre The Actor has been initialized.
- * @return True if the parent effect is inherited.
+ * @return false
*/
bool GetInheritShaderEffect() const;
/**
- * @brief Sets the shader effect for the Actor.
+ * @deprecated you need to call RenderableActor::SetShaderEffect
*
- * Shader effects provide special effects like rippling and bending.
- * Setting a shader effect removes any shader effect previously set by SetShaderEffect.
- * @pre The actor has been initialized.
- * @pre effect has been initialized.
* @param [in] effect The shader effect.
*/
void SetShaderEffect(ShaderEffect effect);
/**
- * @brief Retrieve the shader effect for the Actor.
+ * @deprecated you need to call RenderableActor::GetShaderEffect
*
- * @pre The Actor has been initialized.
* @return The shader effect
*/
ShaderEffect GetShaderEffect() const;
/**
- * @brief Removes the current shader effect.
- *
- * @pre The Actor has been initialized.
+ * @deprecated you need to call RenderableActor::GetShaderEffect
*/
void RemoveShaderEffect();
// INTERNAL INCLUDES
#include <dali/internal/event/actors/renderable-actor-impl.h>
+#include <dali/internal/event/effects/shader-effect-impl.h>
namespace Dali
{
GetImplementation(*this).GetFilterMode( minFilter, magFilter );
}
+void RenderableActor::SetShaderEffect(ShaderEffect effect)
+{
+ GetImplementation(*this).SetShaderEffect(GetImplementation(effect));
+}
+
+ShaderEffect RenderableActor::GetShaderEffect() const
+{
+ Internal::ShaderEffectPtr internal = GetImplementation(*this).GetShaderEffect();
+
+ return ShaderEffect(internal.Get());
+}
+
+void RenderableActor::RemoveShaderEffect()
+{
+ GetImplementation(*this).RemoveShaderEffect();
+}
+
RenderableActor::RenderableActor(Internal::RenderableActor* internal)
: Actor(internal)
{
}
+void SetShaderEffectRecursively( Actor actor, ShaderEffect effect )
+{
+ // only do something if the actor and effect are valid
+ if( actor && effect )
+ {
+ // first remove from this actor
+ RenderableActor renderable = RenderableActor::DownCast( actor );
+ if( renderable )
+ {
+ renderable.SetShaderEffect( effect );
+ }
+ // then all children recursively
+ const unsigned int count = actor.GetChildCount();
+ for( unsigned int index = 0; index < count; ++index )
+ {
+ Actor child( actor.GetChildAt( index ) );
+ SetShaderEffectRecursively( child, effect );
+ }
+ }
+}
+
+void RemoveShaderEffectRecursively( Actor actor )
+{
+ // only do something if the actor is valid
+ if( actor )
+ {
+ // first remove from this actor
+ RenderableActor renderable = RenderableActor::DownCast( actor );
+ if( renderable )
+ {
+ renderable.RemoveShaderEffect();
+ }
+ // then all children recursively
+ const unsigned int count = actor.GetChildCount();
+ for( unsigned int index = 0; index < count; ++index )
+ {
+ Actor child( actor.GetChildAt( index ) );
+ RemoveShaderEffectRecursively( child );
+ }
+ }
+}
+
} // namespace Dali
*/
void GetFilterMode( FilterMode::Type& minFilter, FilterMode::Type& magFilter) const;
+ /**
+ * @brief Sets the shader effect for the RenderableActor.
+ *
+ * Shader effects provide special effects like ripple and bend.
+ * Setting a shader effect removes any shader effect previously set by SetShaderEffect.
+ * @pre The actor has been initialized.
+ * @pre effect has been initialized.
+ * @param [in] effect The shader effect.
+ */
+ void SetShaderEffect( ShaderEffect effect );
+
+ /**
+ * @brief Retrieve the custom shader effect for the RenderableActor.
+ * If default shader is used an empty handle is returned.
+ *
+ * @pre The Actor has been initialized.
+ * @return The shader effect
+ */
+ ShaderEffect GetShaderEffect() const;
+
+ /**
+ * @brief Removes the current shader effect.
+ *
+ * @pre The Actor has been initialized.
+ */
+ void RemoveShaderEffect();
+
public: // Not intended for application developers
/**
explicit DALI_INTERNAL RenderableActor(Internal::RenderableActor* actor);
};
+/**
+ * @brief Sets the shader effect for all RenderableActors in a tree of Actors.
+ *
+ * @see RenderableActor::SetShaderEffect
+ *
+ * @param [in] actor root of a tree of actors.
+ * @param [in] effect The shader effect.
+ */
+void SetShaderEffectRecursively( Actor actor, ShaderEffect effect );
+
+/**
+ * @brief Removes the shader effect from all RenderableActors in a tree of Actors.
+ *
+ * @see RenderableActor::RemoveShaderEffect
+ *
+ * @param [in] actor root of a tree of actors.
+ */
+void RemoveShaderEffectRecursively( Actor actor );
+
} // namespace Dali
#endif // __DALI_RENDERABLE_ACTOR_H__