ผลต่างระหว่างรุ่นของ "418383/418587 ภาคปลาย 2553/การเขียนเกมสามมิติด้วย XNA 4.0"
ไปยังการนำทาง
ไปยังการค้นหา
Cardcaptor (คุย | มีส่วนร่วม) |
Cardcaptor (คุย | มีส่วนร่วม) |
||
(ไม่แสดง 9 รุ่นระหว่างกลางโดยผู้ใช้ 2 คน) | |||
แถว 16: | แถว 16: | ||
} | } | ||
</geshi> | </geshi> | ||
+ | |||
+ | * เวลาแสดงโมเดลให้ใช้โค้ดต่อไปนี้ | ||
+ | |||
+ | <geshi lang="C#"> | ||
+ | public class Game1 : Microsoft.Xna.Framework.Game | ||
+ | { | ||
+ | protected override void Draw(GameTime gameTime) | ||
+ | { | ||
+ | GraphicsDevice.Clear(Color.CornflowerBlue); | ||
+ | |||
+ | Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); | ||
+ | Matrix projectMatrix = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4, 1.0f, 0.1f, 100.0f); | ||
+ | |||
+ | // Copy any parent transforms. | ||
+ | Matrix[] transforms = new Matrix[model.Bones.Count]; | ||
+ | model.CopyAbsoluteBoneTransformsTo(transforms); | ||
+ | |||
+ | foreach (ModelMesh mesh in model.Meshes) | ||
+ | { | ||
+ | foreach (BasicEffect effect in mesh.Effects) | ||
+ | { | ||
+ | effect.EnableDefaultLighting(); | ||
+ | effect.World = transforms[mesh.ParentBone.Index]; | ||
+ | effect.View = viewMatrix; | ||
+ | effect.Projection = projectMatrix; | ||
+ | } | ||
+ | // Draw the mesh, using the effects set above. | ||
+ | mesh.Draw(); | ||
+ | } | ||
+ | |||
+ | base.Draw(gameTime); | ||
+ | } | ||
+ | } | ||
+ | </geshi> | ||
+ | |||
+ | * อธิบาย | ||
+ | :* โค้ดสองบรรทัดที่เกี่ยวข้องกับเมตริกส์สองบรรทัด | ||
+ | <geshi lang="C#"> | ||
+ | Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); | ||
+ | Matrix projectMatrix = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4, 1.0f, 0.1f, 100.0f); | ||
+ | </geshi> | ||
+ | :: มีไว้สำหรับสร้าง view matrix และ projection matrix สำหรับเซตมุมกล้อง | ||
+ | :* โค้ดสองบรรทัดต่อไป | ||
+ | <geshi lang="C#"> | ||
+ | Matrix[] transforms = new Matrix[model.Bones.Count]; | ||
+ | model.CopyAbsoluteBoneTransformsTo(transforms); | ||
+ | </geshi> | ||
+ | :* จำเป็นต้องมีเนื่องจาก | ||
+ | ::* Model ใน XNA สามารถแบ่งออกเป็นหลายๆ ส่วน | ||
+ | ::* แต่ละส่วนนี้แทนด้วย object ชนิด <tt>ModelMesh</tt> | ||
+ | ::* แต่ละส่วนของ Model นี้ถูกยึดเข้าด้วยกันด้วยกระุดูก (bone) เพื่อให้ทำ skeletal animation แบบง่ายๆ ได้ | ||
+ | ::* แต่ละ bone จะมี transform ของตัวมันเอง | ||
+ | ::* สองบรรทัดข้างบนทำหน้าที่ไปดึง transform ของกระดูกแต่ละตัวออกมาใส่ในอะเรย์ <tt>transforms</tt> | ||
+ | :* ในลูปหลัก | ||
+ | <geshi lang="C#"> | ||
+ | foreach (ModelMesh mesh in model.Meshes) | ||
+ | { | ||
+ | foreach (BasicEffect effect in mesh.Effects) | ||
+ | { | ||
+ | effect.EnableDefaultLighting(); | ||
+ | effect.World = transforms[mesh.ParentBone.Index]; | ||
+ | effect.View = viewMatrix; | ||
+ | effect.Projection = projectMatrix; | ||
+ | } | ||
+ | // Draw the mesh, using the effects set above. | ||
+ | mesh.Draw(); | ||
+ | } | ||
+ | </geshi> | ||
+ | ::* เราลูปวนเข้าไปดู <tt>ModelMesh</tt> แต่ละตัวใน Model | ||
+ | ::* ใน ModelMesh แต่ละส่วนอาจสามารถแบ่งออกเป็นหลายๆ ส่วนย่อยๆ ที่แต่ละส่วนใช้ effect (สี, texture, transform, shader ฯลฯ) แบบเดียวกันในการวาดรูป | ||
+ | ::* ดังนั้นใน ModelMesh อันหนึ่งจะมี object ชนิด Effect ที่ใช้แทน shader ที่ใช้ในการวาดส่วนต่างๆ ของโมเดลอยู่หลายๆ อัน | ||
+ | ::* สิ่งที่เราทำกับ effect เหล่านี้คือ | ||
+ | :::* เราเรียก effect.EnableDefaultLighting() เพื่อตั้งค่าแหล่งกำเนิดแสง | ||
+ | :::* เราเซตมุมกล้องด้วยการกำหนด view (ด้วยคำสั่ง effect.View = viewMatrix;) และ projection matrix (ด้วยคำสั่ง (effect.Projection = projectMatrix;) | ||
+ | :::* เรา transform ตัว mesh ด้วยการเซตค่าให้ world matrix ของ effect นั้น | ||
+ | :::* เราเซตให้ effect.World มีค่าเท่ากับ transforms[mesh.ParentBone.Index] เพื่อให้ mesh ทั้ง mesh ถูกแปลงด้วย transform ของ bone ที่มันติดอยู่ (เรียกว่า parent bone ใน XNA) | ||
+ | ::* หลังจากเซตต่าแล้ว เราเรียก mesh.Draw(); เพื่อสั่งให้ XNA วาด mesh ให้เรา | ||
+ | |||
+ | == การเซตมุมกล้อง == | ||
+ | * การเซตมุมกล้องใน XNA ทำได้โดยการไปกำหนด World, View, และ Project matrix ของ effect ที่เราใช้ | ||
+ | * XNA มีเมธอดสำหรับสร้าง transform ที่ใช้สะดวกอยู่หลายเมธอด | ||
+ | :* Matrix.CreatePerspctiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance) | ||
+ | ::* สร้าง perspective matrix | ||
+ | ::* fieldOfView = ความกว้างของมุมยอดของ frustum ที่ผู้ใช้มองเห็น '''มีหน่วยเป็น radian''' | ||
+ | ::* Argument ตัวอื่นมีความหมายเหมือนฟังก์ชัน [http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml gluPerspective ของ OpenGL] | ||
+ | :* Matrix.CreateLoopAt(Vector3 cameraPostition, Vector3 cameraTarget, Vector3 cameraUpVector) | ||
+ | ::* สร้าง look-at matrix | ||
+ | ::* มีความหมายเหมือน [http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml gluLookAt ของ OpenGL] | ||
+ | :* Matrix.CreateTranslation(Vector3 displacement) | ||
+ | ::* สร้าง translation matrix | ||
+ | :* Matrix.CreateRotation( |
รุ่นแก้ไขปัจจุบันเมื่อ 14:59, 27 มกราคม 2554
Model
- ใน XNA มีีคลาส Model สำหรับโมเดลสามมิติพื้นฐาน
- Content pipeline ที่ติดมากับ XNA สามารถอ่านไฟล์ .x (ไฟล์ของ DirectX) และไฟล์ .fbx (ไฟล์ของ Adobe ที่สามารถ export ได้จาก Maya และ 3D Studio Max) ได้
- ตัวอย่างการอ่านไฟล์
<geshi lang="C#">
public class Game1 : Microsoft.Xna.Framework.Game { Model model;
protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); model = Content.Load<Model>("teapot"); } }
</geshi>
- เวลาแสดงโมเดลให้ใช้โค้ดต่อไปนี้
<geshi lang="C#">
public class Game1 : Microsoft.Xna.Framework.Game { protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue);
Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); Matrix projectMatrix = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4, 1.0f, 0.1f, 100.0f);
// Copy any parent transforms. Matrix[] transforms = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(transforms); foreach (ModelMesh mesh in model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index]; effect.View = viewMatrix; effect.Projection = projectMatrix; } // Draw the mesh, using the effects set above. mesh.Draw(); }
base.Draw(gameTime); } }
</geshi>
- อธิบาย
- โค้ดสองบรรทัดที่เกี่ยวข้องกับเมตริกส์สองบรรทัด
<geshi lang="C#">
Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0, 5), new Vector3(0, 0, 0), new Vector3(0, 1, 0)); Matrix projectMatrix = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 4, 1.0f, 0.1f, 100.0f);
</geshi>
- มีไว้สำหรับสร้าง view matrix และ projection matrix สำหรับเซตมุมกล้อง
- โค้ดสองบรรทัดต่อไป
<geshi lang="C#">
Matrix[] transforms = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(transforms);
</geshi>
- จำเป็นต้องมีเนื่องจาก
- Model ใน XNA สามารถแบ่งออกเป็นหลายๆ ส่วน
- แต่ละส่วนนี้แทนด้วย object ชนิด ModelMesh
- แต่ละส่วนของ Model นี้ถูกยึดเข้าด้วยกันด้วยกระุดูก (bone) เพื่อให้ทำ skeletal animation แบบง่ายๆ ได้
- แต่ละ bone จะมี transform ของตัวมันเอง
- สองบรรทัดข้างบนทำหน้าที่ไปดึง transform ของกระดูกแต่ละตัวออกมาใส่ในอะเรย์ transforms
- ในลูปหลัก
<geshi lang="C#">
foreach (ModelMesh mesh in model.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.EnableDefaultLighting(); effect.World = transforms[mesh.ParentBone.Index]; effect.View = viewMatrix; effect.Projection = projectMatrix; } // Draw the mesh, using the effects set above. mesh.Draw(); }
</geshi>
- เราลูปวนเข้าไปดู ModelMesh แต่ละตัวใน Model
- ใน ModelMesh แต่ละส่วนอาจสามารถแบ่งออกเป็นหลายๆ ส่วนย่อยๆ ที่แต่ละส่วนใช้ effect (สี, texture, transform, shader ฯลฯ) แบบเดียวกันในการวาดรูป
- ดังนั้นใน ModelMesh อันหนึ่งจะมี object ชนิด Effect ที่ใช้แทน shader ที่ใช้ในการวาดส่วนต่างๆ ของโมเดลอยู่หลายๆ อัน
- สิ่งที่เราทำกับ effect เหล่านี้คือ
- เราเรียก effect.EnableDefaultLighting() เพื่อตั้งค่าแหล่งกำเนิดแสง
- เราเซตมุมกล้องด้วยการกำหนด view (ด้วยคำสั่ง effect.View = viewMatrix;) และ projection matrix (ด้วยคำสั่ง (effect.Projection = projectMatrix;)
- เรา transform ตัว mesh ด้วยการเซตค่าให้ world matrix ของ effect นั้น
- เราเซตให้ effect.World มีค่าเท่ากับ transforms[mesh.ParentBone.Index] เพื่อให้ mesh ทั้ง mesh ถูกแปลงด้วย transform ของ bone ที่มันติดอยู่ (เรียกว่า parent bone ใน XNA)
- หลังจากเซตต่าแล้ว เราเรียก mesh.Draw(); เพื่อสั่งให้ XNA วาด mesh ให้เรา
การเซตมุมกล้อง
- การเซตมุมกล้องใน XNA ทำได้โดยการไปกำหนด World, View, และ Project matrix ของ effect ที่เราใช้
- XNA มีเมธอดสำหรับสร้าง transform ที่ใช้สะดวกอยู่หลายเมธอด
- Matrix.CreatePerspctiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
- สร้าง perspective matrix
- fieldOfView = ความกว้างของมุมยอดของ frustum ที่ผู้ใช้มองเห็น มีหน่วยเป็น radian
- Argument ตัวอื่นมีความหมายเหมือนฟังก์ชัน gluPerspective ของ OpenGL
- Matrix.CreateLoopAt(Vector3 cameraPostition, Vector3 cameraTarget, Vector3 cameraUpVector)
- สร้าง look-at matrix
- มีความหมายเหมือน gluLookAt ของ OpenGL
- Matrix.CreateTranslation(Vector3 displacement)
- สร้าง translation matrix
- Matrix.CreateRotation(