2013-07-19 133 views
2

我最近學習xna並試圖使用頂點創建一個房間。我去嘗試Riemeres XNA教程,並學習了很多,但我似乎無法讓我的相機工作得很好,每當我向左或向右移動時,我的一些圖像或紋理似乎消失並重新出現。請幫忙。圍繞創建的頂點旋轉

這是我的代碼。

public struct MyOwnVertexFormat 
{ 
    public Vector3 position; 
    private Vector2 texCoord; 

    public MyOwnVertexFormat(Vector3 position, Vector2 texCoord) 
    { 
     this.position = position; 
     this.texCoord = texCoord; 
    } 

    public readonly static VertexDeclaration VertexDeclaration = new VertexDeclaration 
     (
      new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0), 
      new VertexElement(sizeof(float) * 3, VertexElementFormat.Vector2, VertexElementUsage.TextureCoordinate, 0) 
     ); 
} 

public class Game1 : Microsoft.Xna.Framework.Game 
{ 
    GraphicsDeviceManager graphics; 
    GraphicsDevice device; 

    Effect effect; 
    Matrix viewMatrix; 
    Matrix projectionMatrix; 
    VertexBuffer vertexBuffer; 
    Vector3 cameraPos; 
    Texture2D streetTexture; 
    private Vector3 Position = Vector3.One; 
    private float Zoom = 2500; 
    private float RotationY = 0.0f; 
    private float RotationX = 0.0f; 
    private Matrix gameWorldRotation; 
    public Game1() 
    { 
     graphics = new GraphicsDeviceManager(this); 
     Content.RootDirectory = "Content"; 
    } 

    protected override void Initialize() 
    { 
     graphics.PreferredBackBufferWidth =1024; 
     graphics.PreferredBackBufferHeight = 768; 
     graphics.IsFullScreen = false; 
     graphics.ApplyChanges(); 

     base.Initialize(); 
    } 

    protected override void LoadContent() 
    { 
     device = GraphicsDevice; 


     effect = Content.Load<Effect>("OurHLSLfile"); SetUpVertices(); 
     SetUpCamera(); 


     streetTexture = Content.Load<Texture2D>("streettexture"); 
    } 
    private void UpdateKeyboard() 
    { 
     if (Keyboard.GetState().IsKeyDown(Keys.Escape)) 
      Exit(); 
     if (Keyboard.GetState().IsKeyDown(Keys.Up)) 
      RotationX += 1.0f; 
     if (Keyboard.GetState().IsKeyDown(Keys.Down)) 
      RotationX -= 1.0f; 
     if (Keyboard.GetState().IsKeyDown(Keys.Left)) 
      RotationY += 1.0f; 
     if (Keyboard.GetState().IsKeyDown(Keys.Right)) 
      RotationY -= 1.0f; 
     gameWorldRotation = 
      Matrix.CreateRotationX(MathHelper.ToRadians(RotationX)) * 
      Matrix.CreateRotationY(MathHelper.ToRadians(RotationY)); 
    } 
    private void SetUpVertices() 
    { 

     MyOwnVertexFormat[] vertices = new MyOwnVertexFormat[12]; 

     vertices[0] = new MyOwnVertexFormat(new Vector3(-20, 0, 10), new Vector2(-0.25f, 25.0f)); 
     vertices[1] = new MyOwnVertexFormat(new Vector3(-20, 0, -100), new Vector2(-0.25f, 0.0f)); 
     vertices[2] = new MyOwnVertexFormat(new Vector3(2, 0, 10), new Vector2(0.25f, 25.0f)); 
     vertices[3] = new MyOwnVertexFormat(new Vector3(2, 0, -100), new Vector2(0.25f, 0.0f)); 

     vertices[4] = new MyOwnVertexFormat(new Vector3(2, 1, 10), new Vector2(0.375f, 25.0f)); 
     vertices[5] = new MyOwnVertexFormat(new Vector3(2, 1, -100), new Vector2(0.375f, 0.0f)); 
     vertices[6] = new MyOwnVertexFormat(new Vector3(3, 1, 10), new Vector2(0.5f, 25.0f)); 
     vertices[7] = new MyOwnVertexFormat(new Vector3(3, 1, -100), new Vector2(0.5f, 0.0f)); 

     vertices[8] = new MyOwnVertexFormat(new Vector3(-13, 1, 10), new Vector2(0.75f, 25.0f)); 
     vertices[9] = new MyOwnVertexFormat(new Vector3(-13, 1, -100), new Vector2(0.75f, 0.0f)); 
     vertices[10] = new MyOwnVertexFormat(new Vector3(-13, 21, 10), new Vector2(1.25f, 25.0f)); 
     vertices[11] = new MyOwnVertexFormat(new Vector3(-13, 21, -100), new Vector2(1.25f, 0.0f)); 

     vertexBuffer = new VertexBuffer(device, MyOwnVertexFormat.VertexDeclaration, vertices.Length, BufferUsage.WriteOnly); 
     vertexBuffer.SetData(vertices); 
    } 

