XNA原语未按预期呈现

时间:2012-11-22 23:42:33

标签: c# 3d rendering xna-4.0 primitive

我对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

我的完整代码如下(更新:这是固定代码,正确呈现):

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

感谢任何帮助。

1 个答案:

答案 0 :(得分:4)

我会把它放在评论中,但我还没有这样做的权限。

我没有在这里安装XNA,所以我无法对此进行测试,但看起来你的面部被绘制为面向错误的方向。

脸部将始终具有可见和透视的一面。穿过你的脸,翻过来。当你这样做时,你会看到它们出现和消失。