void Renderer::SetDepthIndex( int depthIndex )
{
- SceneGraph::AnimatablePropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mDepthIndex, &SceneGraph::AnimatableProperty<int>::Bake, depthIndex );
+ SetDepthIndexMessage( GetEventThreadServices(), *mSceneObject, depthIndex );
}
int Renderer::GetCurrentDepthIndex() const
void Material::SetBlendMode( BlendingMode::Type mode )
{
- // TODO: MESH_REWORK
- DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
+ mBlendingMode = mode;
+
+ if( NULL != mSceneObject )
+ {
+ SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, static_cast<int>(mode) );
+ }
}
+// @todo MESH_REWORK API change, or store here
BlendingMode::Type Material::GetBlendMode() const
{
- // TODO: MESH_REWORK
- DALI_ASSERT_ALWAYS( false && "TODO: MESH_REWORK" );
- return BlendingMode::AUTO;
+ return mBlendingMode;
}
void Material::SetBlendFunc( BlendingFactor::Type srcFactorRgba, BlendingFactor::Type destFactorRgba )
}
case Dali::Material::Property::BLENDING_MODE:
{
- DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+ if( mSceneObject )
+ {
+ SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mBlendingMode, &SceneGraph::DoubleBufferedProperty<int>::Set, propertyValue.Get<int>() );
+ }
break;
}
case Dali::Material::Property::BLEND_EQUATION:
}
case Dali::Material::Property::BLENDING_MODE:
{
- DALI_ASSERT_ALWAYS( 0 && "Mesh Rework" );
+ if( mSceneObject )
+ {
+ value = mSceneObject->mBlendingMode[bufferIndex];
+ }
break;
}
case Dali::Material::Property::BLEND_EQUATION:
SamplerConnectorContainer mSamplerConnectors; ///< Vector of connectors that hold the samplers used by this material
SceneGraph::Material* mSceneObject;
+
+ BlendingMode::Type mBlendingMode; ///< Local store
bool mOnStage;
};
{
//TODO: MESH_REWORK
ShaderPtr shader( new Shader() );
- shader->Initialize( vertexShader, fragmentShader );
+ shader->Initialize( vertexShader, fragmentShader, hints );
return shader;
}
{
}
-void Shader::Initialize( const std::string& vertexSource, const std::string& fragmentSource )
+void Shader::Initialize(
+ const std::string& vertexSource,
+ const std::string& fragmentSource,
+ Dali::Shader::ShaderHints hints )
{
DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() && "Core is not running" );
EventThreadServices& eventThreadServices = GetEventThreadServices();
SceneGraph::UpdateManager& updateManager = eventThreadServices.GetUpdateManager();
- Dali::ShaderEffect::GeometryHints hint = Dali::ShaderEffect::HINT_NONE;
- mSceneObject = new SceneGraph::Shader(hint);
+ // @todo MESH_REWORK - Pass hints directly to a new scene graph shader
+ int effectHint = Dali::ShaderEffect::HINT_NONE;
+ if( hints & Dali::Shader::HINT_OUTPUT_IS_TRANSPARENT )
+ {
+ effectHint |= Dali::ShaderEffect::HINT_BLENDING;
+ }
+
+ if( hints & Dali::Shader::HINT_REQUIRES_SELF_DEPTH_TEST )
+ {
+ effectHint |= Dali::ShaderEffect::HINT_DEPTH_BUFFER;
+ }
+
+ if( (hints & Dali::Shader::HINT_MODIFIES_GEOMETRY) == 0x0 )
+ {
+ effectHint |= Dali::ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY;
+ }
+ Dali::ShaderEffect::GeometryHints shaderEffectHint = static_cast<Dali::ShaderEffect::GeometryHints>( effectHint );
+
+ mSceneObject = new SceneGraph::Shader(shaderEffectHint);
// Add to update manager
AddShaderMessage( updateManager, *mSceneObject );
/**
* Second stage initialization
*/
- void Initialize( const std::string& vertexShader, const std::string& fragmentShader );
+ void Initialize( const std::string& vertexShader, const std::string& fragmentShader, Dali::Shader::ShaderHints hints );
protected:
/**
{
if( NULL != mSceneObject )
{
- SceneGraph::DoubleBufferedPropertyMessage<int>::Send( GetEventThreadServices(), mSceneObject, &mSceneObject->mGeometryType, &SceneGraph::DoubleBufferedProperty<int>::Set, static_cast<int>(geometryType) );
+ SceneGraph::DoubleBufferedPropertyMessage<int>::Send(
+ GetEventThreadServices(),
+ mSceneObject,
+ &mSceneObject->mGeometryType,
+ &SceneGraph::DoubleBufferedProperty<int>::Set,
+ static_cast<int>(geometryType) );
}
}
*/
#include <dali/public-api/common/dali-vector.h>
+#include <dali/public-api/actors/blending.h>
namespace Dali
{
{
}
+ virtual const Vector4& GetBlendColor( BufferIndex bufferIndex ) const = 0;
+
+ /**
+ * Get the RGB source factor
+ * @return the RGB source factor
+ */
+ virtual BlendingFactor::Type GetBlendSrcFactorRgb( BufferIndex bufferIndex ) const = 0;
+
+ /**
+ * Get the Alpha source factor
+ * @return the Alpha source factor
+ */
+ virtual BlendingFactor::Type GetBlendSrcFactorAlpha( BufferIndex bufferIndex ) const = 0;
+
+ /**
+ * Get the RGB destination factor
+ * @return the RGB destination factor
+ */
+ virtual BlendingFactor::Type GetBlendDestFactorRgb( BufferIndex bufferIndex ) const = 0;
+
+ /**
+ * Get the Alpha destination factor
+ * @return the Alpha destination factor
+ */
+ virtual BlendingFactor::Type GetBlendDestFactorAlpha( BufferIndex bufferIndex ) const = 0;
+
+ /**
+ * Get the RGB blending equation
+ * @return the RGB blending equation
+ */
+ virtual BlendingEquation::Type GetBlendEquationRgb( BufferIndex bufferIndex ) const = 0;
+
+ /**
+ * Get the Alpha blending equation
+ * @return the Alpha blending equation
+ */
+ virtual BlendingEquation::Type GetBlendEquationAlpha( BufferIndex bufferIndex ) const = 0;
+
protected:
/**
* Destructor. No deletion through this interface
// Do nothing, we're going to set up the uniforms with our own code instead
}
+void NewRenderer::DoSetCullFaceMode( Context& context, BufferIndex bufferIndex )
+{
+}
+
+void NewRenderer::DoSetBlending( Context& context, BufferIndex bufferIndex )
+{
+ context.SetBlend(mUseBlend); // @todo MESH_REWORK Should use a RendererDataProvider
+
+ if( mUseBlend )
+ {
+ const MaterialDataProvider& material = mRenderDataProvider->GetMaterial();
+
+ context.SetCustomBlendColor( material.GetBlendColor( bufferIndex ) );
+
+ // Set blend source & destination factors
+ context.BlendFuncSeparate( material.GetBlendSrcFactorRgb( bufferIndex ),
+ material.GetBlendDestFactorRgb( bufferIndex ),
+ material.GetBlendSrcFactorAlpha( bufferIndex ),
+ material.GetBlendDestFactorAlpha( bufferIndex ) );
+
+ // Set blend equations
+ context.BlendEquationSeparate( material.GetBlendEquationRgb( bufferIndex ),
+ material.GetBlendEquationAlpha( bufferIndex ) );
+ }
+}
void NewRenderer::DoRender( Context& context, TextureCache& textureCache, BufferIndex bufferIndex, Program& program, const Matrix& modelViewMatrix, const Matrix& viewMatrix )
{
virtual void DoSetUniforms( Context& context, BufferIndex bufferIndex, Shader* shader, Program* program, unsigned int programIndex, ShaderSubTypes subType );
/**
+ * @copydoc SceneGraph::Renderer::DoSetCullFaceMode
+ */
+ virtual void DoSetCullFaceMode(Context& context, BufferIndex bufferIndex );
+
+ /**
+ * @copydoc SceneGraph::Renderer::DoSetBlending
+ */
+ virtual void DoSetBlending(Context& context, BufferIndex bufferIndex );
+
+ /**
* @copydoc SceneGraph::Renderer::DoRender()
*/
virtual void DoRender( Context& context,
// Take the program into use so we can send uniforms to it
program->Use();
- // Enables/disables blending mode.
- context.SetBlend( mUseBlend );
-
- // Set face culling mode
- context.CullFace( mCullFaceMode );
-
- // Set the blend color
- const Vector4* const customColor = mBlendingOptions.GetBlendColor();
- if( customColor )
- {
- context.SetCustomBlendColor( *customColor );
- }
- else
- {
- context.SetDefaultBlendColor();
- }
+ DoSetCullFaceMode( context, bufferIndex );
- // Set blend source & destination factors
- context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(),
- mBlendingOptions.GetBlendDestFactorRgb(),
- mBlendingOptions.GetBlendSrcFactorAlpha(),
- mBlendingOptions.GetBlendDestFactorAlpha() );
-
- // Set blend equations
- context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(),
- mBlendingOptions.GetBlendEquationAlpha() );
+ DoSetBlending( context, bufferIndex );
// Ignore missing uniforms - custom shaders and flat color shaders don't have SAMPLER
// set projection and view matrix if program has not yet received them yet this frame
shader->SetUniforms( context, *program, bufferIndex, programIndex, subType );
}
+// can be overridden by deriving class
+void Renderer::DoSetCullFaceMode(Context& context, BufferIndex bufferIndex )
+{
+ // Set face culling mode
+ context.CullFace( mCullFaceMode );
+}
+
+// can be overridden by deriving class
+void Renderer::DoSetBlending(Context& context, BufferIndex bufferIndex )
+{
+ // Enables/disables blending mode.
+ context.SetBlend( mUseBlend );
+
+ // Set the blend color
+ const Vector4* const customColor = mBlendingOptions.GetBlendColor();
+ if( customColor )
+ {
+ context.SetCustomBlendColor( *customColor );
+ }
+ else
+ {
+ context.SetDefaultBlendColor();
+ }
+
+ // Set blend source & destination factors
+ context.BlendFuncSeparate( mBlendingOptions.GetBlendSrcFactorRgb(),
+ mBlendingOptions.GetBlendDestFactorRgb(),
+ mBlendingOptions.GetBlendSrcFactorAlpha(),
+ mBlendingOptions.GetBlendDestFactorAlpha() );
+
+ // Set blend equations
+ context.BlendEquationSeparate( mBlendingOptions.GetBlendEquationRgb(),
+ mBlendingOptions.GetBlendEquationAlpha() );
+
+}
+
Renderer::Renderer( NodeDataProvider& dataprovider )
: mDataProvider( dataprovider ),
mContextDELETEME(NULL),
* Called from Render prior to DoRender().
* @todo MESH_REWORK Remove after merge
*/
- virtual void DoSetUniforms(Context& context, BufferIndex bufferIndex, Shader* shader, Program* program, unsigned int programIndex, ShaderSubTypes subType );
+ virtual void DoSetUniforms( Context& context, BufferIndex bufferIndex, Shader* shader, Program* program, unsigned int programIndex, ShaderSubTypes subType );
+
+ /**
+ * Called from Render prior to DoRender(). Default method to set CullFaceMode
+ * @todo MESH_REWORK Remove after merge
+ */
+ virtual void DoSetCullFaceMode( Context& context, BufferIndex bufferIndex );
+
+ /**
+ * Called from Render prior to DoRender(). Default method to set blending options
+ * @todo MESH_REWORK Remove after merge
+ */
+ virtual void DoSetBlending( Context& context, BufferIndex bufferIndex );
/**
* Called from Render; implemented in derived classes.
Shader* mShader;
unsigned int mSamplerBitfield; ///< Sampler options used for texture filtering
+ bool mUseBlend:1; ///< True if blending should be enabled, 1 bit is enough
private:
BlendingOptions mBlendingOptions;
- bool mUseBlend:1; ///< True if blending should be enabled, 1 bit is enough
CullFaceMode mCullFaceMode:3; ///< cullface enum, 3 bits is enough
};
// INTERNAL HEADERS
#include <dali/public-api/shader-effects/material.h>
+#include <dali/public-api/shader-effects/shader-effect.h>
#include <dali/internal/render/data-providers/sampler-data-provider.h>
#include <dali/internal/update/effects/scene-graph-sampler.h>
+#include <dali/internal/render/shaders/scene-graph-shader.h>
+#include <dali/public-api/actors/blending.h>
namespace Dali
{
: mColor( Color::WHITE ),
mBlendColor( Color::WHITE ),
mFaceCullingMode(Dali::Material::NONE),
- mShader(NULL)
+ mBlendingMode(Dali::BlendingMode::AUTO),
+ mBlendFuncSrcFactorRgb(DEFAULT_BLENDING_SRC_FACTOR_RGB),
+ mBlendFuncSrcFactorAlpha(DEFAULT_BLENDING_SRC_FACTOR_ALPHA),
+ mBlendFuncDestFactorRgb(DEFAULT_BLENDING_DEST_FACTOR_RGB),
+ mBlendFuncDestFactorAlpha(DEFAULT_BLENDING_SRC_FACTOR_ALPHA),
+ mBlendEquationRgb(DEFAULT_BLENDING_EQUATION_RGB),
+ mBlendEquationAlpha(DEFAULT_BLENDING_EQUATION_ALPHA),
+ mShader(NULL),
+ mBlendingEnabled(false)
{
// Observe own property-owner's uniform map
AddUniformMapObserver( *this );
}
}
+void Material::PrepareRender( BufferIndex bufferIndex )
+{
+ mBlendingEnabled[bufferIndex] = false; // The best default
+
+ switch(mBlendingMode[bufferIndex])
+ {
+ case BlendingMode::OFF:
+ {
+ mBlendingEnabled[bufferIndex] = false;
+ break;
+ }
+ case BlendingMode::ON:
+ {
+ mBlendingEnabled[bufferIndex] = true;
+ break;
+ }
+ case BlendingMode::AUTO:
+ {
+ bool opaque = true;
+
+ // @todo: MESH_REWORK - Change hints for new SceneGraphShader
+ if( mShader->GeometryHintEnabled( Dali::ShaderEffect::HINT_BLENDING ) )
+ {
+ opaque = false;
+ }
+
+ if( opaque )
+ {
+ // Require that all affecting samplers are opaque
+ unsigned int opaqueCount=0;
+ unsigned int affectingCount=0;
+
+ for( Vector<Sampler*>::ConstIterator iter = mSamplers.Begin();
+ iter != mSamplers.End(); ++iter )
+ {
+ const Sampler* sampler = *iter;
+ if( sampler != NULL )
+ {
+ if( sampler->AffectsTransparency( bufferIndex ) )
+ {
+ affectingCount++;
+ if( sampler->IsFullyOpaque( bufferIndex ) )
+ {
+ opaqueCount++;
+ }
+ }
+ }
+ }
+ opaque = (opaqueCount == affectingCount);
+ }
+
+ mBlendingEnabled[bufferIndex] = ! opaque;
+ }
+ }
+}
+
Vector<Sampler*>& Material::GetSamplers()
{
return mSamplers;
}
+bool Material::GetBlendingEnabled( BufferIndex bufferIndex ) const
+{
+ return mBlendingEnabled[bufferIndex];
+}
+
+const Vector4& Material::GetBlendColor(BufferIndex bufferIndex) const
+{
+ return mBlendColor[bufferIndex];
+}
+
+BlendingFactor::Type Material::GetBlendSrcFactorRgb( BufferIndex bufferIndex ) const
+{
+ return static_cast<Dali::BlendingFactor::Type>(mBlendFuncSrcFactorRgb[bufferIndex]);
+}
+
+BlendingFactor::Type Material::GetBlendSrcFactorAlpha( BufferIndex bufferIndex ) const
+{
+ return static_cast<Dali::BlendingFactor::Type>(mBlendFuncSrcFactorAlpha[bufferIndex]);
+}
+
+BlendingFactor::Type Material::GetBlendDestFactorRgb( BufferIndex bufferIndex ) const
+{
+ return static_cast<Dali::BlendingFactor::Type>(mBlendFuncDestFactorRgb[bufferIndex]);
+}
+
+BlendingFactor::Type Material::GetBlendDestFactorAlpha( BufferIndex bufferIndex ) const
+{
+ return static_cast<Dali::BlendingFactor::Type>(mBlendFuncDestFactorAlpha[bufferIndex]);
+}
+
+BlendingEquation::Type Material::GetBlendEquationRgb( BufferIndex bufferIndex ) const
+{
+ return static_cast<Dali::BlendingEquation::Type>(mBlendEquationRgb[bufferIndex]);
+}
+
+BlendingEquation::Type Material::GetBlendEquationAlpha( BufferIndex bufferIndex ) const
+{
+ return static_cast<Dali::BlendingEquation::Type>(mBlendEquationAlpha[bufferIndex]);
+}
+
void Material::ConnectToSceneGraph( SceneController& sceneController, BufferIndex bufferIndex )
{
}
mColor.ResetToBaseValue( updateBufferIndex );
mBlendColor.ResetToBaseValue( updateBufferIndex );
mFaceCullingMode.CopyPrevious( updateBufferIndex );
+
+ mBlendingMode.CopyPrevious( updateBufferIndex );
+ mBlendFuncSrcFactorRgb.CopyPrevious( updateBufferIndex );
+ mBlendFuncSrcFactorAlpha.CopyPrevious( updateBufferIndex );
+ mBlendFuncDestFactorRgb.CopyPrevious( updateBufferIndex );
+ mBlendFuncDestFactorAlpha.CopyPrevious( updateBufferIndex );
+ mBlendEquationRgb.CopyPrevious( updateBufferIndex );
+ mBlendEquationAlpha.CopyPrevious( updateBufferIndex );
}
} // namespace SceneGraph
void RemoveSampler( Sampler* sampler );
/**
+ * Prepare the material for rendering.
+ *
+ * Determine whether blending is enabled for this material, and store the result.
+ * @param[in] bufferIndex The current buffer index
+ */
+ void PrepareRender( BufferIndex bufferIndex );
+
+ /**
+ * Return true if the material requires blending
+ * @return true if the material requires blending
+ */
+ bool GetBlendingEnabled( BufferIndex bufferIndex ) const;
+
+public: // Implementation of MaterialDataProvider
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendColor
+ */
+ virtual const Vector4& GetBlendColor(BufferIndex bufferIndex) const;
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendSrcFactorRgb
+ */
+ virtual BlendingFactor::Type GetBlendSrcFactorRgb(BufferIndex bufferIndex) const;
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendSrcFactorAlpha
+ */
+ virtual BlendingFactor::Type GetBlendSrcFactorAlpha( BufferIndex bufferIndex ) const;
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendDestFactorRgb
+ */
+ virtual BlendingFactor::Type GetBlendDestFactorRgb( BufferIndex bufferIndex ) const;
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendDestFactorAlpha
+ */
+ virtual BlendingFactor::Type GetBlendDestFactorAlpha( BufferIndex bufferIndex ) const;
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendEquationRgb
+ */
+ virtual BlendingEquation::Type GetBlendEquationRgb( BufferIndex bufferIndex ) const;
+
+ /**
+ * @copydoc MaterialDataProvider::GetBlendEquationAlpha
+ */
+ virtual BlendingEquation::Type GetBlendEquationAlpha( BufferIndex bufferIndex ) const;
+
+public: // Implementation of ObjectOwnerContainer template methods
+ /**
* Connect the object to the scene graph
*
* @param[in] sceneController The scene controller - used for sending messages to render thread
*/
void DisconnectFromSceneGraph( SceneController& sceneController, BufferIndex bufferIndex );
+public: // Implementation of ConnectionChangePropagator
/**
* @copydoc ConnectionChangePropagator::AddObserver
*/
AnimatableProperty<Vector4> mColor;
AnimatableProperty<Vector4> mBlendColor;
DoubleBufferedProperty<int> mFaceCullingMode;
+ DoubleBufferedProperty<int> mBlendingMode;
+
+ // @todo MESH_REWORK Consider storing only mBlendingOptions bitmask
+ DoubleBufferedProperty<int> mBlendFuncSrcFactorRgb;
+ DoubleBufferedProperty<int> mBlendFuncSrcFactorAlpha;
+ DoubleBufferedProperty<int> mBlendFuncDestFactorRgb;
+ DoubleBufferedProperty<int> mBlendFuncDestFactorAlpha;
+ DoubleBufferedProperty<int> mBlendEquationRgb;
+ DoubleBufferedProperty<int> mBlendEquationAlpha;
private:
Shader* mShader;
Vector<Sampler*> mSamplers; // Not owned
ConnectionChangePropagator mConnectionObservers;
-
- // @todo MESH_REWORK add property values for cull face mode, blending options, blend color
- // Add getters/setters?
+ DoubleBuffered<bool> mBlendingEnabled; // The output of the current blending mode and sampler properties
};
inline void SetShaderMessage( EventThreadServices& eventThreadServices, const Material& material, const Shader& shader )
void PrepareRenderables( BufferIndex updateBufferIndex, SortedLayerPointers& sortedLayers )
{
-
const SortedLayersIter endIter = sortedLayers.end();
for ( SortedLayersIter iter = sortedLayers.begin(); iter != endIter; ++iter )
{
layer->overlayRenderables.push_back( renderable );
}
- else if ( ! renderable->IsBlendingOn( updateBufferIndex ) )
+ else if ( renderable->IsFullyOpaque( updateBufferIndex ) )
{
layer->opaqueRenderables.push_back( renderable );
}
void UpdateManager::ResetNodeProperty( Node& node )
{
- node.ResetToBaseValues( mSceneGraphBuffers.GetUpdateBufferIndex() );
+ BufferIndex bufferIndex = mSceneGraphBuffers.GetUpdateBufferIndex();
+
+ node.ResetToBaseValues( bufferIndex );
+
+ // @todo MESH_REWORK Only perform this step for RendererAttachments - consider
+ // storing them again? Split out to separate scene graph object owned by UpdateManager
+ // It is after all, a property owner, and always requires resetting...
+ // The depth index should not be an animatable property... and probably not even
+ // a constraint input? (Double buffering will slow down the sort algorithm slightly)
+ if( node.HasAttachment() )
+ {
+ node.GetAttachment().ResetToBaseValues( bufferIndex );
+ }
}
void UpdateManager::ResetProperties()
// Update methods
/**
+ * Called to reset attachment's properties to base values.
+ * Attachments without properties should not override this method
+ */
+ virtual void ResetToBaseValues(BufferIndex bufferIndex) { }
+
+ /**
* Called when the attachment or it's owning node is flagged as dirty during scene graph updates.
* Allows derived classes to perform extra processing
* @param[in] updateBufferIndex The current update buffer index.
}
}
+void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
+{
+ mBlendingMode = mode;
+}
+
+BlendingMode::Type RenderableAttachment::GetBlendingMode() const
+{
+ return mBlendingMode;
+}
+
bool ImageAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
{
- /**
- * 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 blending
- */
- bool opaque = mBitmapMetadata.IsFullyOpaque();
-
- if ( opaque && mParent )
- {
- opaque = ( mParent->GetWorldColor(updateBufferIndex).a >= FULLY_OPAQUE );
+ bool fullyOpaque = true;
- if ( opaque && mShader != NULL )
+ switch( mBlendingMode )
+ {
+ case BlendingMode::OFF:
{
- opaque = !PreviousHintEnabled( Dali::ShaderEffect::HINT_BLENDING );
+ fullyOpaque = true;
+ break;
}
- }
+ case BlendingMode::ON:
+ {
+ // Blending always.
+ fullyOpaque = false;
+ break;
+ }
+ case BlendingMode::AUTO:
+ {
+ /**
+ * 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 blending
+ */
+ fullyOpaque = mBitmapMetadata.IsFullyOpaque();
+
+ if ( fullyOpaque && mParent )
+ {
+ fullyOpaque = ( mParent->GetWorldColor(updateBufferIndex).a >= FULLY_OPAQUE );
- return opaque;
+ if ( fullyOpaque && mShader != NULL )
+ {
+ fullyOpaque = !PreviousHintEnabled( Dali::ShaderEffect::HINT_BLENDING );
+ }
+ }
+ }
+ }
+ return fullyOpaque;
}
void ImageAttachment::SendShaderChangeMessage( BufferIndex updateBufferIndex )
// Chain to derived attachments
Initialize2( updateBufferIndex );
-
- // @todo MESH_REWORK: removed: renderer.SetCullFace & renderer.SetShader;
}
void RenderableAttachment::OnDestroy()
mSceneController = NULL;
}
-void RenderableAttachment::SetBlendingMode( BlendingMode::Type mode )
-{
- mBlendingMode = mode;
-}
-
-BlendingMode::Type RenderableAttachment::GetBlendingMode() const
-{
- return mBlendingMode;
-}
-
void RenderableAttachment::SetRecalculateScaleForSize()
{
mScaleForSizeDirty = true;
return mHasSizeAndColorFlag;
}
-bool RenderableAttachment::IsBlendingOn( BufferIndex updateBufferIndex )
-{
- // Check whether blending needs to be disabled / enabled
- bool blend = false;
- switch( mBlendingMode )
- {
- case BlendingMode::OFF:
- {
- // No blending.
- blend = false;
- break;
- }
- case BlendingMode::AUTO:
- {
- // Blending if the node is not fully opaque only.
- blend = !IsFullyOpaque( updateBufferIndex );
- break;
- }
- case BlendingMode::ON:
- {
- // Blending always.
- blend = true;
- break;
- }
- default:
- {
- DALI_ASSERT_ALWAYS( !"RenderableAttachment::PrepareRender. Wrong blending mode" );
- }
- }
- return blend;
-}
-
-void RenderableAttachment::ChangeBlending( BufferIndex updateBufferIndex, bool useBlend )
-{
- if ( mUseBlend != useBlend )
- {
- mUseBlend = useBlend;
-
- // Enable/disable blending in the next render
- typedef MessageValue1< Renderer, bool > 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( &GetRenderer(), &Renderer::SetUseBlend, useBlend );
- }
-}
-
void RenderableAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
{
scaling = Vector3::ONE;
}
-
void RenderableAttachment::PrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
{
mHasUntrackedResources = false; // Only need to know this if the resources are not yet complete
}
}
-
void RenderableAttachment::PrepareRender( BufferIndex updateBufferIndex )
{
// call the derived class first as it might change its state regarding blending
DoPrepareRender( updateBufferIndex );
- bool blend = IsBlendingOn( updateBufferIndex );
- ChangeBlending( updateBufferIndex, blend );
-}
+ // @todo MESH_REWORK Remove remainder of method after removing ImageAttachment
+ bool blend = !IsFullyOpaque( updateBufferIndex );
+
+ if ( mUseBlend != blend )
+ {
+ mUseBlend = blend;
+
+ // Enable/disable blending in the next render
+ typedef MessageValue1< Renderer, bool > 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( &GetRenderer(), &Renderer::SetUseBlend, blend );
+ }
+}
RenderableAttachment* RenderableAttachment::GetRenderable()
{
}
/**
- * Query whether the attachment has blending enabled.
- * @param[in] updateBufferIndex The current update buffer index.
- * @return true if blending is enabled, false otherwise.
- */
- bool IsBlendingOn( BufferIndex updateBufferIndex );
-
- /**
- * Check if the blending mode has changed - if it has, send message to renderer
- * @param[in] updateBufferIndex The current update buffer index.
- * @param[in] useBlending True if the renderer should use blending option
- */
- void ChangeBlending( BufferIndex updateBufferIndex, bool useBlending );
-
- /**
* Prepare the object resources.
* This must be called by the UpdateManager before calling PrepareRender, for each frame.
* @param[in] updateBufferIndex The current update buffer index.
virtual const Renderer& GetRenderer() const = 0;
/**
+ * Prepare the object resources.
+ * This must be called by the UpdateManager before calling PrepareRender, for each frame.
+ * @param[in] updateBufferIndex The current buffer index.
+ * @param[in] resourceManager The resource manager.
+ * @return True if resources are ready, false will prevent PrepareRender being called for this attachment.
+ */
+ virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0;
+
+ /**
* @copydoc RenderableAttachment::PrepareRender()
*/
virtual void DoPrepareRender( BufferIndex updateBufferIndex ) = 0;
private:
- /**
- * Prepare the object resources.
- * This must be called by the UpdateManager before calling PrepareRender, for each frame.
- * @param[in] updateBufferIndex The current buffer index.
- * @param[in] resourceManager The resource manager.
- * @return True if resources are ready, false will prevent PrepareRender being called for this attachment.
- */
- virtual bool DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager ) = 0;
-
// Undefined
RenderableAttachment( const RenderableAttachment& );
return *mGeometry;
}
-int RendererAttachment::GetDepthIndex(BufferIndex bufferIndex) const
+void RendererAttachment::SetDepthIndex( BufferIndex updateBufferIndex, int depthIndex )
{
- return mDepthIndex[bufferIndex];
+ mDepthIndex.Bake(updateBufferIndex, depthIndex);
+
+ if( mParent )
+ {
+ // only do this if we are on-stage
+ mParent->SetDirtyFlag( SortModifierFlag );
+ }
+
+ // @todo MESH_REWORK Change SortTransparentRenderItems to use GetDepthIndex instead
+ mSortModifier = depthIndex;
+}
+
+void RendererAttachment::ResetToBaseValues( BufferIndex updateBufferIndex )
+{
+ mDepthIndex.ResetToBaseValue( updateBufferIndex );
}
Renderer& RendererAttachment::GetRenderer()
return *mRenderer;
}
+// Called by ProcessRenderTasks after DoPrepareRender
+bool RendererAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
+{
+ bool opaque = false;
+
+ if( mParent )
+ {
+ opaque = mParent->GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE;
+ }
+
+ if( opaque && mMaterial != NULL )
+ {
+ // Calculated by material in PrepareRender step
+ opaque = ! mMaterial->GetBlendingEnabled( updateBufferIndex );
+ }
+
+ return opaque;
+}
+
+void RendererAttachment::SizeChanged( BufferIndex updateBufferIndex )
+{
+ // Do nothing.
+}
+
+bool RendererAttachment::DoPrepareResources(
+ BufferIndex updateBufferIndex,
+ ResourceManager& resourceManager )
+{
+ DALI_ASSERT_DEBUG( mSceneController );
+
+ CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
+ bool ready = false;
+ mFinishedResourceAcquisition = false;
+
+ // Can only be considered ready when all the scene graph objects are connected to the renderer
+ if( ( mGeometry ) &&
+ ( mGeometry->GetVertexBuffers().Count() > 0 ) &&
+ ( mMaterial ) &&
+ ( mMaterial->GetShader() != NULL ) )
+ {
+ unsigned int completeCount = 0;
+ unsigned int neverCount = 0;
+ unsigned int frameBufferCount = 0;
+
+ Vector<Sampler*>& samplers = mMaterial->GetSamplers();
+ for( Vector<Sampler*>::ConstIterator iter = samplers.Begin();
+ iter != samplers.End(); ++iter )
+ {
+ Sampler* sampler = *iter;
+
+ ResourceId textureId = sampler->GetTextureId( updateBufferIndex );
+ BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId );
+
+ sampler->SetFullyOpaque( metaData.IsFullyOpaque() );
+
+ switch( completeStatusManager.GetStatus( textureId ) )
+ {
+ case CompleteStatusManager::NOT_READY:
+ {
+ ready = false;
+ if( metaData.GetIsFramebuffer() )
+ {
+ frameBufferCount++;
+ }
+ FollowTracker( textureId ); // @todo MESH_REWORK Trackers per sampler rather than per actor?
+ }
+ break;
+
+ case CompleteStatusManager::COMPLETE:
+ {
+ completeCount++;
+ }
+ break;
+
+ case CompleteStatusManager::NEVER:
+ {
+ neverCount++;
+ }
+ break;
+ }
+ }
+
+ // We are ready if all samplers are complete, or those that aren't are framebuffers
+ // We are complete if all samplers are either complete or will never complete
+
+ ready = ( completeCount + frameBufferCount >= samplers.Count() ) ;
+ mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() );
+ }
+
+ return ready;
+}
+
+
// Uniform maps are checked in the following priority order:
// Renderer (this object)
// Actor
// VertexBuffers
void RendererAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
{
+ // @todo MESH_REWORK - call DoPrepareRender on all scene objects? in caller class?
+ mMaterial->PrepareRender( updateBufferIndex );
+
if( mRegenerateUniformMap > 0)
{
if( mRegenerateUniformMap == REGENERATE_UNIFORM_MAP)
}
}
-bool RendererAttachment::IsFullyOpaque( BufferIndex updateBufferIndex )
-{
- bool opaque = false;
-
- if( mParent )
- {
- opaque = mParent->GetWorldColor( updateBufferIndex ).a >= FULLY_OPAQUE;
- }
-
- if( mMaterial != NULL )
- {
- // Require that all affecting samplers are opaque
- unsigned int opaqueCount=0;
- unsigned int affectingCount=0;
-
- Vector<Sampler*>& samplers = mMaterial->GetSamplers();
- for( Vector<Sampler*>::ConstIterator iter = samplers.Begin();
- iter != samplers.End(); ++iter )
- {
- const Sampler* sampler = *iter;
- if( sampler != NULL )
- {
- if( sampler->AffectsTransparency( updateBufferIndex ) )
- {
- affectingCount++;
- if( sampler->IsFullyOpaque( updateBufferIndex ) )
- {
- opaqueCount++;
- }
- }
- }
- }
- opaque = (opaqueCount == affectingCount);
- }
-
- return opaque;
-}
-
-void RendererAttachment::SizeChanged( BufferIndex updateBufferIndex )
-{
- // Do nothing.
-}
-
-bool RendererAttachment::DoPrepareResources(
- BufferIndex updateBufferIndex,
- ResourceManager& resourceManager )
-{
- DALI_ASSERT_DEBUG( mSceneController );
-
- CompleteStatusManager& completeStatusManager = mSceneController->GetCompleteStatusManager();
-
- bool ready = false;
- mFinishedResourceAcquisition = false;
-
- // Can only be considered ready when all the scene graph objects are connected to the renderer
- if( ( mGeometry ) &&
- ( mGeometry->GetVertexBuffers().Count() > 0 ) &&
- ( mMaterial ) &&
- ( mMaterial->GetShader() != NULL ) )
- {
- unsigned int completeCount = 0;
- unsigned int neverCount = 0;
- unsigned int frameBufferCount = 0;
-
- Vector<Sampler*>& samplers = mMaterial->GetSamplers();
- for( Vector<Sampler*>::ConstIterator iter = samplers.Begin();
- iter != samplers.End(); ++iter )
- {
- Sampler* sampler = *iter;
-
- ResourceId textureId = sampler->GetTextureId( updateBufferIndex );
- BitmapMetadata metaData = resourceManager.GetBitmapMetadata( textureId );
-
- sampler->SetFullyOpaque( metaData.IsFullyOpaque() );
-
- switch( completeStatusManager.GetStatus( textureId ) )
- {
- case CompleteStatusManager::NOT_READY:
- {
- ready = false;
- if( metaData.GetIsFramebuffer() )
- {
- frameBufferCount++;
- }
- FollowTracker( textureId ); // @todo MESH_REWORK Trackers per sampler rather than per actor?
- }
- break;
-
- case CompleteStatusManager::COMPLETE:
- {
- completeCount++;
- }
- break;
-
- case CompleteStatusManager::NEVER:
- {
- neverCount++;
- }
- break;
- }
- }
-
- // We are ready if all samplers are complete, or those that aren't are framebuffers
- // We are complete if all samplers are either complete or will never complete
-
- ready = ( completeCount + frameBufferCount >= samplers.Count() ) ;
- mFinishedResourceAcquisition = ( completeCount + neverCount >= samplers.Count() );
- }
-
- return ready;
-}
void RendererAttachment::ConnectionsChanged( PropertyOwner& object )
{
Geometry& GetGeometry();
/**
- * Get the depth index
+ * Set the depth index
+ * @param[in] bufferIndex The buffer index
+ * @param[in] depthIndex the new depth index to use
+ */
+ void SetDepthIndex( BufferIndex bufferIndex, int depthIndex );
+
+ /**
+ * Get the depth index.
+ * Inlined, as called from sort algorithm
* @return The depth index of the renderer attachment in the current frame
*/
- int GetDepthIndex( BufferIndex bufferIndex ) const ;
+ int GetDepthIndex( BufferIndex bufferIndex ) const
+ {
+ return mDepthIndex[bufferIndex];
+ }
+
+
+protected: // From NodeAttachment
+ /**
+ * @copydoc NodeAttachment::ResetToBaseValues
+ */
+ virtual void ResetToBaseValues( BufferIndex updateBufferIndex );
protected: // From RenderableAttachment
/**
virtual const Renderer& GetRenderer() const;
/**
+ * @copydoc RenderableAttachment::DoPrepareResources()
+ */
+ virtual bool DoPrepareResources( BufferIndex updateBufferIndex,
+ ResourceManager& resourceManager );
+
+ /**
* @copydoc RenderableAttachment::DoPrepareRender()
*/
virtual void DoPrepareRender( BufferIndex updateBufferIndex );
*/
virtual void SizeChanged( BufferIndex updateBufferIndex );
- /**
- * @copydoc RenderableAttachment::DoPrepareResources()
- */
- virtual bool DoPrepareResources( BufferIndex updateBufferIndex,
- ResourceManager& resourceManager );
-
protected: // From ConnectionObserver
/**
* @copydoc ConnectionObservers::Observer::ConnectionsChanged
new (slot) LocalType( &attachment, &RendererAttachment::SetGeometry, const_cast<Geometry*>(&geometry) );
}
+inline void SetDepthIndexMessage( EventThreadServices& eventThreadServices, const RendererAttachment& attachment, int depthIndex )
+{
+ typedef MessageDoubleBuffered1< RendererAttachment, int > LocalType;
+
+ // Reserve some memory inside the message queue
+ unsigned int* slot = eventThreadServices.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, &RendererAttachment::SetDepthIndex, depthIndex );
+}
+
} // namespace SceneGraph
} // namespace Internal
} // namespace Dali
GetImplementation(*this).SetDepthIndex( depthIndex );
}
+int Renderer::GetCurrentDepthIndex()
+{
+ return GetImplementation(*this).GetCurrentDepthIndex();
+}
+
Renderer::Renderer( Internal::Renderer* pointer )
: Handle( pointer )
{
* @sa SetDepthIndex()
* @return the depth index
*/
- int GetDepthIndex();
+ int GetCurrentDepthIndex();
public:
/**