본문 바로가기
프로그래밍

3D모델을 가져오기

by 건우아빠유리남편 2009. 7. 9.
반응형

드디어 3D의 세계로 들어왔습니다..  
이번 프로그램은 3D모델을 불러오는 프로그램입니다.

 

 

리소스 추가

이번 프로그램에서는 3D모델!!!을 하나 쓰고, 텍스쳐 한 장과 효과 하나를 사용하겠습니다.

모델과 텍스쳐는 XNA Creators Club의 Video Tutorial을 참고하시길..

폴더구조는 다음과 같습니다.

 

 

1.     프로젝트를 생성한다.

2.     프로젝트 이름을 우 클릭하여 추가->새로운 폴더 를 선택하여 Content폴더 를 생성하여, 그 아래에 같은 방법으로 Models폴더 Textures폴더를 생성한다.

3.     Models폴더를 우 클릭하여 추가->이미 있는 항목 을 선택하여 *.fbx를 추가한다.

4.     Textures폴더를 우 클릭하여 추가->이미 있는 항목 을 선택하여 *.tga를 추가한다. 프로그램으로부터 읽어 들이지 못하므로 솔루션탐색기에서 지운다. *.tga를 우 클릭하여 프로젝트에서 제거를 선택한다. (디렉토리 에는 그대로. 제거와는 다릅니다.)

 

모델 클래스

모델정보를 가지고 있습니다.

ModelMeshCollection Meshes

메쉬정보

 

모델메쉬콜렉션 클래스

메쉬 정보를 2개 이상 가지고 있습니다.

모델 메쉬 클래스

메쉬 정보를 가지고 있습니다.

ModelBone ParentBone

ParentBone

ModelEffectCollection Effects

2개이상의 효과정보

void Draw();

그리기

 

메쉬 이펙트 콜렉션 클래스

효과정보를 2개 이상 가지고 있습니다.

 

베이직 이펙트 클래스

기본적인 효과정보를 가지고 있습니다.

Matrix World

월드 변환행렬

Matrix View

뷰 변환행렬

Matrix Projection

사영변환행렬

void EnableDefaultLighting()

디폴트 라이트 지정

 

패런트 본 클래스

부모 본의 정보를 가지고 있습니다.

Matrix Transform

위치?회전?확대축소

 

매트릭스 클래스

행렬정보를 가지고 있습니다.

M11,M12,M13,M14
M21,M22,M23,M24
M31,M32,M33,M34
M41,M42,M43,M44

Matrix CreateTranslation(float,float,float)

평행이동

Matrix CreateTranslation(Vector3)

평행이동

static Matrix CreateRotationX(float)

X축회전

static Matrix CreateRotationY(float)

Y축회전

static Matrix CreateRotationZ(float)

Z축회전

static Matrix CreateLookAt(Vector3,Vector3,Vector3)

변환행렬

static Matrix CreatePerspectiveFieldOfView(float,float,float,float)

사영 변환행렬

 

매스헬퍼 클래스

산술연산을 합니다.

static float ToDegrees(float)

라디안각도

static float ToRadians(float)

각도라디안

 

소스코드편집

Game1.cs를 편집합니다.

 

Game1.cs

#region Using Statements

using System;

using Microsoft.Xna.Framework;

using Microsoft.Xna.Framework.Content;

using Microsoft.Xna.Framework.Graphics;

using Microsoft.Xna.Framework.Input;

using Microsoft.Xna.Framework.Audio;

#endregion

 

namespace FerrariEnzo

{

    public class Ferrari : Microsoft.Xna.Framework.Game

    {

        #region Fields

 

        GraphicsDeviceManager graphics;

        ContentManager content;

        private AudioEngine audioEngine; //오디오엔진

        private WaveBank waveBank;   //Wave뱅크

        private SoundBank soundBank;  //Sound뱅크

 

        #endregion

 

        #region Initialization

 

 

        public Ferrari()

        {

            graphics = new GraphicsDeviceManager(this);

            content = new ContentManager(Services);

 

            graphics.PreferredBackBufferWidth = 853;

            graphics.PreferredBackBufferHeight = 480;

        }

 

 

 

