Как добавить перспективу глубины Z к нарисованным линиям в XNA? - PullRequest
3 голосов
/ 22 ноября 2011

Я экспериментировал с рисованием линий в XNA.У меня нет проблем с рисованием линий в направлениях X и Y, но всякий раз, когда я пытаюсь добавить данные Z к точкам, это, кажется, не дает никакого эффекта.

Вот то, что я надеялся Я мог бы сделать это, добавив информацию Z (которую я смоделировал здесь, изменив Y и усреднив точки X со средней точкой)

enter image description here

И вот что я на самом деле получение (я перевел 2-ю строку вверх, чтобы убедиться, что на самом деле две линии прорисовываются - когда я только меняю Z, две линии рисуются сверхудруг друга) enter image description here

Я что-то путаю с моей матрицей перспективы?Пропустить важный шаг?Код ниже предназначен для 2-го изображения.

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 Ответ

3 голосов
/ 22 ноября 2011

Используемая вами функция 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...