DirectX Coordinate System Causes Texture Flipping

早过忘川 提交于 2020-06-29 08:32:20

问题


I recently posted a question about a texture issue I was having. And I think I've discovered the culprit of my problem, but I'm unsure how to handle this, or what I should be doing. Here is the link to the question I had asked:

DirectX Texturing Inversion Issues

After asking that question I got to work just sitting there toying with everything, and eventually ended up just randomly trying to switch from a left handed coordinate system, to a right handed one. Changing to a right handed coordinate system fixed the texturing issue. I would like to know why using a left handed coordinate system results in this sort of texturing glitch. DirectX uses a left handed coordinate system. So why is it slightly broken in my example?

Here is a picture of what my scene looks like using a left handed Projection:

And here is a picture of using a right handed projection:

As I explained in my previous question, the red dot is supposed to be at the top left. It looks just fine in Blender. But when loaded into a left handed coordinate system, it's flipped horizontally on the x axis. When using the right handed system, it's seemingly fixed.

Does anyone know what's going on here?

Here is my camera class:

using SharpDX;
using System;

namespace VoidwalkerEngine.Framework.DirectX
{
    public enum CameraMode
    {
        FreeLook,
        Orbit
    }

    public class Camera
    {
        /// <summary>
        /// The name of this camera
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// The eye location of this camera
        /// </summary>
        public Vector3 Location { get; set; }
        /// <summary>
        /// The Pitch of this Camera, as Radians
        /// </summary>
        public float Pitch { get; set; }
        /// <summary>
        /// The Yaw of this Camera, as Radians
        /// </summary>
        public float Yaw { get; set; }
        /// <summary>
        /// The Roll of this Camera, as Radians
        /// </summary>
        public float Roll { get; set; }
        /// <summary>
        /// The NearZ of this Camera
        /// </summary>
        public float NearZ { get; set; }
        /// <summary>
        /// The FarZ of this Camera
        /// </summary>
        public float FarZ { get; set; }
        /// <summary>
        /// The Field of View of this Camera, value should be
        /// between 0.70 and 1.20
        /// </summary>
        public float FieldOfView { get; set; }
        public float AspectRatio { get; set; }
        public float LookSpeed { get; set; }
        public float MoveSpeed { get; set; }
        /// <summary>
        /// Determines if this Camera is currently accelerating.
        /// </summary>
        public bool IsAccelerating { get; set; }
        /// <summary>
        /// The acceleration speed multiplier of this Camera.
        /// </summary>
        public float AccelerationMultiplier { get; set; }
        public CameraMode Mode { get; set; }
        public float ViewportWidth;
        public float ViewportHeight;

        /// <summary>
        /// The BoundingSphere of this Camera
        /// </summary>
        public BoundingSphere Bounds
        {
            get
            {
                return new BoundingSphere()
                {
                    Center = this.Location,
                    Radius = 2.0f
                };
            }
        }

        /// <summary>
        /// The Target Vector of this Camera
        /// </summary>
        public Vector3 Target
        {
            get
            {
                return new Vector3(
                    (float)Math.Sin(this.Yaw),
                    (float)Math.Tan(this.Pitch),
                    (float)Math.Cos(this.Yaw));
            }
        }

        /// <summary>
        /// The Frustum of this Camera
        /// </summary>
        public BoundingFrustum Frustum
        {
            get
            {
                return new BoundingFrustum(this.ModelViewProjectionMatrix);
            }
        }

        public Matrix ModelViewMatrix
        {
            get
            {
                return Matrix.LookAtLH(this.Location, Location + Target, Up);
            }
        }

        public Matrix ProjectionMatrix
        {
            get
            {
                // Changing this to Matrix.PerspectiveFovRH() fixes the issue...but why?
                return Matrix.PerspectiveFovLH(FieldOfView, AspectRatio, NearZ, FarZ);
            }
        }

        public Matrix ModelViewProjectionMatrix
        {
            get
            {
                return ModelViewMatrix * ProjectionMatrix;
            }
        }

        //public CardinalDirectionType Direction
        //{
        //    get
        //    {
        //        return VoidwalkerMath.GetCardinalDirection(VoidwalkerMath.ToDegrees(Yaw));
        //    }
        //}

        public Vector3 Forward
        {
            get
            {
                return new Vector3((float)Math.Cos(Pitch), 0, (float)Math.Sin(Pitch));
            }
        }

        public Vector3 Right
        {
            get
            {
                return new Vector3(Forward.X, 0, -Forward.X);
            }
        }

