XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   
My XNA Book
      
       Go to section on this site

Additional info


Latest Forum posts

 Account settings
  Posted by: Anonymous
  When: 07/05/2014 at 09:48:39

 forced subtitle
  Posted by: Applefly
  When: 07/05/2014 at 06:00:48

 convert DVD into PMS
  Posted by: Applefly
  When: 07/05/2014 at 05:55:25

 DVD to Digital Copy easily
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:52:29

 DVD on Xbox 360/Xbox One Console
  Posted by: VIKIVannessa
  When: 05/05/2014 at 06:51:47

 Extract .Srt Subtitles
  Posted by: Applefly
  When: 04/05/2014 at 03:54:38

 Encode Movie collection
  Posted by: Applefly
  When: 04/05/2014 at 03:52:41

 Convert DVD to WMV
  Posted by: Applefly
  When: 29/04/2014 at 05:53:50

 rip DVDs into digital files
  Posted by: Applefly
  When: 29/04/2014 at 05:51:20

 iTunes movies/music to Kindle Fire
  Posted by: ciciyu80
  When: 29/04/2014 at 05:10:20


Ads

월드 좌표와 카메라 뷰

tutorial 03에서 우리는 미리 변환된(Pretransformed) 좌표계(Coordinate)를 사용하여 삼각형을 그려보았습니다.

이 미리 변환된(Pretransformed) 좌표계는 말 그대로 3D 좌표계와 우리 눈에 보이는 화면인 2D 좌표계 간의 변환이 미리 이루어져 있기 때문에, 우리는 vertex들의 좌표를 매우 직관적으로 설정할 수 있었습니다.

하지만 안타깝게도 이런 미리 변환된(Pretransformed) 좌표계는 실제로 많이 사용되는 좌표계가 아닙니다. 보통은 월드 좌표계라고 불리는 3D 좌표계를 많이 사용하지요. 월드 좌표계에서는 지금까지와는 달리 객체의 위치와 우리가 눈으로 보는 화면, 즉 카메라의 위치가 매우 중요해 집니다.

이쯤에서 코드로 들어가봅시다. 새로운 Windows Game 프로젝트를 생성합니다. 물론 코드는 tutorial 03에서 출발하므로Game1.cs와 effects.fx파일을 복사해 오는등 만반의 준비를 갖추도록 합시다.

먼저 우리의 삼각형을 구성하는 vertex들의 좌표값을 재정의 해 보겠습니다.

 vertices[0].Position = new Vector3(0.0f, 0.0f, 0.0f);
 vertices[0].Color = Color.Red;
 vertices[1].Position = new Vector3(5.0f, 10.0f, 0.0f);
 vertices[1].Color = Color.Green;
 vertices[2].Position = new Vector3(10.0f, 0.0f, -5.0f);
 vertices[2].Color = Color.Yellow;

보이는 것과 같이 이번에는 z좌표값을 설정해 보았습니다. tutorial이 끝나고 좌표값들을 자유롭게 수정하여 그 결과를 테스트 해보길 바랍니다.

다음으로 이제 우리는 더 이상 Pretransformed 좌표계를 쓰지 않을 것이므로 Pretransformed Technique 또한 쓰지 않을 것 입니다. Draw함수의 Pretransformed Technique를 다른 Technique로 바꿔 보겠습니다. 여기서는 Colored Technique를 사용하겠습니다.

 effect.CurrentTechnique = effect.Techniques["Colored"];

아직 tutorial이 끝난것은 아니지만, 한번 디버그(F5)키를 눌러 윈도우를 띄워 봅시다. 아마도 우리의 삼각형은 온데간데 없이 사라지고 말았을 것 입니다. 하지만 너무 슬퍼할 필요는 없습니다. 우리의 삼각형은 아주 사라져 버린것이 아니라 다만 우리의 눈에 보이지 않는것 이니까요.

즉, 우리가 삼각형을 다시 보기 위해서는 우리가 보는 화면, 즉 카메라의 위치가 우리의 삼각형을 바라보도록 설정해줘야 합니다. 몇개의 matrix를 정의해서 말이죠.

