본문 바로가기

Programming/OpenGL

Understanding Coordiante Transformations

다른 기본적인 과정을 준비하느라 포스팅이 늦었네요 :) 저번 포스팅에서 부터 OpenGL의 아주 기본적인 요소들에 배우면서, 물체(라고 하기엔 좀 그런 간단한 것 들 이지만ㅋ)를 띄우고, 보는 것들을 했었죠. 하지만 아직 상호작용을 통한 과정이 없어 지루했을 거에요.(물론, 아주 처음 보는 사람들은 일단 띄웠다! 에 만족하실 수도 있구요ㅋ)
 
사용자에게 입력을 받는 것은 어려운 것이 아니에요. 이미 제공되는 함수들이 있으니까 사용하면 되는데, 그전에 어떠한 방식으로 물체나, 카메라, 화면의 디스플레이등을 조작 하는가를 알아야 실제 게임처럼 사용자와 상호작용을 할 수 있겠죠~
 
그 기본적인 배경지식이 "coordinate transformations" 라는 거에요. 좌표계변환? 쯤으로 번역이 되려나….? @_@ㅋ 일단은 그 기본 지식부터 써보려고 합니다.
 
"Transformations"은 3D세계에서의 요소들을 이동, 회전, 조작 할 수 있게끔 해줍니다. 그 중 하나가 전에 잠시 살펴보았던 3D좌표계로부터 2D좌표계로 변환이 있었죠. 모델좌표계(Model coordinate system)을 회전시킨다면 (우리들이 입력했던 모델의 정점들)이 회전된 상태에서 그려지게 되는 거죠.
   
3차원 상의 정점들로 부터 보여지는 화면은 다음과 같은 변환들에 의해서 최종적으로 화면에 뿌려지게 됩니다.   
  • Viewing transformation : 카메라와 관련된 변환
  • Modeling transformation : 물체(Object)와 관련된 변환
  • Projection transformation : 뷰 볼륨(View Volume)과 클리핑 영역에 관련된 정의   
추가적으로 viewport transformation이 있는데, 얘는 화면에 뿌려지는 2D 프로젝션에 관련된 거고, ModelView transformation은 Viewing과 Modeling의 결합에 의한 변환에요.
여기서 주의해서 알아 두어야 할 것은, viewing transformation은 반드시 modeling transformation 전에 해야 한다는 거에요! 하지만, projection과 viewport transformation은 언제 해도 상관 없구요.
하나의 점에 대해서 동작하는 파이프라인은 아래와 같아요.


대부분 영어인 것은 적절한 번역이 생각나지 않고, 번역으로 인한 모호함 보다 단어 자체의 직관성을 높여주기 위함이에요.
   
…. 죄송합니다ㅋㅋㅋㅋ

비디오 카드의 행렬처리 토막 설명
진행 되는 과정에 대해서 설명을 할게요. 설명은 더욱 빠른 이해를 돕기 위해서 2차원 상에서 하는게 좋겠죠?ㅎ

좌표계라는 것은 서로서로 다른 것을 가지고 있는 거에요. 특별히 좌표계라는 말이 자칫 좀 무겁게 다가 설수도 있는데(저는 그랬어요ㅋ), 오브젝트든, 카메라든, 월드든 각각 서로 가지고 있는 위치들의 집합 쯤이라고 이해 하는 게 편할 듯 싶어요.

무슨 소리인고 하니, 일단 어떤 오브젝트들을 만든다고 할게요. 각각의 오브젝트를 만들 때는 절대적인 좌표(0, 0)을 기준으로 만들어 지게 된답니다(2차원 예시에요). 그런 백지 상태에다가 오브젝트를 만드는 거에요. 아래 두 개의 오브젝트를 만들었다고 해봐요.


오브젝트들은 각각의 절대적인 좌표상에서 저런 모양으로 만들어 졌죠. 이게 정점들의 정보가 되는 거에요. 카메라 또한 기본적으로 (0, 0)에 있다고 합니다.

우리는 OpenGL한테 이걸 3D월드에 그려 달라고 해야 하니까, 아래와 같이 풀어 쓰게 됩니다.
여기서는 이해를 돕기 위해 OpenGL의 함수 대신에 수도코드와 같이 말로 풀어 쓸게요. 앞으로 쓰게될 포스트에서 코드로 볼 수 있어요 :)

그리기 시작()
별의 정점들 정보 // 이후에는 "별" 이라고만 할게요.
나무의 정점들 정보 // 마찮가지로 "나무" 라고만 할게요.
그리기 끝()

그럼 아래와 같은 결과가 나오게 됩니다.



하늘색 좌표축이 월드 좌표계에요. 아직은 변환을 주지 않았기 때문에 서로 겹쳐 있는 거에요. 카메라는 실제로 보이는 오브젝트는 아닙니다ㅋ. 이제 배치를 해야 겠죠? 우리가 일상적으로 느끼는 세계와 같게 하기 위해서 "지표면"이라는 개념을 정해줄 필요가 있어요. x축, y축, 또는 임의의 어떤 축이든 상관은 없어요. 하지만 기본적으로 제공되는 좌표계가 이미 존재하고 우리가 바로 이해되도록 하는 게 좋겠죠?

