F.R.I.D.A.Y.

Direct2D - SetTransform 본문

DEV/Direct2D

Direct2D - SetTransform

F.R.I.D.A.Y. 2021. 5. 5. 22:50
반응형

 Direct2D에서 그래픽 변형을 가할 수 있는 SetTransform 메서드


그래픽 변형

 그래픽 변형이라 함은 아래의 것들이 있습니다.

  • 크기 조절
  • 회전
  • 반전
  • 이동

 이러한 항목들은 WIC 컴포넌트에서도 구현할 수 있지만, 그 속도가 느립니다. 만일 그리기 위한 그래픽 변형을 한다면 Direct2D에서 제공하는 SetTransform 메서드를 이용하는 것이 좋습니다.

 

SetTransform

 SetTransform 메서드는 그래픽 변형을 가하는 메서드로서, 두 개의 오버로드가 존재합니다. 여기에서는 레퍼런스 참조를 통한 메서드를 기본으로 합니다.[# 레퍼런스 참조를 하는 메서드는 아마도 어드레스 참조를 하는 메서드를 이용해 구현했겠죠.]

 

메서드 원형

void SetTransform(
  const D2D1_MATRIX_3X2_F & transform
);

 void 타입이며, 인자는 하나를 가지고 있습니다. 이 인자를 이용해 대상에 변형을 가할 수 있습니다.

 

 

Matrix

 SetTransform에서 사용하는 변형은 행렬을 사용합니다. 다만 행렬에 대한 이해를 할 필요는 없는데, 이는 Direct2D에서 변형에 필요한 행렬 정보를 생성할 수 있기 때문입니다.

 

Rotation

 회전 정보를 가지고 있는 행렬을 만들 수 있습니다.

float r = 90.f;
pRT->SetTransform(D2D1::Matrix3x2F::Rotation(r, D2D1::Point2F(centerX, centerY)));

 값 r만큼 그리기 영역이 회전합니다. 이 내용은 다음 변형이 가해질 때까지 그대로 유지됩니다. 두 번째 인자는 회전의 중심점이며, 그 점을 중심으로 대상이 회전합니다.

 

Scale

pRT->SetTransform(D2D1::Matrix3x2F::Scale(0.5,0.5, D2D1::Point2F(centerX, centerY)));

 기존 크기 대비 절반만큼 크기가 줄어듭니다. 두 번째 인자를 기준으로 크기가 늘거나 줄어듭니다. 만일 (0, 0)을 기준으로 늘리면 좌측과 상단은 고정된 채로 우측과 하단으로 크기가 늘어나는 방식입니다.

 

Skew

pRT->SetTransform(D2D1::Matrix3x2F::Skew(45, 0, D2D1::Point2F(centerX, centerY)));

 이미지에 기울임을 적용할 수 있습니다. 첫 번째 인자와 두 번째 인자는 각각 x축과 y축으로 얼마나 기울일 것인지를, 세 번째 인자는 어떤 점을 중심으로 기울일 것인지를 전달합니다.

 

 

여러 변형 적용 : 행렬곱

 이러한 변형은 따로, 또 함께 사용할 수 있습니다. D2D1::Matrix3x2F의 내부 메서드를 보면 operator*()이라는 메서드가 존재합니다. 행렬 곱을 할 수 있도록 자체적으로 지원합니다. 행렬 곱을 행하는 가장 큰 이유는, 변형의 동시 적용을 위함입니다.

 

 다음은 이미지의 크기를 50%만큼 줄이고, 기울임 효과를 준 것입니다.

 가운데 변형된 이미지가 안내한 변형을 적용한 것이며, 뒤쪽의 배경 이미지가 변형을 가하기 전의 이미지입니다. 이러한 변형을 한꺼번에 적용하기 위해서는 행렬 곱을 이용해 두 변형을 위한 행렬을 연산을 거쳐 하나의 행렬로 만들어야합니다.

 

 다음은 위 이미지를 출력하기 위해 작성한 코드의 일부입니다.

		pRT->SetTransform(D2D1::IdentityMatrix());
		pRT->DrawBitmap(pMainBitmap, D2D1::RectF(0,0,rc.right, rc.bottom));
		pRT->SetTransform(D2D1::Matrix3x2F::Scale(0.5, 0.5, D2D1::Point2F((rc.right + rc.left) / 2, (rc.bottom + rc.top) / 2))
			* D2D1::Matrix3x2F::Skew(45, 0, D2D1::Point2F((rc.right + rc.left) / 2, (rc.bottom + rc.top) / 2))
		);
		pRT->DrawBitmap(pMainBitmap, D2D1::RectF(0,0,rc.right, rc.bottom));

 

자세히 보면 세 번째 줄의 코드에 * 기호를 통해 행렬 곱을 행한 것을 알 수 있습니다. 이러한 정보와 약간의 C/C++ 지식을 통해 아래와 같이 회전하는 이미지를 출력할 수도 있습니다.

 

기본 매트릭스

 SetTransform 메서드를 통해 렌더링 영역에 변형을 가하면 다음 변형이 들어오기 전까지 그 변형이 유지됩니다. 따라서 변형을 풀기 위해서는 기본이 되는 행렬이 있어야합니다. 이 기본이 되는 행렬 또한 Direct2D에서 기본적으로 제공합니다.

D2D1::IdentityMatrix();

 이 메서드를 호출하면 기본이 되는 행렬식을 반환합니다. 위 <여러 변형 적용>에서 제공한 코드의 첫 라인이 IdentityMatrix()를 이용해 변형을 초기화하고 있습니다. 따라서 처음 그릴 때는 변형되지 않은 이미지를 출력하고, 두 번째 출력에서는 변형된 이미지가 출력됩니다.

 

# index

728x90
반응형

'DEV > Direct2D' 카테고리의 다른 글

물리엔진 - 중력 구현 안정화  (0) 2021.05.10
물리엔진 - 중력 구현  (0) 2021.05.10
Direct2D - WIC IWICBitmapFlipRotator  (0) 2021.05.04
Direct2D - WIC IWICBitmapClipper  (0) 2021.05.01
Direct2D - WIC IWICFormatConverter  (0) 2021.04.29
Comments