2D 변환을 적용하는 방법
참고
Windows 10 앱의 경우 DirectComposition 대신 Windows.UI.Composition API를 사용하는 것이 좋습니다. 자세한 내용은 시각적 계층을 사용하여 데스크톱 앱 현대화를 참조하세요.
이 항목에서는 Microsoft DirectComposition을 사용하여 시각적 개체에 2D 변환을 적용하는 방법을 보여 줍니다. 이 항목의 예제에서는 다음과 같은 변환 그룹을 적용합니다.
- 시각적 개체를 180도 회전합니다.
- 시각적 개체를 원래 크기의 3배로 확장합니다.
- 시각적 개체를 원래 위치의 오른쪽으로 150픽셀 변환(이동)합니다.
다음 스크린샷은 2D 변환을 적용하기 전과 후에 시각적 개체를 보여 줍니다.
알아야 하는 작업
기술
필수 구성 요소
- C/C++
- Microsoft Win32
- COM(구성 요소 개체 모델)
지침
1단계: DirectComposition 개체 초기화
- 디바이스 개체 및 컴퍼지션 대상 개체를 만듭니다.
- 시각적 개체를 만들고, 콘텐츠를 설정하고, 시각적 트리에 추가합니다.
자세한 내용은 DirectComposition을 초기화하는 방법을 참조하세요.
2단계: 변환 그룹 배열 만들기
IDCompositionTransform *pTransforms[3];
3단계: 변환 개체 만들기, 해당 속성 설정 및 변환 그룹 배열에 추가
- IDCompositionDevice::CreateRotateTransform, ::CreateScaleTransform 및 ::CreateTranslateTransform 메서드를 사용하여 변환 개체를 만듭니다.
- IDCompositionRotateTransform, IDCompositionScaleTransform 및 IDCompositionTranslateTransform 인터페이스의 멤버 함수를 사용하여 변환의 속성을 설정합니다.
- 변환 인터페이스 포인터를 변환 그룹 배열에 복사합니다.
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;
}
관련 항목