2012-11-22 72 views
1

XNA有一個奇怪的問題。XNA原語不按預期呈現

我已經經歷了以下教程: http://www.i-programmer.info/projects/119-graphics-and-games/1108-getting-started-with-3d-xna.html

我已經完成了教程,但我完成的立方體呈現像這樣: enter image description here

enter image description here

enter image description here

如您所見,根據多維數據集的旋轉,某些頂點不會呈現。

如果旋轉被刪除,立方體呈現像這樣: enter image description here

我完整的代碼如下(UPDATE:這是固定的代碼,正常顯示):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace _3DTutorial { 
    /// <summary> 
    /// This is the main type for your game 
    /// </summary> 
    public class Game1 : Microsoft.Xna.Framework.Game { 
     GraphicsDeviceManager graphics; 
     SpriteBatch spriteBatch; 

     // Tut items 
     private BasicEffect effect; 
     private VertexPositionNormalTexture[] cube; 
     private float angle = 0; 

     public Game1() { 
      graphics = new GraphicsDeviceManager(this); 
      Content.RootDirectory = "Content"; 
     } 

     /// <summary> 
     /// Allows the game to perform any initialization it needs to before starting to run. 
     /// This is where it can query for any required services and load any non-graphic 
     /// related content. Calling base.Initialize will enumerate through any components 
     /// and initialize them as well. 
     /// </summary> 
     protected override void Initialize() { 
      // TODO: Add your initialization logic here 

      effect = new BasicEffect(graphics.GraphicsDevice); 

      effect.AmbientLightColor = new Vector3(0.0f, 1.0f, 0.0f); 
      effect.DirectionalLight0.Enabled = true; 
      effect.DirectionalLight0.DiffuseColor = Vector3.One; 
      effect.DirectionalLight0.Direction = Vector3.Normalize(Vector3.One); 

      effect.LightingEnabled = true; 

      Matrix projection = Matrix.CreatePerspectiveFieldOfView(
       (float)Math.PI/4.0f, 
       (float)this.Window.ClientBounds.Width/(float)this.Window.ClientBounds.Height, 
       1f, 
       10f 
      ); 

      effect.Projection = projection; 
      Matrix V = Matrix.CreateTranslation(0f, 0f, -10f); 
      effect.View = V; 

      RasterizerState rs = new RasterizerState(); 
      rs.FillMode = FillMode.WireFrame; 
      graphics.GraphicsDevice.RasterizerState = rs; 

      base.Initialize(); 
     } 

     /// <summary> 
     /// LoadContent will be called once per game and is the place to load 
     /// all of your content. 
     /// </summary> 
     protected override void LoadContent() { 
      // Create a new SpriteBatch, which can be used to draw textures. 
      spriteBatch = new SpriteBatch(GraphicsDevice); 

      // TODO: use this.Content to load your game content here 

      cube = MakeCube(); 
     } 

     /// <summary> 
     /// UnloadContent will be called once per game and is the place to unload 
     /// all content. 
     /// </summary> 
     protected override void UnloadContent() { 
      // TODO: Unload any non ContentManager content here 
     } 

     /// <summary> 
     /// Allows the game to run logic such as updating the world, 
     /// checking for collisions, gathering input, and playing audio. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     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 

      angle = angle + 0.005f; 
      if (angle > 2 * Math.PI) { 
       angle = 0; 
      } 

      Matrix R = Matrix.CreateRotationY(angle) * Matrix.CreateRotationX(.4f); 
      Matrix T = Matrix.CreateTranslation(0.0f, 0f, 5f); 
      effect.World = R * T; 

      base.Update(gameTime); 
     } 

     /// <summary> 
     /// This is called when the game should draw itself. 
     /// </summary> 
     /// <param name="gameTime">Provides a snapshot of timing values.</param> 
     protected override void Draw(GameTime gameTime) { 
      GraphicsDevice.Clear(Color.CornflowerBlue); 

      // TODO: Add your drawing code here 

      foreach (EffectPass pass in effect.CurrentTechnique.Passes) { 
       pass.Apply(); 
       graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, cube, 0, (cube.Length/3)); 
      } 

      base.Draw(gameTime); 
     } 

     protected VertexPositionNormalTexture[] MakeCube() { 
      VertexPositionNormalTexture[] vertexes = new VertexPositionNormalTexture[36]; 
      Vector2 Texcoords = new Vector2(0f, 0f); 

      // A square made of two triangles 
      Vector3[] face = new Vector3[6]; 
      // First triangle - bottom left 
      face[0] = new Vector3(-1f, -1f, 0.0f); 
      // First triangle - top left 
      face[1] = new Vector3(-1f, 1f, 0.0f); 
      // First triangle - top right 
      face[2] = new Vector3(1f, 1f, 0.0f); 
      // Second triangle - top right 
      face[3] = new Vector3(1f, 1f, 0.0f); 
      // Second triangle - bottom right 
      face[4] = new Vector3(1f, -1f, 0.0f); 
      // Second triangle - bottom left 
      face[5] = new Vector3(-1f, -1f, 0.0f); 

      Matrix RotY90 = Matrix.CreateRotationY(-(float)Math.PI/2f); 
      Matrix RotX90 = Matrix.CreateRotationX(-(float)Math.PI/2f); 

      for (int i = 0; i <= 2; i++) { 

       // Front face 
       vertexes[i] = new VertexPositionNormalTexture(
        face[i] + Vector3.UnitZ, 
        Vector3.UnitZ, 
        Texcoords 
       ); 
       vertexes[i + 3] = new VertexPositionNormalTexture(
        face[i + 3] + Vector3.UnitZ, 
        Vector3.UnitZ, 
        Texcoords 
       ); 
       // Back face 
       vertexes[i + 6] = new VertexPositionNormalTexture(
        face[2 - i] - Vector3.UnitZ, 
        -Vector3.UnitZ, 
        Texcoords 
       ); 
       vertexes[i + 6 + 3] = new VertexPositionNormalTexture(
        face[5 - i] - Vector3.UnitZ, 
        -Vector3.UnitZ, 
        Texcoords 
       ); 

       // Left face 
       vertexes[i + 12] = new VertexPositionNormalTexture(
        Vector3.Transform(face[i], RotY90) - Vector3.UnitX, 
        -Vector3.UnitX, 
        Texcoords 
       ); 
       vertexes[i + 12 + 3] = new VertexPositionNormalTexture(
        Vector3.Transform(face[i + 3], RotY90) - Vector3.UnitX, 
        -Vector3.UnitX, 
        Texcoords 
       ); 
       // Right face 
       vertexes[i + 18] = new VertexPositionNormalTexture(
        Vector3.Transform(face[2 - i], RotY90) + Vector3.UnitX, 
        Vector3.UnitX, 
        Texcoords 
       ); 
       vertexes[i + 18 + 3] = new VertexPositionNormalTexture(
        Vector3.Transform(face[5 - i], RotY90) + Vector3.UnitX, 
        Vector3.UnitX, 
        Texcoords 
       ); 

       // Top face 
       vertexes[i + 24] = new VertexPositionNormalTexture(
        Vector3.Transform(face[i], RotX90) + Vector3.UnitY, 
        Vector3.UnitY, 
        Texcoords 
       ); 
       vertexes[i + 24 + 3] = new VertexPositionNormalTexture(
        Vector3.Transform(face[i + 3], RotX90) + Vector3.UnitY, 
        Vector3.UnitY, 
        Texcoords 
       ); 
       // Bottom face 
       vertexes[i + 30] = new VertexPositionNormalTexture(
        Vector3.Transform(face[2 - i], RotX90) - Vector3.UnitY, 
        -Vector3.UnitY, 
        Texcoords 
       ); 
       vertexes[i + 30 + 3] = new VertexPositionNormalTexture(
        Vector3.Transform(face[5 - i], RotX90) - Vector3.UnitY, 
        -Vector3.UnitY, 
        Texcoords 
       ); 

      } 

      return vertexes; 
     } 
    } 
} 

任何幫助表示讚賞。

回答

4

我會把這個評論,但我沒有prividge這樣做呢。

我沒有在這裏安裝XNA,所以我不能測試這個,但它看起來好像你的臉被繪製成面對錯誤的方向。

面孔總會有一個可見的透視面。穿過你的臉並翻轉它們。你會看到它們出現並消失。

+0

是的,這可能是問題所在。我只是補充說,你通過改變你定義點的方向 - 順時針或逆時針「翻轉」你的臉。 – Blorgbeard

+0

哪個方向是可見側的標準,順時針還是逆時針? – Djentleman

+0

這是順時針 - 請參閱[這裏](http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.renderstate.cullmode(v = xnagamestudio.31).aspx) - 默認值是剔除逆時針臉。 – Blorgbeard