Presentation is loading. Please wait.

Presentation is loading. Please wait.

2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第五章 頂點定義與基本形狀的繪出.

Similar presentations


Presentation on theme: "2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第五章 頂點定義與基本形狀的繪出."— Presentation transcript:

1 2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第五章 頂點定義與基本形狀的繪出

2 本章目的 介紹頂點格式、基本形狀 (Primitives)與基本特效 (BasicEffect)

3 XNA內定的頂點格式 VertexPositionColor3D 座標和顏色
VertexPositionTexture3D 座標和一組紋理圖UV座標 VertexPositionColorTexture3D 座標、顏色和一組紋理圖UV座標 VertexPositionNormalTexture3D 座標、法向量和一組紋理圖UV座標

4 VertexPositionColor public struct VertexPositionColor {
public Vector3 Position; // 3D 座標 public Color Color; // 顏色 public static readonly VertexElement[] VertexElements; //頂點格式宣告 public VertexPositionColor(Vector3 position, Color color); //建構元 public static int SizeInBytes { get; }); // 每個頂點大小 ..... }

5 VertexPositionTexture
public struct VertexPositionTexture { public Vector3 Position; // 3D 座標 public Vector2 TextureCoordinate; // 紋理圖UV座標 public static readonly VertexElement[] VertexElements; //頂點格式宣告 public VertexPositionTexture (Vector3 position, Vector2 textureCoordinate;); //建構元 public static int SizeInBytes { get; } // 每個頂點大小 ..... }

6 VertexPositionColorTexture
public struct VertexPositionColorTexture { public Vector3 Position; // 3D 座標 public Color Color; // 顏色 public Vector2 TextureCoordinate; // 紋理圖UV座標 public static readonly VertexElement[] VertexElements; //頂點格式宣告 public VertexPositionColorTexture(Vector3 position, Color color, Vector2 textureCoordinate;); //建構元 public static int SizeInBytes { get; } // 每個頂點大小 ..... }

7 VertexPositionNormalTexture
public struct VertexPositionNormalTexture { public Vector3 Position; // 3D 座標 public Vector3 Normal; // 法向量 public Vector2 TextureCoordinate; // 紋理圖UV座標 public static readonly VertexElement[] VertexElements; //頂點格式宣告 public VertexPositionNormalTexture(Vector3 position, Vector3 normal, Vector2 textureCoordinate;); //建構元 public static int SizeInBytes { get; } // 每個頂點大小 ..... }

8 頂點陣列 (宣告六個頂點) VertexPositionColor[] vertices = new VertexPositionColor[6]; vertices[0] = new VertexPositionColor(new Vector3(-1, 0.0f, 0.0f), Color.White); vertices[1] = new VertexPositionColor(new Vector3(1, 0.0f, 0.0f), Color.White); …..

9 將頂點陣列的內容複製到頂點緩衝 private VertexBuffer vertexBuffer; // 頂點緩衝區
vertexBuffer = new VertexBuffer(this.GraphicsDevice, 6 * VertexPositionColor.SizeInBytes, // 總共要多大的空間 BufferUsage.WriteOnly); // 使用方式--寫入 // 把頂點陣列複製到頂點緩衝區內 vertexBuffer.SetData<VertexPositionColor>(vertices);

10 建立一個六個頂點資料的頂點緩衝區

11 繪出前的頂點設定 // 頂點格式宣告 graphics.GraphicsDevice.VertexDeclaration =
// 頂點格式宣告 graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionColor.VertexElements); // 設定 頂點資料流 編號 0 就是第一條 的 來源 graphics.GraphicsDevice.Vertices[0].SetSource( vertexBuffer, // 使用 vertexBuffer 頂點緩衝區 0, // 從頭開始 VertexPositionColor.SizeInBytes); // 每一個頂點 的大小

12 基本形狀 (Primitives) public enum PrimitiveType { PointList = 1, // 點
LineList = 2, // 兩點成一線 LineStrip = 3, // 點串成一線 TriangleList = 4, // 三點成一個面 TriangleStrip = 5, // 三點成一個面 TriangleFan = 6, // 三點成一個面 }

13 PointList基本形狀

14 LineList基本形狀

15 LineStrip基本形狀

16 TriangleList 基本形狀

17 TriangleStrip 基本形狀

18 TriangleFan 基本形狀

19 DrawPrimitives()方法

20 BasicEffect (基本特效) 在繪出時,必須要有一種設定來描述世界座標、相機位置、相機投影方式、燈光來源等等。XNA提供一個簡易的類別 BasicEffect (基本特效)來負責這項工作。

21 BasicEffect (基本特效) BasicEffect effect; // 基本特效
effect = new BasicEffect(graphics.GraphicsDevice, null); effect.World = Matrix.Identity; // 世界矩陣 effect.View = Matrix.CreateLookAt(new Vector3(2.0f, 2.0f, 2.0f), Vector3.Zero, Vector3.Up); // 視覺矩陣 effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), 1.333f, 1.0f, 10.0f); // 投影矩陣

22 範例一:顯示出六個頂點 定義兩個旋轉角度的global variable. 在initialize()定義六個頂點及
在update()改變旋轉角度 在draw()定義世界矩陣與投影矩陣,並顯示出結果

23 範例一:顯示出六個頂點 定義兩個旋轉角度的global variable.
public class Game1 : Microsoft.Xna.Framework.Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; private VertexBuffer vertexBuffer; // 頂點緩衝區 private BasicEffect effect; // 基本 特效 float modelRotation_Y = 0; // 旋轉角度 全域變數 float modelRotation_X = 0; // 旋轉角度 全域變數 public Game1() { ……… }

24 範例一:顯示出六個頂點 2. 在initialize()定義六個頂點
protected override void Initialize() { // TODO: Add your initialization logic here effect = new BasicEffect(graphics.GraphicsDevice, null); VertexPositionColor[] vertices = new VertexPositionColor[6]; // X axis at [0,1], Y axis at[2,3], Z axis at [4,5] vertices[0] = new VertexPositionColor(new Vector3(-1, 0.0f, 0.0f), Color.Red); vertices[1] = new VertexPositionColor(new Vector3(1, 0.0f, 0.0f), Color.Red); vertices[2] = new VertexPositionColor(new Vector3(0.0f, -1, 0.0f), Color.Green); vertices[3] = new VertexPositionColor(new Vector3(0.0f, 1, 0.0f), Color.Green); vertices[4] = new VertexPositionColor(new Vector3(0.0f, 0.0f, -1), Color.Blue); vertices[5] = new VertexPositionColor(new Vector3(0.0f, 0.0f, 1), Color.Blue); vertexBuffer = new VertexBuffer(this.GraphicsDevice, *VertexPositionColor.SizeInBytes, BufferUsage.WriteOnly); vertexBuffer.SetData<VertexPositionColor>(vertices); base.Initialize(); }

25 範例一:顯示出六個頂點 3. 在update()改變旋轉角度
protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // TODO: Add your update logic here modelRotation_Y += 0.01f; modelRotation_X += 0.01f; base.Update(gameTime); }

26 範例一:顯示出六個頂點 4.在draw()定義世界矩陣與投影矩陣,並顯示出結果
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // Set the World Matrix effect.World = Matrix.CreateRotationY(modelRotation_Y) * Matrix.CreateRotationX(modelRotation_X); // 世界矩陣 effect.View = Matrix.CreateLookAt(new Vector3(2.0f, 2.0f, 2.0f), Vector3.Zero, Vector3.Up); // 視覺矩陣 effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), 1.333f, 1.0f, 10.0f); // 投影矩陣 effect.LightingEnabled = false; // 沒設光源 所以不作燈光運算 effect.VertexColorEnabled = true; ……… }

27 範例一:顯示出六個頂點 4.在draw()定義世界矩陣與投影矩陣,並顯示出結果
protected override void Draw(GameTime gameTime) { …….. // 頂點格式宣告 graphics.GraphicsDevice.VertexDeclaration = new VertexDeclaration(graphics.GraphicsDevice, VertexPositionColor.VertexElements); // 設定 頂點資料流 編號 0 就是第一條 的 來源 graphics.GraphicsDevice.Vertices[0].SetSource( vertexBuffer, //使用 vertexBuffer 頂點緩衝區 0, // 從頭開始 VertexPositionColor.SizeInBytes); // 每一個頂點 的大小 graphics.GraphicsDevice.RenderState.PointSize = 10;

28 範例一:顯示出六個頂點 4.在draw()定義世界矩陣與投影矩陣,並顯示出結果
protected override void Draw(GameTime gameTime) { …….. // Draw the 3D axis effect.Begin(); foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes) { CurrentPass.Begin(); graphics.GraphicsDevice.DrawPrimitives(PrimitiveType.PointList, 0, 6); CurrentPass.End(); } effect.End(); base.Draw(gameTime); } }

29 範例一:顯示出六個頂點 改變點的尺寸 畫出三個軸(範例二) 畫出對Y軸旋轉(範例三) 畫出七個點
Homework: 將XYZ三個字母化在對應的軸上 Homework: 顯示出一個正立方體的外框,不需要考慮每一面是否有方向性(normal向量皆朝外)

30 範例一:顯示出六個頂點 4.在draw()定義世界矩陣與投影矩陣,並顯示出結果
protected override void Draw(GameTime gameTime) { …….. // Draw the 3D axis effect.Begin(); foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes) { CurrentPass.Begin(); graphics.GraphicsDevice.DrawPrimitives(PrimitiveType.PointList, 0, 6); CurrentPass.End(); } effect.End(); base.Draw(gameTime); } }

31 範例二:顯示出三個軸線 4.在draw()定義世界矩陣與投影矩陣,並顯示出結果
protected override void Draw(GameTime gameTime) { …….. // Draw the 3D axis effect.Begin(); foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes) { CurrentPass.Begin(); graphics.GraphicsDevice.DrawPrimitives(PrimitiveType.PointList, 0, 6); CurrentPass.End(); } effect.End(); base.Draw(gameTime); } }

32 範例三:顯示出一個立方體 1. 定義八個頂點 2. 定義十二個三角形,其中兩個三角形形成一平面 3. 繪出

33 範例三:顯示出一個立方體 定義八個頂點 protected override void Initialize() { ………
{ ……… VertexPositionColor[] vertices = new VertexPositionColor[8]; // X, Y, Z axis vertices[0] = new VertexPositionColor(new Vector3(-1.0f, -1.0f, -1.0f), Color.White); vertices[1] = new VertexPositionColor(new Vector3(-1.0f, 1.0f, -1.0f), Color.White); vertices[2] = new VertexPositionColor(new Vector3(1.0f, 1.0f, -1.0f), Color.White); vertices[3] = new VertexPositionColor(new Vector3(1.0f, -1.0f, -1.0f), Color.White); vertices[4] = new VertexPositionColor(new Vector3(-1.0f, -1.0f, 1.0f), Color.White); vertices[5] = new VertexPositionColor(new Vector3(-1.0f, 1.0f, 1.0f), Color.White); vertices[6] = new VertexPositionColor(new Vector3(1.0f, 1.0f, 1.0f), Color.White); vertices[7] = new VertexPositionColor(new Vector3(1.0f, -1.0f, 1.0f), Color.White); vertexBuffer = new VertexBuffer(this.GraphicsDevice, 8*VertexPositionColor.SizeInBytes, BufferUsage.WriteOnly); // 產生 頂點緩衝區 vertexBuffer.SetData<VertexPositionColor>(vertices); // 複製 頂點資料

34 範例三:顯示出一個立方體 2. 在initialize定義六個平面,共十二個三角形
short[] vertexIndices = new short[36]; // 36 個 頂點索引 vertexIndices[0] = 3; vertexIndices[1] = 2; vertexIndices[2] = 1; // 後面 vertexIndices[3] = 3; vertexIndices[4] = 1; vertexIndices[5] = 0; vertexIndices[6] = 4; vertexIndices[7] = 5; vertexIndices[8] = 6; // 前面 vertexIndices[9] = 4; vertexIndices[10] = 6; vertexIndices[11] = 7; vertexIndices[12] = 0; vertexIndices[13] = 1; vertexIndices[14] = 5; // 左面 vertexIndices[15] = 0; vertexIndices[16] = 5; vertexIndices[17] = 4; vertexIndices[18] = 7; vertexIndices[19] = 6; vertexIndices[20] = 2; // 右面 vertexIndices[21] = 7; vertexIndices[22] = 2; vertexIndices[23] = 3; vertexIndices[24] = 5; vertexIndices[25] = 1; vertexIndices[26] = 2;// 上面 vertexIndices[27] = 5; vertexIndices[28] = 2; vertexIndices[29] = 6; vertexIndices[30] = 0; vertexIndices[31] = 4; vertexIndices[32] = 7;// 下面 vertexIndices[33] = 0; vertexIndices[34] = 7; vertexIndices[35] = 3;

35 範例三:顯示出一個立方體 2. 在initialize定義六個平面,共十二個三角形
indexBuffer = new IndexBuffer(this.GraphicsDevice, 36 * sizeof(short), BufferUsage.WriteOnly, IndexElementSize.SixteenBits); // 產生 頂點索引緩衝區 indexBuffer.SetData<short>(vertexIndices); // 複製 頂點索引資料個三角形, base.Initialize(); }

36 範例三:顯示出一個立方體 3. 繪出 protected override void Draw(GameTime gameTime)
{ ………. // Set the World Matrix modelRotation += 0.01f; effect.World = Matrix.CreateRotationY(modelRotation); // 世界矩陣 effect.View = Matrix.CreateLookAt(new Vector3(4.0f, 4.0f, 4.0f), Vector3.Zero, Vector3.Up); // 視覺矩陣 effect.Projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f), 1.333f, 1.0f, 10.0f); // 投影矩陣 effect.LightingEnabled = false; // 沒設光源 所以不作燈光運算

37 範例三:顯示出一個立方體 3. 繪出 protected override void Draw(GameTime gameTime)
{ ………. // 頂點格式宣告 graphics.GraphicsDevice.VertexDeclaration = new vertexDeclaration(this.GraphicsDevice, VertexPositionColor.VertexElements); // 設定 頂點資料流 編號 0 就是第一條 的 來源 graphics.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, //使用頂點緩衝區 0, // 從頭開始 VertexPositionColor.SizeInBytes); // 每一個頂點 的大小 graphics.GraphicsDevice.Indices = indexBuffer; // 頂點索引緩衝區 graphics.GraphicsDevice.RenderState.FillMode = FillMode.WireFrame; // 畫線條 graphics.GraphicsDevice.RenderState.CullMode = CullMode.CullCounterClockwiseFace; //內定 逆時間 裁掉

38 範例三:顯示出一個立方體 3. 繪出 protected override void Draw(GameTime gameTime)
{ ………. // Draw the 3D axis effect.Begin(); foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes) { CurrentPass.Begin(); effect.DiffuseColor = new Vector3(1.0f, 0.0f, 0.0f); effect.CommitChanges();

39 範例三:顯示出一個立方體 3. 繪出 protected override void Draw(GameTime gameTime)
{ ………. graphics.GraphicsDevice.DrawIndexedPrimitives( PrimitiveType.TriangleList, // 三個點 為一個面 0, // 索引偏移値 Offset to add to each vertex index in the index buffer. 0, // 頂點緩衝區 的 頂點 偏移値 8, // 頂點 個數 0, // 開始 的 索引 Location in the index array at which to start reading vertices 12 // 畫 12 個 三角面 ); CurrentPass.End(); } effect.End(); base.Draw(gameTime); } } }

40 範例四:有文理貼圖的立方體 宣告變數 Load 貼圖 產生特效

41 範例四:有文理貼圖的立方體 public class Game1 : Microsoft.Xna.Framework.Game // 1.
{…… private BasicEffect effect; // 基本 特效 Texture2D texture; ……..} protected override void LoadContent() // 2 {…… texture = Content.Load<Texture2D>("Sun"); ………} protected override void Draw(GameTime gameTime) {…… // Draw the 3D axis effect.Begin(); foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes) { CurrentPass.Begin(); effect.Texture = texture; effect.TextureEnabled = true; this.GraphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, 12); CurrentPass.End(); } effect.End(); ……….}

42 範例五:格線類別製作 Page 5-21~25 新增專案並加入類別: 專案/加入類別 建立檔案:
新增專案並加入類別: 專案/加入類別 建立檔案: 在『加入新項目』中選擇『Game Component』,存入檔案名稱GameComponent_Grid.cs 開啟檔案,將父親類別改為Microsoft.Xna.Framework.DrawableGameComponent

43 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent { public int gridSize = 12; // 每邊有 幾格 public float gridScale = 5.0f; // 每格 的 寬 public Color gridColor = new Color(0xFF, 0xFF, 0xFF, 0xFF); //格線的顏色黑色 VertexBuffer vertexBuffer; // 頂點緩衝區, private VertexDeclaration vertexDeclaration; // 頂點格式 (每個頂點 包含什麼內容) BasicEffect effect; // 產出時會用到的 效果 int vertexCount; // 頂點 數目 GraphicsDevice device; //繪圖設備 …….}

44 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent {…….. public Matrix world = Matrix.Identity; // 世界 觀測 投影 矩陣 public Matrix view = Matrix.CreateLookAt(new Vector3(0.0f, 20.0f, 20.0f), Vector3.Zero, Vector3.Up); public Matrix projection = Matrix.CreatePerspectiveFieldOfView( MathHelper.ToRadians(45.0f),1.333f, 1.0f, f); //在GameComponent_Grid的Constructor先存好繪圖設備備用 public GameComponent_Grid(Game game) : base(game) { // TODO: Construct any child components here this.device = game.GraphicsDevice; ……… }

45 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent {…….. // Allows the game component to perform any initialization it // needs to before starting to run. This is where it can query for any required // services and load content. public override void Initialize() { // TODO: Add your initialization code here effect = new BasicEffect(device, null); // 效果 vertexCount=(gridSize + 1)*4; // 每邊的頂點數比每邊的格數多一,共有四個邊 // 每個頂點 包含 位置 和 顏色 ,先空出 vertexCount 個頂點 VertexPositionColor[] vertices = new VertexPositionColor[vertexCount]; float length = (float)gridSize * gridScale; // 邊長 等於 格數 乘以 格寬 float halfLength = length * 0.5f; // 半邊長 因為是要以原點為中心左右半

46 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent {…… int index = 0; // 頂點 索引 // 定義頂點位置 頂都是 躺在 X Z 平面上 for (int i = 0; i <= gridSize; ++i) { vertices[index++] = new VertexPositionColor( new Vector3(-halfLength, 0.0f, i*gridScale-halfLength), gridColor); // 左邊的頂點 vertices[index++] = new VertexPositionColor( new Vector3(halfLength, 0.0f, i*gridScale-halfLength), gridColor); // 右邊的頂點 new Vector3(i*gridScale-halfLength, 0.0f, -halfLength), gridColor); // 上緣的頂點 new Vector3(i*gridScale-halfLength, 0.0f, halfLength), gridColor); // 下緣的頂點 }

47 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent {……// 建立 頂點緩衝區 vertexBuffer = new VertexBuffer(device, vertexCount * VertexPositionColor.SizeInBytes, BufferUsage.WriteOnly); // 將頂點資料複製入頂點緩衝區內 vertexBuffer.SetData<VertexPositionColor>(vertices); // 頂點格式 vertexDeclaration = new VertexDeclaration(device, VertexPositionColor.VertexElements); base.Initialize(); }

48 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent { …..// Allows the game component to update itself. // name="gameTime">Provides a snapshot of timing values. public override void Update(GameTime gameTime) { // TODO: Add your update code here base.Update(gameTime); }

49 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent { ….. public override void Draw(GameTime gameTime) { // 效果 三大矩陣 設定 effect.World = world; effect.View = view; effect.Projection = projection; effect.VertexColorEnabled = true; // 使用 頂點顏色 效果 device.VertexDeclaration = vertexDeclaration; // 頂點格式 device.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes); // 頂點來源

50 範例五:格線類別製作 (GameComponent_Grid.cs)
public class GameComponent_Grid : Microsoft.Xna.Framework.DrawableGameComponent { ….. public override void Draw(GameTime gameTime) ………….. effect.Begin(); // 效果 開始 foreach (EffectPass CurrentPass in effect.CurrentTechnique.Passes) { CurrentPass.Begin(); device.DrawPrimitives(PrimitiveType.LineList, 0, vertexCount / 2); // 兩兩畫線 所以只有 vertexCount/2 條線 CurrentPass.End(); } effect.End();

51 範例五:格線類別製作 (Game1.cs) protected override void Initialize() {
// TODO: Add your initialization logic here Grid = new GameComponent_Grid(this); this.Components.Add(Grid); base.Initialize(); }


Download ppt "2D / 3D 遊戲程式設計入門 使用 XNA 3.0 與 C# 第五章 頂點定義與基本形狀的繪出."

Similar presentations


Ads by Google