摘要:XNA-顯示3D模型
XNA預設是支援.x 和.fbx 這兩種3D模型檔案,
而載入模型的方式也非常簡單,先建立一個Model物件,設定好座標,
再畫出來即可,讓我們直接看程式碼吧!
加入以下程式碼:
01 //模型類別
02 Model FD;
03
04 protected override void LoadContent() {
05 // 載入模型
06 FD = Content.Load("FD");
07 }
08
09 protected override void Draw(GameTime gameTime) {
10 graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
11
12 Matrix gameWorldRotation = Matrix.CreateWorld(Vector3.One, Vector3.Forward, Vector3.Up);
13 Matrix[] transforms = new Matrix[FD.Bones.Count];
14 float aspectRatio = graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height;
15 FD.CopyAbsoluteBoneTransformsTo(transforms);
16 Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
17 aspectRatio, 1.0f, 10000.0f);
18 Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 50.0f, Zoom), Vector3.Zero, Vector3.Up);
19
20 foreach (ModelMesh mesh in FD.Meshes) {
21 foreach (BasicEffect effect in mesh.Effects) {
22 //使用基本光源打光
23 effect.EnableDefaultLighting();
24
25 effect.View = view;
26 effect.Projection = projection;
27 effect.World = gameWorldRotation * transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(Vector3.One);
28 }
29 mesh.Draw();
30 }
31
32 base.Draw(gameTime);
33 }
02 Model FD;
03
04 protected override void LoadContent() {
05 // 載入模型
06 FD = Content.Load("FD");
07 }
08
09 protected override void Draw(GameTime gameTime) {
10 graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
11
12 Matrix gameWorldRotation = Matrix.CreateWorld(Vector3.One, Vector3.Forward, Vector3.Up);
13 Matrix[] transforms = new Matrix[FD.Bones.Count];
14 float aspectRatio = graphics.GraphicsDevice.Viewport.Width / graphics.GraphicsDevice.Viewport.Height;
15 FD.CopyAbsoluteBoneTransformsTo(transforms);
16 Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
17 aspectRatio, 1.0f, 10000.0f);
18 Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 50.0f, Zoom), Vector3.Zero, Vector3.Up);
19
20 foreach (ModelMesh mesh in FD.Meshes) {
21 foreach (BasicEffect effect in mesh.Effects) {
22 //使用基本光源打光
23 effect.EnableDefaultLighting();
24
25 effect.View = view;
26 effect.Projection = projection;
27 effect.World = gameWorldRotation * transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(Vector3.One);
28 }
29 mesh.Draw();
30 }
31
32 base.Draw(gameTime);
33 }
比較會有問題的應該是20,21兩行,通常一個3D模型不會只有一個部分,幾乎都是由多個不同的小模型組成,
而我們載入模型的時候會將相對位置做階層式記錄,也就是會以一個主要物件為主,
其他物件和此主要物件的相對位置都會被記錄,也因此我們在做旋轉時必須將所有物件一並旋轉,
不然會出現身體轉向了,手腳卻還留在原地的怪異畫面。
而這件事情也非常容易完成,先產生所有物件的矩陣,呼叫Model.Bones.Count可以取得相依的物件數量,
接著將此物件陣列傳入CopyAbsoluteBoneTransformsTo,他會把所有物件的相對位置存到陣列中。
CopyAbsoluteBoneTransformsTo
public void CopyAbsoluteBoneTransformsTo ( Matrix[] destinationBoneTransforms ) 參數: destinationBoneTransforms 矩陣陣列 |
最後畫出每個部分就完成了!