다음을 통해 공유


2D 변환을 적용하는 방법

참고

Windows 10 앱의 경우 DirectComposition 대신 Windows.UI.Composition API를 사용하는 것이 좋습니다. 자세한 내용은 시각적 계층을 사용하여 데스크톱 앱 현대화를 참조하세요.

이 항목에서는 Microsoft DirectComposition을 사용하여 시각적 개체에 2D 변환을 적용하는 방법을 보여 줍니다. 이 항목의 예제에서는 다음과 같은 변환 그룹을 적용합니다.

  1. 시각적 개체를 180도 회전합니다.
  2. 시각적 개체를 원래 크기의 3배로 확장합니다.
  3. 시각적 개체를 원래 위치의 오른쪽으로 150픽셀 변환(이동)합니다.

다음 스크린샷은 2D 변환을 적용하기 전과 후에 시각적 개체를 보여 줍니다.

시각적 개체에 2d 변환 그룹을 적용한 결과

알아야 하는 작업

기술

필수 구성 요소

  • C/C++
  • Microsoft Win32
  • COM(구성 요소 개체 모델)

지침

1단계: DirectComposition 개체 초기화

  1. 디바이스 개체 및 컴퍼지션 대상 개체를 만듭니다.
  2. 시각적 개체를 만들고, 콘텐츠를 설정하고, 시각적 트리에 추가합니다.

자세한 내용은 DirectComposition을 초기화하는 방법을 참조하세요.

2단계: 변환 그룹 배열 만들기

IDCompositionTransform *pTransforms[3];

3단계: 변환 개체 만들기, 해당 속성 설정 및 변환 그룹 배열에 추가

  1. IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform::CreateTranslateTransform 메서드를 사용하여 변환 개체를 만듭니다.
  2. IDCompositionRotateTransform, IDCompositionScaleTransformIDCompositionTranslateTransform 인터페이스의 멤버 함수를 사용하여 변환의 속성을 설정합니다.
  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;
}

4단계: 변환 그룹 개체 만들기

IDCompositionDevice::CreateTransformGroup 메서드를 호출하여 변환 그룹 개체를 만듭니다.

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

5단계: 시각적 개체에 변환 그룹 개체 적용

IDCompositionVisual::SetTransform 메서드를 사용하여 시각적 개체의 Transform 속성을 변환 그룹 개체와 연결합니다.

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

6단계: 컴퍼지션 커밋

IDCompositionDevice::Commit 메서드를 호출하여 처리를 위해 시각적 개체에 대한 업데이트를 DirectComposition으로 커밋합니다. 2D 변환 그룹을 적용한 결과가 대상 창에 표시됩니다.

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

7단계: DirectComposition 개체 해제

더 이상 필요하지 않은 경우 2D 변환 개체 그룹을 해제해야 합니다. 다음 예제에서는 애플리케이션 정의 SafeRelease 매크로를 호출하여 변환 개체를 해제합니다.

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

또한 애플리케이션이 종료되기 전에 디바이스 개체, 컴퍼지션 대상 개체 및 시각적 개체를 해제해야 합니다.

전체 예제

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

변형