1
XNA有一個奇怪的問題。XNA原語不按預期呈現
我已經經歷了以下教程: http://www.i-programmer.info/projects/119-graphics-and-games/1108-getting-started-with-3d-xna.html
我已經完成了教程,但我完成的立方體呈現像這樣:
如您所見,根據多維數據集的旋轉,某些頂點不會呈現。
如果旋轉被刪除,立方體呈現像這樣:
我完整的代碼如下(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;
}
}
}
任何幫助表示讚賞。
是的,這可能是問題所在。我只是補充說,你通過改變你定義點的方向 - 順時針或逆時針「翻轉」你的臉。 – Blorgbeard
哪個方向是可見側的標準,順時針還是逆時針? – Djentleman
這是順時針 - 請參閱[這裏](http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.renderstate.cullmode(v = xnagamestudio.31).aspx) - 默認值是剔除逆時針臉。 – Blorgbeard