        protected override void Initialize()

        {

            //사운드 읽어오기

            audioEngine = new AudioEngine("ferrari.xgs");

            waveBank = new WaveBank(audioEngine, "Wave Bank.xwb");

            soundBank = new SoundBank(audioEngine, "Sound Bank.xsb");

 

            //초기화

            base.Initialize();

        }

 

// 3D모델을 그립니다.

        Model myModel;

float aspectRatio;

 

        protected override void LoadGraphicsContent(bool loadAllContent)

        {

            if (loadAllContent)

            {

                myModel = content.Load<Model>("Content\\Models\\Ferrari Enzo");

            }

 

            aspectRatio = (float)graphics.GraphicsDevice.Viewport.Width /

                graphics.GraphicsDevice.Viewport.Height;

        }

 

protected override void UnloadGraphicsContent(bool unloadAllContent)

        {

            if (unloadAllContent)

                content.Unload();

        }

 

 

        #endregion

 

        #region Update and Draw

 

protected override void Update(GameTime gameTime)

        {

            KeyboardState keyboardState = Keyboard.GetState();

 

 

            if (keyboardState.IsKeyDown(Keys.Escape))

                this.Exit();

            if (keyboardState.IsKeyDown(Keys.Up))

            {

                modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds *

                                    MathHelper.ToRadians(0.2f);

            }

            else

            {

                modelRotation += (float)gameTime.ElapsedGameTime.TotalMilliseconds *

                                    MathHelper.ToRadians(0.1f);

            }

 

            if (keyboardState.IsKeyDown(Keys.S))

            {

                soundBank.GetCue("ferrarien").Play();

            }

            base.Update(gameTime);

        }

 

        // 모델의 포지션과 로테이션을 세팅.

        Vector3 modelPosition = Vector3.Zero;

        float modelRotation = 0.0f;

 

        // 카메라 포지션 세팅.

        Vector3 cameraPosition = new Vector3(25.0f, 50.0f, 150.0f);

 

        protected override void Draw(GameTime gameTime)

        {

            graphics.GraphicsDevice.Clear(Color.MidnightBlue);

 

            // transform parent를 카피

            Matrix[] transforms = new Matrix[myModel.Bones.Count];

            myModel.CopyAbsoluteBoneTransformsTo(transforms);

 

            // 모델을 그립니다만 여러 개의 mesh를 가지고 있을 수 있으므로 루프를 돌아줍니다.

            foreach (ModelMesh mesh in myModel.Meshes)

            {

foreach (BasicEffect effect in mesh.Effects)

                {

                    effect.EnableDefaultLighting();

                    effect.World = transforms[mesh.ParentBone.Index] *

                        Matrix.CreateRotationY(modelRotation) *

                        Matrix.CreateTranslation(modelPosition);

                    effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero,

                                                      Vector3.Up);

                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(

                                            MathHelper.ToRadians(45.0f),

                                            aspectRatio, 1.0f, 10000.0f);

                }

                // Mesh를 그린다.

                mesh.Draw();

            }

 

            base.Draw(gameTime);

 

        }

 

        #endregion

 

    }

 

}

소스를 보시면 아시겠지만, 3D파일만 데리고 오는 것도 심심하고 하니..

화살표 위의 키를 누르면 속도가 빨라지고 S를 누르면 엔진음이 나고, ESC로 상황종료하는.. 이벤트를 넣어봤습니다.

3D파일은 해당 프로젝트내부에 있습니다.  fbx파일을 구하기 쉽지 않았는데, 갑자기 3D파일을 만드는 법을 배우고 싶네요..

반응형

'프로그래밍' 카테고리의 다른 글

알고리즘 중간고사 정리  (0) 2009.07.09
그래프의 용어v2.0  (0) 2009.07.09
사운드를 재생하기  (0) 2009.07.09
XNA Framework 정리  (0) 2009.07.09
데이타를 스토리지에 저장하기  (0) 2009.07.09

댓글