简体   繁体   English

DirectX (SharpDX) 线框错误

[英]DirectX (SharpDX) Wireframe Bug

I am experiencing an issue with wireframe within my 3D scene.我在 3D 场景中遇到线框问题。 For some strange reason, the wireframe is showing as incomplete in certain places.出于某种奇怪的原因,线框在某些地方显示为不完整。 Moving the camera around makes some of the lines appear, and others disappear, instead of just being one complete wireframe.移动相机会使一些线条出现,而另一些则消失,而不仅仅是一个完整的线框。 Here are a few pictures and some code.这是一些图片和一些代码。 I am using SharpDX.我正在使用 SharpDX。 Does anyone know what's going on?有谁知道发生了什么?

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

(The following code has been trimmed down signifincantly to show only what I believe to be the relevant bits to this question) (以下代码已显着缩减,仅显示我认为与此问题相关的部分)

using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DirectInput;
using SharpDX.DXGI;
using SharpDX.Windows;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Windows.Forms;
using VoidwalkerEngine.Framework.DirectX;
using VoidwalkerEngine.Framework.DirectX.Rendering;
using VoidwalkerEngine.Framework.DirectX.Shaders;
using VoidwalkerEngine.Framework.Logic;
using VoidwalkerEngine.Framework.Maths;

namespace GrimoireTacticsGame.Client
{
    public class GameWindow : RenderForm
    {

        /**
         * Client Variables
         */
        public Camera Camera { get; set; }
        public Keyboard Keyboard { get; set; }
        public Mouse Mouse { get; set; }
        public bool IsMouseLookEnabled { get; private set; }
        public Point CurrentMouseLocation { get; set; }
        public Stopwatch ClientTimer { get; set; }
        public int RenderFrequency { get; private set; }
        public VsyncLevel Vsync { get; set; }
        private bool _isResizeNeeded { get; set; } = true;
        private Point _mouseLockLocation { get; set; }
        private float _previousFrameDeltaTime { get; set; }
        private int _frameCounter;
        private System.DateTime _previousDateTime;
        /**
         * DirectX Variables
         */
        private Texture2D _depthBuffer;
        private SwapChain _swapChain;
        private SwapChainDescription _swapChainDescription;
        private Texture2D _backBuffer = null;
        private RenderTargetView _renderView = null;
        private DepthStencilView _depthView = null;
        private SharpDX.Direct3D11.Device _device;
        private DeviceContext _graphicsCardContext;
        private Factory _factory;
        public PointLightShaderArgs _pointLightArgs;
        private BlendState BlendState { get; set; }
        private RasterizerStateDescription RasterizerState { get; set; }
        public List<StaticGeometry> StaticGeometry { get; set; }
        /**
         * Shaders
         */
        public WorldShader WorldShader;


        public GameWindow()
            : base("Grimoire Tactics")
        {
            Initialize();

        }

        public void InitializeDirectX()
        {
            // SwapChain description
            _swapChainDescription = new SwapChainDescription()
            {
                BufferCount = 1,
                ModeDescription = new ModeDescription(
                    this.ClientSize.Width,
                    this.ClientSize.Height,
                    new Rational(60, 1),
                    Format.R8G8B8A8_UNorm),
                IsWindowed = true,
                OutputHandle = this.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect = SwapEffect.Discard,
                Usage = Usage.RenderTargetOutput
            };

            SharpDX.Direct3D11.Device.CreateWithSwapChain(
                DriverType.Hardware,
                DeviceCreationFlags.None,
                _swapChainDescription,
                out _device,
                out _swapChain);
            _graphicsCardContext = _device.ImmediateContext;
            _factory = _swapChain.GetParent<Factory>();
            _factory.MakeWindowAssociation(this.Handle, WindowAssociationFlags.IgnoreAll);
            /**
             * Create RasterizerState
             */ 
            RasterizerState = new RasterizerStateDescription
            {
                CullMode = CullMode.None,
                DepthBias = 0,
                DepthBiasClamp = 0,
                FillMode = FillMode.Solid,
                IsAntialiasedLineEnabled = false,
                IsDepthClipEnabled = false,
                IsFrontCounterClockwise = false,
                IsMultisampleEnabled = false,
                IsScissorEnabled = false,
                SlopeScaledDepthBias = 0
            };
            _graphicsCardContext.Rasterizer.State = new RasterizerState(_device, RasterizerState);

            /**
             * Create BlendState
             */
            BlendStateDescription blendStateDescription = new BlendStateDescription
            {
                AlphaToCoverageEnable = false,
            };

            blendStateDescription.RenderTarget[0].IsBlendEnabled = true;
            blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha;
            blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha;
            blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add;
            blendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.Zero;
            blendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
            blendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add;
            blendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            this.BlendState = new BlendState(_device, blendStateDescription);
            this._graphicsCardContext.OutputMerger.BlendState = this.BlendState;
        }

