XNAで奇妙な問題が発生しています。
私は次のチュートリアルを行ってきました: http ://www.i-programmer.info/projects/119-graphics-and-games/1108-getting-started-with-3d-xna.html
チュートリアルを終了しましたが、完成した立方体は次のようにレンダリングされます。
ご覧のとおり、立方体の回転によっては、一部の頂点がレンダリングされません。
回転を削除すると、立方体は次のようにレンダリングされます。
私の完全なコードは以下のとおりです(更新:これは修正されたコードであり、正しくレンダリングされます):
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;
}
}
}
どんな助けでも大歓迎です。