如何在XNA中为绘制的线条添加Z深度透视图?

时间:2011-11-21 20:25:54

标签: c# graphics xna

我一直在尝试在XNA中绘制线条。我在X和Y方向上绘制线条没有任何问题,但每当我尝试将Z数据添加到点时,似乎没有效果。

这就是我希望通过添加Z信息(我在这里通过改变Y并用中点平均X点来模拟)来做希望

enter image description here

这就是我实际得到的东西(我已经向上翻译第二行以确认实际上有两行被绘制 - 当我 >改变Z,两条线相互叠加) 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 WindowsGame3
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        BasicEffect baseEffect;
        VertexPositionColor[] vertices;
        VertexPositionColor[] verticesTop;
    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()
    {
        float AspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
        baseEffect = new BasicEffect(graphics.GraphicsDevice);
        baseEffect.World = Matrix.Identity;
        baseEffect.View = Matrix.Identity;

        baseEffect.VertexColorEnabled = true;
        baseEffect.Projection = Matrix.CreateOrthographicOffCenter
           (0, graphics.GraphicsDevice.Viewport.Width,     // left, right
            graphics.GraphicsDevice.Viewport.Height, 0,    // bottom, top
            -100, 100);                                     // near, far plane

        vertices = new VertexPositionColor[7];
        verticesTop = new VertexPositionColor[7];

        vertices[0].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 1/8, graphics.GraphicsDevice.Viewport.Height * 5/7, 0);
        vertices[0].Color = Color.Black;
        vertices[1].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 2/8, graphics.GraphicsDevice.Viewport.Height * 5/7, 1/8);
        vertices[1].Color = Color.Red;
        vertices[2].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 3 / 8, graphics.GraphicsDevice.Viewport.Height * 5 / 7, -2/8);
        vertices[2].Color = Color.Black;
        vertices[3].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 4 / 8, graphics.GraphicsDevice.Viewport.Height * 5 / 7, 3/8);
        vertices[3].Color = Color.Red;
        vertices[4].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 5 / 8, graphics.GraphicsDevice.Viewport.Height * 5 / 7, -4/8);
        vertices[4].Color = Color.Black;
        vertices[5].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 6 / 8, graphics.GraphicsDevice.Viewport.Height * 5 / 7, 5/8);
        vertices[5].Color = Color.Red;
        vertices[6].Position = new Vector3(graphics.GraphicsDevice.Viewport.Width * 7 / 8, graphics.GraphicsDevice.Viewport.Height * 5 / 7, -6/8);
        vertices[6].Color = Color.Black; 



        for (int i = 0; i < 7; i++)
        {
            verticesTop[i] = vertices[i];
            verticesTop[i].Position.Y -= 200; // remove this line once perspective is working
            verticesTop[i].Position.Z += 100;

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

    /// <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

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

        baseEffect.CurrentTechnique.Passes[0].Apply();
        graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, vertices, 0, 6);
        graphics.GraphicsDevice.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineStrip, verticesTop, 0, 6);


        base.Draw(gameTime);
    }
}

}

1 个答案:

答案 0 :(得分:3)

您正在使用的函数Matrix.CreateOrthographicOffCenter()创建一个没有透视的正交投影矩阵。

请尝试使用Matrix.CreatePerspectiveOffCenter()Matrix.CreatePerspectiveFieldOfView()

baseEffect.Projection = Matrix.CreatePerspectiveFieldOfView (
    1.57f,          // 90 degrees field of view
    width / height, // aspect ratio
    1.0f,           // near plane, you want that as far as possible
    10000.0f);      // far plane, you want that as near as possible