Condividi tramite


Come applicare trasformazioni 2D

Nota

Per le app in Windows 10, ti consigliamo di usare le API Windows.UI.Composition anziché DirectComposition. Per ulteriori informazioni, vedi Modernizza l'app desktop usando il layer visivo.

In questo argomento viene illustrato come applicare trasformazioni 2D a un oggetto visivo usando Microsoft DirectComposition. L'esempio in questo argomento applica un gruppo di trasformazioni che:

  1. Ruotare l'immagine di 180 gradi.
  2. Aumentare le dimensioni dell'oggetto visivo fino a tre volte la dimensione originale.
  3. Sposta l'oggetto visivo di 150 pixel a destra rispetto alla posizione originale.

Le schermate seguenti mostrano l'oggetto visivo prima e dopo l'applicazione delle trasformazioni 2D.

risultato dell'applicazione di un gruppo di trasformazioni 2d a un oggetto visivo

Cosa è necessario sapere

Tecnologie

Prerequisiti

  • C/C++
  • Microsoft Win32
  • Modello a Oggetti Componenti (Component Object Model - COM)

Disposizioni

Passaggio 1: Inizializzare oggetti DirectComposition

  1. Creare l'oggetto dispositivo e l'oggetto di destinazione della composizione.
  2. Creare un oggetto visivo, impostarne il contenuto e aggiungerlo alla struttura ad albero visuale.

Per altre informazioni, vedere Come inizializzare DirectComposition.

Passaggio 2: Creare la matrice di gruppi di trasformazione

IDCompositionTransform *pTransforms[3];

Passaggio 3: Creare gli oggetti transform, impostarne le proprietà e aggiungerli alla matrice di gruppi di trasformazione

  1. Usare i metodi IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransforme ::CreateTranslateTransform per creare gli oggetti di trasformazione.
  2. Usare le funzioni membro delle interfacce IDCompositionRotateTransform, IDCompositionScaleTransform, e IDCompositionTranslateTransform per impostare le proprietà delle trasformazioni.
  3. Copiare i puntatori dell'interfaccia di trasformazione nella matrice di gruppi di trasformazione.
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;
}

Passaggio 4: Creare l'oggetto gruppo di trasformazione

Chiamare il metodo IDCompositionDevice::CreateTransformGroup per creare l'oggetto gruppo di trasformazione.

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

Passaggio 5: Applicare l'oggetto gruppo di trasformazione all'oggetto visivo

Utilizzare il metodo IDCompositionVisual::SetTransform per associare la proprietà Transform dell'oggetto visivo all'oggetto gruppo di trasformazione.

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

Passaggio 6: Confermare la composizione

Chiamare il metodo IDCompositionDevice::Commit per applicare gli aggiornamenti al livello visivo in modo che possano essere elaborati da DirectComposition. Il risultato dell'applicazione del gruppo di trasformazioni 2D viene visualizzato nella finestra di destinazione.

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

Passaggio 7: Liberare gli oggetti DirectComposition

Assicurarsi di liberare il gruppo di oggetti di trasformazione 2D quando non sono più necessari. Nell'esempio seguente, si utilizza la macro SafeRelease definita dall'applicazione per liberare gli oggetti di trasformazione.

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

Ricordarsi anche di liberare l'oggetto dispositivo, l'oggetto di destinazione della composizione e gli oggetti visivi prima che l'applicazione venga chiusa.

Esempio completo

#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;
}

Trasforma