여기 예시에서는 x축을 지표면이라고 할게요. 그럼 나무는 너무 땅 깊숙히 박혀 있고, 별은 땅에 붙어 있죠? 그래서 각각의 오브젝트(즉, 모델)에 변환을 가하게 됩니다. 나무는 y축으로 +4만큼, 별은 y축으로 +10만큼 올리면 될거 같아요.

그리기 시작()
이동변환(x축으로 0, y축으로 +10)

이동변환(x축으로 0, y축으로 +4)
나무
그리기 끝()

그럼 결과는 아래처럼 거지같이 나옵니다 :D



별은 원하는 대로 10만큼 올렸지만, 나무도 같이 올라가 버리는데다가 +4만큼 더 올라간 상황…@_@ㅋ
나중에 더욱 자세히 설명하겠지만, 별도로 행렬계산을 하는 영역을 묶어주지 않으면 코드상 밑에 쪽에 나오는 모든 행렬계산에 대해서 적용이 된답니다. 일단은 { } 이걸로 묶는다고 한다고 할게요 :)

그리기 시작()
이동변환(x축으로 0, y축으로 +10)
{ 별 }
이동변환(x축으로 0, y축으로 +4)
{ 나무 }
그리기 끝()

일단은 어느정도 원하는 대로 나오게 되요.


각 오브젝트에 대한 coordinate에 적용이 되는 거에요.

그럼 어느정도 모양을 맞추려면 어떻게 해야 하는지 알겠죠? 확대 변화까지 써서 그럴싸한 배치를 한다면, 아래와 같이 하면 되겠죠~

그리기 시작()
확대변환(x축 *0.2, y축 *0.2)
이동변환(x축으로 +10, y축으로 +10)
{별}
확대변환(x축 *0.8, y축은 그대로)
이동변환(x축으로 +5, y축으로 +4)
{나무}
그리기 끝()



환경은 어느정도 만들어 졌으니까 이제 카메라를 볼까요? 카메라가 바라보고 있는 곳이 곧 우리가 보게 될 화면 입니다. 카메라의 위치와 기능에 따라서 화면에 어떻게 보이냐가 달라지겠죠? 특히 알아두어야 하는 것이 클리핑 영역 입니다. 화면에 보이지 않게 될 거를 애초에 차단하는 거죠. 그 영역에 대한 것을 점선 삼각형으로 표현하자면 아래 그림과 같아요.


나무와 별을 모두 보려면 카메라를 이동 시켜야 겠죠? 역시 대략적인 수도코드로 적을게요.
카메라 위치(-7, +5)
그리기 시작() ~ 그리기 끝()


그럼 이제 나무와 카메라가 모두 보일게 될 거에요.

이런 카메라와 물체의 세팅이 끝나게 되면, OpenGL은 최종적으로 우리에게 보여 질 화면을 행렬계산의 연산으로 처리하게 됩니다. 하나의 점에 대해서 그때의 행렬처리는 아래와 같이 진행 됩니다.


2차원에서 계산하기 때문에 행렬변환에 차원이 하나 더 붙게 됩니다. 이 부분은 예전 포스팅을 참고 하세요 :)

원래 나무 오브젝트중 밑둥의 절대적인 좌표가 (0, -4) 라고 했다면,
나무 오브젝트가 (+5, +4) 만큼 이동변환 되었고,
카메라자체가 (-7, +5) 만큼 이동 했지만, 오브젝트들의 정점의 좌표로 부터는 오히려 (+7, -5)만큼 이동했기 때문에 (+7, -5) 만큼 이동변환 을 시키게 되면
최종적으로 카메라로 부터(카메라의 현재 위치가 (0, 0)이라고 했을 때) 나무 밑둥의 좌표는 (12, 5)가 되는 것이죠.

위쪽의 저 행렬만 있다면, 나무 오브젝트의 전체 정점들에 대해서 한번에 계산이 되겠죠?


각 색갈이 빗금으로 칠해 진 사각형이 행렬들은 각 계산에 대한 것들이며, 갈색으로 된 화살표가 계산이 이루어 지는 거에요. 다만, 초록색과 파랑색은 각각 행렬계산을 따로 하세요~ 라고 알려 줬기 때문에 1, 2로 별에 대한 거, 나무에 대한 거를 나눈거구요.

부연설명이 길었는데, 이러한 변환들에 대해서 하나하나 공부할 생각입니다~

참조 : OPENGL GAME PROGRAMMING(Foreword by Mark.Kilgard)

'Programming > OpenGL' 카테고리의 다른 글

OpenGL Transformations_Modeling  (0) 2012.03.17
OpenGL Transformations_Viewing(Camera)  (0) 2012.03.15
OpenGL primitives_2  (2) 2011.12.24
OpenGL primitives_1  (0) 2011.12.22
OpenGL states  (0) 2011.12.22