드디어 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 |
값 |
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 |
댓글