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

index를 이용한 vertex 재사용

지금까지 우리의 삼각형은 움직이고 뒤집히거나 빙글빙글 돌기도 하면서 우리가 XNA를 공부하는데 큰 도움을 주었습니다. 하지만 아쉽게도 이제 우리의 삼각형과 헤어져야 할 시간이 온 것 같네요. 하지만 우리의 삼각형(vertex)과 아주 이별하는 것은 아닙니다. 다루는 방법이 달라지는 것뿐, 모든 객체의 기본은 삼각형(triangle)이고, 삼각형은 3개의 vertex로 구성되어 있다는 사실은 변함이 없으니까요. 그럼 다음 그림을 살펴봅시다.



삼각형을 그리는 데는 익히 알고 있는 바와 같이 3개의 vertex가 필요합니다. 그림에서는 2개의 삼각형이 그려져 있으니 6개의 vertex가 필요하겠네요. 그러나 그림과 같이 한 면이 접해있는 삼각형 2개를 그리는데 6개의 vertex를 사용한다면 명백한 메모리 낭비가 되고 맙니다.

한 면이 인접한 2개의 삼각형은 6개가 아니라 4개의 vertex만으로도 표현할 수 있습니다. 그림에서 보이는 것과 같이 첫번째 삼각형은 1번, 2번, 3번 vertex로 그리고 두번째 삼각형은 2번, 3번, 4번 vertex로 그릴 수 있습니다. 이러한 방법은 중복으로 낭비되는 vertex가 없게 해줍니다.

이것이 index buffer의 기본 배경입니다.

두개의 삼각형을 그린 그림을 하나 더 살펴 봅시다.



하나의 점이 접해있으므로 그림과 같은 2개의 삼각형을 그리는 데는 5개의 vertex가 필요하겠네요. 이 그림은 코드로 표현해 보도록 합시다.

새로운 Windows Game 프로젝트를 생성하고 이전 tutorial로 부터 필요한 파일들을 복사해 옵시다. 물론 코드는 이전 tutorial에서 이어집니다.

먼저 전역 변수를 선언합니다.

 VertexBuffer vb;
 IndexBuffer ib;

DirectX를 다뤄봤다면 익숙하게 느껴질 것 입니다. 전역변수로 vertex buffer와 index buffer를 선언 했습니다.

이제 우리가 그릴 삼각형은 이전까지의 삼각형과는 전혀 다르기 때문에 vertex값들을 바꾸어줄 필요가 있습니다. SetupVertices함수를 다음과 같이 수정합니다.

 private void SetupVertices()
 {
     vertices = new VertexPositionColor[5];
 
     vertices[0].Position = new Vector3(0.0f, 0.0f, 0.0f);
     vertices[0].Color = Color.White;
     vertices[1].Position = new Vector3(5.0f, 0.0f, 0.0f);
     vertices[1].Color = Color.White;
     vertices[2].Position = new Vector3(10.0f, 0.0f, 0.0f);
     vertices[2].Color = Color.White;
     vertices[3].Position = new Vector3(5.0f, 5.0f, 0.0f);
     vertices[3].Color = Color.White;
     vertices[4].Position = new Vector3(10.0f, 5.0f, 0.0f);
     vertices[4].Color = Color.White;
 
     vb = new VertexBuffer(device, VertexPositionColor.SizeInBytes * 5, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
     vb.SetData(vertices);
 }

코드에서 보는 것과 같이 기존 vertex들의 값이 수정되고 2개의 vertex가 추가되었습니다. 마지막 두 라인은 vertex buffer를 생성하고 vertices 배열을 buffer에 저장합니다.

다음으로 함수를 하나 추가해 봅시다. 함수의 이름은 SetupIndices이고 접근자는 private, return type은 void입니다.

 private void SetupIndices()
 {
     short[] indices = new short[6];
 
     indices[0] = 3;
     indices[1] = 1;
     indices[2] = 0;
     indices[3] = 4;
     indices[4] = 2;
     indices[5] = 1;
 
     ib = new IndexBuffer(device, typeof(short), 6, ResourceUsage.WriteOnly, ResourceManagementMode.Automatic);
     ib.SetData(indices);
 }

첫 번째 라인은 삼각형 모양을 그리는데 사용될 index buffer를 채워 넣을 배열을 생성합니다. Bu배열의 item 순서는 그려질 순서를 의미하고, 해당 item에 들어가는 값은 이미 설정된 vertex의 번호입니다. 즉, 두 번째 라인 indices[0] = 3의 의미는 vertices[3]을 가장 먼저 그리겠다는 것 입니다. 그리고 세 번째 라인 indices[1] = 1의 의미는 당연히 두 번째로는 vertices[1]을 그리겠다는 것이 되겠지요. 코드에서 미루어보아 vertices[3] → vertices[1] → vertices[0] → vertices[4] → vertices[2] → vertices[1]의 순서로 vertex들을 그리게 될 것입니다. 당연한 얘기지만 index buffer에도 시계 방향(clock-wise) 순서로 vertex번호가 채워져야 합니다. index buffer를 사용한다고 해도 결국 그리고자 하는 것은 삼각형이니까요. vertices[1]은 두 번 쓰여서 똑같은 vertex를 두 번 선언하는 수고를 덜어주었습니다. index buffer 없이 vertex들로만 이 삼각형들을 그리려 했다면 vertice[1]을 재사용하지 못하고 똑같은 좌표값을 가지는 vertex인 vertice[6]을 선언해야만 하므로 그만큼 메모리와 수행 시간에서 손해를 보았겠지요.
마지막의 두 라인은 실제로 index buffer를 생성하고 buffer에 이미 만들어 놓은 배열을 채워넣습니다.

이제 Initialize함수에 다음과 같이 추가합시다.

 ...
 SetupVertices();
 SetupIndices();
 ...

이제 index buffer가 준비되었으니 삼각형들을 그려봅시다. Draw함수의 기존의 우리의 삼각형을 그리는 코드를 다음의 코드로 대체합니다.

 device.Vertices[0].SetSource(vb, 0, VertexPositionColor.SizeInBytes);
 device.Indices = ib;
 device.VertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements);
 device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 5, 0, 2);

