# 2D Scene Graph Dynamics

#### <a class="anchor" id="bkmrk--215"></a>Description

Usually all required nodes are already specified and preconfigured via SceneComposer, so in most cases it won't be necessary to make any adaptations within the scene graph loaded from an asset at runtime.

However, some use cases might require such adaptations. This tutorial covers the most common means to manipulate the scene graph structure dynamically.

#### Example Solution

<div class="contents" id="bkmrk-scenegraphdynamicsso-1"><div class="textblock">- SceneGraphDynamicsSolution\_2D in folder *cgi\_studio\_player/content/Tutorials/03\_SceneGraphAndNodes*

</div></div>#### **Adding and Removing 2D Nodes** 

##### <a class="anchor" id="bkmrk--218"></a>Scene Graph Dynamics 2D Example

There are some differences between a 2D and a 3D scene graph. This chapter will explain the differences in detail.

For 2D scene graph dynamics, the following examples can be used:

<div class="contents" id="bkmrk-scenegraphdynamicsso-2"><div class="contents"><div class="textblock">- **SceneGraphDynamicsSolution\_2D** from folder *cgi\_studio\_player/content/Tutorials/03\_SceneGraphAndNodes*
- **SceneGraphDynamicsWidget\_2D**

</div></div></div>##### <a class="anchor" id="bkmrk--219"></a>Adding and Removing 2D Nodes

In the widget a RenderNode with text is created and added/removed to/from the 2D scene graph. For adding and removing 2D nodes on the scene graph the following properties can be used:

<div class="contents" id="bkmrk-addtonode2d%3A-select-"><div class="contents"><div class="contents"><div class="textblock">- **AddToNode2D:** Select the node where the new RenderNode should be attached. This node can be any sub-type of <span style="color: rgb(230, 126, 35);">[Candera::Node2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_node2_d.html "The class Node2D is an abstract base class for all 2D scene graph nodes.")</span>.

<div class="fragment">  
</div></div></div></div></div>```
        CdaProperty(AddToNode, <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_node2_d.html" title="The class Node2D is an abstract base class for all 2D scene graph nodes.">Candera::Node2D</a>*, GetAddToNode, SetAddToNode)
            CdaDescription("Node2D, where a new TextNode shall be added to")
            CdaCategory("Adding and Removing 2D Nodes")
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___meta_info.html#ga119bef57449bd05d8b3c40d7d514e375">CdaPropertyEnd</a>()
```

<div class="contents" id="bkmrk-textnodefont%3A-select"><div class="contents"><div class="contents"><div class="textblock"><div class="fragment">  
</div>- **TextNodeStyle :** Sets the style to be used for the text node. This allows the user to provide a custom style for the dynamic text.

</div></div></div></div>```
CdaProperty(TextNodeStyle, Candera::TextRendering::SharedStyle::SharedPointer, GetTextNodeStyle, SetTextNodeStyle)
 CdaDescription("Style for the new Text Node ")
 CdaCategory("Adding and Removing 2D Nodes ")
```

<div class="contents" id="bkmrk-addtextnode%3A-if-addt"><div class="contents"><div class="contents"><div class="textblock"><div class="fragment">  
</div>- **AddTextNode:** If AddTextNode is enabled, a new text node with the selected font is created and attached to the selected node. If disabled, the text node is removed from the scene graph again.

<div class="fragment">  
</div></div></div></div></div>```
        CdaProperty(AddTextNode, bool, GetAddTextNode, SetAddTextNode)
            CdaDescription("If AddTextNode is enabled, a new TextNode with Selected TextNodeStyle Will be added to the selected AddToNode property. If disabled the new TextNode will be removed.")
            CdaCategory("Adding and Removing 2D Nodes")
        CdaPropertyEnd()

```

##### <a class="anchor" id="bkmrk--220"></a>Creating a new Text Node

To display new text, a new TextNode2D is created. TextNode2D represents a Render Node (Candera::TextNode2D). It requires a BitmapBrush effect for rendering. The Candera::BitmapTextNodeRenderer then generates the bitmap images from the given text, and these images are finally rendered using the attached Bitmap Brush effect.

Create an instance of BitmapBrushEffect and a text node for the scene graph using the following code used.

```
BitmapBrushColorBlend::SharedPointer bbc = BitmapBrushColorBlend::Create();
bbc->GetColorEffect().Color().Set(Color(255 / 255, 255, 255 / 255, 1));
m_addedNode = TextNode2D::Create();
m_addedNode ->AddEffect(bbc.GetPointerToSharedInstance());
m_addedNode ->SetName("AddedTextNode");
m_addedNode ->SetText("AddedNode");
m_addedNode ->SetStyle(m_textNodeStyle);
m_addedNode ->SetTextNodeRenderer(BitmapTextNodeRenderer::Create());
m_addedNode ->SetPosition(100, 200);    
```

