在 Kanzi Engine API 中使用效果

您可以使用 Kanzi Engine API 为 2D 节点创建效果。

将效果分配给节点

要创建效果:

// An effect that is assigned to a 2D node is an effect prefab.
// Before you can construct an effect prefab, you must create an effect template.
// This example creates an effect template for the ShadowEffect2D effect prefab.
NodeEffectTemplate2DSharedPtr shadowEffectTemplate =
    NodeEffectTemplate2D::create(ShadowEffect2D::getStaticMetaclass()->getName(), "DropShadow");

// Create a node effect prefab from the effect template.
NodeEffectPrefab2DSharedPtr shadowEffectPrefab =
    NodeEffectPrefab2D::create(getDomain(), "DropShadow prefab", shadowEffectTemplate);

要设置 2D 节点以使用效果:

// To assign an effect prefab to a 2D node, set the Node2D::EffectPrefabProperty.
node2d->setProperty(Node2D::EffectPrefabProperty, shadowEffectPrefab);
// To assign an effect prefab to a 2D node, call the Node2D::setEffectPrefab method.
node2d->setEffectPrefab(shadowEffectPrefab);

要禁用效果:

// Enable an effect on a 2D node by assigning an effect prefab.
node2d->setEffectPrefab(shadowEffectPrefab);
// Disable an effect by assigning a nullptr or an empty shared pointer.
node2d->setEffectPrefab(nullptr);

要将多个 2D 节点设置为使用相同的效果:

// Create an effect template.
NodeEffectTemplate2DSharedPtr shadowEffectTemplate =
    NodeEffectTemplate2D::create(ShadowEffect2D::getStaticMetaclass()->getName(), "DropShadow");

// Create an effect prefab from the effect template.
NodeEffectPrefab2DSharedPtr shadowEffectPrefab =
    NodeEffectPrefab2D::create(getDomain(), "DropShadow prefab", shadowEffectTemplate);

// Set two nodes to use the same effect prefab. The nodes create separate instances
// of NodeEffect2D but share the same NodeEffectPrefab2D instance.
node1->setEffectPrefab(shadowEffectPrefab);
node2->setEffectPrefab(shadowEffectPrefab);

创建模糊效果

使用 Blur Effect 2D 效果对二维节点应用高斯模糊。

要使用 Kanzi Engine API 为 2D 节点创建模糊效果:

// Create a blur effect template.
NodeEffectTemplate2DSharedPtr blurEffectTemplate =
    NodeEffectTemplate2D::create(BlurEffect2D::getStaticMetaclass()->getName(), "BlurEffect");

// Set the value of the RadiusProperty in the blur effect template.
// RadiusProperty defines the amount of blur.
blurEffectTemplate->addPropertyValue(BlurEffect2D::RadiusProperty, Variant(6.f));

// Create a blur effect prefab.
NodeEffectPrefab2DSharedPtr blurEffectPrefab =
    NodeEffectPrefab2D::create(getDomain(), "BlurEffect prefab", blurEffectTemplate);

// Assign the blur effect to a 2D node.
node2d->setEffectPrefab(blurEffectPrefab);

// Get the node-specific effect instance created from the assigned prefab.
BlurEffect2DSharedPtr blurEffect = dynamic_pointer_cast<BlurEffect2D>(node2d->getEffect());

// Set the MaskedProperty to true. Masked mode maintains the original alpha channel and
// prevents the blur from spreading to fully transparent pixels.
blurEffect->setMasked(true);

有关详细信息,请参阅 BlurEffect2D 类。

创建遮罩效果

使用 Mask Effect 2D 效果将遮罩应用于 2D 节点。

要使用 Kanzi Engine API 为 2D 节点创建遮罩效果:

// Create an effect template.
NodeEffectTemplate2DSharedPtr maskEffectTemplate =
    NodeEffectTemplate2D::create(MaskEffect2D::getStaticMetaclass()->getName(), "MaskEffect");

// Set the value of the MaskProperty in the template.
// The MaskProperty defines the mask texture which you must set before you can use the mask effect.
TextureSharedPtr maskTexture = acquireMaskTexture(getDomain());
maskEffectTemplate->addPropertyValue(MaskEffect2D::MaskProperty, Variant(maskTexture));

// Create a mask effect prefab.
NodeEffectPrefab2DSharedPtr maskEffectPrefab =
    NodeEffectPrefab2D::create(getDomain(), "MaskEffect prefab", maskEffectTemplate);

// Assign the mask effect to a 2D node.
node2d->setEffectPrefab(maskEffectPrefab);

// Get the node-specific effect instance created from the assigned prefab.
MaskEffect2DSharedPtr maskEffect = dynamic_pointer_cast<MaskEffect2D>(node2d->getEffect());

// Set the mask stretch mode to uniform.
maskEffect->setStretch(MaskEffect2D::Stretch::Uniform);

有关详细信息,请参阅 MaskEffect2D 类。

创建轮廓效果

使用 Outline Effect 2D 效果为 2D 节点的内容应用轮廓。

使用 Kanzi Engine API 为 2D 节点创建轮廓效果:

// Create an outline effect template.
NodeEffectTemplate2DSharedPtr outlineEffectTemplate =
    NodeEffectTemplate2D::create(OutlineEffect2D::getStaticMetaclass()->getName(), "OutlineEffect");

// Set the value of the WidthProperty in the outline effect template.
// The WidthProperty defines the maximum width of the outline outside the content area.
outlineEffectTemplate->addPropertyValue(OutlineEffect2D::WidthProperty, Variant(8));

// Create an outline effect prefab.
NodeEffectPrefab2DSharedPtr outlineEffectPrefab =
    NodeEffectPrefab2D::create(getDomain(), "OutlineEffect prefab", outlineEffectTemplate);

// Assign the outline effect to a 2D node.
node2d->setEffectPrefab(outlineEffectPrefab);

// Get the node-specific effect instance created from the assigned prefab.
OutlineEffect2DSharedPtr outlineEffect = dynamic_pointer_cast<OutlineEffect2D>(node2d->getEffect());

// Set the SoftnessProperty to 0.7 for this node only. This overrides
// the property default value defined by the OutlineEffect2D metaclass.
outlineEffect->setSoftness(0.7f);

有关详细信息,请参阅 OutlineEffect2D 类。

创建阴影效果

使用 Shadow Effect 2D 效果为 2D 节点的内容应用阴影。

要使用 Kanzi Engine API 为 2D 节点创建阴影效果:

// Create an effect template.
NodeEffectTemplate2DSharedPtr shadowEffectTemplate =
    NodeEffectTemplate2D::create(ShadowEffect2D::getStaticMetaclass()->getName(), "DropShadow");

// Set the value of the AngleProperty in the template. This value serves as the default value
// of the property in instances of the effect prefab.
shadowEffectTemplate->addPropertyValue(ShadowEffect2D::AngleProperty, Variant(35.f));

// Create an effect prefab.
NodeEffectPrefab2DSharedPtr shadowEffectPrefab =
    NodeEffectPrefab2D::create(getDomain(), "DropShadow prefab", shadowEffectTemplate);

// Assign the effect to a 2D node.
node2d->setEffectPrefab(shadowEffectPrefab);

// Get the node-specific effect instance created from the assigned prefab.
ShadowEffect2DSharedPtr shadowEffect = dynamic_pointer_cast<ShadowEffect2D>(node2d->getEffect());

// Set the shadow distance to 15 pixels for this node only. This overrides
// the property default value defined by the ShadowEffect2D metaclass.
shadowEffect->setDistance(15.f);

// Set the direction of the shadow to 55 degrees relative to the positive x axis.
// This overrides the default value of 35 degrees set in the shadow effect template.
shadowEffect->setAngle(55.f);

有关详细信息,请参阅 ShadowEffect2D 类。

将多个效果分配给一个2D节点

要使用 Kanzi Engine API 为 2D 节点分配多个效果:

// Create an outline effect template.
NodeEffectTemplate2DSharedPtr outlineEffectTemplate =
    NodeEffectTemplate2D::create(OutlineEffect2D::getStaticMetaclass()->getName(), "OutlineEffect");

// Set the value of the WidthProperty in the outline effect template.
// The WidthProperty defines the maximum width of the outline outside the content area.
outlineEffectTemplate->addPropertyValue(OutlineEffect2D::WidthProperty, Variant(8));

// Create an effect stack template.
NodeEffectTemplate2DSharedPtr effectStackTemplate = NodeEffectTemplate2D::create(EffectStack2D::getStaticMetaclass()->getName(), "Group");

// Add the outline effect template to the effect stack template.
effectStackTemplate->addChild(outlineEffectTemplate);

// Create a shadow effect template and add it to the effect stack template.
effectStackTemplate->addChild(NodeEffectTemplate2D::create(ShadowEffect2D::getStaticMetaclass()->getName(), "DropShadow"));

// Create a prefab from the effect stack template.
NodeEffectPrefab2DSharedPtr effectStackPrefab =
    NodeEffectPrefab2D::create(getDomain(), "Effect Stack prefab", effectStackTemplate);

// Set a 2D node to use the effect stack prefab.
// This way, you apply to the node both the outline and the shadow effect.
node->setEffectPrefab(effectStackPrefab);

有关详细信息,请参阅 EffectStack2D 类。

使用绑定与效果

要使用绑定与效果:

// Create an outline effect template.
NodeEffectTemplate2DSharedPtr outlineEffectTemplate =
    NodeEffectTemplate2D::create(OutlineEffect2D::getStaticMetaclass()->getName(), "OutlineEffect");

// Create a shadow effect template.
NodeEffectTemplate2DSharedPtr shadowEffectTemplate =
    NodeEffectTemplate2D::create(ShadowEffect2D::getStaticMetaclass()->getName(), "DropShadow");

// Add to the shadow effect a binding that binds the shadow distance to a value in the root
// of the effect template.
shadowEffectTemplate->addBinding(BindingLoadInfo(Binding::create("##Template", ShadowEffect2D::DistanceProperty), ShadowEffect2D::DistanceProperty));