    private void SetUpCamera() 
    { 
     cameraPos = new Vector3(-25, 13, 75); 
     viewMatrix = Matrix.CreateLookAt(cameraPos, new Vector3(0, 2, -12), new Vector3(0, 1, 0)); 
     projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 1.0f, 5000.0f); 
    } 

    protected override void UnloadContent() 
    { 
    } 

    protected override void Update(GameTime gameTime) 
    { 
     if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) 
      this.Exit(); 
     UpdateKeyboard(); 
     base.Update(gameTime); 
    } 

    protected override void Draw(GameTime gameTime) 
    { 
     device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.DarkSlateBlue, 1.0f, 0); 

     effect.CurrentTechnique = effect.Techniques["Simplest"]; 
     effect.Parameters["xViewProjection"].SetValue(viewMatrix * projectionMatrix * gameWorldRotation); 
     effect.Parameters["xTexture"].SetValue(streetTexture); 

     foreach (EffectPass pass in effect.CurrentTechnique.Passes) 
     { 
      pass.Apply(); 

      device.SetVertexBuffer(vertexBuffer); 
      device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 10); 
     } 

     base.Draw(gameTime); 
    } 
} 

回答

1

我認爲這是一個預測問題。這條線,從你的代碼採取加強我的假設:

viewMatrix * projectionMatrix * gameWorldRotation 

TL;博士,正確的順序是:

gameWorldRotation * viewMatrix * projectionMatrix 

乘以矩陣時,請記住,爲了事宜。用數學術語表示:

矩陣乘法不可交換!

這三個矩陣將一個矢量映射到三個不同的座標系,即世界,視圖和投影空間。通常頂點是在對象空間中定義的。相乘的矢量與世界(圖,投影)矩陣帶來你的載體世界(圖,投影)空間:

object space => world space => view space => projection space 

XNA使用的行向量佈局(與列矢量)。這意味着矢量被水平聲明(x, y, z)。跳過 dry interesting details,這意味着轉化矢量時(用矩陣的向量乘以),則矢量是左操作數,而矩陣是右操作數

A := [3x3 Matrix] 

(x, y, z) * A = (x', y', z') // The result is another 3D vector 

現在,爲了應用所有三個矩陣,我們簡單地使用先前的變換輸入下一個變換的結果:

W .... world matrix 
V .... view matrix 
W .... projection matrix 
x .... vector 
x' ... transformed vector 

x' = ((x * W) * V) * P 

最後,矩陣乘法是聯想(括號沒有馬tter)。這就是爲什麼我們可以把它發送到設備前的世界,視圖和投影矩陣合併爲一個矩陣:

x' = ((x * W) * V) * P = x * W * V * P = x * (W * V * P) 

世界*查看*投影。這就是你需要的。 (也許一些基本的矩陣數學爲您的未來工作。)

+0

謝謝你的幫助..我沒有意識到訂單問題。你是一個很大的幫助! – kivra