첫 번째 라인과 두 번째 라인은 디바이스에게 사용될 vertex buffer와 index buffer가 무엇인지 알려주는 코드입니다. 당연한 얘기입니다만, 각 buffer들을 선언하고 그 내용을 채워 넣었다고 해도 디바이스에게 가르쳐주지 않는다면 작동하지 않습니다. 첫 번째 라인은 vertex buffer, 두 번째 라인은 index buffer를 설정하는 코드입니다. 단, vertex buffer를 지정할 때는 한 vertex가 몇 바이트인지 같이 설정해주어야 하는데 운 좋게도 VertexPositionColor 구조체가 이미 제공해주고 있습니다. 세 번째 라인은 지금껏 익히 사용해온 코드이군요. 디바이스에게 vertex의 속성을 알려줍니다. 마지막으로 네 번째 라인은 index buffer를 사용하여 삼각형을 그리는 코드입니다. parameter로는 분리된 두 개의 삼각형을 그릴 것 이므로 TriangleList를 사용했습니다. 다음 0은 index buffer의 시작 위치를 나타냅니다. Indices[0]부터 그리게 되겠네요. 다음으로 보여지게 될 index의 최소 개수와 최대 개수가 이어지고, vertex buffer의 시작 위치를 지정한 후, 마지막으로 그려지게 될 삼각형의 개수를 지정합니다.

이제 당장이라도 삼각형을 그릴 수 있지만 아직 할 일이 조금 더 남았습니다. Draw함수를 보면 이전 tutorial에서 사용한 삼각형의 회전 좌표계를 생성하는 코드가 아직 남아있습니다. 원한다면 남겨두어도 상관은 없지만 이번 tutorial에서는 삼각형을 회전시키는 것이 목적이 아니고, 또 결과를 확인하는데 방해가 되지 않도록 이 코드를 다음의 코드로 대체합시다.

 Matrix worldMatrix = Matrix.Identity;

identity matrix는 unit matrix로 가장 기본이 되는 좌표계입니다. 월드 좌표계를 identity matrix로 설정하면 월드 좌표계가 기본 좌표계로 reset 됩니다.

마지막으로 결과의 확인을 좀더 수월하고 정확하게 하기 위해 renderstate를 하나 더 설정하겠습니다. Draw함수의 첫 라인에 다음과 같은 코드를 추가합시다.

 device.RenderState.FillMode = FillMode.WireFrame;

fillmode를 wireframe으로 설정하면 지금까지의 삼각형처럼 내부가 색으로 채워지지 않고 vertex들끼리의 선으로만 삼각형이 표현됩니다.

이제 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!