1

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;
        }
    }
}

どんな助けでも大歓迎です。

4

1 に答える 1

4

私はこれをコメントに入れますが、私にはまだそうする特権がありません。

ここにXNAがインストールされていないのでテストできませんが、顔が間違った方向を向いているように見えます。

面には常に可視面とシースルー面があります。あなたの顔を通り抜けて、それらをひっくり返します。あなたがそうするとき、あなたはそれらが現れたり消えたりするのを見るでしょう。

于 2012-11-22T23:51:32.963 に答える