##### <a class="anchor" id="bkmrk--221"></a>Adding Text Node to Scene Graph

Next the text node is uploaded to VRAM and appended to the selected node.

```
        static_cast<void>(m_addedNode->Upload());
        static_cast<void>(m_addToNode->AddChild(m_addedNode));
```

##### <a class="anchor" id="bkmrk--222"></a>Removing and Destructing Text Node

A 2D node can be removed by calling <span style="color: rgb(230, 126, 35);">[Candera::Node2D::RemoveChild](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_node2_d.html#a2c5fb3b53f03a11d0cc1336eebcbddef).</span> This is also described in the 3D part of this chapter (see <span style="color: rgb(230, 126, 35);">[Removing and destructing the Billboard](https://doc316en.candera.eu/link/449#bkmrk-removing-and-destruc)</span>). For removing and completely destructing the node, following code is used:

```
        static_cast<void>(m_addedNode->Unload());
        m_addedNode->Dispose();
        m_addedNode = 0;
```

The text node is unloaded from VRAM. The method <span style="color: rgb(230, 126, 35);">[Candera::Node2D::Dispose](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_node2_d.html#abaf2f0b8fd406b23a626560ff8395c7c)</span> removes the node from its parent and frees the resources.

<div class="contents" id="bkmrk-in-scenecomposer-the-3"><div class="textblock"><dl class="note"><dd><p class="callout info">In SceneComposer the manipulated scene graph and the changed properties do not appear because it is only changed dynamically by the widget.</p>

<p class="callout info">The widget must control memory and VRAM management of its internal dynamic subtree autonomously.</p>

</dd></dl></div></div>#### **Replacing a 2D Effect** 

##### <a class="anchor" id="bkmrk--223"></a>Replacing an Effect

In the SceneGraphDynamicsWidget\_2D example, the effect of a <span style="color: rgb(230, 126, 35);">[Candera::RenderNode](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_render_node.html "RenderNode is a 2D node that links to an effect chain. Therefore this is the only type of 2D node whi...") </span>can be either replaced by a <span style="color: rgb(230, 126, 35);">[Candera::SolidColorBrushBlend](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_solid_color_brush_blend.html "Output rectangle filled with a solid color and blend it with the store buffer. Same as chaining (Soli...") </span>or a <span style="color: rgb(230, 126, 35);">[Candera::BitmapBrushBlend](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_bitmap_brush_blend.html "This effect outputs a bitmap image, and blend it with the store buffer. Same as chaining (BitmapBrush...")</span> effect. Of course the same procedure works for Text effects.

To replace the effect in the example, the following properties can be used:

<div class="contents" id="bkmrk-nodetochange%3A-select"><div class="contents"><div class="contents"><div class="textblock">- **NodeToChange:** Select any render node with an effect whose appearance should be changed. Ensure that just a render node which has an effect is selected (in the sample solution this could be e.g. the node BitmapNode\_BarTop). For further information see <span style="color: rgb(230, 126, 35);">[Adding Replacing Effect](#bkmrk-adding-replacing-eff)</span>.

<div class="fragment">  
</div></div></div></div></div>```
        CdaProperty(NodeToChange, <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_node2_d.html" title="The class Node2D is an abstract base class for all 2D scene graph nodes.">Candera::Node2D</a>* , GetNodeToChange, SetNodeToChange)
            CdaDescription("Select a RenderNode which effect should be exchanged")
            CdaCategory("Replacing a 2D Effect")
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___meta_info.html#ga119bef57449bd05d8b3c40d7d514e375">CdaPropertyEnd</a>()
```

<div class="contents" id="bkmrk-changeeffect%3A-if-cha"><div class="contents"><div class="contents"><div class="textblock"><div class="fragment">  
</div>- **ChangeEffect:** If ChangeEffect is enabled, the effect of the selected NodeToChange will be removed and a <span style="color: rgb(230, 126, 35);">[Candera::SolidColorBrushBlend](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_solid_color_brush_blend.html "Output rectangle filled with a solid color and blend it with the store buffer. Same as chaining (Soli...") </span>effect is added to the node, instead. If disabled, the actual effect will be removed too and a <span style="color: rgb(230, 126, 35);">[Candera::BitmapBrushBlend](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_bitmap_brush_blend.html "This effect outputs a bitmap image, and blend it with the store buffer. Same as chaining (BitmapBrush...")</span> effect is added to the node.

<div class="fragment">  
</div></div></div></div></div>```
        CdaProperty(ChangeEffect, bool, GetChangeEffect, SetChangeEffect)
            CdaDescription("<a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___c_o_u_r_i_e_r___v_i_s_u_a_l_i_z_a_t_i_o_n.html#ggaebf7a2d5677fc4e6ddcb367db56e9c15af6e24437ca5022a15546ac6a5abac675">Change</a> effect of selected NodeToChange. Set either a SolidColorBrushAlphaBlend (enabled) or BitmapBrushAlphaBlend effect (disabled).")
            CdaCategory("Replacing a 2D Effect")
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___meta_info.html#ga119bef57449bd05d8b3c40d7d514e375">CdaPropertyEnd</a>()
```

##### <a class="anchor" id="bkmrk--224"></a>Creating a Color Effect

First a new effect is created by creating an instance of <span style="color: rgb(230, 126, 35);">[Candera::SolidColorBrushBlend](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_solid_color_brush_blend.html "Output rectangle filled with a solid color and blend it with the store buffer. Same as chaining (Soli...").</span>

<div class="contents" id="bkmrk-2d-effects-are-part--0"><div class="contents"><div class="contents"><div class="textblock"><dl class="note"><dt></dt><dd><p class="callout info">2D effects are part of the device package, therefore in order to create a concrete instance of the effect, the effect must be enabled for the device. Please see chapter **2D Effects** of this tutorial to see how to enable an effect for a certain device.</p>

</dd></dl><div class="fragment">  
</div></div></div></div></div>```
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_feat_std_1_1_memory_management_1_1_shared_pointer.html" title="An intrusive reference-counting smart pointer. If you want your class to be managed by SharedPointer ...">Candera::SolidColorBrushBlend::SharedPointer</a> brush = <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___c_o_u_r_i_e_r___v_i_s_u_a_l_i_z_a_t_i_o_n.html#ggaf0e93dc4242f607c3c8d13dafd036af9aaabfa5309af24986d3111a092449f857">Candera::SolidColorBrushBlend::Create</a>();
        brush->GetSolidColorBrush().Size().Set(m_Rect);
        brush->GetSolidColorBrush().Color().Set(m_ColorBlue);
        brush->GetBlendEffect().SetBlendMode(RenderDevice2D::SourceAlpha, RenderDevice2D::InverseSourceAlpha, RenderDevice2D::Add);
```

##### <a class="anchor" id="bkmrk--225"></a>Adding Replacing Effect

Once the effect is created it can be added to the render node. In the following code snippet the selected NodeToChange is cast to a <span style="color: rgb(230, 126, 35);">[Candera::RenderNode](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_render_node.html "RenderNode is a 2D node that links to an effect chain. Therefore this is the only type of 2D node whi...")</span> (for this a RenderNode **must** be selected, otherwise the cast will fail). The first effect of the node is removed via its reference and the new created effect added.

```
    RenderNode* rn = Dynamic_Cast<RenderNode*>(m_nodeToChange);
    if (rn == 0) {
        return;
    }

    static_cast<void>(rn->Unload());

    //remove old effect
    Effect2D* oldEffect = rn->GetEffect(0);
    static_cast<void>(rn->RemoveEffect(oldEffect));

    //add new effect
    static_cast<void>(rn->AddEffect(effect));
    static_cast<void>(rn->Upload());
```

##### <a class="anchor" id="bkmrk--226"></a>Creating a Bitmap Effect

Creating a <span style="color: rgb(230, 126, 35);">[Candera::BitmapBrushBlend](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_bitmap_brush_blend.html "This effect outputs a bitmap image, and blend it with the store buffer. Same as chaining (BitmapBrush...")</span> effect is similar to creating other effects (see <span style="color: rgb(230, 126, 35);">[Creating a Color Effect](#bkmrk-creating-a-color-eff)</span>). Just apply other properties.

```
        <a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_feat_std_1_1_memory_management_1_1_shared_pointer.html" title="An intrusive reference-counting smart pointer. If you want your class to be managed by SharedPointer ...">Candera::MemoryManagement::SharedPointer<Candera::BitmapBrushBlend></a> brush = <a class="code" href="http://dev.doc.cgistudio.at/APILINK/group___c_o_u_r_i_e_r___v_i_s_u_a_l_i_z_a_t_i_o_n.html#ggaf0e93dc4242f607c3c8d13dafd036af9aaabfa5309af24986d3111a092449f857">Candera::BitmapBrushBlend::Create</a>();
        Bitmap::SharedPointer bitmap = Base::GetAssetProvider()->GetBitmapById(CgiAssetNames::cosmosbgBmp);
        if (m_image != 0) {
            static_cast<void>(m_image->SetBitmap(bitmap));
        }
        brush.<a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_feat_std_1_1_memory_management_1_1_shared_pointer.html#a5f3988146f96e93069657ec84a969c40">GetSharedInstance</a>().<a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_bitmap_brush_blend.html#ae26ca8fce23a9566c2f291c969ec6697">GetBitmapBrush</a>().Image().Set(m_image);
        brush.<a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_feat_std_1_1_memory_management_1_1_shared_pointer.html#a5f3988146f96e93069657ec84a969c40">GetSharedInstance</a>().<a class="code" href="http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_bitmap_brush_blend.html#a0c3cc14496925e1b90a91f241e382c04">GetBlendEffect</a>().SetBlendMode(RenderDevice2D::SourceAlpha, RenderDevice2D::InverseSourceAlpha, RenderDevice2D::Add);
```

<div class="contents" id="bkmrk-in-scenecomposer-the-4"><div class="textblock"><div class="fragment">  
</div><dl class="note"><dt>  
</dt><dd><p class="callout info">In SceneComposer the manipulated scene graph and the changed properties do not appear because it is only changed dynamically by the widget.</p>

<p class="callout info">The widget must control memory and VRAM management of its internal dynamic subtree autonomously.</p>

<p class="callout info">Don't forget to set a name for the dynamically created nodes.</p>

</dd></dl></div></div>#### **Cloning 2D Nodes** 

Cloning 2D nodes is equivalent to cloning of 3D nodes. In accordance to Tree Cloning Strategies, the following support is provided for deep cloning:

<div class="contents" id="bkmrk-candera%3A%3Atreecloner2"><div class="contents"><div class="textblock">- <span style="color: rgb(230, 126, 35);">[Candera::TreeCloner2D](http://dev.doc.cgistudio.at/APILINK/group___cloning2_d.html#ga3422d4b6927060f781728ced9fa020fa "Specialization of TreeClonerBase for use with Node2D.")</span> is a specialization for the 2D scene tree of<span style="color: rgb(230, 126, 35);"> [Candera::TreeClonerBase](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_tree_cloner_base.html "This class clones scene subtrees.").</span>
- <span style="color: rgb(230, 126, 35);">[Candera::DeepNode2DCloneStrategy](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_deep_node2_d_clone_strategy.html "This is the default clone strategy for deep cloning.")</span> provides a generic node strategy that clones the delegates the cloning of derived Nodes to specialized strategies.
- <span style="color: rgb(230, 126, 35);">[Candera::DeepCompositeGroup2DCloneStrategy](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_deep_composite_group2_d_clone_strategy.html "This is the default clone strategy for deep cloning composite groups. See DeepNode2DCloneStrategy for...") </span>resolves node binding by use of <span style="color: rgb(230, 126, 35);">[Candera::TreeMatch2D](http://dev.doc.cgistudio.at/APILINK/group___cloning2_d.html#ga47d53fd45a19ef3060e551d576bb8245 "Specialization of TreeMatchBase for use with Node2D.")</span>.
- <span style="color: rgb(230, 126, 35);">[Candera::DeepRenderNodeCloneStrategy](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_deep_render_node_clone_strategy.html "This is the default clone strategy for deep cloning render nodes. See DeepNode2DCloneStrategy for rul...") </span>resolves the sharing of effects by use of a map.
- <span style="color: rgb(230, 126, 35);">[Candera::DeepTreeCloner2D](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_deep_tree_cloner2_d.html "This class creates deep clones scene subtrees.")</span> is a wrapper of <span style="color: rgb(230, 126, 35);">[Candera::DeepNode2DCloneStrategy](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_deep_node2_d_clone_strategy.html "This is the default clone strategy for deep cloning.")</span> that provides an interface similar to <span style="color: rgb(230, 126, 35);">[Candera::TreeCloner2D](http://dev.doc.cgistudio.at/APILINK/group___cloning2_d.html#ga3422d4b6927060f781728ced9fa020fa "Specialization of TreeClonerBase for use with Node2D.").</span>

</div></div></div>Refer to

<div class="contents" id="bkmrk-candera%3A%3Anode2d%3A%3Aclo"><div class="contents"><div class="textblock">- <span style="color: rgb(230, 126, 35);">[Candera::Node2D::Clone](http://dev.doc.cgistudio.at/APILINK/class_candera_1_1_node2_d.html#aabc132c0ed42fc91e2491eadbb69eff4)</span>

</div></div></div>as well as the example for cloning 3D nodes:

<div class="contents" id="bkmrk-cloning-3d-nodes"><div class="textblock">- <span style="color: rgb(230, 126, 35);">[Cloning 3D Nodes](https://doc316en.candera.eu/link/449#bkmrk-cloning-3d-nodes%C2%A0)</span>

</div></div>