여기서 잠깐 matrix에 대한 얘기를 잠깐하고 넘어가겠습니다. 일반적으로 우리는 3D공간에 vertex라 부르는 일련의 점들을 위치시키곤 합니다. 하지만 우리가 눈으로 보고 있는 화면은 결국 2D입니다. 즉 우리가 3D라고 생각하는 공간은 어디까지나 가상으로 존재하는 공간일뿐, 실제하는 것은 2D인 화면뿐입니다. 그래서 우리는 가상의 3D공간을 2D의 화면을 통해 출력하기위해 matrix를 씁니다. 3D공간의 위치값을 matrix로 표현하면 이를 2D 화면의 위치값으로 변환하기가 간단해집니다. 일종의 논리적인 수학 연산만 거치면 됩니다. matrix에 대해서는 관련 자료가 인터넷에 많이 존재하니 해당 자료를 참조하기 바랍니다. 혹시 나중에 기회가 된다면 matrix에 대해서도 다뤄보겠습니다.

카메라의 위치를 설정하기 위해 간단한 함수를 추가하겠습니다.

 private void SetupCamera()
 {
     Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 40.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
     Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Window.ClientBounds.Width / Window.ClientBounds.Height, 1.0f, 50.0f);
 }

첫번째 라인은 카메라의 위치와 방향을 정의하는 matrix를 만드는 코드입니다. 첫번째 parameter는 카메라의 위치를 정의합니다. 두번째 parameter는 카메라가 바라볼 위치입니다. (0.0f, 0.0f, 0.0f)이니 좌표축의 원점(origin)을 바라보고 있네요. 세번째 parameter는 이 카메라의 윗쪽(up)이 어느 방향인지를 정의합니다. 지금은 (0.0f, 1.0f, 0.0f)로 y축 양수의 방향을 윗쪽으로 고정되어 있습니다. (0.0f, -1.0f, 0.0f)로 수정하면 카메라가 y축 음수의 방향을 윗쪽으로 고정될 것 이므로 마치 화면이 180º만큼 회전한것 처럼 보이겠네요.

두번째 라인은 카메라가 대상을 어떻게 바라볼 것 인지 정의하는 matrix를 만드는 코드입니다. 예를 들어, 실제로 우리가 카메라를 사용할때 어디서 무엇을 찍을지 결정했다고 하더라도 줌(zoom)으로 확대/축소를 한다던지 혹은 광각 렌즈를 써서 넚은 각도를 찍을 것인지 좁게 찍을 것인지를 마저 결정해야 하는것(프로젝션 Projection)과 같습니다. 코드로 돌아가서, 첫번째 parameter는 카메라의 앵글을 정의합니다. 여기서는 90º로 설정했습니다. 두번째 parameter는 가로 세로 비율을 정의합니다. 우리의 윈도우는 가로 500px, 세로 500px의 정사각형이므로 이를 나누기하면 비율은 1입니다. 마지막 2개의 parameter는 대상이 보여질 최소/최대 구간입니다. 즉, 카메라에 1.0f 보다 가까워지거나 50.0f보다 멀어지면 대상 위치는 카메라에 보이지 않게 됩니다. 즉, 카메라에 너무 가깝거나 너무 멀면 보이지 않는다는 것으로 이 parameter들은 그 최소/최대 값을 설정합니다. 그려질 객체들은 반드시 이 구간안에 있어야 화면에서 볼 수 있습니다.

이제 matrix들이 정의되었으니 이 matrix들을 설정해 주어야 합니다. tutorial 02 앞부분에서 말했듯 XNA는 무엇이든지간에 Effect없이 표현할 수 없습니다. 따라서 만들어진 matrix들을 Effect에 설정해 주기 위해 SetupCamera함수 끝에 다음과 같이 추가합시다.

 effect.Parameters["xView"].SetValue(viewMatrix);
 effect.Parameters["xProjection"].SetValue(projectionMatrix);
 effect.Parameters["xWorld"].SetValue(Matrix.Identity);

여기에 대해서는 series 3에서 설명합니다.

다음은 이렇게 해서 만들어진 SetupCamera함수의 모습 입니다.

 private void SetupCamera()
 {
     Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, -40.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
     Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Window.ClientBounds.Width / Window.ClientBounds.Height, 1.0f, 50.0f);
 
     effect.Parameters["xView"].SetValue(viewMatrix);
     effect.Parameters["xProjection"].SetValue(projectionMatrix);
     effect.Parameters["xWorld"].SetValue(Matrix.Identity);
 }

그리고, 지금까지 했던 것처럼 함수가 실제로 동작할 수 있도록 Initialize함수 끝에 SetupCamera함수를 추가합시다.

 protected override void Initialize()
 {
     // TODO: Add your initialization logic here
 
     ......
 
     SetupCamera();
 }

