Condividi tramite


Come applicare trasformazioni 2D

Nota

Per le app in Windows 10, è consigliabile usare le API Windows.UI.Composition anziché DirectComposition. Per altre informazioni, vedere Modernizzare l'app desktop usando il livello visuale.

Questo argomento illustra 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'oggetto visivo di 180 gradi.
  2. Aumentare l'oggetto visivo fino a tre volte le dimensioni originali.
  3. Tradurre (spostare) l'oggetto visivo 150 pixel a destra della posizione originale.

Le schermate seguenti mostrano l'oggetto visivo prima e dopo aver applicato le trasformazioni 2D.

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

Informazioni importanti

Tecnologie

Prerequisiti

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

Istruzioni

Passaggio 1: Inizializzare oggetti DirectComposition

  1. Creare l'oggetto device e l'oggetto di destinazione della composizione.
  2. Creare un oggetto visivo, impostarne il contenuto e aggiungerlo all'albero visivo.

Per altre informazioni, vedere Come inizializzare DirectComposition.

Passaggio 2: Creare la matrice di gruppi di trasformazione

IDCompositionTransform *pTransforms[3];

Passaggio 3: Creare gli oggetti di trasformazione, impostare le proprietà e aggiungerle alla matrice di gruppi di trasformazione

  1. Usare i metodi IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform e ::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 trasformazioni

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: Eseguire il commit della composizione

Chiamare il metodo IDCompositionDevice::Commit per eseguire il commit degli aggiornamenti all'oggetto visivo in DirectComposition per l'elaborazione. 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 viene chiamata 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]);
}

Ricorda anche di liberare l'oggetto dispositivo, l'oggetto target di 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;
}

Trasformazioni