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

标签 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);
    }
}

最佳答案

您使用的函数 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

关于c# - 如何在 XNA 中为绘制的线条添加 Z 深度透视图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8218082/

相关文章:

c# - Asp.net 核心 2.1 单元测试自动映射器?

c# - DataGrid行背景色MVVM

java - 在 Java 中从边和顶点绘制 map

c# - XNA 4.0 打印到 Visual Studio 2012 控制台

c# - 如何在 .NET 中卡住冰棒(使类不可变)

c# - VSTO Word 2010 getScreentip getSupertip 未触发

c# - 检测移动物体与静止物体之间的碰撞

c# - 如何获取 XNA 游戏屏幕上的窗口位置?

java - 计算贝塞尔剪裁中的距离函数时遇到问题

java - 最佳 Java 图形库