개인적으로 공부하는 내용이므로 틀린 부분이 있을 수 있습니다. 있다면 알려주세요 :)
행렬 변환
기하와 벡터 또는 선형대수학에서 배웠다면 행렬을 통한 도형 변환에 대해 배웠을 것이다. 예를 들면 다음 그림과 같이 다양한 동작을 수행하는 행렬을 곱하여 도형을 변환시킬 수 있다.
행렬의 장점은 편리함에 있다. 예를 들어 어떤 도형의 크기를 늘리고 회전시키고 싶다면 따로 따로 적용하는 것이 아니라 크기를 늘리는 행렬과 회전을 시키는 행렬을 서로 곱하여 하나의 행렬을 얻기만 하면 된다. 그리고 얻은 행렬을 원하는 점에 적용하면 크기와 회전 등이 알맞게 적용된다. Direct3D 에서는 이와 같은 행렬 변환을 지원한다. 최종적으로 변환이 완료된 행렬을 정점에 곱하면 변환된 정점을 얻을 수 있다.
변환 종류에는 크게 다음과 같은 것들이 있다.
- 이동 행렬(Translation matrix)
- 크기 행렬(Scale matrix)
- 회전 행렬(Rotation matrix)
이동 행렬은 말 그대로 이동이므로 위치를 변환해주는 행렬이다. 크기 행렬은 크기를 축소 및 확대시킨다. 회전은 말 그대로 회전시킨다.
공간은 3차원이지만 Direct3D에선 투영과 반사와 같은 기능을 위해 4x4 행렬을 이용한다. 정점(벡터)은 1x3인 (x,y,z) 이지만 4x4 행렬과의 곱 연산을 위해 1x4(x,y,z,1)를 사용한다. 예를 들어 x' = x + a를 나타내고 싶을 경우 1열만 사용하는 대신 (x) + (a) = (x+a)과 같이 행렬의 덧셈으로 표현 가능하다. 이를 곱셈으로 바꾸려고 시도해보면 하나의 요소가 더 필요하다는 것을 알게 될 것이다. (혹은 동차 좌표 검색) 또한 앞으로(Direct3D에서) 행렬의 곱은 (행)벡터 x 행렬 순으로 나타낸다.
D3DXMATRIX
Direct3D에선 다음과 같은 행렬 구조체를 지원한다. 아래 구조체는 D3DMATRIX인데, 이 클래스를 상속하여 연산자 오버로딩을 추가한 D3DXMATRIX도 존재한다. 주로 D3DXMATRIX를 사용한다. 아래와 같이 4x4 배열로 4x4 행렬을 표현한다.
이동 행렬(Translation matrix)
이동 행렬은 다음과 같이 점 또는 도형을 이동시키는 행렬이다.
이동 행렬은 위와 같이 단위 행렬(identity matrix)에서 마지막 행의 마지막 열을 제외하고 이동하고 싶은 만큼 값을 넣어준다. 변환 이전의 (x,y)에서 각각 a,b만큼 이동하고 싶다면 결과는 (x+a, x+b)가 된다. 원한다면 (x,y,1) 과 행렬 T를 곱해보면 (x+dx, x+dy, 1)이 나올 것이다. 우리는 3차원이므로 x,y,z을 고려하여 4행의 1,2,3열을 변경해주면 된다.
이러한 이동 변환을 위해 D3DXMatrixTranslation()
함수를 지원한다.
// Build a matrix which translates by (x, y, z)
D3DXMATRIX* WINAPI D3DXMatrixTranslation
( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z );
pOut
에 미리 생성한 행렬 변수를 넣어준다. 그리고 x, y, z에 이동을 원하는 만큼의 값을 각각 넣어준다. 위 그림으로 따지면 dx, dy, dz에 해당한다. 그러면 pOut엔 T와 같은 행렬이 저장된다.
아래와 같이 x,y,z 축으로 각각 3,3,0만큼 이동시키는 행렬을 출력하면 다음과 같다.
D3DXMATRIX mat;
D3DXMatrixTranslation(&mat, 3.f, 3.f, 0.f);
크기 행렬(Scale matrix)
크기 행렬은 다음과 같이 점 또는 도형의 크기를 축소 및 확대시키는 행렬이다.
크기를 변환시키기 위해선 각 좌표값에 실수배를 해주면 된다. 이를 위해선 주대각원소의 각 x,y,z값을 변경해주면 된다.
이러한 크기 변환을 위해 D3DXMatrixScaling()
함수를 지원한다.
// Build a matrix which scales by (sx, sy, sz)
D3DXMATRIX* WINAPI D3DXMatrixScaling
( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz );
다음은 D3DXMatrixScaling() 함수를 적용한 행렬이다.
D3DXMATRIX mat;
D3DXMatrixScaling(&mat, 3.f, 3.f, 0.f);
아래 사진의 오른쪽 사진은 왼쪽의 DirectX 사진을 1/2로 축소시킨 것이다. 물론 겹치면 보이지 않기 때문에 이동 변환도 포함되어 있다.
회전 행렬(Rotation matrix)
회전 행렬은 다음과 같이 점 또는 도형을 회전시켜주는 행렬이다.
회전 변환의 종류로는 크게 다음과 같은 것들이 존재한다. 여기서는 x,y,z 세 개만 알아본다.
- x축 회전
- y축 회전
- z축 회전
- 임의의 축을 기준으로 한 회전
우선 x축 회전은 다음과 같은 함수를 사용한다. 이때 각도는 라디안 값을 이용해야 한다. 30도 45도와 같은 것은 호도법이고 파이로 나타내는 것이 라디안이다. 우리는 호도법이 편하므로 호도법을 라디안으로 변환해주는 D3DXToRadian
라는 매크로를 이용한다.
// Build a matrix which rotates around the X axis
D3DXMATRIX* WINAPI D3DXMatrixRotationX
( D3DXMATRIX *pOut, FLOAT Angle );
다음은 x축으로 30도만큼 회전시켜주는 행렬이다. 행렬의 값을 보면 중앙의 4부분이 순서대로 cos,sin,-sin,cos과 같이 되어있는 것을 볼 수 있다.
D3DXMatrixRotationX(&mat, D3DXToRadian(30));
다음은 y축으로 30도만큼 회전시켜주는 행렬이다.
다음은 z축으로 30도만큼 회전시켜주는 행렬이다.
만약 x, y, z축 회전 중 여러개를 적용하고 싶다면 z->x->y 순으로 곱해야 한다. 이를 위해 D3DXMatrixRotationYawPitchRoll()
라는 함수도 존재한다. 이 함수는 x,y,z를 인자로 받아 알아서 연산해준다.
다음은 z축으로 30도 만큼 회전한 결과이다. (크기와 이동 변환도 적용되었다.)
참고로 이동, 크기, 회전 변환을 모두 적용하고 싶을 땐 크기 -> 회전(z->x->y) -> 이동
순으로 곱해야 한다.
'게임 공부 > DirectX' 카테고리의 다른 글
DirectDraw 학습 (2) - Draw (0) | 2020.11.17 |
---|---|
DirectDraw 학습 (1) - Initialization (0) | 2020.11.15 |
D3DXCreateTextureFromFileEx 함수의 color key (0) | 2020.06.23 |
Direct3D 라이브러리를 이용하여 간단한 게임 화면을 만들어 보았다. (0) | 2020.06.16 |
2D 게임 프로그래밍 (2) | 간단한 디바이스 만들기 (0) | 2020.06.15 |
댓글