        private void InitializeShaders()
        {
            WorldShader = new WorldShader(_device);
        }

        private void Initialize()
        {
            this.StaticGeometry = new List<StaticGeometry>();
            this.StartPosition = FormStartPosition.CenterScreen;
            this.Camera = new Camera
            {
                MoveSpeed = 128f,
                LookSpeed = 0.50f, // 0 ~ 1 (0.50 = 50%)
                Location = new Vector3(0, 0, 0),
                FieldOfView = 1.0f, // 0.7 ~ 1.20
                NearZ = 1f,
                FarZ = 8000f,
                AccelerationMultiplier = 2.5f
            };

            InitializeDirectX();
            InitializeShaders();
            InitializeGeometry();

            /**
             * Initialize Clock
             * Probably use a DateTime instead.
             */
            ClientTimer = new Stopwatch();


            /**
             * Setup Handlers
             */
            this.KeyDown += OnKeyDown;
            this.KeyUp += OnKeyUp;
            this.UserResized += OnResize;
            this.MouseUp += OnMouseUp;
            this.MouseMove += OnMouseMove;
            this.MouseDown += OnMouseDown;
            this.FormClosing += OnFormClosing;
            /**
             * Setup User Input
             */
            DirectInput input = new DirectInput();
            this.Keyboard = new Keyboard(input);
            this.Keyboard.Properties.BufferSize = 128;
            this.Keyboard.Acquire();
            this.Mouse = new Mouse(input);
            this.Mouse.Properties.BufferSize = 8;
            this.Mouse.Acquire();
        }

        private void DrawScene(float deltaTime)
        {
            this.Text = this.Camera.Location.ToString();
            float elapsedClientTime = ClientTimer.ElapsedMilliseconds / 1000.0f;
            Matrix modelViewMatrix = Camera.ModelViewMatrix;
            Matrix projectionMatrix = Camera.ProjectionMatrix;
            Matrix modelViewProjectionMatrix = Camera.ModelViewProjectionMatrix;

            if (!WorldShader.IsBound)
            {
                WorldShader.Bind(_graphicsCardContext);
            }
            this._pointLightArgs = new PointLightShaderArgs(
                        new Vector3(16, 32, 16),
                        1024,
                        new Vector3(0, 0.06f, 0),
                        new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
                        new Vector4(1, 1, 1, 1));


            _graphicsCardContext.UpdateSubresource(ref _pointLightArgs, WorldShader.PointLightShaderArgsBuffer);

            foreach (StaticGeometry geometry in this.StaticGeometry)
            {
                if (geometry.IsVisible)
                {
                    Matrix worldPositionMatrix = VoidwalkerMath.CreateRotationMatrix(geometry.Rotation) * Matrix.Translation(geometry.Location);
                    Matrix localMatrix = worldPositionMatrix * modelViewProjectionMatrix;

                    worldPositionMatrix.Transpose();
                    localMatrix.Transpose();
                    _graphicsCardContext.UpdateSubresource(ref localMatrix, WorldShader.LocalMatrixBuffer);
                    _graphicsCardContext.UpdateSubresource(ref worldPositionMatrix, WorldShader.WorldPositionBuffer);

                    Vector2 textureResolution = geometry.Mesh.DiffuseMaterial.Resolution;
                    _graphicsCardContext.UpdateSubresource(ref textureResolution, WorldShader.TextureResolutionBuffer);

                    geometry.Draw(_graphicsCardContext);
                }
            }
        }