그리고 다시 디버그(F5)키를 누르면 우리의 삼각형이 다시 윈도우에 나타났음을 확인 할 수 있습니다.



물론 삼각형의 위치나 모양이 이전과 다르게 보이는 것은 vertex들의 좌표값이 달라졌기 때문입니다.

지금까지 우리는 우리의 삼각형의 앞 모습만 보아 왔습니다. 하지만 이전과는 다르게 우리는 이제 카메라를 가지고 있고, 또 카메라를 다룰줄도 압니다.

그렇다면 우리의 삼각형의 뒷모습은 어떤지 보도록 합시다.

카메라를 설정되어 있다면 대상 객체의 뒷모습을 보는것은 간단합니다. 카메라 위치의 z축 좌표값을 음수로 바꾸어 카메라를 좌표축 원점(0.0f, 0.0f, 0.0f)을 중심으로 180º 회전시키면 됩니다.

Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, -40.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));

코드에서 보이는 것과 같이 카메라의 z축 위치가 음수로 바뀌었습니다.

그러나 디버그(F5)키를 눌러 윈도우를 띄우면 우리의 삼각형은 다시 온데간데 없이 사라지고 말았습니다. 비록 삼각형은 사라졌지만 여러분은 슬퍼할 필요는 없습니다. 우리 눈에 보이지 않을뿐 삼각형은 분명 제 위치에 존재하고 있으니까요.

게다가 이 사실을 통해 한가지 중요한 XNA의 특징을 배울 수 있습니다.

XNA는 기본적으로 외면, 즉 표면(face)만을 그립니다. 그리고 표면이나 아니냐의 여부는 카메라의 방향에 따라 결정됩니다. DirectX는 삼각형을 카메라의 시점에서 볼때 vertex가 시계 방향(clock-wise)으로 구성되는 삼각형을 표면으로 정의합니다. 태생이 DirectX인 XNA도 마찬가지 입니다.

즉, 우리의 삼각형이 화면에서 사라진 이유는 우리의 삼각형이 표면(face)이 아니기 때문입니다. 카메라가 z축 양수의 방향에 위치할때 우리의 삼각형을 구성하고 있는 vertex들은 그 배열 순서가 시계 방향이기 때문에 그려(draw)지지만, 카메라를 z축 음수의 방향으로 이동시키면 우리의 삼각형의 vertex 배열 순서는 반 시계 방향(counter-clock-wise)이 되고 XNA는 이제 우리의 삼각형을 그리지 않습니다.

우리는 이런 기법을 Culling기법이라고 부르며 설정하기에 따라서는 기본값인 시계 방향 대신에 반 시계 방향으로 설정할 수도 있습니다. Culling기법은 그려야 할 삼각형의 갯수를 줄일 수 있기 때문에 성능을 대폭 향상시키는 중요한 기법중 하나입니다.

여기서는 우리의 삼각형의 뒷모습을 보기위해 Culling 모드를 None으로 설정해 해당 모드를 off시킵시다. (Culling-off)

Culling 모드를 끄기 위해서는 Draw함수 시작 부분에 다음과 같은 코드를 추가하면 됩니다.

 protected override void Draw(GameTime gameTime)
 {
     device.RenderState.CullMode = CullMode.None;
 
     ......
 
     base.Draw(gameTime);
 }

이제 다시 디버그(F5)키를 눌러 윈도우를 띄우면 우리의 삼각형의 뒷모습을 볼 수 있습니다.






Google
 
Webwww.riemers.net


If you appreciate the amount of time I spend creating and updating
these pages, feel free to donate -- any amount is welcome !



- Website design & XNA + DirectX code : Riemer Grootjans -
©2003 - 2011 Riemer Grootjans
Translations

This site in English
This site in Korean
This site in Czech

Microsoft MVP Award



2007 - 2011 MVP Award
DirectX - XNA

Contents

[Tutorials]
[XNA in C#]
Series 1: 지형
XNA의 시작
이펙트 파일
첫 번째 삼각형
월드 좌표계
회전, 위치 변환
인덱스
지형 생성의 기본
파일로부터 지형 생성
키보드 입력
[tut10]
[tut11]
[tut12]
[tut13]
-- Expand all --


Thank you!

Support this site --
any amount is welcome !

Stay up-to-date

I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!