이번에도 과제'_'
그래도 작년에 OpenGL 과제를 했던 기억을 되살리... 는게 아니라 외장하드를 뒤적거려서 찾아냈다.
자료 보관의 중요성을 새삼 또 느끼는 중..
구현 목표!
- Z 키를 눌렀을 때는 카메라가 줌 인. X 키를 눌렀을 때는 카메라 줌 아웃.
- 카메라가 뒤집어지는 불상사가 일어나지 않게 한다.
아무튼.
카메라 줌 인/아웃 구현에 대해서는 사실 시야각을 조정해서 하는게 맞는지
아니면 Near Plane/Far Plane을 설정해서 하는 게 맞는지는 잘 모르겠는데
작년에 OpenGL 과제를 했을 때는 시야각을 조정해서 하고 A 받았으니까
아마 맞겠지... @_@
일단 시야각은 카메라 위치, 타겟좌표, 업벡터 등을 설정하고(뷰 스페이스 설정) 나서
투영 작업을 해줄 때 설정해준다.
DirectX 에서는 π 값에 0.5를 곱한 float 형태의 값을 초기값으로 설정해주고 있다.
따라서 일단 전역으로 Zoom In/Out을 조정해줄 변수를 하나 선언하고 PI*0.5 값으로 초기화해준다.
float Zoom = D3DX_PI * 0.5f;
투영 작업을 해주는 부분을 살펴보자.
대부분, 예제의 Setup() 함수 끝자락에 투영 설정에 관한 코드가 있음.
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj,
D3DX_PI * 0.5f,
(float)Width / (float)Height,
1.0f,
1000.0f);
Device->SetTransform(D3DTS_PROJECTION, &proj);
D3DXMatrixPerspectiveFovLH 함수의 매개변수를 하나하나 살펴보면..
맨 처음 값은 그냥 pOut 값. SetTransform 함수를 통해 투영행렬에 넣어줄 값이므로
그냥 D3DXMATRIX 형태의 포인터 값을 넣어주면 된다.
두번째 값이 이번 포스팅에서 제일 중요한 부분! 시야각을 설정해주는 변수이다.
세번째는 종횡비.
네번째와 다섯번째는 각각 Near plane과 Far Plane이다. 거리 설정으로, 오늘은 여길 건들일 필요가 없다.
이제 저 부분을 고대로 복사한다음 Display() 함수에서 키 입력을 받는 부분 바로 다음에 넣어준다.
초기값인 D3DX_PI * 0.5 값이 들어가는 부분에는 아까 만들어준 Zoom 변수를 넣어준다.
먼저 키 입력을 받아온다. 키 입력은 저번 포스팅에도 했지만 그건 특수키이므로@''@
if( ::GetAsyncKeyState('Z') ) // Zoom In!
{
// Zoom 변수를 조정해준다.
}
else if( ::GetAsyncKeyState('X') ) // Zoom Out!
{
// Zoom 변수를 조정해준다.
}
이제 Zoom 변수를 설정해준다.
처음에 뭣도 모르고 최대최소가 3.14 / 0.0 이니까 0.5씩 늘려주거나 줄여주면 되겠지!!!!!^^ 하다가 피봄.. 폭풍 출혈..
소심하게 0.001f 씩 가감시키기로 한다.
여기서 잊지 말아야할 게,
Zoom 변수룰 증가시키면 시야각이 넓어지므로 물체가 작게 보여서 Zoom Out 의 효과가 나타나고
감소시키면 시야각이 좁아지므로 물체가 크게 보여서 Zoom In의 효과가 나타남.
따라서 if 문 안에 아래와 같은 코드를 삽입한다.
if( ::GetAsyncKeyState('Z') )
{
Zoom -= 0.001f;
}
else if( ::GetAsyncKeyState('X') )
{
Zoom += 0.001f;
}
이제 실행해본다!
그리고 Z 키를 마구 눌러대면!!!!!!
좌측은 맨 처음 화면. 우측은 Z키를 마구 눌러댄 화면!!!!
카메라가 오른쪽처럼 훼까닥 뒤집어진다.
이게 다 .. Zoom 값이 값의 범위를 지나쳐서 생기는 문제!!
그렇기 때문에 Z/X 키를 눌렀을 때 Zoom 값의 범위를 한정해주는 코드를 추가한다.
if( ::GetAsyncKeyState('Z') )
{
Zoom -= 0.001f;
if(Zoom <= D3DX_PI * 0.25f)
Zoom = D3DX_PI * 0.25f;
}
else if( ::GetAsyncKeyState('X') )
{
Zoom += 0.001f;
if(Zoom >= D3DX_PI * 0.75f)
Zoom = D3DX_PI * 0.75f;
}
가장 안전한 범위 설정은 초기 값에서 ± 해주는 값인 것 같다.
추가해준 코드를 이제 실행하면 Zoom In/Out 이 제대로 구현되는 것을 볼 수 있다.
왼쪽이 Zoom In, 오른쪽이 Zoom Out.
과제 후기는 다음 시간에.
'스터디' 카테고리의 다른 글
Unity3D :: Time.timeScale (0) | 2013.10.06 |
---|---|
안드로이드 (0) | 2013.09.23 |
OpenGL :: .....예전에 했던 stanford bunny 과제 (0) | 2013.08.16 |
중간고사 대비 관련해서 이것저것 남겨두는 포스팅. (0) | 2013.04.21 |
Direct3D :: 간단한 슈팅 게임 맛보기로 구현하기. (0) | 2013.03.14 |