        private void OnRenderFrame()
        {
            if (_isResizeNeeded)
            {
                ResizeFrameBuffers();
            }
            float elapsedClientTime = ClientTimer.ElapsedMilliseconds / 1000.0f;
            float currentFrameDeltaTime = elapsedClientTime - _previousFrameDeltaTime;
            _previousFrameDeltaTime = elapsedClientTime;
            System.DateTime dateTimeNow = System.DateTime.Now;
            System.TimeSpan subtractedTime = dateTimeNow.Subtract(_previousDateTime);
            if (subtractedTime.TotalSeconds >= 1)
            {
                this.RenderFrequency = _frameCounter;
                _frameCounter = 0;
                this._previousDateTime = dateTimeNow;
            }
            _graphicsCardContext.ClearDepthStencilView(_depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
            _graphicsCardContext.ClearRenderTargetView(_renderView, Color.CornflowerBlue);
            CheckKeyboardInput(currentFrameDeltaTime);
            DrawScene(elapsedClientTime);

            _swapChain.Present((int)this.Vsync, PresentFlags.None);

            _frameCounter++;
        }

        private void OnKeyUp(object sender, KeyEventArgs args)
        {
            switch (args.KeyCode)
            {
                case Keys.F2:
                    RasterizerStateDescription previousDescription = _graphicsCardContext.Rasterizer.State.Description;
                    FillMode mode;
                    mode = previousDescription.FillMode == FillMode.Solid
                        ? FillMode.Wireframe
                        : FillMode.Solid;
                    _graphicsCardContext.Rasterizer.State = new RasterizerState(_device, new RasterizerStateDescription
                    {
                        CullMode = previousDescription.CullMode,
                        DepthBias = previousDescription.DepthBias,
                        DepthBiasClamp = previousDescription.DepthBiasClamp,
                        FillMode = mode,
                        IsAntialiasedLineEnabled = previousDescription.IsAntialiasedLineEnabled,
                        IsDepthClipEnabled = previousDescription.IsDepthClipEnabled,
                        IsFrontCounterClockwise = previousDescription.IsFrontCounterClockwise,
                        IsMultisampleEnabled = previousDescription.IsMultisampleEnabled,
                        IsScissorEnabled = previousDescription.IsScissorEnabled,
                        SlopeScaledDepthBias = previousDescription.SlopeScaledDepthBias
                    });
                    break;
            }
        }

        private void ResizeFrameBuffers()
        {
            Utilities.Dispose(ref _backBuffer);
            Utilities.Dispose(ref _renderView);
            Utilities.Dispose(ref _depthBuffer);
            Utilities.Dispose(ref _depthView);
            _swapChain.ResizeBuffers(_swapChainDescription.BufferCount, this.ClientSize.Width, this.ClientSize.Height, Format.Unknown, SwapChainFlags.None);
            _backBuffer = Texture2D.FromSwapChain<Texture2D>(_swapChain, 0);
            _renderView = new RenderTargetView(_device, _backBuffer);
            _depthBuffer = new Texture2D(_device, new Texture2DDescription()
            {
                Format = Format.D32_Float_S8X24_UInt,
                ArraySize = 1,
                MipLevels = 1,
                Width = this.ClientSize.Width,
                Height = this.ClientSize.Height,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Default,
                BindFlags = BindFlags.DepthStencil,
                CpuAccessFlags = CpuAccessFlags.None,
                OptionFlags = ResourceOptionFlags.None
            });

            _depthView = new DepthStencilView(_device, _depthBuffer);
            _graphicsCardContext.Rasterizer.SetViewport(new Viewport(0, 0, this.ClientSize.Width, this.ClientSize.Height, 0.0f, 1.0f));
            _graphicsCardContext.OutputMerger.SetTargets(_depthView, _renderView);
            Camera.AspectRatio = this.ClientSize.Width / (float)this.ClientSize.Height;
            _isResizeNeeded = false;
        }
    }
}

Nevermind, I figured it out.没关系,我想通了。 I have to disable alpha blending.我必须禁用 alpha 混合。 Should have guessed that.应该猜到了。

blendStateDescription.RenderTarget[0].IsBlendEnabled = false;

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM