Partager via


Comment appliquer des transformations 2D

Notes

Pour les applications sur Windows 10, nous vous recommandons d’utiliser les API Windows.UI.Composition au lieu de DirectComposition. Pour plus d’informations, consultez Moderniser votre application de bureau à l’aide de la couche visuelle.

Cette rubrique montre comment appliquer des transformations 2D à un visuel à l’aide de Microsoft DirectComposition. L’exemple de cette rubrique applique un groupe de transformations qui :

  1. Faites pivoter le visuel de 180 degrés.
  2. Effectuez un scale-up du visuel à trois fois sa taille d’origine.
  3. Traduire (déplacer) le visuel de 150 pixels à droite de sa position d’origine.

Les captures d’écran suivantes montrent le visuel avant et après l’application des transformations 2D.

résultat de l’application d’un groupe de transformations 2d à un visuel

Bon à savoir

Technologies

Prérequis

  • C/C++
  • Microsoft Win32
  • COM (Component Object Model)

Instructions

Étape 1 : Initialiser les objets DirectComposition

  1. Créez l’objet d’appareil et l’objet cible de composition.
  2. Créez un visuel, définissez son contenu et ajoutez-le à l’arborescence du visuel.

Pour plus d’informations, consultez Guide pratique pour initialiser DirectComposition.

Étape 2 : Créer le tableau de groupes de transformations

IDCompositionTransform *pTransforms[3];

Étape 3 : Créer les objets de transformation, définir leurs propriétés et les ajouter au tableau de groupes de transformations

  1. Utilisez les méthodes IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform et ::CreateTranslateTransform pour créer les objets de transformation.
  2. Utilisez les fonctions membres des interfaces IDCompositionRotateTransform, IDCompositionScaleTransform et IDCompositionTranslateTransform pour définir les propriétés des transformations.
  3. Copiez les pointeurs d’interface de transformation dans le tableau de groupes de transformations.
IDCompositionRotateTransform *pRotateTransform = nullptr;
IDCompositionScaleTransform *pScaleTransform = nullptr;
IDCompositionTranslateTransform *pTranslateTransform = nullptr;
IDCompositionTransform *pTransformGroup = nullptr;

// Create the rotate transform.
hr = pDevice->CreateRotateTransform(&pRotateTransform);

if (SUCCEEDED(hr))
{
    // Set the center of rotation to the center point of the visual.
    hr = pRotateTransform->SetCenterX(BITMAP_WIDTH/2.0f);
    
    if (SUCCEEDED(hr)) {
        hr = pRotateTransform->SetCenterY(BITMAP_HEIGHT/2.0f);
    }

    // Set the rotate angle to 180 degrees.
    if (SUCCEEDED(hr)) {
        hr = pRotateTransform->SetAngle(180.0f);
    }

    // Add the rotate transform to the transform group array.
    pTransforms[0] = pRotateTransform;

    // Create the scale transform.
    if (SUCCEEDED(hr)) {
        hr = pDevice->CreateScaleTransform(&pScaleTransform);
    }
}

if (SUCCEEDED(hr))
{
    // Set the scaling origin to the upper-right corner of the visual.
    hr = pScaleTransform->SetCenterX(0.0f);
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetCenterY(0.0f);
    }

    // Set the scaling factor to three for both the width and height. 
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetScaleX(3.0f);
    }
    if (SUCCEEDED(hr)) {
        hr = pScaleTransform->SetScaleY(3.0f);
    }

    // Add the scale transform to the transform group array.
    pTransforms[1] = pScaleTransform;

    // Create the translate transform.
    if (SUCCEEDED(hr)) {
        hr = pDevice->CreateTranslateTransform(&pTranslateTransform);
    }
}

if (SUCCEEDED(hr))
{
    // Move the visual 150 pixels to the right.
    hr = pTranslateTransform->SetOffsetX(150.0f);
    if (SUCCEEDED(hr)) {
        hr = pTranslateTransform->SetOffsetY(0.0f);
    }

    // Add the translate transform to the transform group array.
    pTransforms[2] = pTranslateTransform;
}

Étape 4 : Créer l’objet de groupe de transformation

Appelez la méthode IDCompositionDevice::CreateTransformGroup pour créer l’objet de groupe de transformation.

if (SUCCEEDED(hr))
{
    // Create the transform group.
    hr = pDevice->CreateTransformGroup(pTransforms, 3, &pTransformGroup);
}

Étape 5 : Appliquer l’objet de groupe de transformation au visuel

Utilisez la méthode IDCompositionVisual::SetTransform pour associer la propriété Transform du visuel à l’objet de groupe de transformation.

if (SUCCEEDED(hr))
{
    // Apply the transform group to the visual.
    hr = pVisual->SetTransform(pTransformGroup);
}

Étape 6 : Valider la composition

Appelez la méthode IDCompositionDevice::Commit pour valider les mises à jour du visuel dans DirectComposition en vue de leur traitement. Le résultat de l’application du groupe de transformations 2D s’affiche dans la fenêtre cible.

if (SUCCEEDED(hr))
{
    // Commit the composition.
    hr = pDevice->Commit();
}

Étape 7 : Libérer les objets DirectComposition

Veillez à libérer le groupe d’objets de transformation 2D lorsque vous n’en avez plus besoin. L’exemple suivant appelle la macro SafeRelease définie par l’application pour libérer les objets de transformation.

// Release the transform objects.
for (int i = 0; i < 3; i++)
{
    SafeRelease(&pTransforms[i]);
}

Pensez également à libérer l’objet appareil, l’objet cible de composition et les visuels avant la fermeture de votre application.

Exemple complet

#define BITMAP_WIDTH  80.0
#define BITMAP_HEIGHT 80.0

HRESULT DemoApp::ApplyTransformGroup(IDCompositionDevice *pDevice, 
                                     IDCompositionVisual *pVisual)
{
    HRESULT hr = S_OK;

    if (pDevice == nullptr || pVisual == nullptr)
        return E_INVALIDARG; 
    
    IDCompositionTransform *pTransforms[3];

    IDCompositionRotateTransform *pRotateTransform = nullptr;
    IDCompositionScaleTransform *pScaleTransform = nullptr;
    IDCompositionTranslateTransform *pTranslateTransform = nullptr;
    IDCompositionTransform *pTransformGroup = nullptr;

    // Create the rotate transform.
    hr = pDevice->CreateRotateTransform(&pRotateTransform);

    if (SUCCEEDED(hr))
    {
        // Set the center of rotation to the center point of the visual.
        hr = pRotateTransform->SetCenterX(BITMAP_WIDTH/2.0f);
        
        if (SUCCEEDED(hr)) {
            hr = pRotateTransform->SetCenterY(BITMAP_HEIGHT/2.0f);
        }

        // Set the rotate angle to 180 degrees.
        if (SUCCEEDED(hr)) {
            hr = pRotateTransform->SetAngle(180.0f);
        }

        // Add the rotate transform to the transform group array.
        pTransforms[0] = pRotateTransform;

        // Create the scale transform.
        if (SUCCEEDED(hr)) {
            hr = pDevice->CreateScaleTransform(&pScaleTransform);
        }
    }

    if (SUCCEEDED(hr))
    {
        // Set the scaling origin to the upper-right corner of the visual.
        hr = pScaleTransform->SetCenterX(0.0f);
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetCenterY(0.0f);
        }

        // Set the scaling factor to three for both the width and height. 
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetScaleX(3.0f);
        }
        if (SUCCEEDED(hr)) {
            hr = pScaleTransform->SetScaleY(3.0f);
        }

        // Add the scale transform to the transform group array.
        pTransforms[1] = pScaleTransform;

        // Create the translate transform.
        if (SUCCEEDED(hr)) {
            hr = pDevice->CreateTranslateTransform(&pTranslateTransform);
        }
    }

    if (SUCCEEDED(hr))
    {
        // Move the visual 150 pixels to the right.
        hr = pTranslateTransform->SetOffsetX(150.0f);
        if (SUCCEEDED(hr)) {
            hr = pTranslateTransform->SetOffsetY(0.0f);
        }

        // Add the translate transform to the transform group array.
        pTransforms[2] = pTranslateTransform;
    }

    if (SUCCEEDED(hr))
    {
        // Create the transform group.
        hr = pDevice->CreateTransformGroup(pTransforms, 3, &pTransformGroup);
    }

    if (SUCCEEDED(hr))
    {
        // Apply the transform group to the visual.
        hr = pVisual->SetTransform(pTransformGroup);
    }

    if (SUCCEEDED(hr))
    {
        // Commit the composition.
        hr = pDevice->Commit();
    }

    // Release the transform objects.
    for (int i = 0; i < 3; i++)
    {
        SafeRelease(&pTransforms[i]);
    }

    // Release the transform group pointer.
    SafeRelease(&pTransformGroup);

    return hr;
}

Transformations