// Add to the host node a binding that binds the shadow distance value in the effect template root
// to the value in the node.
node->setBinding(
    ToSourceBinding::create(
        ObjectPropertyBindingSource::create(".", ShadowEffect2D::DistanceProperty),
        ObjectPropertyBindingSource::create(".Node2D.Effect", ShadowEffect2D::DistanceProperty)));

// Create an effect stack template
NodeEffectTemplate2DSharedPtr effectStackTemplate = NodeEffectTemplate2D::create(EffectStack2D::getStaticMetaclass()->getName(), "Group");

// Add the outline effect template to the effect stack template.
effectStackTemplate->addChild(outlineEffectTemplate);

// Add the shadow effect template to the effect stack template.
effectStackTemplate->addChild(shadowEffectTemplate);

// Create a prefab from the effect stack template.
NodeEffectPrefab2DSharedPtr effectStackPrefab =
    NodeEffectPrefab2D::create(getDomain(), "Effect Stack prefab", effectStackTemplate);

// Assign the effect stack to a 2D node.
node->setEffectPrefab(effectStackPrefab);

// In the host node, set the shadow distance.
node->setProperty(ShadowEffect2D::DistanceProperty, 20.f);

创建自定义效果

您可以使用 Kanzi Engine API 为 2D 节点创建自己的效果。

要使用 Kanzi Engine API 为 2D 节点创建自定义效果:

// To create an effect resource type, inherit a new class from NodeEffect2D
// and define a new associated metaclass. Each effect resource class must
// have an associated renderer class inherited from NodeEffectRenderer2D.

class EmptyEffectRenderer2D;
using EmptyEffectRenderer2DUniquePtr = unique_ptr<EmptyEffectRenderer2D>;

class EmptyEffect2D;
using EmptyEffect2DSharedPtr = shared_ptr<EmptyEffect2D>;

// EmptyEffect2D defines a new effect that defines no properties
// nor padding.
class EmptyEffect2D : public NodeEffect2D
{
public:
    KZ_METACLASS_BEGIN(EmptyEffect2D, NodeEffect2D, "Kanzi.EmptyEffect2D")
    KZ_METACLASS_END()

    // Create an instance of EmptyEffect2D.
    static EmptyEffect2DSharedPtr create(Domain* domain, string_view name)
    {
        return make_polymorphic_shared_ptr<Resource>(new EmptyEffect2D(domain, name));
    }

protected:
    // Constructor.
    explicit EmptyEffect2D(Domain* domain, string_view name) :
        NodeEffect2D(domain, name)
    {
    }

    // NodeEffect2D::createRendererOverride implementation.
    NodeEffectRenderer2DUniquePtr createRendererOverride() override;

    // NodeEffect2D::initializeRendererOverride implementation.
    void initializeRendererOverride() override
    {
    }
};

// EmptyEffectRenderer2D implements the rendering of the effect.
// Because this example effect does not render anything, Kanzi renders
// the original node as is.
class EmptyEffectRenderer2D : public NodeEffectRenderer2D
{
public:
    // Creates an instance of MinimalEffectRenderer2D. Never call this
    // function directly. Instead, use NodeEffect2D::createRenderer().
    static EmptyEffectRenderer2DUniquePtr create(EmptyEffect2DSharedPtr effect)
    {
        return unique_ptr<EmptyEffectRenderer2D>(new EmptyEffectRenderer2D(effect));
    }

private:
    // Constructor.
    explicit EmptyEffectRenderer2D(EmptyEffect2DSharedPtr effect) :
        NodeEffectRenderer2D(effect)
    {
    }

    // Implementation of NodeEffectRenderer2D::beginEffectOverride.
    void beginEffectOverride(Renderer& /*renderer*/, CompositionManager* /*compositionManager*/,
                             const Matrix3x3& /*worldTransform*/, const CompositionContentRequirements& /*requirements*/) override
    {
    }

    // Implementation of NodeEffectRenderer2D::endEffectOverride.
    void endEffectOverride(Renderer& /*renderer*/, CompositionManager* /*compositionManager*/) override
    {
    }

    // Implementation of NodeEffectRenderer2D::blitEffectOverride.
    void blitEffectOverride(Renderer& /*renderer*/, CompositionManager* /*compositionManager*/,
                            const QuadDescription& /*effectQuad*/, const Matrix3x3& /*transform*/, const Matrix4x4* /*perspectiveMatrix*/,
                            const Matrix4x4* /*projectionMatrix*/, int /*blendMode*/, bool /*needsClear*/) override
    {
    }

    // Implementation of NodeEffectRenderer2D::restoreResourcesOverride.
    virtual void restoreResourcesOverride() override
    {
    }
};

NodeEffectRenderer2DUniquePtr EmptyEffect2D::createRendererOverride()
{
    return EmptyEffectRenderer2D::create(static_pointer_cast<EmptyEffect2D>(shared_from_this()));
}

有关详细信息,请参阅 NodeEffect2D 类。

另请参阅

2D 节点的效果

使用 Blur Effect 2D 效果

使用 Mask Effect 2D 效果

使用 Outline Effect 2D 效果

使用 Shadow Effect 2D 效果