        public Vector3 Up
        {
            get
            {
                return new Vector3(-(float)Math.Sin(Roll), (float)Math.Cos(Roll), 0);
            }
        }

        public Camera()
        {

        }

        public Camera(string name)
            : this()
        {
            this.Name = name;
            this.Location = new Vector3();
        }

        public void ToOrigin()
        {
            Transform(Vector3.Zero, 0, 0, 0);
        }

        public void Transform(Vector3 location, float pitch, float yaw, float roll)
        {
            this.Location = location;
            this.Pitch = pitch;
            this.Yaw = yaw;
            this.Roll = roll;
        }

        public float GetCurrentMoveSpeed()
        {
            if (IsAccelerating)
            {
                return this.MoveSpeed * this.AccelerationMultiplier;
            }
            return this.MoveSpeed;
        }

        public void TranslateLeft(float deltaTime)
        {
            float moveSpeed = GetCurrentMoveSpeed();
            this.Location = new Vector3(
                Location.X - (float)Math.Sin(Yaw + MathUtil.PiOverTwo) * moveSpeed * deltaTime,
                Location.Y,
                Location.Z - (float)Math.Cos(Yaw + MathUtil.PiOverTwo) * moveSpeed * deltaTime);
        }

        public void TranslateRight(float deltaTime)
        {
            float moveSpeed = GetCurrentMoveSpeed();
            this.Location = new Vector3(
                Location.X + (float)Math.Sin(Yaw + MathUtil.PiOverTwo) * moveSpeed * deltaTime,
                Location.Y,
                Location.Z + (float)Math.Cos(Yaw + MathUtil.PiOverTwo) * moveSpeed * deltaTime);
        }

        public void TranslateForward(float deltaTime)
        {
            float degreesX = MathUtil.RadiansToDegrees(Pitch) * 0.01745329F; // X rotation
            float degreesY = MathUtil.RadiansToDegrees(Yaw) * 0.01745329F; // Y rotation
            float moveSpeed = GetCurrentMoveSpeed();
            this.Location = new Vector3(
                this.Location.X + (float)(moveSpeed * Math.Sin(degreesY) * Math.Cos(degreesX)) * deltaTime,
                this.Location.Y + (float)(moveSpeed * Math.Sin(degreesX)) * deltaTime,
                this.Location.Z + (float)(moveSpeed * Math.Cos(degreesY) * Math.Cos(degreesX)) * deltaTime);
        }

        public void TranslateBackward(float deltaTime)
        {

            float degreesX = MathUtil.RadiansToDegrees(Pitch) * 0.01745329F; // X rotation
            float degreesY = MathUtil.RadiansToDegrees(Yaw) * 0.01745329F; // Y rotation
            float moveSpeed = GetCurrentMoveSpeed();
            this.Location = new Vector3(
                this.Location.X - (float)(moveSpeed * Math.Sin(degreesY) * Math.Cos(degreesX)) * deltaTime,
                this.Location.Y - (float)(moveSpeed * Math.Sin(degreesX)) * deltaTime,
                this.Location.Z - (float)(moveSpeed * Math.Cos(degreesY) * Math.Cos(degreesX)) * deltaTime);
        }

        public void TransformYawPitch(float dx, float dy)
        {
            Yaw += dx * LookSpeed;
            Pitch -= dy * LookSpeed;
            const float pitchClamp = 1.56f;
            if (Pitch <= -pitchClamp)
            {
                Pitch = -pitchClamp;
            }
            if (Pitch >= pitchClamp)
            {
                Pitch = pitchClamp;
            }
        }

        public void TranslateUp(float deltaTime)
        {
            this.Location = new Vector3(
                this.Location.X,
                this.Location.Y + GetCurrentMoveSpeed() * deltaTime,
                this.Location.Z); // TODO implement up/down based upon roll orientation.
        }

        public void TranslateDown(float deltaTime)
        {
            this.Location = new Vector3(
                this.Location.X,
                this.Location.Y - GetCurrentMoveSpeed() * deltaTime,
                this.Location.Z);
        }

        public void LookAt(Vector3 location, float pitch, float yaw, float roll)
        {
            this.Location = location;
            this.Pitch = pitch;
            this.Yaw = yaw;
            this.Roll = roll;
        }

        public void SetAspectRatio(int width, int height)
        {
            this.ViewportWidth = width;
            this.ViewportHeight = height;
            this.AspectRatio = width / (float)height;
        }
    }
}

If I'm doing something incredibly stupid, please feel free to call me out on it. I've already spent 2 days trying to figure this out.

来源:https://stackoverflow.com/questions/62205875/directx-coordinate-system-causes-texture-flipping

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!