일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- VS ERROR
- 김성엽
- Kotlin
- doit코틀린프로그래밍
- Programming
- Win32
- 프로그래밍
- 연산자
- 백준
- 포인터
- 문법
- Javascript
- Tips프로그래밍강좌
- Windows
- tipssoft
- 배열
- c#
- 알고리즘
- Desktop
- 이지스퍼블리싱
- CS
- Visual Studio
- c++
- 리뷰
- 티스토리
- Direct2D
- 함수
- 지식나눔강좌
- c
- Tips강좌
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
Direct2D - SetTransform 본문
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
'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 |