Example #1
9
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            wireframeState = new RasterizerStateDescription(CullMode.Back) { FillMode = FillMode.Wireframe };

            simpleEffect = new EffectInstance(new Effect(GraphicsDevice, SpriteEffect.Bytecode));

            // TODO GRAPHICS REFACTOR
            simpleEffect.Parameters.Set(TexturingKeys.Texture0, UVTexture);
            simpleEffect.UpdateEffect(GraphicsDevice);

            primitives = new List<GeometricPrimitive>();

            // Creates all primitives
            primitives = new List<GeometricPrimitive>
                             {
                                 GeometricPrimitive.Plane.New(GraphicsDevice),
                                 GeometricPrimitive.Cube.New(GraphicsDevice),
                                 GeometricPrimitive.Sphere.New(GraphicsDevice),
                                 GeometricPrimitive.GeoSphere.New(GraphicsDevice),
                                 GeometricPrimitive.Cylinder.New(GraphicsDevice),
                                 GeometricPrimitive.Torus.New(GraphicsDevice),
                                 GeometricPrimitive.Teapot.New(GraphicsDevice),
                                 GeometricPrimitive.Capsule.New(GraphicsDevice, 0.5f, 0.3f),
                                 GeometricPrimitive.Cone.New(GraphicsDevice)
                             };


            view = Matrix.LookAtRH(new Vector3(0, 0, 5), new Vector3(0, 0, 0), Vector3.UnitY);

            Window.AllowUserResizing = true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="depthBias"></param>
        protected override void OnRasterStateChanged(int depthBias)
        {
            if (this.IsAttached)
            {
                Disposer.RemoveAndDispose(ref this.rasterState);
                /// --- set up rasterizer states
                var rasterStateDesc = new RasterizerStateDescription()
                {
                    FillMode = FillMode.Solid,
                    CullMode = CullMode.Back,
                    DepthBias = depthBias,
                    DepthBiasClamp = -1000,
                    SlopeScaledDepthBias = +0,
                    IsDepthClipEnabled = true,
                    IsFrontCounterClockwise = true,

                    //IsMultisampleEnabled = true,
                    //IsAntialiasedLineEnabled = true,                    
                    //IsScissorEnabled = true,
                };
                try
                {
                    this.rasterState = new RasterizerState(this.Device, rasterStateDesc);
                }
                catch (System.Exception)
                {
                }
            }
        }
 public RasterizerStateChangeCommand(RasterizerStateDescription rStateDesc)
     : base(CommandType.RasterizerStateChange)
 {
     CommandAttributes |= CommandAttributes.MonoRendering;
     Description = rStateDesc;
     rasterizerState = RasterizerState.FromDescription(Game.Context.Device, Description);
 }
 public static PrimitiveRasterizer CreateRasterizer(
     PrimitiveTopology primitiveTopology,
     RasterizerStateDescription rasterizerState, 
     int multiSampleCount, 
     ShaderOutputInputBindings outputInputBindings, 
     ref Viewport viewport,
     Func<int, int, bool> fragmentQuadFilter)
 {
     switch (primitiveTopology)
     {
         case PrimitiveTopology.PointList:
             throw new NotImplementedException();
         case PrimitiveTopology.LineList:
         case PrimitiveTopology.LineStrip:
             throw new NotImplementedException();
         case PrimitiveTopology.TriangleList:
         case PrimitiveTopology.TriangleStrip:
             return new TriangleRasterizer(
                 rasterizerState, multiSampleCount,
                 outputInputBindings, ref viewport,
                 fragmentQuadFilter);
         default:
             throw new ArgumentOutOfRangeException("primitiveTopology");
     }
 }
Example #5
0
        protected override async Task LoadContent()
        {
            await base.LoadContent();

            batch = new Sprite3DBatch(GraphicsDevice);
            sphere = Content.Load<Texture>("Sphere");
            rotatedImages = Content.Load<SpriteSheet>("RotatedImages");
            rasterizerState = new RasterizerStateDescription(CullMode.None);
        }
	    public TriangleRasterizer(
            RasterizerStateDescription rasterizerState, 
            int multiSampleCount, 
            ShaderOutputInputBindings outputInputBindings, 
            ref Viewport viewport,
            Func<int, int, bool> fragmentFilter) 
            : base(rasterizerState, multiSampleCount, outputInputBindings, ref viewport, fragmentFilter)
	    {
	        
	    }
	    protected PrimitiveRasterizer(
            RasterizerStateDescription rasterizerState, int multiSampleCount,
            ShaderOutputInputBindings outputInputBindings,
            ref Viewport viewport,
            Func<int, int, bool> fragmentFilter)
	    {
            RasterizerState = rasterizerState;
            MultiSampleCount = multiSampleCount;
	        OutputInputBindings = outputInputBindings;
            ScreenBounds = new Box2D(
                viewport.TopLeftX, viewport.TopLeftY,
                viewport.TopLeftX + viewport.Width, 
                viewport.TopLeftY + viewport.Height);
	        FragmentFilter = fragmentFilter;
	    }
 public void MakeBothSidesRendered()
 {
     var rsDesc = new RasterizerStateDescription();
     rsDesc.IsAntialiasedLineEnabled = false;
     rsDesc.CullMode = CullMode.None;
     rsDesc.DepthBias = 0;
     rsDesc.DepthBiasClamp = 0;
     rsDesc.IsDepthClipEnabled = true;
     rsDesc.FillMode = FillMode.Solid;
     rsDesc.IsFrontCounterclockwise = false;
     rsDesc.IsMultisampleEnabled = false;
     rsDesc.IsScissorEnabled = false;
     rsDesc.SlopeScaledDepthBias = 0;
     Device.Rasterizer.State = RasterizerState.FromDescription(Device, rsDesc);
 }
Example #9
0
 public void SetDefaultRasterizer()
 {
     this.Rasterizer = new RasterizerStateDescription()
     {
         CullMode = CullMode.Back,
         DepthBias = 0,
         DepthBiasClamp = 0.0f,
         FillMode = FillMode.Solid,
         IsAntialiasedLineEnabled = false,
         IsDepthClipEnabled = true,
         IsFrontCounterclockwise = false,
         IsMultisampleEnabled = false,
         IsScissorEnabled = false,
         SlopeScaledDepthBias = 0.0f
     };
 }
        // ReSharper restore NotAccessedField.Local

        public void CreateDeviceObjects(IRendererContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            var c  = (VeldridRendererContext)context;
            var cl = c.CommandList;
            var gd = c.GraphicsDevice;
            var sc = c.SceneContext;

            ResourceFactory factory = gd.ResourceFactory;

            _vb = factory.CreateBuffer(new BufferDescription(Vertices.SizeInBytes(), BufferUsage.VertexBuffer));
            _ib = factory.CreateBuffer(new BufferDescription(Indices.SizeInBytes(), BufferUsage.IndexBuffer));
            _miscUniformBuffer      = factory.CreateBuffer(new BufferDescription(MiscUniformData.SizeInBytes, BufferUsage.UniformBuffer));
            _vb.Name                = "TileMapVertexBuffer";
            _ib.Name                = "TileMapIndexBuffer";
            _miscUniformBuffer.Name = "TileMapMiscBuffer";
            cl.UpdateBuffer(_vb, 0, Vertices);
            cl.UpdateBuffer(_ib, 0, Indices);

            var shaderCache = Resolve <IShaderCache>();

            _shaders = shaderCache.GetShaderPair(gd.ResourceFactory,
                                                 VertexShaderName,
                                                 FragmentShaderName,
                                                 shaderCache.GetGlsl(VertexShaderName),
                                                 shaderCache.GetGlsl(FragmentShaderName));

            var shaderSet = new ShaderSetDescription(new[] { VertexLayout, InstanceLayout }, _shaders);

            _layout         = factory.CreateResourceLayout(PerSpriteLayoutDescription);
            _textureSampler = gd.ResourceFactory.CreateSampler(new SamplerDescription(
                                                                   SamplerAddressMode.Clamp,
                                                                   SamplerAddressMode.Clamp,
                                                                   SamplerAddressMode.Clamp,
                                                                   SamplerFilter.MinPoint_MagPoint_MipPoint,
                                                                   null, 1, 0, 0, 0, SamplerBorderColor.TransparentBlack
                                                                   ));

            var depthStencilMode = gd.IsDepthRangeZeroToOne
                    ? DepthStencilStateDescription.DepthOnlyLessEqual
                    : DepthStencilStateDescription.DepthOnlyGreaterEqual;

            var rasterizerMode = new RasterizerStateDescription(
                FaceCullMode.Front, PolygonFillMode.Solid, FrontFace.Clockwise,
                true, true);

            var pd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleAlphaBlend,
                depthStencilMode,
                rasterizerMode,
                PrimitiveTopology.TriangleList,
                new ShaderSetDescription(new[] { VertexLayout, InstanceLayout },
                                         shaderSet.Shaders,
                                         ShaderHelper.GetSpecializations(gd)),
                new[] { _layout, sc.CommonResourceLayout },
                gd.SwapchainFramebuffer.OutputDescription);

            _pipeline      = factory.CreateGraphicsPipeline(ref pd);
            _pipeline.Name = "P_TileMapRenderer";
            _disposeCollector.Add(_vb, _ib, _layout, _textureSampler, _pipeline);
        }
Example #11
0
        /// <summary>
        /// Dessine cette cellule.
        /// </summary>
        public void Draw()
        {
            // Dessine la cellule.
            var device = Scene.GetGraphicsDevice().ImmediateContext;
            device.InputAssembler.SetIndexBuffer(Generation.ModelGenerator.GetIndexBuffer(GridResolution), Format.R32_UInt, 0);
            device.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleList);
            device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(m_vBuffer, Graphics.VertexPositionTextureNormal.Vertex.Stride, 0));
            RasterizerStateDescription rsd = new RasterizerStateDescription()
            {
                CullMode = CullMode.Back,
                DepthBias = 0,
                DepthBiasClamp = 0.0f,
                FillMode = FillMode.Solid,
                IsAntialiasedLineEnabled = true,
                IsDepthClipEnabled = true,
                IsFrontCounterclockwise = false,
                IsMultisampleEnabled = false,
                IsScissorEnabled = false,
                SlopeScaledDepthBias = 0.0f
            };

            // Alpha blending
            var transDesc = new BlendStateDescription
            {
                AlphaToCoverageEnable = false,
                IndependentBlendEnable = false
            };
            transDesc.RenderTargets[0].BlendEnable = true;
            transDesc.RenderTargets[0].SourceBlend = BlendOption.SourceAlpha;
            transDesc.RenderTargets[0].DestinationBlend = BlendOption.InverseSourceAlpha;
            transDesc.RenderTargets[0].BlendOperation = BlendOperation.Add;
            transDesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One;
            transDesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero;
            transDesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add;
            transDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            var bs = BlendState.FromDescription(device.Device, transDesc);
            device.OutputMerger.BlendState = bs;

            RasterizerState rs = RasterizerState.FromDescription(Scene.GetGraphicsDevice(), rsd);
            device.Rasterizer.State = rs;

            // Variables
            Graphics.WaterEffect effect = Scene.GetGraphicsEngine().WaterEffect;
            effect.Apply(Matrix.Identity, Scene.Instance.Camera.View, Scene.Instance.Camera.Projection, m_material);
            device.DrawIndexed(Generation.ModelGenerator.GetIndexBuffer(GridResolution).Description.SizeInBytes / sizeof(int), 0, 0);

            device.OutputMerger.BlendState = null;
        }
        private SharpDX.Direct3D12.RasterizerStateDescription CreateRasterizerState(RasterizerStateDescription description)
        {
            SharpDX.Direct3D12.RasterizerStateDescription nativeDescription;

            nativeDescription.CullMode = (SharpDX.Direct3D12.CullMode)description.CullMode;
            nativeDescription.FillMode = (SharpDX.Direct3D12.FillMode)description.FillMode;
            nativeDescription.IsFrontCounterClockwise = description.FrontFaceCounterClockwise;
            nativeDescription.DepthBias = description.DepthBias;
            nativeDescription.SlopeScaledDepthBias = description.SlopeScaleDepthBias;
            nativeDescription.DepthBiasClamp = description.DepthBiasClamp;
            nativeDescription.IsDepthClipEnabled = description.DepthClipEnable;
            //nativeDescription.IsScissorEnabled = description.ScissorTestEnable;
            nativeDescription.IsMultisampleEnabled = description.MultiSampleLevel >= MSAALevel.None;
            nativeDescription.IsAntialiasedLineEnabled = description.MultiSampleAntiAliasLine;

            nativeDescription.ConservativeRaster = ConservativeRasterizationMode.Off;
            nativeDescription.ForcedSampleCount = 0;

            return nativeDescription;
        }
Example #13
0
        public static void Initialize(Device device)
        {
            {
                var blendStateDescription = new BlendStateDescription();
                blendStateDescription.RenderTargets[0].BlendEnable = false;
                blendStateDescription.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
                blendStateDescription.RenderTargets[1].BlendEnable = false;
                blendStateDescription.RenderTargets[1].RenderTargetWriteMask = ColorWriteMaskFlags.None;
                blendStateDescription.RenderTargets[2].BlendEnable = false;
                blendStateDescription.RenderTargets[2].RenderTargetWriteMask = ColorWriteMaskFlags.None;
                blendStateDescription.RenderTargets[3].BlendEnable = false;
                blendStateDescription.RenderTargets[3].RenderTargetWriteMask = ColorWriteMaskFlags.None;

                m_BlendStates[(int)BlendType.None] = BlendState.FromDescription(device, blendStateDescription);

                blendStateDescription.RenderTargets[0].BlendEnable = true;
                blendStateDescription.RenderTargets[0].BlendOperation = BlendOperation.Add;
                blendStateDescription.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add;
                blendStateDescription.RenderTargets[0].DestinationBlend = BlendOption.One;
                blendStateDescription.RenderTargets[0].DestinationBlendAlpha = BlendOption.One;
                blendStateDescription.RenderTargets[0].SourceBlend = BlendOption.One;
                blendStateDescription.RenderTargets[0].SourceBlendAlpha = BlendOption.One;
                blendStateDescription.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

                m_BlendStates[(int)BlendType.Additive] = BlendState.FromDescription(device, blendStateDescription);
            }

            {
                var depthStencilStateDescription = new DepthStencilStateDescription();
                depthStencilStateDescription.DepthComparison = Comparison.Always;
                depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero;
                depthStencilStateDescription.IsDepthEnabled = false;
                depthStencilStateDescription.IsStencilEnabled = false;
                depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero;

                m_DepthStencilStates[(int)DepthConfigurationType.NoDepth] = DepthStencilState.FromDescription(device, depthStencilStateDescription);

                depthStencilStateDescription.DepthComparison = Comparison.LessEqual;
                depthStencilStateDescription.DepthWriteMask = DepthWriteMask.All;
                depthStencilStateDescription.IsDepthEnabled = true;

                m_DepthStencilStates[(int)DepthConfigurationType.DepthWriteCompare] = DepthStencilState.FromDescription(device, depthStencilStateDescription);

                depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero;

                m_DepthStencilStates[(int)DepthConfigurationType.DepthCompare] = DepthStencilState.FromDescription(device, depthStencilStateDescription);
            }

            {
                var rasterizerStateDescription = new RasterizerStateDescription();
                rasterizerStateDescription.DepthBias = 0;
                rasterizerStateDescription.DepthBiasClamp = 0;
                rasterizerStateDescription.FillMode = FillMode.Solid;
                rasterizerStateDescription.IsAntialiasedLineEnabled = false;
                rasterizerStateDescription.IsDepthClipEnabled = true;
                rasterizerStateDescription.IsMultisampleEnabled = false;
                rasterizerStateDescription.IsScissorEnabled = false;
                rasterizerStateDescription.SlopeScaledDepthBias = 0;
                rasterizerStateDescription.CullMode = CullMode.None;
                m_RasterizerStates[(int)RasterizerStateType.CullNone] = RasterizerState.FromDescription(device, rasterizerStateDescription);

                rasterizerStateDescription.CullMode = CullMode.Front;
                m_RasterizerStates[(int)RasterizerStateType.CullFront] = RasterizerState.FromDescription(device, rasterizerStateDescription);

                rasterizerStateDescription.CullMode = CullMode.Back;
                m_RasterizerStates[(int)RasterizerStateType.CullBack] = RasterizerState.FromDescription(device, rasterizerStateDescription);
            }

        }
Example #14
0
        /// <summary>
        /// Dessine cette cellule.
        /// </summary>
        public override void Draw()
        {
            if (!m_genTask.IsRessourceReady)
                throw new Exception("Unable to draw this ressource when it is not ready !");

            // Dessine la cellule.
            var device = Scene.GetGraphicsDevice().ImmediateContext;
            device.InputAssembler.SetIndexBuffer(Generation.ModelGenerator.GetIndexBuffer(GridResolution), Format.R32_UInt, 0);
            device.InputAssembler.PrimitiveTopology = (PrimitiveTopology.TriangleList);
            device.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(m_genTask.Ressource.VertexBuffer, Graphics.VertexPositionTextureNormal.Vertex.Stride, 0));

            RasterizerStateDescription rsd = new RasterizerStateDescription()
            {
                CullMode = CullMode.Back,
                DepthBias = 0,
                DepthBiasClamp = 0.0f,
                FillMode = RasterizerFillMode,
                IsAntialiasedLineEnabled = true,
                IsDepthClipEnabled = true,
                IsFrontCounterclockwise = false,
                IsMultisampleEnabled = false,
                IsScissorEnabled = false,
                SlopeScaledDepthBias = 0.0f
            };
            RasterizerState rs = RasterizerState.FromDescription(Scene.GetGraphicsDevice(), rsd);
            device.Rasterizer.State = rs;

            // Variables
            Graphics.BasicEffect effect = Scene.GetGraphicsEngine().BasicEffect;
            effect.Apply(Matrix.Identity, Scene.Instance.Camera.View, Scene.Instance.Camera.Projection, m_material);
            device.DrawIndexed(Generation.ModelGenerator.GetIndexBuffer(GridResolution).Description.SizeInBytes / sizeof(int), 0, 0);
        }
        protected override void OnRasterStateChanged()
        {
            if (this.IsAttached)
            {
                Disposer.RemoveAndDispose(ref this.rasterState);
                /// --- set up rasterizer states
                var rasterStateDesc = new RasterizerStateDescription()
                {
                    FillMode = FillMode.Solid,
                    CullMode = CullMode.None,
                    DepthBias = DepthBias,
                    DepthBiasClamp = -1000,
                    SlopeScaledDepthBias = -2,
                    IsDepthClipEnabled = true,
                    IsFrontCounterClockwise = false,

                    IsMultisampleEnabled = true,
                    //IsAntialiasedLineEnabled = true, // Intel HD 3000 doesn't like this (#10051) and it's not needed
                    //IsScissorEnabled = true,
                };

                try { this.rasterState = new RasterizerState(this.Device, rasterStateDesc); }
                catch (System.Exception)
                {
                }
            }
        }
Example #16
0
        public override void Run()
        {
            #region Create renderers

            // Note: the renderers take care of creating their own
            // device resources and listen for DeviceManager.OnInitialize

            #region Initialize MeshRenderer instances

            // Create and initialize the mesh renderer
            var loadedMesh             = Common.Mesh.LoadFromFile("Scene.cmo");
            List <MeshRenderer> meshes = new List <MeshRenderer>();
            meshes.AddRange((from mesh in loadedMesh
                             select ToDispose(new MeshRenderer(mesh))));

            // We will support a envmap for each mesh that contains "reflector" in its name
            List <DualParaboloidMap> envMaps = new List <DualParaboloidMap>();

            // We will rotate any meshes that contains "rotate" in its name
            List <MeshRenderer> rotateMeshes = new List <MeshRenderer>();

            // We will generate meshRows * meshColumns of any mesh that contains "replicate" in its name
            int meshRows    = 10;
            int meshColumns = 10;

            // Define an action to initialize our meshes so that we can
            // dynamically change the number of reflective surfaces and
            // replicated meshes
            Action createMeshes = () =>
            {
                // Clear context states, ensures we don't have
                // any of the resources we are going to release
                // assigned to the pipeline.
                DeviceManager.Direct3DContext.ClearState();
                if (contextList != null)
                {
                    foreach (var context in contextList)
                    {
                        context.ClearState();
                    }
                }

                // Remove meshes
                foreach (var mesh in meshes)
                {
                    mesh.Dispose();
                }
                meshes.Clear();

                // Remove environment maps
                foreach (var envMap in envMaps)
                {
                    envMap.Dispose();
                }
                envMaps.Clear();

                // Create non-replicated MeshRenderer instances
                meshes.AddRange(from mesh in loadedMesh
                                where !((mesh.Name ?? "").ToLower().Contains("replicate"))
                                select ToDispose(new MeshRenderer(mesh)));

                #region Create replicated meshes
                // Add the same mesh multiple times, separate by the combined extent
                var replicatedMeshes = (from mesh in loadedMesh
                                        where (mesh.Name ?? "").ToLower().Contains("replicate")
                                        select mesh).ToArray();
                if (replicatedMeshes.Length > 0)
                {
                    var minExtent = (from mesh in replicatedMeshes
                                     orderby new { mesh.Extent.Min.X, mesh.Extent.Min.Z }
                                     select mesh.Extent).First();
                    var maxExtent = (from mesh in replicatedMeshes
                                     orderby new { mesh.Extent.Max.X, mesh.Extent.Max.Z } descending
                                     select mesh.Extent).First();
                    var extentDiff = (maxExtent.Max - minExtent.Min);

                    for (int x = -(meshColumns / 2); x < (meshColumns / 2); x++)
                    {
                        for (int z = -(meshRows / 2); z < (meshRows / 2); z++)
                        {
                            var meshGroup = (from mesh in replicatedMeshes
                                             where (mesh.Name ?? "").ToLower().Contains("replicate")
                                             select ToDispose(new MeshRenderer(mesh))).ToList();

                            // Reposition based on width/depth of combined extent
                            foreach (var m in meshGroup)
                            {
                                m.World.TranslationVector = new Vector3(m.Mesh.Extent.Center.X + extentDiff.X * x, m.Mesh.Extent.Min.Y, m.Mesh.Extent.Center.Z + extentDiff.Z * z);
                            }

                            meshes.AddRange(meshGroup);
                        }
                    }
                }
                #endregion

                #region Create reflective meshes
                // Create reflections where necessary and add rotation meshes
                int reflectorCount = 0;
                meshes.ForEach(m =>
                {
                    var name = (m.Mesh.Name ?? "").ToLower();
                    if (name.Contains("reflector") && reflectorCount < maxReflectors)
                    {
                        reflectorCount++;
                        var envMap       = ToDispose(new DualParaboloidMap(512));
                        envMap.Reflector = m;
                        envMap.Initialize(this);
                        m.EnvironmentMap = envMap;
                        envMaps.Add(envMap);
                    }
                    if (name.Contains("rotate"))
                    {
                        rotateMeshes.Add(m);
                    }

                    m.Initialize(this);
                });
                #endregion

                // Initialize each mesh
                meshes.ForEach(m => m.Initialize(this));
            };
            createMeshes();

            // Set the first animation as the current animation and start clock
            meshes.ForEach(m =>
            {
                if (m.Mesh.Animations != null && m.Mesh.Animations.Any())
                {
                    m.CurrentAnimation = m.Mesh.Animations.First().Value;
                }
                m.Clock.Start();
            });

            // Create the overall mesh World matrix
            var meshWorld = Matrix.Identity;

            #endregion

            // Create and initialize a Direct2D FPS text renderer
            var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16));
            fps.Initialize(this);

            // Create and initialize a general purpose Direct2D text renderer
            // This will display some instructions and the current view and rotation offsets
            var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12));
            textRenderer.Initialize(this);

            #endregion

            // Initialize the world matrix
            var worldMatrix = Matrix.Identity;

            // Set the camera position slightly behind (z)
            var cameraPosition = new Vector3(0, 1, 2);
            var cameraTarget   = Vector3.Zero;  // Looking at the origin 0,0,0
            var cameraUp       = Vector3.UnitY; // Y+ is Up

            // Prepare matrices
            // Create the view matrix from our camera position, look target and up direction
            var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp);
            viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0);

            // Create the projection matrix
            /* FoV 60degrees = Pi/3 radians */
            // Aspect ratio (based on window size), Near clip, Far clip
            var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);

            // Maintain the correct aspect ratio on resize
            Window.Resize += (s, e) =>
            {
                projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);
            };

            #region Rotation and window event handlers

            // Create a rotation vector to keep track of the rotation
            // around each of the axes
            var rotation = new Vector3(0.0f, 0.0f, 0.0f);

            // We will call this action to update text
            // for the text renderer
            Action updateText = () =>
            {
                textRenderer.Text =
                    String.Format(
                        "\nPause rotation: P"
                        + "\nThreads: {0} (+/-)"
                        + "\nReflectors: {1} (Shift-Up/Down)"
                        + "\nCPU load: {2} matrix ops (Shift +/-)"
                        + "\nRotating meshes: {3} (Up/Down, Left/Right)"
                        ,
                        threadCount,
                        maxReflectors,
                        additionalCPULoad,
                        meshRows * meshColumns);
            };

            Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>();
            keyToggles[Keys.Z] = false;
            keyToggles[Keys.F] = false;

            // Support keyboard/mouse input to rotate or move camera view
            var moveFactor = 0.02f; // how much to change on each keypress
            var shiftKey   = false;
            var ctrlKey    = false;
            var background = Color.White;
            Window.KeyDown += (s, e) =>
            {
                var context = DeviceManager.Direct3DContext;

                shiftKey = e.Shift;
                ctrlKey  = e.Control;

                switch (e.KeyCode)
                {
                // WASD -> pans view
                case Keys.A:
                    viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.D:
                    viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.S:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                case Keys.W:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                // Up/Down and Left/Right - rotates around X / Y respectively
                // (Mouse wheel rotates around Z)
                //case Keys.Down:
                //    worldMatrix *= Matrix.RotationX(moveFactor);
                //    rotation += new Vector3(moveFactor, 0f, 0f);
                //    break;
                //case Keys.Up:
                //    worldMatrix *= Matrix.RotationX(-moveFactor);
                //    rotation -= new Vector3(moveFactor, 0f, 0f);
                //    break;
                //case Keys.Left:
                //    worldMatrix *= Matrix.RotationY(moveFactor);
                //    rotation += new Vector3(0f, moveFactor, 0f);
                //    break;
                //case Keys.Right:
                //    worldMatrix *= Matrix.RotationY(-moveFactor);
                //    rotation -= new Vector3(0f, moveFactor, 0f);
                //    break;
                case Keys.T:
                    fps.Show          = !fps.Show;
                    textRenderer.Show = !textRenderer.Show;
                    break;

                case Keys.B:
                    if (background == Color.White)
                    {
                        background = new Color(30, 30, 34);
                    }
                    else
                    {
                        background = Color.White;
                    }
                    break;

                case Keys.P:
                    // Pause or resume mesh animation
                    meshes.ForEach(m => {
                        if (m.Clock.IsRunning)
                        {
                            m.Clock.Stop();
                        }
                        else
                        {
                            m.Clock.Start();
                        }
                    });
                    break;

                case Keys.X:
                    // To test for correct resource recreation
                    // Simulate device reset or lost.
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    DeviceManager.Initialize(DeviceManager.Dpi);
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    break;

                //case Keys.Z:
                //    keyToggles[Keys.Z] = !keyToggles[Keys.Z];
                //    if (keyToggles[Keys.Z])
                //    {
                //        context.PixelShader.Set(depthPixelShader);
                //    }
                //    else
                //    {
                //        context.PixelShader.Set(pixelShader);
                //    }
                //    break;
                case Keys.F:
                    keyToggles[Keys.F] = !keyToggles[Keys.F];
                    RasterizerStateDescription rasterDesc;
                    if (context.Rasterizer.State != null)
                    {
                        rasterDesc = context.Rasterizer.State.Description;
                    }
                    else
                    {
                        rasterDesc = new RasterizerStateDescription()
                        {
                            CullMode = CullMode.Back,
                            FillMode = FillMode.Solid
                        }
                    };
                    if (keyToggles[Keys.F])
                    {
                        rasterDesc.FillMode = FillMode.Wireframe;
                        rasterizerState     = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    else
                    {
                        rasterDesc.FillMode = FillMode.Solid;
                        rasterizerState     = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    break;
                    //case Keys.D1:
                    //    context.PixelShader.Set(pixelShader);
                    //    break;
                    //case Keys.D2:
                    //    context.PixelShader.Set(lambertShader);
                    //    break;
                    //case Keys.D3:
                    //    context.PixelShader.Set(phongShader);
                    //    break;
                    //case Keys.D4:
                    //    context.PixelShader.Set(blinnPhongShader);
                    //    break;
                    //case Keys.D5:
                    //    context.PixelShader.Set(simpleUVShader);
                    //    break;
                    //case Keys.D6:
                    //    context.PixelShader.Set(lambertUVShader);
                    //    break;
                    //case Keys.D7:
                    //    context.PixelShader.Set(phongUVShader);
                    //    break;
                    //case Keys.D8:
                    //    context.PixelShader.Set(blinnPhongUVShader);
                    //    break;
                }

                updateText();
            };
            Window.KeyUp += (s, e) =>
            {
                // Clear the shift/ctrl keys so they aren't sticky
                if (e.KeyCode == Keys.ShiftKey)
                {
                    shiftKey = false;
                }
                if (e.KeyCode == Keys.ControlKey)
                {
                    ctrlKey = false;
                }
            };
            Window.MouseWheel += (s, e) =>
            {
                if (shiftKey)
                {
                    // Zoom in/out
                    viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2);
                }
                else
                {
                    // rotate around Z-axis
                    viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor);
                    rotation   += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor);
                }
                updateText();
            };

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    // Mouse move changes
                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
            };

            // Display instructions with initial values
            updateText();

            #endregion

            var clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            // Setup the deferred contexts
            SetupContextList();

            #region Render loop

            // Whether or not to reinitialize meshes
            bool initializeMesh = false;

            // Define additional key handlers for controlling the
            // number of threads, reflectors, and replicated meshes
            #region Dynamic Cube map and threading KeyDown handlers
            Window.KeyDown += (s, e) =>
            {
                switch (e.KeyCode)
                {
                case Keys.Up:
                    if (shiftKey)
                    {
                        maxReflectors++;
                    }
                    else
                    {
                        meshRows += 2;
                    }
                    initializeMesh = true;
                    break;

                case Keys.Down:
                    if (shiftKey)
                    {
                        maxReflectors = Math.Max(0, maxReflectors - 1);
                    }
                    else
                    {
                        meshRows = Math.Max(2, meshRows - 2);
                    }
                    initializeMesh = true;
                    break;

                case Keys.Right:
                    meshColumns   += 2;
                    initializeMesh = true;
                    break;

                case Keys.Left:
                    meshColumns    = Math.Max(2, meshColumns - 2);
                    initializeMesh = true;
                    break;

                case Keys.Add:
                    if (shiftKey)
                    {
                        additionalCPULoad += 100;
                    }
                    else
                    {
                        threadCount++;
                    }
                    break;

                case Keys.Subtract:
                    if (shiftKey)
                    {
                        additionalCPULoad = Math.Max(0, additionalCPULoad - 100);
                    }
                    else
                    {
                        threadCount = Math.Max(1, threadCount - 1);
                    }
                    break;

                case Keys.Enter:
                    if (keyToggles.ContainsKey(Keys.Enter))
                    {
                        keyToggles[Keys.Enter] = !keyToggles[Keys.Enter];
                    }
                    else
                    {
                        keyToggles[Keys.Enter] = true;
                    }
                    break;

                default:
                    break;
                }
                updateText();
            };
            #endregion

            #region Render mesh group
            // Action for rendering a group of meshes for a
            // context (based on number of available contexts)
            Action <int, DeviceContext, Matrix, Matrix> renderMeshGroup = (contextIndex, renderContext, view, projection) =>
            {
                var viewProjection = view * projection;

                // Determine the meshes to render for this context
                int batchSize  = (int)Math.Floor((double)meshes.Count / contextList.Length);
                int startIndex = batchSize * contextIndex;
                int endIndex   = Math.Min(startIndex + batchSize, meshes.Count - 1);
                // If this is the last context include whatever remains to be
                // rendered due to the rounding above.
                if (contextIndex == contextList.Length - 1)
                {
                    endIndex = meshes.Count - 1;
                }

                // Loop over the meshes for this context and render them
                var perObject = new ConstantBuffers.PerObject();
                for (var i = startIndex; i <= endIndex; i++)
                {
                    // Simulate additional CPU load
                    for (var j = 0; j < additionalCPULoad; j++)
                    {
                        viewProjection = Matrix.Multiply(view, projection);
                    }

                    // Retrieve current mesh
                    var m = meshes[i];

                    // Check if this is a rotating mesh
                    if (rotateMeshes.Contains(m))
                    {
                        var rotate = Matrix.RotationAxis(Vector3.UnitY, m.Clock.ElapsedMilliseconds / 1000.0f);
                        perObject.World = m.World * rotate * worldMatrix;
                    }
                    else
                    {
                        perObject.World = m.World * worldMatrix;
                    }

                    // Update perObject constant buffer
                    perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                    perObject.WorldViewProjection   = perObject.World * viewProjection;
                    perObject.Transpose();
                    renderContext.UpdateSubresource(ref perObject, perObjectBuffer);

                    // Provide the material and armature constant buffer to the mesh renderer
                    m.PerArmatureBuffer = perArmatureBuffer;
                    m.PerMaterialBuffer = perMaterialBuffer;

                    // Render the mesh using the provided DeviceContext
                    m.Render(renderContext);
                }
            };

            #endregion

            #region Render scene

            // Action for rendering the entire scene
            Action <DeviceContext, Matrix, Matrix, RenderTargetView, DepthStencilView, DualParaboloidMap> renderScene = (context, view, projection, rtv, dsv, envMap) =>
            {
                // We must initialize the context every time we render
                // the scene as we are changing the state depending on
                // whether we are rendering the envmaps or final scene
                InitializeContext(context, false);

                // We always need the immediate context
                // Note: the passed in context will normally be the immediate context
                // however it is possible to run this method threaded also.
                var immediateContext = this.DeviceManager.Direct3DDevice.ImmediateContext;

                // Clear depth stencil view
                context.ClearDepthStencilView(dsv, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                // Clear render target view
                context.ClearRenderTargetView(rtv, background);

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(view, projection);

                // Extract camera position from view
                var camPosition = Matrix.Transpose(Matrix.Invert(view)).Column4;
                cameraPosition = new Vector3(camPosition.X, camPosition.Y, camPosition.Z);

                // Setup the per frame constant buffer
                var perFrame = new ConstantBuffers.PerFrame();
                perFrame.Light.Color = new Color(0.9f, 0.9f, 0.9f, 1.0f);
                var lightDir = Vector3.Transform(new Vector3(-1f, -1f, -1f), worldMatrix);
                perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);
                perFrame.CameraPosition  = cameraPosition;
                context.UpdateSubresource(ref perFrame, perFrameBuffer);

                // Render each object

                // Prepare the default per material constant buffer
                var perMaterial = new ConstantBuffers.PerMaterial();
                perMaterial.Ambient       = new Color4(0.2f);
                perMaterial.Diffuse       = Color.White;
                perMaterial.Emissive      = new Color4(0);
                perMaterial.Specular      = Color.White;
                perMaterial.SpecularPower = 20f;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                // ----------Render meshes------------

                if (contextList.Length == 1)
                {
                    // If there is only one context available there is no need to
                    // generate command lists and execute them so just render the
                    // mesh directly on the current context (which may or may
                    // not be an immediate context depending on the caller).
                    renderMeshGroup(0, context, view, projection);
                }
                else
                {
                    // There are multiple contexts therefore
                    // we are using deferred contexts. Prepare a
                    // separate thread for each available context
                    // and render a group of meshes on each.
                    Task[]        renderTasks = new Task[contextList.Length];
                    CommandList[] commands    = new CommandList[contextList.Length];
                    var           viewports   = context.Rasterizer.GetViewports();

                    for (var i = 0; i < contextList.Length; i++)
                    {
                        // Must store the iteration value in another variable
                        // or each task action will use the last iteration value.
                        var contextIndex = i;

                        // Create task to run on new thread from ThreadPool
                        renderTasks[i] = Task.Run(() =>
                        {
                            // Retrieve context for this thread
                            var renderContext = contextList[contextIndex];
                            // Initialize the context state
                            InitializeContext(renderContext, false);

                            // Set the render targets and viewport
                            renderContext.OutputMerger.SetRenderTargets(dsv, rtv);
                            renderContext.Rasterizer.SetViewports(viewports);

                            // If we are rendering for an env map we must set the
                            // per environment map buffer.
                            if (envMap != null)
                            {
                                renderContext.VertexShader.SetConstantBuffer(4, envMap.PerEnvMapBuffer);
                                renderContext.PixelShader.SetConstantBuffer(4, envMap.PerEnvMapBuffer);
                            }
                            // Render logic
                            renderMeshGroup(contextIndex, renderContext, view, projection);

                            // Create the command list
                            if (renderContext.TypeInfo == DeviceContextType.Deferred)
                            {
                                commands[contextIndex] = renderContext.FinishCommandList(false);
                            }
                        });
                    }
                    // Wait for all the tasks to complete
                    Task.WaitAll(renderTasks);

                    // Replay the command lists on the immediate context
                    for (var i = 0; i < contextList.Length; i++)
                    {
                        if (contextList[i].TypeInfo == DeviceContextType.Deferred && commands[i] != null)
                        {
                            immediateContext.ExecuteCommandList(commands[i], false);
                            // Clean up command list
                            commands[i].Dispose();
                            commands[i] = null;
                        }
                    }
                }
            };

            #endregion

            long frameCount      = 0;
            int  lastThreadCount = threadCount;

            keyToggles[Keys.Enter] = false;

            // Create and run the render loop
            RenderLoop.Run(Window, () =>
            {
                // Allow dynamic changes to number of reflectors and replications
                if (initializeMesh)
                {
                    initializeMesh = false;
                    createMeshes();
                }

                if (keyToggles[Keys.Enter])
                {
                    // Export the paraboloid maps
                    var i = 0;
                    foreach (var item in envMaps)
                    {
                        using (var tex = item.EnvMapSRV.ResourceAs <Texture2D>())
                        {
                            for (var j = 0; j < tex.Description.ArraySize; j++)
                            {
                                CopyTexture.SaveToFile(DeviceManager, tex, String.Format("DualMap{0}_{1}.png", i, j), null, tex.Description.MipLevels * j);
                            }
                            i++;
                        }
                    }

                    keyToggles[Keys.Enter] = false;
                }

                // Allow dynamic chnages to the number of threads to use
                if (lastThreadCount != threadCount)
                {
                    SetupContextList();
                    lastThreadCount = threadCount;
                }

                // Start of frame:
                frameCount++;

                // Retrieve immediate context
                var context = DeviceManager.Direct3DContext;

                //if (frameCount % 3 == 1) // to update envmap once every third frame
                //{
                #region Update environment maps

                // Update each of the environment maps
                activeVertexShader   = envMapVSShader;
                activeGeometryShader = envMapGSShader;
                activePixelShader    = envMapPSShader;

                // Render the scene from the perspective of each of the environment maps
                foreach (var envMap in envMaps)
                {
                    var mesh = envMap.Reflector as MeshRenderer;
                    if (mesh != null)
                    {
                        // Calculate view point for reflector
                        var meshCenter = Vector3.Transform(mesh.Mesh.Extent.Center, mesh.World * worldMatrix);
                        envMap.SetViewPoint(new Vector3(meshCenter.X, meshCenter.Y, meshCenter.Z));
                        // Render envmap in single full render pass using
                        // geometry shader instancing.
                        envMap.UpdateSinglePass(context, renderScene);
                    }
                }

                #endregion
                //}

                #region Render final scene
                // Reset the vertex, geometry and pixel shader
                activeVertexShader   = vertexShader;
                activeGeometryShader = null;
                activePixelShader    = blinnPhongShader;
                // Initialize context (also resetting the render targets)
                InitializeContext(context, true);

                // Render the final scene
                renderScene(context, viewMatrix, projectionMatrix, RenderTargetView, DepthStencilView, null);
                #endregion

                // Render FPS
                fps.Render();

                // Render instructions + position changes
                textRenderer.Render();

                // Present the frame
                Present();
            });
            #endregion
        }
    }
Example #17
0
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout,
                                                                 // Root Parameters
                                                                 new[]
            {
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.ShaderResourceView,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0
                })
            },
                                                                 // Samplers
                                                                 new[]
            {
                new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
                {
                    Filter     = Filter.MinimumMinMagMipPoint,
                    AddressUVW = TextureAddressMode.Border,
                }
            });

            rootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("shaders.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            var inputElementDescs = new []
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            var psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = rootSignature,
                VertexShader       = vertexShader,
                PixelShader        = pixelShader,
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = false, IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            var triangleVertices = new []
            {
                new Vertex()
                {
                    Position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), TexCoord = new Vector2(0.5f, 0.0f)
                },
                new Vertex()
                {
                    Position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), TexCoord = new Vector2(1.0f, 1.0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), TexCoord = new Vector2(0.0f, 1.0f)
                },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            var pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <Vertex>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;

            // Create the texture.
            // Describe and create a Texture2D.
            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1);

            // Create the GPU upload buffer.
            var textureUploadHeap = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            var handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            var ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D = { MipLevels = 1 },
            };

            device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            commandQueue.ExecuteCommandList(commandList);

            // Create synchronization objects.
            fence      = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);

            WaitForPreviousFrame();

            //release temp texture
            textureUploadHeap.Dispose();
        }
        public override void Run()
        {
            #region Create renderers

            // Note: the renderers take care of creating their own
            // device resources and listen for DeviceManager.OnInitialize

            // Create a axis-grid renderer
            var axisGrid = ToDispose(new AxisGridRenderer());
            axisGrid.Initialize(this);

            // Create and initialize the mesh renderer
            var loadedMesh             = Common.Mesh.LoadFromFile("PhysicsScene1.cmo");
            List <MeshRenderer> meshes = new List <MeshRenderer>();
            meshes.AddRange(from mesh in loadedMesh
                            select ToDispose(new MeshRenderer(mesh)));
            foreach (var m in meshes)
            {
                m.Initialize(this);
                m.World = Matrix.Identity;
            }


            // Set the first animation as the current animation and start clock
            foreach (var m in meshes)
            {
                if (m.Mesh.Animations != null && m.Mesh.Animations.Any())
                {
                    m.CurrentAnimation = m.Mesh.Animations.First().Value;
                }
                m.Clock.Start();
            }


            loadedMesh = Common.Mesh.LoadFromFile("SubdividedPlane.cmo");
            var waterMesh = ToDispose(new MeshRenderer(loadedMesh.First()));
            waterMesh.Initialize(this);

            loadedMesh = Common.Mesh.LoadFromFile("Bataux.cmo");
            List <MeshRenderer> shipMeshes = new List <MeshRenderer>();
            shipMeshes.AddRange((from mesh in loadedMesh
                                 select ToDispose(new MeshRenderer(mesh))));
            foreach (var m in shipMeshes)
            {
                m.Initialize(this);
                m.World = Matrix.Scaling(3) * Matrix.RotationAxis(Vector3.UnitY, -1.57079f);
            }

            //var anchor = new SphereRenderer(0.05f);
            //anchor.Initialize(this);
            //var anchorWorld = Matrix.Identity;

            //var sphere = new SphereRenderer();
            //sphere.Initialize(this);
            //var sphereWorld = Matrix.Identity;

            // Create and initialize a Direct2D FPS text renderer
            var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16));
            fps.Initialize(this);

            // Create and initialize a general purpose Direct2D text renderer
            // This will display some instructions and the current view and rotation offsets
            var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12));
            textRenderer.Initialize(this);

            #endregion

            #region Initialize physics engine

            CollisionConfiguration defaultConfig = new DefaultCollisionConfiguration();
            ConstraintSolver       solver        = new SequentialImpulseConstraintSolver();
            BulletSharp.Dispatcher dispatcher    = new CollisionDispatcher(defaultConfig);
            BroadphaseInterface    broadphase    = new DbvtBroadphase();
            DynamicsWorld          world         = null;
            Action initializePhysics             = () =>
            {
                RemoveAndDispose(ref world);
                world         = ToDispose(new BulletSharp.DiscreteDynamicsWorld(dispatcher, broadphase, solver, defaultConfig));
                world.Gravity = new BulletSharp.Math.Vector3(0, -10, 0);

                // For each mesh, create a RigidBody and add to "world" for simulation
                meshes.ForEach(m =>
                {
                    // We use the name of the mesh to determine the correct body
                    if (String.IsNullOrEmpty(m.Mesh.Name))
                    {
                        return;
                    }

                    var name   = m.Mesh.Name.ToLower();
                    var extent = m.Mesh.Extent;

                    BulletSharp.CollisionShape shape;

                    #region Create collision shape
                    if (name.Contains("box") || name.Contains("cube"))
                    {
                        // Assumes the box/cube has an axis-aligned neutral orientation
                        shape = new BulletSharp.BoxShape(
                            Math.Abs(extent.Max.Z - extent.Min.Z) / 2.0f,
                            Math.Abs(extent.Max.Y - extent.Min.Y) / 2.0f,
                            Math.Abs(extent.Max.X - extent.Min.X) / 2.0f);
                    }
                    else if (name.Contains("sphere"))
                    {
                        shape = new BulletSharp.SphereShape(extent.Radius);
                    }
                    else // use mesh vertices directly
                    {
                        // for each SubMesh, retrieve the vertex and index buffers
                        // to create a TriangleMeshShape for collision detection.
                        List <Vector3> vertices = new List <Vector3>();
                        List <int> indices      = new List <int>();
                        int vertexOffset        = 0;
                        foreach (var sm in m.Mesh.SubMeshes)
                        {
                            vertexOffset += vertices.Count;
                            indices.AddRange(
                                (from indx in m.Mesh.IndexBuffers[(int)sm.IndexBufferIndex]
                                 select vertexOffset + (int)indx));
                            vertices.AddRange(
                                (from v in m.Mesh
                                 .VertexBuffers[(int)sm.VertexBufferIndex]
                                 select v.Position - extent.Center));
                        }
                        // Create the collision shape
                        var iva = new BulletSharp.TriangleIndexVertexArray(indices.ToArray(), vertices.ToArray().ToBulletVector3Array());
                        shape   = new BulletSharp.BvhTriangleMeshShape(iva, true);
                    }
                    #endregion

                    m.World = Matrix.Identity; // Reset mesh location
                    float mass; Vector3 vec;
                    BulletSharp.Math.Vector3 bsVec;
                    shape.GetBoundingSphere(out bsVec, out mass);
                    vec      = bsVec.ToSharpDXVector3();
                    var body = new BulletSharp.RigidBody(
                        new BulletSharp.RigidBodyConstructionInfo(name.Contains("static") ? 0 : mass,
                                                                  new MeshMotionState(m),
                                                                  shape, shape.CalculateLocalInertia(mass)));
                    if (body.IsStaticObject)
                    {
                        body.Restitution = 1f;
                        body.Friction    = 0.4f;
                    }
                    // Add to the simulation
                    world.AddRigidBody(body);
                });

#if DEBUG
                world.DebugDrawer           = ToDispose(new PhysicsDebugDraw(this.DeviceManager));
                world.DebugDrawer.DebugMode = DebugDrawModes.DrawAabb | DebugDrawModes.DrawWireframe;
#endif
            };
            initializePhysics();


            // Newton's Cradle

            //var box = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.BoxShape(7, 1, 2));
            //box.Position = new Jitter.LinearMath.JVector(0, 8, 0);
            //world.AddBody(box);
            //box.IsStatic = true;

            //var anchorBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.05f));
            //anchorBody.Position = new Jitter.LinearMath.JVector(0, 4, 0);
            //world.AddBody(anchorBody);
            //anchorBody.IsStatic = true;

            //for (var bodyCount = -3; bodyCount < 4; bodyCount++)
            //{
            //    var testBody = new Jitter.Dynamics.RigidBody(new Jitter.Collision.Shapes.SphereShape(0.501f));
            //    testBody.Position = new Jitter.LinearMath.JVector(bodyCount, 0, 0);

            //    world.AddBody(testBody);

            //    world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody,
            //        testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Forward * 3f + Jitter.LinearMath.JVector.Down * 0.5f,
            //        testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f });

            //    world.AddConstraint(new Jitter.Dynamics.Constraints.PointPointDistance(box, testBody,
            //        testBody.Position + Jitter.LinearMath.JVector.Up * 8f + Jitter.LinearMath.JVector.Backward * 3f + Jitter.LinearMath.JVector.Down * 0.5f,
            //        testBody.Position) { Softness = 1.0f, BiasFactor = 0.8f });

            //    testBody.Material.Restitution = 1.0f;
            //    testBody.Material.StaticFriction = 1.0f;
            //}

            #endregion

            // Initialize the world matrix
            var worldMatrix = Matrix.Identity;

            // Set the camera position slightly behind (z)
            var cameraPosition = new Vector3(0, 1, 10);
            var cameraTarget   = Vector3.Zero;  // Looking at the origin 0,0,0
            var cameraUp       = Vector3.UnitY; // Y+ is Up

            // Prepare matrices
            // Create the view matrix from our camera position, look target and up direction
            var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp);
            viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0);

            // Create the projection matrix
            /* FoV 60degrees = Pi/3 radians */
            // Aspect ratio (based on window size), Near clip, Far clip
            var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);

            // Maintain the correct aspect ratio on resize
            Window.Resize += (s, e) =>
            {
                projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);
            };

            bool debugDraw = false;
            bool paused    = false;

            var simTime = new System.Diagnostics.Stopwatch();
            simTime.Start();
            float time     = 0.0f;
            float timeStep = 0.0f;

            #region Rotation and window event handlers

            // Create a rotation vector to keep track of the rotation
            // around each of the axes
            var rotation = new Vector3(0.0f, 0.0f, 0.0f);

            // We will call this action to update text
            // for the text renderer
            Action updateText = () =>
            {
                textRenderer.Text =
                    String.Format("Rotation ({0}) (Up/Down Left/Right Wheel+-)\nView ({1}) (A/D, W/S, Shift+Wheel+-)"
                                  //+ "\nPress 1,2,3,4,5,6,7,8 to switch shaders"
                                  + "\nTime: {2:0.00} (P to toggle, R to reset scene)"
                                  + "\nPhysics debug draw: {3} (E to toggle)"
                                  + "\nBackspace: toggle between Physics and Waves",
                                  rotation,
                                  viewMatrix.TranslationVector,
                                  simTime.Elapsed.TotalSeconds,
                                  debugDraw);
            };

            Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>();
            keyToggles[Keys.Z]    = false;
            keyToggles[Keys.F]    = false;
            keyToggles[Keys.Back] = false;

            // Support keyboard/mouse input to rotate or move camera view
            var moveFactor      = 0.02f; // how much to change on each keypress
            var shiftKey        = false;
            var ctrlKey         = false;
            var background      = Color.White;
            var showNormals     = false;
            var enableNormalMap = true;
            Window.KeyDown += (s, e) =>
            {
                var context = DeviceManager.Direct3DContext;

                shiftKey = e.Shift;
                ctrlKey  = e.Control;

                switch (e.KeyCode)
                {
                // WASD -> pans view
                case Keys.A:
                    viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.D:
                    viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.S:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                case Keys.W:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                // Up/Down and Left/Right - rotates around X / Y respectively
                // (Mouse wheel rotates around Z)
                case Keys.Down:
                    worldMatrix *= Matrix.RotationX(moveFactor);
                    rotation    += new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Up:
                    worldMatrix *= Matrix.RotationX(-moveFactor);
                    rotation    -= new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Left:
                    worldMatrix *= Matrix.RotationY(moveFactor);
                    rotation    += new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.Right:
                    worldMatrix *= Matrix.RotationY(-moveFactor);
                    rotation    -= new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.T:
                    fps.Show          = !fps.Show;
                    textRenderer.Show = !textRenderer.Show;
                    break;

                case Keys.B:
                    if (background == Color.White)
                    {
                        background = new Color(30, 30, 34);
                    }
                    else
                    {
                        background = Color.White;
                    }
                    break;

                case Keys.G:
                    axisGrid.Show = !axisGrid.Show;
                    break;

                case Keys.P:
                    paused = !paused;
                    if (paused)
                    {
                        simTime.Stop();
                    }
                    else
                    {
                        simTime.Start();
                    }

                    // Pause or resume mesh animation
                    meshes.ForEach(m => {
                        if (m.Clock.IsRunning)
                        {
                            m.Clock.Stop();
                        }
                        else
                        {
                            m.Clock.Start();
                        }
                    });
                    updateText();
                    break;

                case Keys.X:
                    // To test for correct resource recreation
                    // Simulate device reset or lost.
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    DeviceManager.Initialize(DeviceManager.Dpi);
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    break;

                case Keys.Z:
                    keyToggles[Keys.Z] = !keyToggles[Keys.Z];
                    if (keyToggles[Keys.Z])
                    {
                        context.PixelShader.Set(depthPixelShader);
                    }
                    else
                    {
                        context.PixelShader.Set(pixelShader);
                    }
                    break;

                case Keys.F:
                    keyToggles[Keys.F] = !keyToggles[Keys.F];
                    RasterizerStateDescription rasterDesc;
                    if (context.Rasterizer.State != null)
                    {
                        rasterDesc = context.Rasterizer.State.Description;
                    }
                    else
                    {
                        rasterDesc = new RasterizerStateDescription()
                        {
                            CullMode = CullMode.None,
                            FillMode = FillMode.Solid
                        }
                    };
                    if (keyToggles[Keys.F])
                    {
                        rasterDesc.FillMode      = FillMode.Wireframe;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    else
                    {
                        rasterDesc.FillMode      = FillMode.Solid;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    break;

                case Keys.N:
                    if (!shiftKey)
                    {
                        showNormals = !showNormals;
                    }
                    else
                    {
                        enableNormalMap = !enableNormalMap;
                    }
                    break;

                case Keys.E:
                    debugDraw = !debugDraw;
                    break;

                case Keys.R:

                    //world = new Jitter.World(new Jitter.Collision.CollisionSystemSAP());
                    initializePhysics();
                    if (simTime.IsRunning)
                    {
                        simTime.Restart();
                    }
                    else
                    {
                        simTime.Reset();
                    }
                    break;

                case Keys.D1:
                    context.PixelShader.Set(pixelShader);
                    break;

                case Keys.D2:
                    context.PixelShader.Set(lambertShader);
                    break;

                case Keys.D3:
                    context.PixelShader.Set(phongShader);
                    break;

                case Keys.D4:
                    context.PixelShader.Set(blinnPhongShader);
                    break;

                case Keys.Back:
                    keyToggles[Keys.Back] = !keyToggles[Keys.Back];
                    break;
                }

                updateText();
            };
            Window.KeyUp += (s, e) =>
            {
                // Clear the shift/ctrl keys so they aren't sticky
                if (e.KeyCode == Keys.ShiftKey)
                {
                    shiftKey = false;
                }
                if (e.KeyCode == Keys.ControlKey)
                {
                    ctrlKey = false;
                }
            };
            Window.MouseWheel += (s, e) =>
            {
                if (shiftKey)
                {
                    // Zoom in/out
                    viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2);
                }
                else
                {
                    // rotate around Z-axis
                    viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor);
                    rotation   += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor);
                }
                updateText();
            };

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    // Mouse move changes
                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
            };

            // Display instructions with initial values
            updateText();

            #endregion

            var clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            #region Render loop

            // Create and run the render loop
            RenderLoop.Run(Window, () =>
            {
                // Update simulation, at 60fps
                if (!paused)
                {
                    if ((float)simTime.Elapsed.TotalSeconds < time)
                    {
                        time     = 0;
                        timeStep = 0;
                    }
                    timeStep = ((float)simTime.Elapsed.TotalSeconds - time);
                    time     = (float)simTime.Elapsed.TotalSeconds;
                    world.StepSimulation(timeStep, 7);
                    // For how to choose the maxSubSteps see:
                    // http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World
                }

                updateText();
                // Start of frame:

                // Retrieve immediate context
                var context = DeviceManager.Direct3DContext;

                // Clear depth stencil view
                context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                // Clear render target view
                context.ClearRenderTargetView(RenderTargetView, background);

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix);

                // Extract camera position from view
                var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4;
                cameraPosition  = new Vector3(camPosition.X, camPosition.Y, camPosition.Z);

                var perFrame             = new ConstantBuffers.PerFrame();
                perFrame.Light.Color     = new Color(0.8f, 0.8f, 0.8f, 1.0f);
                var lightDir             = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix);
                perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);
                perFrame.CameraPosition  = cameraPosition;
                perFrame.Time            = (float)simTime.Elapsed.TotalSeconds; // Provide simulation time to shader
                context.UpdateSubresource(ref perFrame, perFrameBuffer);

                // Render each object

                var perMaterial           = new ConstantBuffers.PerMaterial();
                perMaterial.Ambient       = new Color4(0.2f);
                perMaterial.Diffuse       = Color.White;
                perMaterial.Emissive      = new Color4(0);
                perMaterial.Specular      = Color.White;
                perMaterial.SpecularPower = 20f;
                perMaterial.HasTexture    = 0;
                perMaterial.UVTransform   = Matrix.Identity;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                var perObject = new ConstantBuffers.PerObject();

                // MESH

                if (!keyToggles[Keys.Back])
                {
                    meshes.ForEach((m) =>
                    {
                        perObject.World = m.World * worldMatrix;
                        // Provide the material constant buffer to the mesh renderer
                        perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                        perObject.WorldViewProjection   = perObject.World * viewProjection;
                        perObject.ViewProjection        = viewProjection;
                        perObject.Transpose();
                        context.UpdateSubresource(ref perObject, perObjectBuffer);

                        m.PerMaterialBuffer = perMaterialBuffer;
                        m.PerArmatureBuffer = perArmatureBuffer;
                        m.Render();

                        if (showNormals)
                        {
                            using (var prevPixelShader = context.PixelShader.Get())
                            {
                                perMaterial.HasTexture  = 0;
                                perMaterial.UVTransform = Matrix.Identity;
                                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);
                                context.PixelShader.Set(pixelShader);

                                context.GeometryShader.Set(debugNormals);

                                m.Render();

                                context.PixelShader.Set(prevPixelShader);
                                context.GeometryShader.Set(null);
                            }
                        }
                    });

                    if (debugDraw)
                    {
                        perObject.World = Matrix.Identity;
                        perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                        perObject.WorldViewProjection   = perObject.World * viewProjection;
                        perObject.ViewProjection        = viewProjection;
                        perObject.Transpose();
                        context.UpdateSubresource(ref perObject, perObjectBuffer);

                        (world.DebugDrawer as PhysicsDebugDraw).DrawDebugWorld(world);
                        context.VertexShader.Set(vertexShader);
                        context.PixelShader.Set(pixelShader);
                        context.InputAssembler.InputLayout = vertexLayout;
                    }
                }
                else
                {
                    perObject.World = waterMesh.World * worldMatrix;
                    perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                    perObject.WorldViewProjection   = perObject.World * viewProjection;
                    perObject.ViewProjection        = viewProjection;
                    perObject.Transpose();
                    context.UpdateSubresource(ref perObject, perObjectBuffer);

                    waterMesh.EnableNormalMap   = enableNormalMap;
                    waterMesh.PerMaterialBuffer = perMaterialBuffer;
                    waterMesh.PerArmatureBuffer = perArmatureBuffer;

                    context.VertexShader.Set(waterVertexShader);
                    waterMesh.Render();

                    if (showNormals)
                    {
                        using (var prevPixelShader = context.PixelShader.Get())
                        {
                            perMaterial.HasTexture  = 0;
                            perMaterial.UVTransform = Matrix.Identity;
                            context.UpdateSubresource(ref perMaterial, perMaterialBuffer);
                            context.PixelShader.Set(pixelShader);

                            context.GeometryShader.Set(debugNormals);

                            waterMesh.Render();

                            context.PixelShader.Set(prevPixelShader);
                            context.GeometryShader.Set(null);
                        }
                    }

                    context.VertexShader.Set(vertexShader);

                    foreach (var m in shipMeshes)
                    {
                        perObject.World = m.World * worldMatrix;
                        perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                        perObject.WorldViewProjection   = perObject.World * viewProjection;
                        perObject.Transpose();
                        context.UpdateSubresource(ref perObject, perObjectBuffer);
                        // Provide the material constant buffer to the mesh renderer
                        perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                        perObject.WorldViewProjection   = perObject.World * viewProjection;
                        perObject.ViewProjection        = viewProjection;
                        perObject.Transpose();
                        context.UpdateSubresource(ref perObject, perObjectBuffer);

                        m.PerMaterialBuffer = perMaterialBuffer;
                        m.PerArmatureBuffer = perArmatureBuffer;
                        m.Render();

                        if (showNormals)
                        {
                            using (var prevPixelShader = context.PixelShader.Get())
                            {
                                perMaterial.HasTexture  = 0;
                                perMaterial.UVTransform = Matrix.Identity;
                                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);
                                context.PixelShader.Set(pixelShader);

                                context.GeometryShader.Set(debugNormals);

                                m.Render();

                                context.PixelShader.Set(prevPixelShader);
                                context.GeometryShader.Set(null);
                            }
                        }
                    }
                }

                perMaterial.Ambient       = new Color4(0.2f);
                perMaterial.Diffuse       = Color.White;
                perMaterial.Emissive      = new Color4(0);
                perMaterial.Specular      = Color.White;
                perMaterial.SpecularPower = 20f;
                perMaterial.UVTransform   = Matrix.Identity;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                // AXIS GRID
                context.HullShader.Set(null);
                context.DomainShader.Set(null);
                context.GeometryShader.Set(null);

                using (var prevPixelShader = context.PixelShader.Get())
                    using (var prevVertexShader = context.VertexShader.Get())
                    {
                        context.VertexShader.Set(vertexShader);
                        context.PixelShader.Set(pixelShader);
                        perObject.World = worldMatrix;
                        perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                        perObject.WorldViewProjection   = perObject.World * viewProjection;
                        perObject.ViewProjection        = viewProjection;
                        perObject.Transpose();
                        context.UpdateSubresource(ref perObject, perObjectBuffer);
                        axisGrid.Render();
                        context.PixelShader.Set(prevPixelShader);
                        context.VertexShader.Set(prevVertexShader);
                    }

                // Render FPS
                fps.Render();

                // Render instructions + position changes
                textRenderer.Render();

                // Present the frame
                Present();
            });
            #endregion
        }
Example #19
0
        public bool Initialize(int screenWidth, int screenHeight, bool vSync, IntPtr hwnd, bool fullScreen, float screenDepth, float screenNear)
        {
            try {
                vSyncEnabled = vSync;

                Rational refreshRate = new Rational(0, 0);

                var factory       = new Factory1();
                var adapter       = factory.Adapters[0];
                var adapterOutput = adapter.Outputs[0];

                var modes = adapterOutput.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced);
                for (int i = 0; i < modes.Length; i++)
                {
                    if (modes[i].Width == screenWidth)
                    {
                        if (modes[i].Height == screenHeight)
                        {
                            refreshRate = modes[i].RefreshRate;
                        }
                    }
                }

                VideoCardMemory      = adapter.Description.DedicatedVideoMemory / 1024 / 1024;
                VideoCardDescription = adapter.Description.Description;

                adapterOutput.Dispose();
                adapter.Dispose();
                factory.Dispose();

                var swapChainDescription = new SwapChainDescription {
                    BufferCount     = 1,
                    ModeDescription =
                    {
                        Width            = screenWidth,
                        Height           = screenHeight,
                        Format           = Format.R8G8B8A8_UNorm,
                        RefreshRate      = vSyncEnabled ? refreshRate : new Rational(0, 0),
                        ScanlineOrdering = DisplayModeScanlineOrder.Unspecified,
                        Scaling          = DisplayModeScaling.Unspecified
                    },
                    Usage             = Usage.RenderTargetOutput,
                    OutputHandle      = hwnd,
                    SampleDescription = { Count = 1, Quality = 0 },
                    IsWindowed        = !fullScreen,
                    SwapEffect        = SwapEffect.Discard,
                    Flags             = SwapChainFlags.None
                };

                var featureLevel = FeatureLevel.Level_11_0;

                Device device;
                Device.CreateWithSwapChain(
                    DriverType.Hardware,
                    DeviceCreationFlags.Debug,
                    new[] { featureLevel },
                    swapChainDescription,
                    out device,
                    out swapChain
                    );
                Device        = device;
                DeviceContext = device.ImmediateContext;

                using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) {
                    renderTargetView = new RenderTargetView(device, backBuffer);
                }

                var depthBufferDescription = new Texture2DDescription {
                    Width             = screenWidth,
                    Height            = screenHeight,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    Format            = Format.D24_UNorm_S8_UInt,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    BindFlags         = BindFlags.DepthStencil,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    OptionFlags       = ResourceOptionFlags.None
                };

                depthStencilBuffer = new Texture2D(device, depthBufferDescription);

                var depthStencilStateDescription = new DepthStencilStateDescription {
                    IsDepthEnabled   = true,
                    DepthWriteMask   = DepthWriteMask.All,
                    DepthComparison  = Comparison.Less,
                    IsStencilEnabled = true,
                    StencilReadMask  = 0xFF,
                    StencilWriteMask = 0xFF,
                    FrontFace        =
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    },
                    BackFace =
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    }
                };

                depthStencilState = new DepthStencilState(device, depthStencilStateDescription);

                var depthStencilViewDescription = new DepthStencilViewDescription {
                    Format    = Format.D24_UNorm_S8_UInt,
                    Dimension = DepthStencilViewDimension.Texture2D,
                    Texture2D =
                    {
                        MipSlice = 0
                    }
                };

                depthStencilView = new DepthStencilView(device, depthStencilBuffer, depthStencilViewDescription);

                DeviceContext.OutputMerger.SetRenderTargets(depthStencilView, renderTargetView);

                var rasterizerStateDescription = new RasterizerStateDescription {
                    IsAntialiasedLineEnabled = false,
                    CullMode                = CullMode.Back,
                    DepthBias               = 0,
                    DepthBiasClamp          = 0.0f,
                    IsDepthClipEnabled      = true,
                    FillMode                = FillMode.Solid,
                    IsFrontCounterClockwise = false,
                    IsMultisampleEnabled    = false,
                    IsScissorEnabled        = false,
                    SlopeScaledDepthBias    = 0.0f
                };

                rasterizerState = new RasterizerState(device, rasterizerStateDescription);

                DeviceContext.Rasterizer.State = rasterizerState;

                var viewport = new Viewport {
                    Width    = screenWidth,
                    Height   = screenHeight,
                    MinDepth = 0.0f,
                    MaxDepth = 1.0f,
                    X        = 0,
                    Y        = 0
                };

                DeviceContext.Rasterizer.SetViewport(viewport);

                var fieldOfView  = MathUtil.Pi / 4.0f;
                var screenAspect = (float)screenWidth / screenHeight;
                Projection = Matrix.PerspectiveFovLH(fieldOfView, screenAspect, screenNear, screenDepth);
                World      = Matrix.Identity;
                Orthogonal = Matrix.OrthoLH(screenWidth, screenHeight, screenNear, screenDepth);
            } catch { return(false); }
            return(true);
        }
Example #20
0
        private void Update(EvaluationContext context)
        {
            var updateLive = UpdateLive.GetValue(context);

            if (_updatedOnce && !updateLive)
            {
                FilteredCubeMap.Value = _prefilteredCubeMap;
                return;
            }

            //ConstantBuffers.GetValues(ref _constantBuffers, context);
            ShaderResources.GetValues(ref _shaderResourceViews, context);
            SamplerStates.GetValues(ref _samplerStates, context);
            var vs = VertexShader.GetValue(context);
            var gs = GeometryShader.GetValue(context);

            if (CubeMap.IsConnected && CubeMap.DirtyFlag.IsDirty)
            {
                //Log.Debug("Dirty");
            }

            var cubeMapSrc = CubeMap.GetValue(context); // Needs to be checked for null!

            if (cubeMapSrc == null)
            {
                FilteredCubeMap.Value = null;
                return;
            }



            var device        = ResourceManager.Instance().Device;
            var deviceContext = device.ImmediateContext;


            // Vertex shader stage
            var vsStage = deviceContext.VertexShader;

            _prevVsConstantBuffers     = vsStage.GetConstantBuffers(0, 1);
            _prevVsShaderResourceViews = vsStage.GetShaderResources(0, _shaderResourceViews.Length);
            _prevVertexShader          = vsStage.Get();

            if (vs == null)
            {
                Log.Warning($"{nameof(_SpecularPrefilter)} requires valid vertex shader", SymbolChildId);
                return;
            }
            vsStage.Set(vs);
            vsStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews);

            // Geometry shader stage
            var gsStage = deviceContext.GeometryShader;

            _prevGsConstantBuffers     = gsStage.GetConstantBuffers(0, 1);
            _prevGsShaderResourceViews = gsStage.GetShaderResources(0, _shaderResourceViews.Length);
            _prevGeometryShader        = gsStage.Get();

            if (gs == null)
            {
                Log.Warning($"{nameof(_SpecularPrefilter)} requires valid geometry shader", SymbolChildId);
                return;
            }

            gsStage.Set(gs);
            gsStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews);

            // Pixel shader stage
            var psStage = deviceContext.PixelShader;

            _prevPixelShader           = psStage.Get();
            _prevPsConstantBuffers     = psStage.GetConstantBuffers(0, 1);
            _prevPsShaderResourceViews = psStage.GetShaderResources(0, _shaderResourceViews.Length);
            _prevPsSamplerStates       = psStage.GetSamplers(0, _samplerStates.Length);

            var ps = PixelShader.GetValue(context);

            if (ps == null)
            {
                Log.Warning($"{nameof(_SpecularPrefilter)} requires valid pixel shader", SymbolChildId);
                return;
            }
            psStage.Set(ps);
            psStage.SetShaderResources(0, _shaderResourceViews.Length, _shaderResourceViews);
            psStage.SetSamplers(0, _samplerStates);


            // if (_prefilteredCubeMap != null && !Changed)
            // {
            //     context.Image = _prefilteredCubeMap;
            //     return context;
            // }

            Vector2 cubeMapSize = new Vector2(cubeMapSrc.Description.Width, cubeMapSrc.Description.Height);
            // Log.Debug($"source size: {cubeMapSrc.Description.Width} num mips in src: {cubeMapSrc.Description.MipLevels}");

            // if ( _prefilteredCubeMap == null )
            // {
            var cubeMapDesc = new Texture2DDescription
            {
                BindFlags         = BindFlags.ShaderResource | BindFlags.RenderTarget,
                Format            = cubeMapSrc.Description.Format,
                Width             = (int)cubeMapSize.X,
                Height            = (int)cubeMapSize.Y,
                MipLevels         = cubeMapSrc.Description.MipLevels,
                SampleDescription = cubeMapSrc.Description.SampleDescription,
                Usage             = ResourceUsage.Default,
                OptionFlags       = ResourceOptionFlags.TextureCube | ResourceOptionFlags.GenerateMipMaps,
                CpuAccessFlags    = CpuAccessFlags.None,
                ArraySize         = 6
            };

            Utilities.Dispose(ref _prefilteredCubeMap);
            try
            {
                _prefilteredCubeMap = new Texture2D(device, cubeMapDesc);
            }
            catch (SharpDXException e)
            {
                Log.Debug($"can't create CubeMap target {e.Message}");
                return;
            }

            var rastDesc = new RasterizerStateDescription
            {
                FillMode           = FillMode.Solid,
                CullMode           = CullMode.None,
                IsDepthClipEnabled = false
            };

            _rasterizerState = new RasterizerState(device, rastDesc);

            // Input Assembler
            var previousTopology = device.ImmediateContext.InputAssembler.PrimitiveTopology;

            device.ImmediateContext.InputAssembler.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList;

            _prevBlendState = device.ImmediateContext.OutputMerger.GetBlendState(out _prevBlendFactor, out _prevSampleMask);
            device.ImmediateContext.OutputMerger.BlendState        = DefaultRenderingStates.DisabledBlendState;
            device.ImmediateContext.OutputMerger.DepthStencilState = DefaultRenderingStates.DisabledDepthStencilState;

            _prevRenderTargetViews = device.ImmediateContext.OutputMerger.GetRenderTargets(1);
            device.ImmediateContext.OutputMerger.GetRenderTargets(out _prevDepthStencilView);

            var rtvDesc = new RenderTargetViewDescription()
            {
                Dimension      = RenderTargetViewDimension.Texture2DArray,
                Format         = cubeMapSrc.Description.Format,
                Texture2DArray = new RenderTargetViewDescription.Texture2DArrayResource()
                {
                    ArraySize       = 6,
                    FirstArraySlice = 0,
                    MipSlice        = 0
                }
            };

            int size = _prefilteredCubeMap.Description.Width;

            _prevViewports = device.ImmediateContext.Rasterizer.GetViewports <RawViewportF>();

            device.ImmediateContext.Rasterizer.State = _rasterizerState;

            int numMipLevels = _prefilteredCubeMap.Description.MipLevels;
            int mipSlice     = 0;

            while (mipSlice < numMipLevels)
            {
                // Log.Debug($"Update mipmap level {mipSlice} size: {size}");
                var viewport = new RawViewportF {
                    X = 0, Y = 0, Width = size, Height = size, MinDepth = 0, MaxDepth = 1
                };
                device.ImmediateContext.Rasterizer.SetViewports(new[] { viewport });


                Utilities.Dispose(ref _cubeMapRtv);
                rtvDesc.Texture2DArray.MipSlice = mipSlice;
                _cubeMapRtv = new RenderTargetView(device, _prefilteredCubeMap, rtvDesc);
                device.ImmediateContext.OutputMerger.SetTargets(_cubeMapRtv, null);

                var roughness = (float)mipSlice / (_prefilteredCubeMap.Description.MipLevels - 1);

                // Is this required?
                if (_settingsBuffer != null)
                {
                    Utilities.Dispose(ref _settingsBuffer);
                }

                for (int i = 0; i < _samplingParameters.Length; ++i)
                {
                    int indexToUse = -1;
                    if (Math.Abs(roughness - _samplingParameters[i].roughness) < 0.001f)
                    {
                        indexToUse = i;
                    }

                    if (indexToUse == -1 && roughness < _samplingParameters[i].roughness)
                    {
                        indexToUse = i - 1;
                    }

                    if (indexToUse != -1)
                    {
                        var param = _samplingParameters[indexToUse];
                        param.roughness = roughness;
                        ResourceManager.Instance().SetupConstBuffer(param, ref _settingsBuffer);
                        break;
                    }
                }

                var constantBuffers = new[] { _settingsBuffer };
                psStage.SetConstantBuffers(0, 1, constantBuffers);
                vsStage.SetConstantBuffers(0, 1, constantBuffers);
                gsStage.SetConstantBuffers(0, 1, constantBuffers);

                device.ImmediateContext.Draw(3, 0);
                size /= 2;
                ++mipSlice;
            }

            FilteredCubeMap.Value = _prefilteredCubeMap;
            Utilities.Dispose(ref _cubeMapRtv);

            //device.ImmediateContext.InputAssembler.PrimitiveTopology = previousTopology;
            Restore(context);
            _updatedOnce = true;
        }
Example #21
0
        void Initialize()
        {
            // shader.fx

            ShaderFlags shaderFlags = ShaderFlags.None;
            //ShaderFlags shaderFlags = ShaderFlags.Debug | ShaderFlags.SkipOptimization;
            ShaderBytecode shaderByteCode = ShaderBytecode.CompileFromFile(Application.StartupPath + "\\shader.fx", "fx_4_0", shaderFlags, EffectFlags.None);

            effect = new Effect(_device, shaderByteCode);
            EffectTechnique technique = effect.GetTechniqueByIndex(0);

            shadowGenPass  = technique.GetPassByIndex(0);
            gBufferGenPass = technique.GetPassByIndex(1);

            BufferDescription sceneConstantsDesc = new BufferDescription()
            {
                SizeInBytes    = Marshal.SizeOf(typeof(ShaderSceneConstants)),
                Usage          = ResourceUsage.Dynamic,
                BindFlags      = BindFlags.ConstantBuffer,
                CpuAccessFlags = CpuAccessFlags.Write,
                OptionFlags    = ResourceOptionFlags.None
            };

            sceneConstantsBuffer = new Buffer(_device, sceneConstantsDesc);
            EffectConstantBuffer effectConstantBuffer = effect.GetConstantBufferByName("scene");

            effectConstantBuffer.SetConstantBuffer(sceneConstantsBuffer);

            RasterizerStateDescription desc = new RasterizerStateDescription()
            {
                CullMode = CullMode.None,
                FillMode = FillMode.Solid,
                IsFrontCounterClockwise = true,
                DepthBias            = 0,
                DepthBiasClamp       = 0,
                SlopeScaledDepthBias = 0,
                IsDepthClipEnabled   = true,
            };

            _device.Rasterizer.State = new RasterizerState(_device, desc);

            DepthStencilStateDescription depthDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled   = true,
                IsStencilEnabled = false,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less
            };

            depthStencilState = new DepthStencilState(_device, depthDesc);

            DepthStencilStateDescription lightDepthStateDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled   = true,
                IsStencilEnabled = false,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less
            };

            lightDepthStencilState = new DepthStencilState(_device, lightDepthStateDesc);


            // grender.fx

            shaderByteCode = ShaderBytecode.CompileFromFile(Application.StartupPath + "\\grender.fx", "fx_4_0", shaderFlags, EffectFlags.None);

            effect2           = new Effect(_device, shaderByteCode);
            technique         = effect2.GetTechniqueByIndex(0);
            gBufferRenderPass = technique.GetPassByIndex(0);

            Buffer quad = MeshFactory.CreateScreenQuad(_device);

            quadBinding = new VertexBufferBinding(quad, 20, 0);
            Matrix quadProjection = Matrix.OrthoLH(1, 1, 0.1f, 1.0f);

            effect2.GetVariableByName("ViewProjection").AsMatrix().SetMatrix(quadProjection);

            InputElement[] elements = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0, InputClassification.PerVertexData, 0),
            };
            quadBufferLayout = new InputLayout(_device, gBufferRenderPass.Description.Signature, elements);


            Info        = new InfoText(_device);
            meshFactory = new MeshFactory(this);

            OnInitialize();
            CreateBuffers();
            SetSceneConstants();
        }
Example #22
0
        public static void Initialize(Device device)
        {
            {
                var blendStateDescription = new BlendStateDescription();
                blendStateDescription.RenderTargets[0].BlendEnable           = false;
                blendStateDescription.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
                blendStateDescription.RenderTargets[1].BlendEnable           = false;
                blendStateDescription.RenderTargets[1].RenderTargetWriteMask = ColorWriteMaskFlags.None;
                blendStateDescription.RenderTargets[2].BlendEnable           = false;
                blendStateDescription.RenderTargets[2].RenderTargetWriteMask = ColorWriteMaskFlags.None;
                blendStateDescription.RenderTargets[3].BlendEnable           = false;
                blendStateDescription.RenderTargets[3].RenderTargetWriteMask = ColorWriteMaskFlags.None;

                m_BlendStates[(int)BlendType.None] = BlendState.FromDescription(device, blendStateDescription);

                blendStateDescription.RenderTargets[0].BlendEnable           = true;
                blendStateDescription.RenderTargets[0].BlendOperation        = BlendOperation.Add;
                blendStateDescription.RenderTargets[0].BlendOperationAlpha   = BlendOperation.Add;
                blendStateDescription.RenderTargets[0].DestinationBlend      = BlendOption.One;
                blendStateDescription.RenderTargets[0].DestinationBlendAlpha = BlendOption.One;
                blendStateDescription.RenderTargets[0].SourceBlend           = BlendOption.One;
                blendStateDescription.RenderTargets[0].SourceBlendAlpha      = BlendOption.One;
                blendStateDescription.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

                m_BlendStates[(int)BlendType.Additive] = BlendState.FromDescription(device, blendStateDescription);
            }

            {
                var depthStencilStateDescription = new DepthStencilStateDescription();
                depthStencilStateDescription.DepthComparison  = Comparison.Always;
                depthStencilStateDescription.DepthWriteMask   = DepthWriteMask.Zero;
                depthStencilStateDescription.IsDepthEnabled   = false;
                depthStencilStateDescription.IsStencilEnabled = false;
                depthStencilStateDescription.DepthWriteMask   = DepthWriteMask.Zero;

                m_DepthStencilStates[(int)DepthConfigurationType.NoDepth] = DepthStencilState.FromDescription(device, depthStencilStateDescription);

                depthStencilStateDescription.DepthComparison = Comparison.LessEqual;
                depthStencilStateDescription.DepthWriteMask  = DepthWriteMask.All;
                depthStencilStateDescription.IsDepthEnabled  = true;

                m_DepthStencilStates[(int)DepthConfigurationType.DepthWriteCompare] = DepthStencilState.FromDescription(device, depthStencilStateDescription);

                depthStencilStateDescription.DepthWriteMask = DepthWriteMask.Zero;

                m_DepthStencilStates[(int)DepthConfigurationType.DepthCompare] = DepthStencilState.FromDescription(device, depthStencilStateDescription);
            }

            {
                var rasterizerStateDescription = new RasterizerStateDescription();
                rasterizerStateDescription.DepthBias                  = 0;
                rasterizerStateDescription.DepthBiasClamp             = 0;
                rasterizerStateDescription.FillMode                   = FillMode.Solid;
                rasterizerStateDescription.IsAntialiasedLineEnabled   = false;
                rasterizerStateDescription.IsDepthClipEnabled         = true;
                rasterizerStateDescription.IsMultisampleEnabled       = false;
                rasterizerStateDescription.IsScissorEnabled           = false;
                rasterizerStateDescription.SlopeScaledDepthBias       = 0;
                rasterizerStateDescription.CullMode                   = CullMode.None;
                m_RasterizerStates[(int)RasterizerStateType.CullNone] = RasterizerState.FromDescription(device, rasterizerStateDescription);

                rasterizerStateDescription.CullMode = CullMode.Front;
                m_RasterizerStates[(int)RasterizerStateType.CullFront] = RasterizerState.FromDescription(device, rasterizerStateDescription);

                rasterizerStateDescription.CullMode = CullMode.Back;
                m_RasterizerStates[(int)RasterizerStateType.CullBack] = RasterizerState.FromDescription(device, rasterizerStateDescription);
            }
        }
Example #23
0
        private void createRasterizerState()
        {
            RasterizerStateDescription rsd = new RasterizerStateDescription()
            {
                //CullMode = CullMode.None,
                CullMode = CullMode.Back,
                DepthBias = 0,
                DepthBiasClamp = 0.0f,

                //FillMode = FillMode.Wireframe,
                FillMode = FillMode.Solid,
                IsAntialiasedLineEnabled = false,
                IsDepthClipEnabled = false,
                IsFrontCounterclockwise = false,
                IsMultisampleEnabled = false,
                IsScissorEnabled = false,
                SlopeScaledDepthBias = 0.0f
            };
            rasterState = RasterizerState.FromDescription(D3DDevice, rsd);
            D3DDevice.ImmediateContext.Rasterizer.State = rasterState;
        }
Example #24
0
        private void LoadAssets()
        {
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange()
                                                               {
                                                                   RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = int.MinValue, DescriptorCount = 1
                                                               } };
            RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges);

            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter });

            rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.
#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout        = new InputLayoutDescription(inputElementDescs),
                RootSignature      = rootSignature,
                VertexShader       = vertexShader,
                PixelShader        = pixelShader,
                RasterizerState    = RasterizerStateDescription.Default(),
                BlendState         = BlendStateDescription.Default(),
                DepthStencilFormat = SharpDX.DXGI.Format.D32_Float,
                DepthStencilState  = new DepthStencilStateDescription()
                {
                    IsDepthEnabled = false, IsStencilEnabled = false
                },
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Create the command list.
            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);

            // Create the vertex buffer.
            float aspectRatio = viewport.Width / viewport.Height;

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                new Vertex()
                {
                    position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f)
                },
                new Vertex()
                {
                    position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f)
                },
                new Vertex()
                {
                    position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
                },
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            // Initialize the vertex buffer view.
            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <Vertex>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;

            // Command lists are created in the recording state, but there is nothing
            // to record yet. The main loop expects it to be closed, so close it now.
            commandList.Close();

            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBuffer>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            // Create synchronization objects.
            fence      = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;

            // Create an event handle to use for frame synchronization.
            fenceEvent = new AutoResetEvent(false);
        }
        internal static void Modify(RasterizerId id, RasterizerStateDescription desc)
        {
            RasterizerStates.Data[id.Index] = desc;
            RasterizerObjects[id.Index].Dispose();
            RasterizerObjects[id.Index] = null;

            InitRasterizerState(id);
        }
Example #26
0
        public VkPipeline(VkGraphicsDevice gd, ref GraphicsPipelineDescription description)
            : base(ref description)
        {
            _gd = gd;
            IsComputePipeline = false;

            VkGraphicsPipelineCreateInfo pipelineCI = VkGraphicsPipelineCreateInfo.New();

            // Blend State
            VkPipelineColorBlendStateCreateInfo blendStateCI = VkPipelineColorBlendStateCreateInfo.New();
            int attachmentsCount = description.BlendState.AttachmentStates.Length;
            VkPipelineColorBlendAttachmentState *attachmentsPtr
                = stackalloc VkPipelineColorBlendAttachmentState[attachmentsCount];

            for (int i = 0; i < attachmentsCount; i++)
            {
                BlendAttachmentDescription          vdDesc          = description.BlendState.AttachmentStates[i];
                VkPipelineColorBlendAttachmentState attachmentState = new VkPipelineColorBlendAttachmentState();
                attachmentState.srcColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceColorFactor);
                attachmentState.dstColorBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationColorFactor);
                attachmentState.colorBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.ColorFunction);
                attachmentState.srcAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.SourceAlphaFactor);
                attachmentState.dstAlphaBlendFactor = VkFormats.VdToVkBlendFactor(vdDesc.DestinationAlphaFactor);
                attachmentState.alphaBlendOp        = VkFormats.VdToVkBlendOp(vdDesc.AlphaFunction);
                attachmentState.blendEnable         = vdDesc.BlendEnabled;
                attachmentState.colorWriteMask      = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
                attachmentsPtr[i] = attachmentState;
            }

            blendStateCI.attachmentCount = (uint)attachmentsCount;
            blendStateCI.pAttachments    = attachmentsPtr;
            RgbaFloat blendFactor = description.BlendState.BlendFactor;

            blendStateCI.blendConstants_0 = blendFactor.R;
            blendStateCI.blendConstants_1 = blendFactor.G;
            blendStateCI.blendConstants_2 = blendFactor.B;
            blendStateCI.blendConstants_3 = blendFactor.A;

            pipelineCI.pColorBlendState = &blendStateCI;

            // Rasterizer State
            RasterizerStateDescription             rsDesc = description.RasterizerState;
            VkPipelineRasterizationStateCreateInfo rsCI   = VkPipelineRasterizationStateCreateInfo.New();

            rsCI.cullMode         = VkFormats.VdToVkCullMode(rsDesc.CullMode);
            rsCI.polygonMode      = VkFormats.VdToVkPolygonMode(rsDesc.FillMode);
            rsCI.depthClampEnable = !rsDesc.DepthClipEnabled;
            rsCI.frontFace        = rsDesc.FrontFace == FrontFace.Clockwise ? VkFrontFace.Clockwise : VkFrontFace.CounterClockwise;
            rsCI.lineWidth        = 1f;

            pipelineCI.pRasterizationState = &rsCI;

            ScissorTestEnabled = rsDesc.ScissorTestEnabled;

            // Dynamic State
            VkPipelineDynamicStateCreateInfo dynamicStateCI = VkPipelineDynamicStateCreateInfo.New();
            VkDynamicState *dynamicStates = stackalloc VkDynamicState[2];

            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;
            dynamicStateCI.dynamicStateCount = 2;
            dynamicStateCI.pDynamicStates    = dynamicStates;

            pipelineCI.pDynamicState = &dynamicStateCI;

            // Depth Stencil State
            DepthStencilStateDescription          vdDssDesc = description.DepthStencilState;
            VkPipelineDepthStencilStateCreateInfo dssCI     = VkPipelineDepthStencilStateCreateInfo.New();

            dssCI.depthWriteEnable  = vdDssDesc.DepthWriteEnabled;
            dssCI.depthTestEnable   = vdDssDesc.DepthTestEnabled;
            dssCI.depthCompareOp    = VkFormats.VdToVkCompareOp(vdDssDesc.DepthComparison);
            dssCI.stencilTestEnable = vdDssDesc.StencilTestEnabled;

            dssCI.front.failOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Fail);
            dssCI.front.passOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.Pass);
            dssCI.front.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilFront.DepthFail);
            dssCI.front.compareMask = vdDssDesc.StencilReadMask;
            dssCI.front.writeMask   = vdDssDesc.StencilWriteMask;
            dssCI.front.reference   = vdDssDesc.StencilReference;

            dssCI.back.failOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Fail);
            dssCI.back.passOp      = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.Pass);
            dssCI.back.depthFailOp = VkFormats.VdToVkStencilOp(vdDssDesc.StencilBack.DepthFail);
            dssCI.back.compareMask = vdDssDesc.StencilReadMask;
            dssCI.back.writeMask   = vdDssDesc.StencilWriteMask;
            dssCI.back.reference   = vdDssDesc.StencilReference;

            pipelineCI.pDepthStencilState = &dssCI;

            // Multisample
            VkPipelineMultisampleStateCreateInfo multisampleCI = VkPipelineMultisampleStateCreateInfo.New();
            VkSampleCountFlags vkSampleCount = VkFormats.VdToVkSampleCount(description.Outputs.SampleCount);

            multisampleCI.rasterizationSamples = vkSampleCount;

            pipelineCI.pMultisampleState = &multisampleCI;

            // Input Assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.topology = VkFormats.VdToVkPrimitiveTopology(description.PrimitiveTopology);

            pipelineCI.pInputAssemblyState = &inputAssemblyCI;

            // Vertex Input State
            VkPipelineVertexInputStateCreateInfo vertexInputCI = VkPipelineVertexInputStateCreateInfo.New();

            VertexLayoutDescription[] inputDescriptions = description.ShaderSet.VertexLayouts;
            uint bindingCount   = (uint)inputDescriptions.Length;
            uint attributeCount = 0;

            for (int i = 0; i < inputDescriptions.Length; i++)
            {
                attributeCount += (uint)inputDescriptions[i].Elements.Length;
            }
            VkVertexInputBindingDescription *  bindingDescs   = stackalloc VkVertexInputBindingDescription[(int)bindingCount];
            VkVertexInputAttributeDescription *attributeDescs = stackalloc VkVertexInputAttributeDescription[(int)attributeCount];

            int targetIndex    = 0;
            int targetLocation = 0;

            for (int binding = 0; binding < inputDescriptions.Length; binding++)
            {
                VertexLayoutDescription inputDesc = inputDescriptions[binding];
                bindingDescs[binding] = new VkVertexInputBindingDescription()
                {
                    binding   = (uint)binding,
                    inputRate = (inputDesc.InstanceStepRate != 0) ? VkVertexInputRate.Instance : VkVertexInputRate.Vertex,
                    stride    = inputDesc.Stride
                };

                uint currentOffset = 0;
                for (int location = 0; location < inputDesc.Elements.Length; location++)
                {
                    VertexElementDescription inputElement = inputDesc.Elements[location];

                    attributeDescs[targetIndex] = new VkVertexInputAttributeDescription()
                    {
                        format   = VkFormats.VdToVkVertexElementFormat(inputElement.Format),
                        binding  = (uint)binding,
                        location = (uint)(targetLocation + location),
                        offset   = inputElement.Offset != 0 ? inputElement.Offset : currentOffset
                    };

                    targetIndex   += 1;
                    currentOffset += FormatHelpers.GetSizeInBytes(inputElement.Format);
                }

                targetLocation += inputDesc.Elements.Length;
            }

            vertexInputCI.vertexBindingDescriptionCount   = bindingCount;
            vertexInputCI.pVertexBindingDescriptions      = bindingDescs;
            vertexInputCI.vertexAttributeDescriptionCount = attributeCount;
            vertexInputCI.pVertexAttributeDescriptions    = attributeDescs;

            pipelineCI.pVertexInputState = &vertexInputCI;

            // Shader Stage

            VkSpecializationInfo specializationInfo;

            SpecializationConstant[] specDescs = description.ShaderSet.Specializations;
            if (specDescs != null)
            {
                uint specDataSize = 0;
                foreach (SpecializationConstant spec in specDescs)
                {
                    specDataSize += VkFormats.GetSpecializationConstantSize(spec.Type);
                }
                byte *fullSpecData                   = stackalloc byte[(int)specDataSize];
                int   specializationCount            = specDescs.Length;
                VkSpecializationMapEntry *mapEntries = stackalloc VkSpecializationMapEntry[specializationCount];
                uint specOffset = 0;
                for (int i = 0; i < specializationCount; i++)
                {
                    ulong data     = specDescs[i].Data;
                    byte *srcData  = (byte *)&data;
                    uint  dataSize = VkFormats.GetSpecializationConstantSize(specDescs[i].Type);
                    Unsafe.CopyBlock(fullSpecData + specOffset, srcData, dataSize);
                    mapEntries[i].constantID = specDescs[i].ID;
                    mapEntries[i].offset     = specOffset;
                    mapEntries[i].size       = (UIntPtr)dataSize;
                    specOffset += dataSize;
                }
                specializationInfo.dataSize      = (UIntPtr)specDataSize;
                specializationInfo.pData         = fullSpecData;
                specializationInfo.mapEntryCount = (uint)specializationCount;
                specializationInfo.pMapEntries   = mapEntries;
            }

            Shader[] shaders = description.ShaderSet.Shaders;
            StackList <VkPipelineShaderStageCreateInfo> stages = new StackList <VkPipelineShaderStageCreateInfo>();

            foreach (Shader shader in shaders)
            {
                VkShader vkShader = Util.AssertSubtype <Shader, VkShader>(shader);
                VkPipelineShaderStageCreateInfo stageCI = VkPipelineShaderStageCreateInfo.New();
                stageCI.module = vkShader.ShaderModule;
                stageCI.stage  = VkFormats.VdToVkShaderStages(shader.Stage);
                stageCI.pName  = CommonStrings.main; // Meh
                stageCI.pSpecializationInfo = &specializationInfo;
                stages.Add(stageCI);
            }

            pipelineCI.stageCount = stages.Count;
            pipelineCI.pStages    = (VkPipelineShaderStageCreateInfo *)stages.Data;

            // ViewportState
            VkPipelineViewportStateCreateInfo viewportStateCI = VkPipelineViewportStateCreateInfo.New();

            viewportStateCI.viewportCount = 1;
            viewportStateCI.scissorCount  = 1;

            pipelineCI.pViewportState = &viewportStateCI;

            // Pipeline Layout
            ResourceLayout[]           resourceLayouts  = description.ResourceLayouts;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = (uint)resourceLayouts.Length;
            VkDescriptorSetLayout *dsls = stackalloc VkDescriptorSetLayout[resourceLayouts.Length];

            for (int i = 0; i < resourceLayouts.Length; i++)
            {
                dsls[i] = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(resourceLayouts[i]).DescriptorSetLayout;
            }
            pipelineLayoutCI.pSetLayouts = dsls;

            vkCreatePipelineLayout(_gd.Device, ref pipelineLayoutCI, null, out _pipelineLayout);
            pipelineCI.layout = _pipelineLayout;

            // Create fake RenderPass for compatibility.

            VkRenderPassCreateInfo renderPassCI = VkRenderPassCreateInfo.New();
            OutputDescription      outputDesc   = description.Outputs;
            StackList <VkAttachmentDescription, Size512Bytes> attachments = new StackList <VkAttachmentDescription, Size512Bytes>();

            // TODO: A huge portion of this next part is duplicated in VkFramebuffer.cs.

            StackList <VkAttachmentDescription> colorAttachmentDescs = new StackList <VkAttachmentDescription>();
            StackList <VkAttachmentReference>   colorAttachmentRefs  = new StackList <VkAttachmentReference>();

            for (uint i = 0; i < outputDesc.ColorAttachments.Length; i++)
            {
                colorAttachmentDescs[i].format         = VkFormats.VdToVkPixelFormat(outputDesc.ColorAttachments[i].Format);
                colorAttachmentDescs[i].samples        = vkSampleCount;
                colorAttachmentDescs[i].loadOp         = VkAttachmentLoadOp.DontCare;
                colorAttachmentDescs[i].storeOp        = VkAttachmentStoreOp.Store;
                colorAttachmentDescs[i].stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                colorAttachmentDescs[i].stencilStoreOp = VkAttachmentStoreOp.DontCare;
                colorAttachmentDescs[i].initialLayout  = VkImageLayout.Undefined;
                colorAttachmentDescs[i].finalLayout    = VkImageLayout.ShaderReadOnlyOptimal;
                attachments.Add(colorAttachmentDescs[i]);

                colorAttachmentRefs[i].attachment = i;
                colorAttachmentRefs[i].layout     = VkImageLayout.ColorAttachmentOptimal;
            }

            VkAttachmentDescription depthAttachmentDesc = new VkAttachmentDescription();
            VkAttachmentReference   depthAttachmentRef  = new VkAttachmentReference();

            if (outputDesc.DepthAttachment != null)
            {
                PixelFormat depthFormat = outputDesc.DepthAttachment.Value.Format;
                bool        hasStencil  = FormatHelpers.IsStencilFormat(depthFormat);
                depthAttachmentDesc.format         = VkFormats.VdToVkPixelFormat(outputDesc.DepthAttachment.Value.Format, toDepthFormat: true);
                depthAttachmentDesc.samples        = vkSampleCount;
                depthAttachmentDesc.loadOp         = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.storeOp        = VkAttachmentStoreOp.Store;
                depthAttachmentDesc.stencilLoadOp  = VkAttachmentLoadOp.DontCare;
                depthAttachmentDesc.stencilStoreOp = hasStencil ? VkAttachmentStoreOp.Store : VkAttachmentStoreOp.DontCare;
                depthAttachmentDesc.initialLayout  = VkImageLayout.Undefined;
                depthAttachmentDesc.finalLayout    = VkImageLayout.DepthStencilAttachmentOptimal;

                depthAttachmentRef.attachment = (uint)outputDesc.ColorAttachments.Length;
                depthAttachmentRef.layout     = VkImageLayout.DepthStencilAttachmentOptimal;
            }

            VkSubpassDescription subpass = new VkSubpassDescription();

            subpass.pipelineBindPoint    = VkPipelineBindPoint.Graphics;
            subpass.colorAttachmentCount = (uint)outputDesc.ColorAttachments.Length;
            subpass.pColorAttachments    = (VkAttachmentReference *)colorAttachmentRefs.Data;
            for (int i = 0; i < colorAttachmentDescs.Count; i++)
            {
                attachments.Add(colorAttachmentDescs[i]);
            }

            if (outputDesc.DepthAttachment != null)
            {
                subpass.pDepthStencilAttachment = &depthAttachmentRef;
                attachments.Add(depthAttachmentDesc);
            }

            VkSubpassDependency subpassDependency = new VkSubpassDependency();

            subpassDependency.srcSubpass    = SubpassExternal;
            subpassDependency.srcStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstStageMask  = VkPipelineStageFlags.ColorAttachmentOutput;
            subpassDependency.dstAccessMask = VkAccessFlags.ColorAttachmentRead | VkAccessFlags.ColorAttachmentWrite;

            renderPassCI.attachmentCount = attachments.Count;
            renderPassCI.pAttachments    = (VkAttachmentDescription *)attachments.Data;
            renderPassCI.subpassCount    = 1;
            renderPassCI.pSubpasses      = &subpass;
            renderPassCI.dependencyCount = 1;
            renderPassCI.pDependencies   = &subpassDependency;

            VkResult creationResult = vkCreateRenderPass(_gd.Device, ref renderPassCI, null, out _renderPass);

            CheckResult(creationResult);

            pipelineCI.renderPass = _renderPass;

            VkResult result = vkCreateGraphicsPipelines(_gd.Device, VkPipelineCache.Null, 1, ref pipelineCI, null, out _devicePipeline);

            CheckResult(result);

            ResourceSetCount    = (uint)description.ResourceLayouts.Length;
            DynamicOffsetsCount = 0;
            foreach (VkResourceLayout layout in ResourceLayouts)
            {
                DynamicOffsetsCount += layout.DynamicBufferCount;
            }
        }
Example #27
0
        private void InitializeGraphics()
        {
            // Creating device (we accept dx10 cards or greater)
            FeatureLevel[] levels = {
                                        FeatureLevel.Level_11_0,
                                        FeatureLevel.Level_10_1,
                                        FeatureLevel.Level_10_0
                                    };

            // Defining our swap chain
            SwapChainDescription desc = new SwapChainDescription();
            desc.BufferCount = 1;
            desc.Usage = Usage.RenderTargetOutput;
            desc.ModeDescription = new ModeDescription(0, 0, new Rational(0, 0), Format.R8G8B8A8_UNorm);
            desc.SampleDescription = new SampleDescription(1, 0);
            desc.OutputHandle = form.Handle;
            desc.IsWindowed = true;
            desc.SwapEffect = SwapEffect.Discard;

            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, levels, desc, out device11, out swapChain);

            Format depthFormat = Format.D24_UNorm_S8_UInt;
            Texture2DDescription depthBufferDesc = new Texture2DDescription
            {
                ArraySize = 1,
                BindFlags = BindFlags.DepthStencil,
                CpuAccessFlags = CpuAccessFlags.None,
                Format = depthFormat,
                Height = form.Height,
                Width = form.Width,
                MipLevels = 1,
                OptionFlags = ResourceOptionFlags.None,
                SampleDescription = new SampleDescription(1, 0),
                Usage = ResourceUsage.Default
            };

            depthBuffer = new Texture2D(device11, depthBufferDesc);

            DepthStencilViewDescription dsViewDesc = new DepthStencilViewDescription
            {
                Format = depthFormat,
                Dimension = DepthStencilViewDimension.Texture2D,
                MipSlice = 0,
            };

            depthView = new DepthStencilView(device11, depthBuffer, dsViewDesc);

            DepthStencilStateDescription dsStateDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                DepthComparison = Comparison.Less,

                IsStencilEnabled = true,
                StencilReadMask = 0xFF,
                StencilWriteMask = 0xFF,

                FrontFace = new DepthStencilOperationDescription()
                {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Increment,
                    PassOperation = StencilOperation.Keep,
                    Comparison = Comparison.Always
                },
                BackFace = new DepthStencilOperationDescription()
                {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Decrement,
                    PassOperation = StencilOperation.Keep,
                    Comparison = Comparison.Always
                },

            };

            depthState = DepthStencilState.FromDescription(device11, dsStateDesc);

            // Getting back buffer
            backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0);

            // Defining render view
            renderTargetView = new RenderTargetView(device11, backBuffer);
            device11.ImmediateContext.OutputMerger.DepthStencilState = depthState;
            device11.ImmediateContext.OutputMerger.SetTargets(depthView, renderTargetView);

            // Setup the raster description which will determine how and what polygons will be drawn.
            RasterizerStateDescription rasterDesc = new RasterizerStateDescription(){
                IsAntialiasedLineEnabled = false,
                CullMode = CullMode.None,
                DepthBias = 0,
                DepthBiasClamp = 0.0f,
                IsDepthClipEnabled = true,
                FillMode = FillMode.Solid,
                IsFrontCounterclockwise = false,
                IsMultisampleEnabled = false,
                IsScissorEnabled = false,
                SlopeScaledDepthBias = 0.0f,
            };

            // Create the rasterizer state from the description we just filled out.
            rasterState = RasterizerState.FromDescription(device11, rasterDesc);

            // Now set the rasterizer state.
            device11.ImmediateContext.Rasterizer.State = rasterState;
            device11.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f));
        }
        public override void Run()
        {
            #region Create renderers

            // Note: the renderers take care of creating their own
            // device resources and listen for DeviceManager.OnInitialize

            // Create a axis-grid renderer
            var axisGrid = ToDispose(new AxisGridRenderer());
            axisGrid.Initialize(this);

            // Determine if the hardware driver supports CommandLists
            // If not, the Direct3D framework will emulate support.
            bool createResourcesConcurrently;
            bool nativeCommandListSupport;
            DeviceManager.Direct3DDevice.CheckThreadingSupport(out createResourcesConcurrently, out nativeCommandListSupport);

            // Create and initialize the mesh renderer
            var loadedMesh             = Common.Mesh.LoadFromFile("Character.cmo");
            List <MeshRenderer> meshes = new List <MeshRenderer>();

            int meshRows    = 10;
            int meshColumns = 10;

            Action createMeshes = () =>
            {
                // Remove meshes
                foreach (var mesh in meshes)
                {
                    mesh.Dispose();
                }
                meshes.Clear();

                // Add the same mesh multiple times, separate by the combined extent
                var minExtent = (from mesh in loadedMesh
                                 orderby new { mesh.Extent.Min.X, mesh.Extent.Min.Z }
                                 select mesh.Extent).First();
                var maxExtent = (from mesh in loadedMesh
                                 orderby new { mesh.Extent.Max.X, mesh.Extent.Max.Z } descending
                                 select mesh.Extent).First();
                var extentDiff = (maxExtent.Max - minExtent.Min);

                for (int x = -(meshColumns / 2); x < (meshColumns / 2); x++)
                {
                    for (int z = -(meshRows / 2); z < (meshRows / 2); z++)
                    {
                        var meshGroup = (from mesh in loadedMesh
                                         select ToDispose(new MeshRenderer(mesh))).ToList();

                        // Reposition based on width/depth of combined extent
                        foreach (var m in meshGroup)
                        {
                            m.World.TranslationVector = new Vector3(m.Mesh.Extent.Center.X + extentDiff.X * x, m.Mesh.Extent.Min.Y, m.Mesh.Extent.Center.Z + extentDiff.Z * z);
                        }

                        meshes.AddRange(meshGroup);
                    }
                }
                // Initialize each mesh
                meshes.ForEach(m => m.Initialize(this));
            };
            createMeshes();

            bool   animationEnabled = false;
            bool   changeAnimation  = false;
            Action toggleAnimation  = () =>
            {
                // Set the first animation as the current animation and start clock
                meshes.ForEach(m =>
                {
                    if (!animationEnabled && m.Mesh.Animations.Any())
                    {
                        m.CurrentAnimation = m.Mesh.Animations.First().Value;
                        m.Clock.Start();
                    }
                    else
                    {
                        m.CurrentAnimation = null;
                    }
                });
                animationEnabled = !animationEnabled;
            };

            var meshWorld = Matrix.Identity;

            // Create and initialize a Direct2D FPS text renderer
            var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16));
            fps.Initialize(this);

            // Create and initialize a general purpose Direct2D text renderer
            // This will display some instructions and the current view and rotation offsets
            var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12));
            textRenderer.Initialize(this);

            #endregion

            // Initialize the world matrix
            var worldMatrix = Matrix.Identity;

            // Set the camera position
            var cameraPosition = new Vector3(0, 1, 10);
            var cameraTarget   = Vector3.Zero;  // Looking at the origin 0,0,0
            var cameraUp       = Vector3.UnitY; // Y+ is Up

            // Prepare matrices
            // Create the view matrix from our camera position, look target and up direction
            var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp);
            viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0);

            // Create the projection matrix
            /* FoV 60degrees = Pi/3 radians */
            // Aspect ratio (based on window size), Near clip, Far clip
            var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f);

            // Maintain the correct aspect ratio on resize
            Window.Resize += (s, e) =>
            {
                projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f);
            };

            #region Rotation and window event handlers

            // Create a rotation vector to keep track of the rotation
            // around each of the axes
            var rotation = new Vector3(0.0f, 0.0f, 0.0f);

            // We will call this action to update text
            // for the text renderer
            Action updateText = () =>
            {
                textRenderer.Text =
                    String.Format(
                        "\nToggle animation: Backspace, Pause animation: P"
                        + "\nThreads: {0} (+/-)"
                        + " Add CPU load: {1} matrix multiplications (Shift +/-)"
                        + "\nMeshes: {2} (Up/Down, Left/Right)",
                        threadCount,
                        additionalCPULoad,
                        meshRows * meshColumns);
            };

            Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>();
            keyToggles[Keys.Z] = false;
            keyToggles[Keys.F] = false;

            // Support keyboard/mouse input to rotate or move camera view
            var moveFactor = 0.02f; // how much to change on each keypress
            var shiftKey   = false;
            var ctrlKey    = false;
            var background = Color.White;
            Window.KeyDown += (s, e) =>
            {
                var context = DeviceManager.Direct3DContext;

                shiftKey = e.Shift;
                ctrlKey  = e.Control;

                switch (e.KeyCode)
                {
                // WASD -> pans view
                case Keys.A:
                    viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.D:
                    viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.S:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                case Keys.W:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                // Up/Down and Left/Right - rotates around X / Y respectively
                // (Mouse wheel rotates around Z)
                case Keys.Down:
                    worldMatrix *= Matrix.RotationX(moveFactor);
                    rotation    += new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Up:
                    worldMatrix *= Matrix.RotationX(-moveFactor);
                    rotation    -= new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Left:
                    worldMatrix *= Matrix.RotationY(moveFactor);
                    rotation    += new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.Right:
                    worldMatrix *= Matrix.RotationY(-moveFactor);
                    rotation    -= new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.T:
                    fps.Show          = !fps.Show;
                    textRenderer.Show = !textRenderer.Show;
                    break;

                case Keys.B:
                    if (background == Color.White)
                    {
                        background = new Color(30, 30, 34);
                    }
                    else
                    {
                        background = Color.White;
                    }
                    break;

                case Keys.G:
                    axisGrid.Show = !axisGrid.Show;
                    break;

                case Keys.P:
                    // Pause or resume mesh animation
                    meshes.ForEach(m => {
                        if (m.Clock.IsRunning)
                        {
                            m.Clock.Stop();
                        }
                        else
                        {
                            m.Clock.Start();
                        }
                    });
                    break;

                case Keys.X:
                    // To test for correct resource recreation
                    // Simulate device reset or lost.
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    DeviceManager.Initialize(DeviceManager.Dpi);
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    break;

                case Keys.Z:
                    keyToggles[Keys.Z] = !keyToggles[Keys.Z];
                    if (keyToggles[Keys.Z])
                    {
                        context.PixelShader.Set(depthPixelShader);
                    }
                    else
                    {
                        context.PixelShader.Set(pixelShader);
                    }
                    break;

                case Keys.F:
                    keyToggles[Keys.F] = !keyToggles[Keys.F];
                    RasterizerStateDescription rasterDesc;
                    if (context.Rasterizer.State != null)
                    {
                        rasterDesc = context.Rasterizer.State.Description;
                    }
                    else
                    {
                        rasterDesc = new RasterizerStateDescription()
                        {
                            CullMode = CullMode.Back,
                            FillMode = FillMode.Solid
                        }
                    };
                    if (keyToggles[Keys.F])
                    {
                        rasterDesc.FillMode      = FillMode.Wireframe;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    else
                    {
                        rasterDesc.FillMode      = FillMode.Solid;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    break;

                case Keys.D1:
                    context.PixelShader.Set(pixelShader);
                    break;

                case Keys.D2:
                    context.PixelShader.Set(lambertShader);
                    break;

                case Keys.D3:
                    context.PixelShader.Set(phongShader);
                    break;

                case Keys.D4:
                    context.PixelShader.Set(blinnPhongShader);
                    break;
                }

                updateText();
            };
            Window.KeyUp += (s, e) =>
            {
                // Clear the shift/ctrl keys so they aren't sticky
                if (e.KeyCode == Keys.ShiftKey)
                {
                    shiftKey = false;
                }
                if (e.KeyCode == Keys.ControlKey)
                {
                    ctrlKey = false;
                }
            };
            Window.MouseWheel += (s, e) =>
            {
                if (shiftKey)
                {
                    // Zoom in/out
                    viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2);
                }
                else
                {
                    // rotate around Z-axis
                    viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor);
                    rotation   += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor);
                }
                updateText();
            };

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    // Mouse move changes
                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
            };

            // Display instructions with initial values
            updateText();

            #endregion

            var clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            SetupContextList();

            bool initializeMesh = false;
            Window.KeyDown += (s, e) =>
            {
                switch (e.KeyCode)
                {
                case Keys.Back:
                    changeAnimation = true;
                    break;

                case Keys.Up:
                    meshRows      += 2;
                    initializeMesh = true;
                    break;

                case Keys.Down:
                    meshRows       = Math.Max(2, meshRows - 2);
                    initializeMesh = true;
                    break;

                case Keys.Right:
                    meshColumns   += 2;
                    initializeMesh = true;
                    break;

                case Keys.Left:
                    meshColumns    = Math.Max(2, meshColumns - 2);
                    initializeMesh = true;
                    break;

                case Keys.Add:
                    if (shiftKey)
                    {
                        additionalCPULoad += 100;
                    }
                    else
                    {
                        threadCount++;
                    }
                    break;

                case Keys.Subtract:
                    if (shiftKey)
                    {
                        additionalCPULoad = Math.Max(0, additionalCPULoad - 100);
                    }
                    else
                    {
                        threadCount = Math.Max(1, threadCount - 1);
                    }
                    break;

                default:
                    break;
                }
                updateText();
            };

            // Action for rendering a mesh using the context
            // from the specified index wtihin contextList
            Action <int> renderMeshGroup = (int contextIndex) =>
            {
                // Retrieve appropriate context
                var renderContext = contextList[contextIndex];

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix);

                // Determine the meshes to render for this context
                int batchSize  = (int)Math.Floor((double)meshes.Count / contextList.Length);
                int startIndex = batchSize * contextIndex;
                int endIndex   = Math.Min(startIndex + batchSize, meshes.Count - 1);
                // If this is the last context include whatever remains to be
                // rendered due to the rounding above.
                if (contextIndex == contextList.Length - 1)
                {
                    endIndex = meshes.Count - 1;
                }

                // Loop over the meshes for this context and render them
                var perObject = new ConstantBuffers.PerObject();
                for (var i = startIndex; i <= endIndex; i++)
                {
                    // Simulate additional CPU load
                    for (var j = 0; j < additionalCPULoad; j++)
                    {
                        viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix);
                    }

                    var m = meshes[i];
                    // Update perObject constant buffer
                    perObject.World = m.World * worldMatrix;
                    perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                    perObject.WorldViewProjection   = perObject.World * viewProjection;
                    perObject.Transpose();
                    renderContext.UpdateSubresource(ref perObject, perObjectBuffer);

                    // Provide the material and armature constant buffer to the mesh renderer
                    m.PerArmatureBuffer = perArmatureBuffer;
                    m.PerMaterialBuffer = perMaterialBuffer;
                    // Specify the context to render with
                    m.Render(renderContext);
                }
            };

            #region Render loop

            var lastThreadCount = threadCount;

            // Create and run the render loop
            RenderLoop.Run(Window, () =>
            {
                if (initializeMesh)
                {
                    initializeMesh = false;
                    createMeshes();
                }

                if (changeAnimation)
                {
                    toggleAnimation();
                    changeAnimation = false;
                }

                if (lastThreadCount != threadCount)
                {
                    SetupContextList();
                    lastThreadCount = threadCount;
                }

                // Start of frame:

                // Retrieve immediate context
                var immediateContext = DeviceManager.Direct3DDevice.ImmediateContext;


                // The context at index 0 is always executed first
                var context = contextList[0];

                // Clear depth stencil view
                context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                // Clear render target view
                context.ClearRenderTargetView(RenderTargetView, background);

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix);

                // Extract camera position from view
                var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4;
                cameraPosition  = new Vector3(camPosition.X, camPosition.Y, camPosition.Z);

                // If Keys.CtrlKey is down, auto rotate viewProjection based on time
                var time = clock.ElapsedMilliseconds / 1000.0f;
                if (ctrlKey)
                {
                    viewProjection = Matrix.RotationY(time * 1.8f) * Matrix.RotationX(time * 1f) * Matrix.RotationZ(time * 0.6f) * viewProjection;
                }
                var worldRotation = Matrix.RotationAxis(Vector3.UnitY, time);

                var perFrame             = new ConstantBuffers.PerFrame();
                perFrame.Light.Color     = new Color(0.8f, 0.8f, 0.8f, 1.0f);
                var lightDir             = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix);
                perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);// new Vector3(Vector3.Transform(new Vector3(1f, -1f, 1f), worldMatrix * worldRotation).ToArray().Take(3).ToArray());
                perFrame.CameraPosition  = cameraPosition;
                context.UpdateSubresource(ref perFrame, perFrameBuffer);

                // Render each object

                var perMaterial           = new ConstantBuffers.PerMaterial();
                perMaterial.Ambient       = new Color4(0.2f);
                perMaterial.Diffuse       = Color.White;
                perMaterial.Emissive      = new Color4(0);
                perMaterial.Specular      = Color.White;
                perMaterial.SpecularPower = 20f;
                perMaterial.HasTexture    = 0;
                perMaterial.UVTransform   = Matrix.Identity;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                var perObject = new ConstantBuffers.PerObject();

                // AXIS GRID
                using (var prevPixelShader = context.PixelShader.Get())
                {
                    perMaterial.HasTexture  = 0;
                    perMaterial.UVTransform = Matrix.Identity;
                    context.UpdateSubresource(ref perMaterial, perMaterialBuffer);
                    context.PixelShader.Set(pixelShader);
                    perObject.World = worldMatrix;
                    perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                    perObject.WorldViewProjection   = perObject.World * viewProjection;
                    perObject.Transpose();
                    context.UpdateSubresource(ref perObject, perObjectBuffer);
                    axisGrid.RenderContext = context;
                    axisGrid.Render();
                    context.PixelShader.Set(prevPixelShader);
                }

                Task[] renderTasks     = new Task[contextList.Length];
                CommandList[] commands = new CommandList[contextList.Length];
                for (var i = 0; i < contextList.Length; i++)
                {
                    //
                    var contextIndex = i;
                    renderTasks[i]   = Task.Run(() =>
                    {
                        // Render logic
                        renderMeshGroup(contextIndex);

                        // Create the command list
                        if (contextList[contextIndex].TypeInfo == DeviceContextType.Deferred)
                        {
                            commands[contextIndex] = contextList[contextIndex].FinishCommandList(true);
                        }
                    });
                }
                // Wait for all the tasks to complete
                Task.WaitAll(renderTasks);

                // Replay the command lists on the immediate context
                for (var i = 0; i < contextList.Length; i++)
                {
                    if (contextList[i].TypeInfo == DeviceContextType.Deferred && commands[i] != null)
                    {
                        immediateContext.ExecuteCommandList(commands[i], false);
                        commands[i].Dispose();
                        commands[i] = null;
                    }
                }

                // Render FPS
                fps.Render();

                // Render instructions + position changes
                textRenderer.Render();

                // Present the frame
                Present();
            });
            #endregion
        }
Example #29
0
		void InitD3D()
		{
			var swapDesc = new Dxgi.SwapChainDescription
			{
				BufferCount = 1,
				ModeDescription = new Dxgi.ModeDescription
					{
						Width = Container.ClientSize.Width,
						Height = Container.ClientSize.Height,
						RefreshRate = new Rational(60, 1),
						Format = Dxgi.Format.R8G8B8A8_UNorm
					},
				IsWindowed = true,
				OutputHandle = Container.Handle,
				SampleDescription = new Dxgi.SampleDescription(1, 0),
				SwapEffect = Dxgi.SwapEffect.Discard,
				Usage = Dxgi.Usage.RenderTargetOutput
			};

			Device device;
			Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug | DeviceCreationFlags.BgraSupport,
				swapDesc, out device, out SwapChain);
			Device = device;
			m_context = Device.ImmediateContext;

			Texture2DDescription colordesc = new Texture2DDescription
			{
				BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
				Format = Dxgi.Format.B8G8R8A8_UNorm,
				Width = Width,
				Height = Height,
				MipLevels = 1,
				SampleDescription = new Dxgi.SampleDescription(1, 0),
				Usage = ResourceUsage.Default,
				OptionFlags = ResourceOptionFlags.Shared,
				CpuAccessFlags = CpuAccessFlags.None,
				ArraySize = 1
			};

			Texture2DDescription depthdesc = new Texture2DDescription
			{
				BindFlags = BindFlags.DepthStencil,
				Format = Dxgi.Format.D24_UNorm_S8_UInt,
				Width = Width,
				Height = Height,
				MipLevels = 1,
				SampleDescription = new Dxgi.SampleDescription(1, 0),
				Usage = ResourceUsage.Default,
				OptionFlags = ResourceOptionFlags.None,
				CpuAccessFlags = CpuAccessFlags.None,
				ArraySize = 1
			};

			SharedTexture = new Texture2D(Device, colordesc);
			DepthTexture = new Texture2D(Device, depthdesc);
			RenderView = new RenderTargetView(Device, SharedTexture);
			DepthView = new DepthStencilView(Device, DepthTexture);

			var rastDesc = new RasterizerStateDescription()
			{
				CullMode = CullMode.None,
				FillMode = FillMode.Solid,
			};
			m_context.Rasterizer.State = RasterizerState.FromDescription(Device, rastDesc);

			QuadIndices = RenderSupport.InitQuadIndices(Device);

			m_context.Flush();
		}
        private static void UpdateSceneFrame()
        {
            var desc = new RasterizerStateDescription();

            desc.FillMode = FillMode.Solid;
            desc.CullMode = CullMode.None;
            desc.IsFrontCounterClockwise = true;

            desc.DepthBias            = 25000;
            desc.DepthBiasClamp       = 2;
            desc.SlopeScaledDepthBias = 1;

            MyPipelineStates.Modify(m_shadowRasterizerState, desc);


            MyMeshes.Load();
            QueryTexturesFromEntities();
            MyTextures.Load();
            GatherTextures();
            MyComponents.UpdateCullProxies();
            MyComponents.ProcessEntities();
            MyComponents.SendVisible();

            MyBillboardRenderer.OnFrameStart();

            MyRender11.GetRenderProfiler().StartProfilingBlock("RebuildProxies");
            foreach (var renderable in MyComponentFactory <MyRenderableComponent> .GetAll())
            {
                renderable.RebuildRenderProxies();
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateProxies");
            UpdateActors();
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyBigMeshTable.Table.MoveToGPU();

            MyRender11.GetRenderProfiler().StartProfilingBlock("Update merged groups");
            MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateBeforeDraw");
            foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                r.UpdateBeforeDraw();
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyRender11.GetRenderProfiler().StartProfilingBlock("MoveToGPU");
            foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                foreach (var val in r.m_materialGroups.Values)
                {
                    // optimize: keep list+set for updating
                    val.MoveToGPU();
                }
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyRender11.GetRenderProfiler().StartProfilingBlock("Fill foliage streams");
            MyGpuProfiler.IC_BeginBlock("Fill foliage streams");
            MyGPUFoliageGenerating.GetInstance().PerFrame();
            MyGPUFoliageGenerating.GetInstance().Begin();
            foreach (var foliage in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                if (foliage.m_owner.CalculateCameraDistance() < MyRender11.RenderSettings.FoliageDetails.GrassDrawDistance())
                {
                    foliage.FillStreams();
                }
                else
                {
                    foliage.InvalidateStreams();
                }
            }
            MyGPUFoliageGenerating.GetInstance().End();
            MyGpuProfiler.IC_EndBlock();
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyCommon.MoveToNextFrame();
        }
Example #31
0
        Pipeline BuildPipeline(GraphicsDevice gd, SceneContext sc, SpriteShaderKey key)
        {
            var shaderCache           = Resolve <IShaderCache>();
            var shaderName            = key.UseCylindricalShader ? "CylindricalSprite" : "Sprite";
            var vertexShaderName      = shaderName + "SV.vert";
            var fragmentShaderName    = shaderName + "SF.frag";
            var vertexShaderContent   = shaderCache.GetGlsl(vertexShaderName);
            var fragmentShaderContent = shaderCache.GetGlsl(fragmentShaderName);

            if (key.UseArrayTexture)
            {
                fragmentShaderName   += ".array";
                fragmentShaderContent =
                    @"#define USE_ARRAY_TEXTURE
" + fragmentShaderContent;
            }

            if (key.UsePalette)
            {
                fragmentShaderName   += ".pal";
                fragmentShaderContent =
                    @"#define USE_PALETTE
" + fragmentShaderContent;
            }

            var shaders = shaderCache.GetShaderPair(
                gd.ResourceFactory,
                vertexShaderName, fragmentShaderName,
                vertexShaderContent, fragmentShaderContent);

            _shaders.AddRange(shaders);

            var depthStencilMode =
                key.PerformDepthTest
                ? gd.IsDepthRangeZeroToOne
                    ? DepthStencilStateDescription.DepthOnlyLessEqual
                    : DepthStencilStateDescription.DepthOnlyGreaterEqual
                : DepthStencilStateDescription.Disabled;

            var rasterizerMode = new RasterizerStateDescription(
                FaceCullMode.None,
                PolygonFillMode.Solid,
                FrontFace.Clockwise,
                key.PerformDepthTest, // depth test
                true);                // scissor test

            var pipelineDescription = new GraphicsPipelineDescription(
                BlendStateDescription.SingleAlphaBlend,
                depthStencilMode,
                rasterizerMode,
                PrimitiveTopology.TriangleList,
                new ShaderSetDescription(new[] { VertexLayout, InstanceLayout },
                                         shaders,
                                         ShaderHelper.GetSpecializations(gd)),
                new[] { _perSpriteResourceLayout, sc.CommonResourceLayout },
                gd.SwapchainFramebuffer.OutputDescription);

            var pipeline = gd.ResourceFactory.CreateGraphicsPipeline(ref pipelineDescription);

            pipeline.Name = $"P_Sprite_{key}";
            return(pipeline);
        }
        public bool Initialize(DSystemConfiguration configuration, IntPtr windowHandle)
        {
            try
            {
                #region Environment Configuration
                VerticalSyncEnabled = DSystemConfiguration.VerticalSyncEnabled;
                var factory  = new Factory1();
                var adapter  = factory.GetAdapter1(0);
                var monitor  = adapter.GetOutput(0);
                var modes    = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced);
                var rational = new Rational(0, 1);
                if (VerticalSyncEnabled)
                {
                    foreach (var mode in modes)
                    {
                        if (mode.Width == configuration.Width && mode.Height == configuration.Height)
                        {
                            rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator);
                            break;
                        }
                    }
                }
                var adapterDescription = adapter.Description;
                VideoCardMemory      = adapterDescription.DedicatedVideoMemory >> 10 >> 10;
                VideoCardDescription = string.Format("VideoCard: {0}", adapterDescription.Description.Trim('\0'));
                monitor.Dispose();
                adapter.Dispose();
                factory.Dispose();
                #endregion

                #region Initialize swap chain and d3d device
                var swapChainDesc = new SwapChainDescription()
                {
                    BufferCount     = 1,
                    ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm)
                    {
                        Scaling = DisplayModeScaling.Unspecified, ScanlineOrdering = DisplayModeScanlineOrder.Unspecified
                    },
                    Usage             = Usage.RenderTargetOutput,
                    OutputHandle      = windowHandle,
                    SampleDescription = new SampleDescription(1, 0),
                    IsWindowed        = !DSystemConfiguration.FullScreen,
                    Flags             = SwapChainFlags.None,
                    SwapEffect        = SwapEffect.Discard
                };
                SharpDX.Direct3D11.Device device;
                SwapChain swapChain;
                SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain);
                Device        = device;
                SwapChain     = swapChain;
                DeviceContext = device.ImmediateContext;
                #endregion

                #region Initialize buffers
                var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0);
                RenderTargetView = new RenderTargetView(device, backBuffer);
                backBuffer.Dispose();
                var depthBufferDesc = new Texture2DDescription()
                {
                    Width             = configuration.Width,
                    Height            = configuration.Height,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    Format            = Format.D24_UNorm_S8_UInt,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    BindFlags         = BindFlags.DepthStencil,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    OptionFlags       = ResourceOptionFlags.None
                };
                DepthStencilBuffer = new Texture2D(device, depthBufferDesc);
                #endregion

                #region Initialize Depth Enabled Stencil
                var depthStencilDesc = new DepthStencilStateDescription()
                {
                    IsDepthEnabled   = true,
                    DepthWriteMask   = DepthWriteMask.All,
                    DepthComparison  = Comparison.Less,
                    IsStencilEnabled = true,
                    StencilReadMask  = 0xFF,
                    StencilWriteMask = 0xFF,
                    FrontFace        = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    },
                    BackFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    }
                };
                DepthStencilState = new DepthStencilState(Device, depthStencilDesc);
                #endregion

                #region Initialize Output Merger
                DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1);
                var depthStencilViewDesc = new DepthStencilViewDescription()
                {
                    Format    = Format.D24_UNorm_S8_UInt,
                    Dimension = DepthStencilViewDimension.Texture2D,
                    Texture2D = new DepthStencilViewDescription.Texture2DResource()
                    {
                        MipSlice = 0
                    }
                };
                DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc);
                DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView);
                #endregion

                #region Initialize Raster State
                var rasterDesc = new RasterizerStateDescription()
                {
                    IsAntialiasedLineEnabled = false,
                    CullMode                = CullMode.Back,
                    DepthBias               = 0,
                    DepthBiasClamp          = .0f,
                    IsDepthClipEnabled      = true,
                    FillMode                = FillMode.Solid,
                    IsFrontCounterClockwise = false,
                    IsMultisampleEnabled    = false,
                    IsScissorEnabled        = false,
                    SlopeScaledDepthBias    = .0f
                };
                RasterState = new RasterizerState(Device, rasterDesc);
                #endregion

                #region Initialize Rasterizer
                DeviceContext.Rasterizer.State = RasterState;
                ViewPort = new ViewportF(0.0f, 0.0f, (float)configuration.Width, (float)configuration.Height, 0.0f, 1.0f);
                DeviceContext.Rasterizer.SetViewport(ViewPort);
                #endregion

                #region Initialize matrices
                ProjectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 4), ((float)configuration.Width / (float)configuration.Height), DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth);
                WorldMatrix      = Matrix.Identity;
                OrthoMatrix      = Matrix.OrthoLH(configuration.Width, configuration.Height, DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth);
                #endregion

                #region Initialize Depth Disabled Stencil
                var depthDisabledStencilDesc = new DepthStencilStateDescription()
                {
                    IsDepthEnabled   = false,
                    DepthWriteMask   = DepthWriteMask.All,
                    DepthComparison  = Comparison.Less,
                    IsStencilEnabled = true,
                    StencilReadMask  = 0xFF,
                    StencilWriteMask = 0xFF,
                    FrontFace        = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    },
                    BackFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    }
                };
                DepthDisabledStencilState = new DepthStencilState(Device, depthDisabledStencilDesc);
                #endregion

                #region Initialize Blend States
                var blendStateDesc = new BlendStateDescription();
                blendStateDesc.RenderTarget[0].IsBlendEnabled        = true;
                blendStateDesc.RenderTarget[0].SourceBlend           = BlendOption.SourceAlpha;
                blendStateDesc.RenderTarget[0].DestinationBlend      = BlendOption.InverseSourceAlpha;
                blendStateDesc.RenderTarget[0].BlendOperation        = BlendOperation.Add;
                blendStateDesc.RenderTarget[0].SourceAlphaBlend      = BlendOption.One;
                blendStateDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
                blendStateDesc.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
                blendStateDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
                AlphaEnableBlendingState = new BlendState(device, blendStateDesc);
                blendStateDesc.RenderTarget[0].IsBlendEnabled = false;
                AlphaDisableBlendingState = new BlendState(device, blendStateDesc);
                #endregion

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
Example #33
0
        /// <summary>
        /// Creates a new instance of the SpriteRenderer
        /// </summary>
        /// <param name="device">The device to use</param>
        /// <param name="maxSpriteInstances">The maximum sprite instances that can be cached before a flush happens</param>
        public SpriteRenderer(Device device, int maxSpriteInstances = 10000)
        {
            /* Initialize our arrays to hold our sprite data */
            m_spriteRenderData = new SpriteRenderData[maxSpriteInstances];
            m_spriteDrawData = new SpriteDrawData[maxSpriteInstances];

            /* Initialize all the items in the array */
            for (int i = 0; i < maxSpriteInstances; i++)
            {
                m_spriteRenderData[i] = new SpriteRenderData();
            }

            m_maxSpriteInstances = maxSpriteInstances;
            m_device = device;

            /* Create our default blend states using our helper */
            m_blendStates = SpriteRendererBlendStateHelper.InitializeDefaultBlendStates(m_device);

            /* Create our vertex shader */
            m_vertexShaderInstanced10 = new VertexShader10(device,
                                                           SHADER_RESOURCE_NAME, Assembly.GetExecutingAssembly(),
                                                           "SpriteInstancedVS", 
                                                           ShaderVersion.Vs_4_0);

            /* Create our pixel shader */
            m_pixelShader10 = new PixelShader10(device,
                                                SHADER_RESOURCE_NAME, Assembly.GetExecutingAssembly(),
                                                "SpritePS", 
                                                ShaderVersion.Ps_4_0,ShaderFlags.Debug);
            
            /* Create a new sprite quad that holds our GPU buffers */
            m_spriteQuad = new SpriteQuad(device, maxSpriteInstances);

            m_spriteQuadShaderBinding = new GeometryInputShaderBinding(m_spriteQuad, 
                                                                       m_vertexShaderInstanced10, 
                                                                       m_pixelShader10);

            var rastDesc = new RasterizerStateDescription();
            rastDesc.IsAntialiasedLineEnabled = false;
            rastDesc.CullMode = CullMode.None;
            rastDesc.DepthBias = 0;
            rastDesc.DepthBiasClamp = 1.0f;
            rastDesc.IsDepthClipEnabled = false;
            rastDesc.FillMode = FillMode.Solid;
            rastDesc.IsFrontCounterclockwise = false;
            rastDesc.IsMultisampleEnabled = false;
            rastDesc.IsScissorEnabled = false;
            rastDesc.SlopeScaledDepthBias = 0;
            m_rasterizerState = RasterizerState.FromDescription(m_device, rastDesc);
            
            var dsDesc = new DepthStencilStateDescription();
            dsDesc.IsDepthEnabled = false;
            dsDesc.DepthWriteMask = DepthWriteMask.All;
            dsDesc.DepthComparison = Comparison.Less;
            dsDesc.IsStencilEnabled = false;
            dsDesc.StencilReadMask = 0xff;
            dsDesc.StencilWriteMask = 0xff;
            dsDesc.FrontFace = new DepthStencilOperationDescription{ DepthFailOperation = StencilOperation.Keep, FailOperation = StencilOperation.Replace, Comparison = Comparison.Always };
            dsDesc.BackFace = dsDesc.FrontFace;
            m_dsState = DepthStencilState.FromDescription(m_device, dsDesc);

            var sampDesc = new SamplerDescription();
            sampDesc.AddressU = TextureAddressMode.Wrap;
            sampDesc.AddressV = TextureAddressMode.Wrap;
            sampDesc.AddressW = TextureAddressMode.Wrap;
            sampDesc.BorderColor = new Color4(0, 0, 0, 0).InternalColor4;
            sampDesc.ComparisonFunction = Comparison.Never;
            sampDesc.Filter = Filter.MinMagMipLinear;
            sampDesc.MaximumAnisotropy = 1;
            sampDesc.MaximumLod = float.MaxValue;
            sampDesc.MinimumLod = 0;
            sampDesc.MipLodBias = 0;
            m_linearSamplerState = SamplerState.FromDescription(m_device, sampDesc);

            sampDesc.Filter = Filter.MinMagMipPoint;
            m_pointSamplerState = SamplerState.FromDescription(m_device, sampDesc);
        }
        public override void Run()
        {
            #region Create renderers

            // Note: the renderers take care of creating their own
            // device resources and listen for DeviceManager.OnInitialize

            // Create and initialize the quad renderer
            var quad = ToDispose(new QuadRenderer(Color.LightGray));
            quad.Initialize(this);
            // Scale and translate the quad
            quad.World = Matrix.Scaling(5f);
            quad.World.TranslationVector = new Vector3(0, 0, 0);

            // Create and initialize the mesh renderer
            var loadedMesh = Common.Mesh.LoadFromFile("Male_base_mesh.cmo");
            var mesh       = ToDispose(new MeshRenderer(loadedMesh.First()));
            mesh.Initialize(this);
            mesh.World = Matrix.Identity;

            // Create and initialize a Direct2D FPS text renderer
            var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16));
            fps.Initialize(this);

            // Create and initialize a general purpose Direct2D text renderer
            // This will display some instructions and the current view and rotation offsets
            var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12));
            textRenderer.Initialize(this);

            #endregion

            // Initialize the world matrix
            var worldMatrix = Matrix.Identity;

            // Set the camera position slightly to the right (x), above (y) and in front (+z)
            var cameraPosition = new Vector3(1, 1, 3);
            var cameraTarget   = Vector3.Zero;  // Looking at the origin 0,0,0
            var cameraUp       = Vector3.UnitY; // Y+ is Up

            // RIGHT-HANDED COORDINATE SYSTEM
            // Prepare matrices
            // Create the view matrix from our camera position, look target and up direction
            var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp);

            // Create the projection matrix
            /* FoV 60degrees = Pi/3 radians */
            // Aspect ratio (based on window size), Near clip, Far clip
            var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f);

            // Maintain the correct aspect ratio on resize
            Window.Resize += (s, e) =>
            {
                projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.5f, 100f);
            };

            #region Rotation and window event handlers

            // Create a rotation vector to keep track of the rotation
            // around each of the axes
            var rotation = new Vector3(0.0f, 0.0f, 0.0f);

            // We will call this action to update text
            // for the text renderer
            Action updateText = () =>
            {
                textRenderer.Text =
                    String.Format("Rotation ({0}) (Up/Down Left/Right Wheel+-)\nView ({1}) (A/D, W/S, Shift+Wheel+-)"
                                  + "\nPress X to reinitialize the device and resources (device ptr: {2})"
                                  + "\nPress Z to show/hide depth buffer - Press F to toggle wireframe"
                                  + "\nPress 1,2,3,4 to switch shaders",
                                  rotation,
                                  viewMatrix.TranslationVector,
                                  DeviceManager.Direct3DDevice.NativePointer);
            };

            Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>();
            keyToggles[Keys.Z] = false;
            keyToggles[Keys.F] = false;

            // Support keyboard/mouse input to rotate or move camera view
            var moveFactor = 0.02f; // how much to change on each keypress
            var shiftKey   = false;
            var ctrlKey    = false;
            Window.KeyDown += (s, e) =>
            {
                var context = DeviceManager.Direct3DContext;

                shiftKey = e.Shift;
                ctrlKey  = e.Control;

                switch (e.KeyCode)
                {
                // WASD -> pans view
                case Keys.A:
                    viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.D:
                    viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.S:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                case Keys.W:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                // Up/Down and Left/Right - rotates around X / Y respectively
                // (Mouse wheel rotates around Z)
                case Keys.Down:
                    worldMatrix *= Matrix.RotationX(moveFactor);
                    rotation    += new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Up:
                    worldMatrix *= Matrix.RotationX(-moveFactor);
                    rotation    -= new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Left:
                    worldMatrix *= Matrix.RotationY(moveFactor);
                    rotation    += new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.Right:
                    worldMatrix *= Matrix.RotationY(-moveFactor);
                    rotation    -= new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.T:
                    fps.Show          = !fps.Show;
                    textRenderer.Show = !textRenderer.Show;
                    break;

                case Keys.X:
                    // To test for correct resource recreation
                    // Simulate device reset or lost.
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    DeviceManager.Initialize(DeviceManager.Dpi);
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    break;

                case Keys.Z:
                    keyToggles[Keys.Z] = !keyToggles[Keys.Z];
                    if (keyToggles[Keys.Z])
                    {
                        context.PixelShader.Set(depthPixelShader);
                    }
                    else
                    {
                        context.PixelShader.Set(pixelShader);
                    }
                    break;

                case Keys.F:
                    keyToggles[Keys.F] = !keyToggles[Keys.F];
                    RasterizerStateDescription rasterDesc;
                    if (context.Rasterizer.State != null)
                    {
                        rasterDesc = context.Rasterizer.State.Description;
                    }
                    else
                    {
                        rasterDesc = new RasterizerStateDescription()
                        {
                            CullMode = CullMode.Back,
                            FillMode = FillMode.Solid
                        }
                    };
                    if (keyToggles[Keys.F])
                    {
                        rasterDesc.FillMode      = FillMode.Wireframe;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    else
                    {
                        rasterDesc.FillMode      = FillMode.Solid;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    break;

                case Keys.D1:
                    context.PixelShader.Set(pixelShader);
                    break;

                case Keys.D2:
                    context.PixelShader.Set(lambertShader);
                    break;

                case Keys.D3:
                    context.PixelShader.Set(phongShader);
                    break;

                case Keys.D4:
                    context.PixelShader.Set(blinnPhongShader);
                    break;
                }

                updateText();
            };
            Window.KeyUp += (s, e) =>
            {
                // Clear the shift/ctrl keys so they aren't sticky
                if (e.KeyCode == Keys.ShiftKey)
                {
                    shiftKey = false;
                }
                if (e.KeyCode == Keys.ControlKey)
                {
                    ctrlKey = false;
                }
            };
            Window.MouseWheel += (s, e) =>
            {
                if (shiftKey)
                {
                    // Zoom in/out
                    viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2);
                }
                else
                {
                    // rotate around Z-axis
                    viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor);
                    rotation   += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor);
                }
                updateText();
            };

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    // Mouse move changes
                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
            };

            // Display instructions with initial values
            updateText();

            #endregion

            var clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            #region Render loop

            // Create and run the render loop
            RenderLoop.Run(Window, () =>
            {
                // Start of frame:

                // Retrieve immediate context
                var context = DeviceManager.Direct3DContext;

                // Clear depth stencil view
                context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                // Clear render target view
                context.ClearRenderTargetView(RenderTargetView, new Color(30, 30, 34));

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix);

                // Extract camera position from view
                var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4;
                cameraPosition  = new Vector3(camPosition.X, camPosition.Y, camPosition.Z);

                // If Keys.CtrlKey is down, auto rotate viewProjection based on time
                var time = clock.ElapsedMilliseconds / 1000.0f;
                if (ctrlKey)
                {
                    viewProjection = Matrix.RotationY(time * 1.8f) * Matrix.RotationX(time * 1f) * Matrix.RotationZ(time * 0.6f) * viewProjection;
                }
                var worldRotation = Matrix.RotationAxis(Vector3.UnitY, time);

                var perFrame             = new ConstantBuffers.PerFrame();
                perFrame.Light.Color     = Color.White;
                var lightDir             = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix);
                perFrame.Light.Direction = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);
                perFrame.CameraPosition  = cameraPosition;
                context.UpdateSubresource(ref perFrame, perFrameBuffer);

                // Render each object

                var perMaterial           = new ConstantBuffers.PerMaterial();
                perMaterial.Ambient       = new Color4(0.2f);
                perMaterial.Diffuse       = Color.White;
                perMaterial.Emissive      = new Color4(0);
                perMaterial.Specular      = Color.White;
                perMaterial.SpecularPower = 20f;
                perMaterial.HasTexture    = 0;
                perMaterial.UVTransform   = Matrix.Identity;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                var perObject = new ConstantBuffers.PerObject();

                // QUAD
                perObject.World = quad.World * worldMatrix;
                perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                perObject.WorldViewProjection   = perObject.World * viewProjection;
                perObject.Transpose();
                context.UpdateSubresource(ref perObject, perObjectBuffer);
                quad.Render();

                // MESH
                perObject.World = mesh.World * worldMatrix;
                perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                perObject.WorldViewProjection   = perObject.World * viewProjection;
                perObject.Transpose();
                context.UpdateSubresource(ref perObject, perObjectBuffer);
                // Provide the material constant buffer to the mesh renderer
                mesh.PerMaterialBuffer = perMaterialBuffer;
                mesh.Render();

                // Render FPS
                fps.Render();

                // Render instructions + position changes
                textRenderer.Render();

                // Present the frame
                Present();
            });
            #endregion
        }
Example #35
0
        public static void InitAll(Device device) {
            Debug.Assert(device != null);
            
            var wfDesc = new RasterizerStateDescription {
                FillMode = FillMode.Wireframe,
                CullMode = CullMode.Back,
                IsFrontCounterclockwise = false,
                IsDepthClipEnabled = true
            };
            WireframeRS = RasterizerState.FromDescription(device, wfDesc);

            var noCullDesc = new RasterizerStateDescription {
                FillMode = FillMode.Solid,
                CullMode = CullMode.None,
                IsFrontCounterclockwise = false,
                IsDepthClipEnabled = true
            };
            NoCullRS = RasterizerState.FromDescription(device, noCullDesc);

            var cullClockwiseDesc = new RasterizerStateDescription {
                FillMode = FillMode.Solid,
                CullMode = CullMode.Back,
                IsFrontCounterclockwise = true,
                IsDepthClipEnabled = true
            };
            CullClockwiseRS = RasterizerState.FromDescription(device, cullClockwiseDesc);

            var atcDesc = new BlendStateDescription {
                AlphaToCoverageEnable = true,
                IndependentBlendEnable = false,
            };
            atcDesc.RenderTargets[0].BlendEnable = false;
            atcDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            AlphaToCoverageBS = BlendState.FromDescription(device, atcDesc);

            var transDesc = new BlendStateDescription {
                AlphaToCoverageEnable = false,
                IndependentBlendEnable = false
            };
            transDesc.RenderTargets[0].BlendEnable = true;
            transDesc.RenderTargets[0].SourceBlend = BlendOption.SourceAlpha;
            transDesc.RenderTargets[0].DestinationBlend = BlendOption.InverseSourceAlpha;
            transDesc.RenderTargets[0].BlendOperation = BlendOperation.Add;
            transDesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One;
            transDesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero;
            transDesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add;
            transDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

            TransparentBS = BlendState.FromDescription(device, transDesc);

            var noRenderTargetWritesDesc = new BlendStateDescription {
                AlphaToCoverageEnable = false,
                IndependentBlendEnable = false
            };
            noRenderTargetWritesDesc.RenderTargets[0].BlendEnable = false;
            noRenderTargetWritesDesc.RenderTargets[0].SourceBlend = BlendOption.One;
            noRenderTargetWritesDesc.RenderTargets[0].DestinationBlend = BlendOption.Zero;
            noRenderTargetWritesDesc.RenderTargets[0].BlendOperation = BlendOperation.Add;
            noRenderTargetWritesDesc.RenderTargets[0].SourceBlendAlpha = BlendOption.One;
            noRenderTargetWritesDesc.RenderTargets[0].DestinationBlendAlpha = BlendOption.Zero;
            noRenderTargetWritesDesc.RenderTargets[0].BlendOperationAlpha = BlendOperation.Add;
            noRenderTargetWritesDesc.RenderTargets[0].RenderTargetWriteMask = ColorWriteMaskFlags.None;

            NoRenderTargetWritesBS = BlendState.FromDescription(device, noRenderTargetWritesDesc);

            var mirrorDesc = new DepthStencilStateDescription {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.Zero,
                DepthComparison = Comparison.Less,
                IsStencilEnabled = true,
                StencilReadMask = 0xff,
                StencilWriteMask = 0xff, 
                FrontFace = new DepthStencilOperationDescription {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Keep,
                    PassOperation = StencilOperation.Replace,
                    Comparison = Comparison.Always
                },
                BackFace = new DepthStencilOperationDescription {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Keep,
                    PassOperation = StencilOperation.Replace,
                    Comparison = Comparison.Always
                }
            };

            MarkMirrorDSS = DepthStencilState.FromDescription(device, mirrorDesc);

            var drawReflectionDesc = new DepthStencilStateDescription {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                DepthComparison = Comparison.Less,
                IsStencilEnabled = true,
                StencilReadMask = 0xff,
                StencilWriteMask = 0xff,
                FrontFace = new DepthStencilOperationDescription {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Keep,
                    PassOperation = StencilOperation.Keep,
                    Comparison = Comparison.Equal
                },
                BackFace = new DepthStencilOperationDescription {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Keep,
                    PassOperation = StencilOperation.Keep,
                    Comparison = Comparison.Equal
                }
            };
            DrawReflectionDSS = DepthStencilState.FromDescription(device, drawReflectionDesc);

            var noDoubleBlendDesc = new DepthStencilStateDescription {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                DepthComparison = Comparison.Less,
                IsStencilEnabled = true,
                StencilReadMask = 0xff,
                StencilWriteMask = 0xff,
                FrontFace = new DepthStencilOperationDescription {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Keep,
                    PassOperation = StencilOperation.Increment,
                    Comparison = Comparison.Equal
                },
                BackFace = new DepthStencilOperationDescription {
                    FailOperation = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Keep,
                    PassOperation = StencilOperation.Increment,
                    Comparison = Comparison.Equal
                }
            };
            NoDoubleBlendDSS = DepthStencilState.FromDescription(device, noDoubleBlendDesc);

            var lessEqualDesc = new DepthStencilStateDescription {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                DepthComparison = Comparison.LessEqual,
                IsStencilEnabled = false
            };
            LessEqualDSS = DepthStencilState.FromDescription(device, lessEqualDesc);

            var equalsDesc = new DepthStencilStateDescription() {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.Zero,
                DepthComparison = Comparison.LessEqual,
                
            };
            EqualsDSS = DepthStencilState.FromDescription(device, equalsDesc);

            var noDepthDesc = new DepthStencilStateDescription() {
                IsDepthEnabled = false,
                DepthComparison = Comparison.Always,
                DepthWriteMask = DepthWriteMask.Zero
            };
            NoDepthDSS = DepthStencilState.FromDescription(device, noDepthDesc);
        }
        public override void Initialize()
        {
            Form.SizeChanged += (o, args) =>
            {
                if (_swapChain == null)
                {
                    return;
                }

                renderView.Dispose();
                depthView.Dispose();
                DisposeBuffers();

                if (Form.WindowState == FormWindowState.Minimized)
                {
                    return;
                }

                _width  = Form.ClientSize.Width;
                _height = Form.ClientSize.Height;
                _swapChain.ResizeBuffers(_swapChain.Description.BufferCount, 0, 0, Format.Unknown, 0);

                CreateBuffers();
                SetSceneConstants();
            };

            _width     = 1024;
            _height    = 768;
            _nearPlane = 1.0f;

            ambient = new Color4(Color.Gray.ToArgb());

            try
            {
                OnInitializeDevice();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString(), "Could not create DirectX 10 device.");
                return;
            }


            // shader.fx

            const ShaderFlags shaderFlags = ShaderFlags.None;
            //const ShaderFlags shaderFlags = ShaderFlags.Debug | ShaderFlags.SkipOptimization;
            ShaderBytecode shaderByteCode = LoadShader("shader.fx", shaderFlags);

            effect = new Effect(_device, shaderByteCode);
            EffectTechnique technique = effect.GetTechniqueByIndex(0);

            shadowGenPass  = technique.GetPassByIndex(0);
            gBufferGenPass = technique.GetPassByIndex(1);
            debugDrawPass  = technique.GetPassByName("debug");

            BufferDescription sceneConstantsDesc = new BufferDescription()
            {
                SizeInBytes    = Marshal.SizeOf(typeof(ShaderSceneConstants)),
                Usage          = ResourceUsage.Dynamic,
                BindFlags      = BindFlags.ConstantBuffer,
                CpuAccessFlags = CpuAccessFlags.Write,
                OptionFlags    = ResourceOptionFlags.None
            };

            sceneConstantsBuffer = new Buffer(_device, sceneConstantsDesc);
            EffectConstantBuffer effectConstantBuffer = effect.GetConstantBufferByName("scene");

            effectConstantBuffer.SetConstantBuffer(sceneConstantsBuffer);

            RasterizerStateDescription desc = new RasterizerStateDescription()
            {
                CullMode = CullMode.None,
                FillMode = FillMode.Solid,
                IsFrontCounterClockwise = true,
                DepthBias            = 0,
                DepthBiasClamp       = 0,
                SlopeScaledDepthBias = 0,
                IsDepthClipEnabled   = true,
            };

            _device.Rasterizer.State = new RasterizerState(_device, desc);

            DepthStencilStateDescription depthDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled   = true,
                IsStencilEnabled = false,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less
            };

            depthStencilState = new DepthStencilState(_device, depthDesc);

            DepthStencilStateDescription lightDepthStateDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled   = true,
                IsStencilEnabled = false,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less
            };

            lightDepthStencilState = new DepthStencilState(_device, lightDepthStateDesc);


            // grender.fx

            shaderByteCode = LoadShader("grender.fx", shaderFlags);

            effect2            = new Effect(_device, shaderByteCode);
            technique          = effect2.GetTechniqueByIndex(0);
            gBufferRenderPass  = technique.GetPassByIndex(0);
            gBufferOverlayPass = technique.GetPassByIndex(1);

            info         = new InfoText(_device);
            _meshFactory = new MeshFactory(this);
            MeshFactory  = _meshFactory;

            CreateBuffers();
            LibraryManager.LibraryStarted();
        }
Example #37
0
 /// <summary>
 /// Registers the specified desc.
 /// </summary>
 /// <param name="desc">The desc.</param>
 /// <returns></returns>
 public RasterizerStateProxy Register(RasterizerStateDescription desc)
 {
     return(RasterStatePool.Register(desc) as RasterizerStateProxy);
 }
Example #38
0
        public bool Init(IntPtr WindowHandle)
        {
            var factory  = new Factory1();
            var adapter  = factory.GetAdapter1(0);
            var monitor  = adapter.GetOutput(0);
            var modes    = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced);
            var rational = new Rational(0, 1);

            if (ToolkitSettings.VSync)
            {
                foreach (var mode in modes)
                {
                    if (mode.Width == ToolkitSettings.Width && mode.Height == ToolkitSettings.Height)
                    {
                        rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator);
                        break;
                    }
                }
            }

            var adapterDescription = adapter.Description;

            VideoCardMemory      = adapterDescription.DedicatedVideoMemory >> 10 >> 10;
            VideoCardDescription = adapterDescription.Description.Trim('\0');
            monitor.Dispose();
            adapter.Dispose();
            factory.Dispose();

            var swapChainDesc = new SwapChainDescription()
            {
                BufferCount       = 2,
                ModeDescription   = new ModeDescription(ToolkitSettings.Width, ToolkitSettings.Height, rational, Format.R8G8B8A8_UNorm),
                Usage             = Usage.RenderTargetOutput,
                OutputHandle      = WindowHandle,
                SampleDescription = new SampleDescription(1, 0),
                IsWindowed        = true,
                Flags             = SwapChainFlags.None,
                SwapEffect        = SwapEffect.Discard
            };

            SharpDX.Direct3D11.Device device;
            SwapChain swapChain;

            SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain);
            Device        = device;
            SwapChain     = swapChain;
            DeviceContext = device.ImmediateContext;
            var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0);

            m_RenderTargetView = new RenderTargetView(device, backBuffer);
            backBuffer.Dispose();

            var depthBufferDesc = new Texture2DDescription()
            {
                Width             = ToolkitSettings.Width,
                Height            = ToolkitSettings.Height,
                MipLevels         = 0,
                ArraySize         = 1,
                Format            = Format.D24_UNorm_S8_UInt,
                SampleDescription = new SampleDescription(1, 0),
                Usage             = ResourceUsage.Default,
                BindFlags         = BindFlags.DepthStencil,
                CpuAccessFlags    = CpuAccessFlags.None,
                OptionFlags       = ResourceOptionFlags.None
            };

            m_depthStencilBuffer = new Texture2D(device, depthBufferDesc);

            var depthStencilDecs = new DepthStencilStateDescription()
            {
                IsDepthEnabled   = true,
                DepthWriteMask   = DepthWriteMask.All,
                DepthComparison  = Comparison.Less,
                IsStencilEnabled = true,
                StencilReadMask  = 0xFF,
                StencilWriteMask = 0xFF,
                FrontFace        = new DepthStencilOperationDescription()
                {
                    FailOperation      = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Increment,
                    PassOperation      = StencilOperation.Keep,
                    Comparison         = Comparison.Always,
                },
                BackFace = new DepthStencilOperationDescription()
                {
                    FailOperation      = StencilOperation.Keep,
                    DepthFailOperation = StencilOperation.Decrement,
                    PassOperation      = StencilOperation.Keep,
                    Comparison         = Comparison.Always
                }
            };

            DepthStencilState = new DepthStencilState(Device, depthStencilDecs);
            DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1);

            var depthStencilViewDesc = new DepthStencilViewDescription()
            {
                Format    = Format.D24_UNorm_S8_UInt,
                Dimension = DepthStencilViewDimension.Texture2D,
                Texture2D = new DepthStencilViewDescription.Texture2DResource()
                {
                    MipSlice = 0
                }
            };

            BlendStateDescription bsd = new BlendStateDescription()
            {
                AlphaToCoverageEnable  = false,//true,
                IndependentBlendEnable = false,
            };

            bsd.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
            bsd.RenderTarget[0].BlendOperation        = BlendOperation.Add;
            bsd.RenderTarget[0].DestinationAlphaBlend = BlendOption.One;
            bsd.RenderTarget[0].DestinationBlend      = BlendOption.InverseSourceAlpha;
            bsd.RenderTarget[0].IsBlendEnabled        = true;
            bsd.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            bsd.RenderTarget[0].SourceAlphaBlend      = BlendOption.Zero;
            bsd.RenderTarget[0].SourceBlend           = BlendOption.SourceAlpha;
            //bsDefault = new BlendState(device, bsd);

            bsd.AlphaToCoverageEnable = true;
            BlendState bsAlpha = new BlendState(device, bsd);

            DeviceContext.OutputMerger.BlendState = bsAlpha;

            m_DepthStencilView = new DepthStencilView(Device, m_depthStencilBuffer, depthStencilViewDesc);
            DeviceContext.OutputMerger.SetTargets(m_DepthStencilView, m_RenderTargetView);

            m_RSDesc = new RasterizerStateDescription()
            {
                IsAntialiasedLineEnabled = true,
                CullMode                = CullMode.Back,
                DepthBias               = 10,
                DepthBiasClamp          = .0f,
                IsDepthClipEnabled      = false,
                FillMode                = FillMode.Solid,
                IsFrontCounterClockwise = true,
                IsMultisampleEnabled    = false,
                IsScissorEnabled        = false,
                SlopeScaledDepthBias    = .0f
            };


            m_RSCullSolid     = new RasterizerState(Device, m_RSDesc);
            m_RSDesc.CullMode = CullMode.None;
            m_RSSolid         = new RasterizerState(Device, m_RSDesc);
            m_RSDesc.FillMode = FillMode.Wireframe;
            m_RSWireFrame     = new RasterizerState(Device, m_RSDesc);
            m_RSDesc.CullMode = CullMode.Back;
            m_RSCullWireFrame = new RasterizerState(Device, m_RSDesc);

            UpdateRasterizer();
            return(true);
        }
Example #39
0
        protected override void CreateDeviceDependentResources()
        {
            RemoveAndDispose(ref vertexShader);
            RemoveAndDispose(ref lightBuffer);
            RemoveAndDispose(ref RTV);
            RemoveAndDispose(ref SRV);
            RemoveAndDispose(ref rsCullBack);
            RemoveAndDispose(ref rsCullFront);
            RemoveAndDispose(ref rsWireframe);
            RemoveAndDispose(ref blendStateAdd);
            RemoveAndDispose(ref depthLessThan);
            RemoveAndDispose(ref depthGreaterThan);
            RemoveAndDispose(ref depthDisabled);
            RemoveAndDispose(ref perLightBuffer);

            RemoveAndDispose(ref psAmbientLight);
            RemoveAndDispose(ref psDirectionalLight);
            RemoveAndDispose(ref psPointLight);
            RemoveAndDispose(ref psSpotLight);
            RemoveAndDispose(ref psDebugLight);
            RemoveAndDispose(ref perLightBuffer);

            // Retrieve our SharpDX.Direct3D11.Device1 instance
            var device = this.DeviceManager.Direct3DDevice;

            int width, height;
            SampleDescription sampleDesc;

            // Retrieve DSV from GBuffer and extract width/height
            // then create a new read-only DSV
            using (var depthTexture = gbuffer.DSV.ResourceAs <Texture2D>())
            {
                width      = depthTexture.Description.Width;
                height     = depthTexture.Description.Height;
                sampleDesc = depthTexture.Description.SampleDescription;

                // Initialize read-only DSV
                var dsvDesc = gbuffer.DSV.Description;
                dsvDesc.Flags = DepthStencilViewFlags.ReadOnlyDepth | DepthStencilViewFlags.ReadOnlyStencil;
                DSVReadonly   = ToDispose(new DepthStencilView(device, depthTexture, dsvDesc));
            }
            // Check if GBuffer is multi-sampled
            bool isMSAA = sampleDesc.Count > 1;

            // Initialize the light render target
            var texDesc = new Texture2DDescription();

            texDesc.BindFlags         = BindFlags.ShaderResource | BindFlags.RenderTarget;
            texDesc.ArraySize         = 1;
            texDesc.CpuAccessFlags    = CpuAccessFlags.None;
            texDesc.Usage             = ResourceUsage.Default;
            texDesc.Width             = width;
            texDesc.Height            = height;
            texDesc.MipLevels         = 1; // No mip levels
            texDesc.SampleDescription = sampleDesc;
            texDesc.Format            = Format.R8G8B8A8_UNorm;

            lightBuffer = ToDispose(new Texture2D(device, texDesc));

            // Render Target View description
            var rtvDesc = new RenderTargetViewDescription();

            rtvDesc.Format             = Format.R8G8B8A8_UNorm;
            rtvDesc.Dimension          = isMSAA ? RenderTargetViewDimension.Texture2DMultisampled : RenderTargetViewDimension.Texture2D;
            rtvDesc.Texture2D.MipSlice = 0;
            RTV = ToDispose(new RenderTargetView(device, lightBuffer, rtvDesc));

            // SRV description for render targets
            var srvDesc = new ShaderResourceViewDescription();

            srvDesc.Format                    = Format.R8G8B8A8_UNorm;
            srvDesc.Dimension                 = isMSAA ? SharpDX.Direct3D.ShaderResourceViewDimension.Texture2DMultisampled : SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D;
            srvDesc.Texture2D.MipLevels       = -1;
            srvDesc.Texture2D.MostDetailedMip = 0;
            SRV = ToDispose(new ShaderResourceView(device, lightBuffer, srvDesc));

            // Initialize additive blend state (assuming single render target)
            BlendStateDescription bsDesc = new BlendStateDescription();

            bsDesc.RenderTarget[0].IsBlendEnabled        = true;
            bsDesc.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
            bsDesc.RenderTarget[0].SourceAlphaBlend      = BlendOption.One;
            bsDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.One;
            bsDesc.RenderTarget[0].BlendOperation        = BlendOperation.Add;
            bsDesc.RenderTarget[0].SourceBlend           = BlendOption.One;
            bsDesc.RenderTarget[0].DestinationBlend      = BlendOption.One;
            bsDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;
            blendStateAdd = ToDispose(new BlendState(device, bsDesc));

            // Initialize rasterizer states
            RasterizerStateDescription rsDesc = new RasterizerStateDescription();

            rsDesc.FillMode = FillMode.Solid;
            rsDesc.CullMode = CullMode.Back;
            rsCullBack      = ToDispose(new RasterizerState(device, rsDesc));
            rsDesc.CullMode = CullMode.Front;
            rsCullFront     = ToDispose(new RasterizerState(device, rsDesc));
            rsDesc.CullMode = CullMode.Front;
            rsDesc.FillMode = FillMode.Wireframe;
            rsWireframe     = ToDispose(new RasterizerState(device, rsDesc));

            // Initialize depth state
            var dsDesc = new DepthStencilStateDescription();

            dsDesc.IsStencilEnabled = false;
            dsDesc.IsDepthEnabled   = true;

            // Less-than depth comparison
            dsDesc.DepthComparison = Comparison.Less;
            depthLessThan          = ToDispose(new DepthStencilState(device, dsDesc));
            // Greater-than depth comparison
            dsDesc.DepthComparison = Comparison.Greater;
            depthGreaterThan       = ToDispose(new DepthStencilState(device, dsDesc));
            // Depth/stencil testing disabled
            dsDesc.IsDepthEnabled = false;
            depthDisabled         = ToDispose(new DepthStencilState(device, dsDesc));

            // Buffer to light parameters
            perLightBuffer = ToDispose(new Buffer(device, Utilities.SizeOf <PerLight>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            if (isMSAA)
            {
                // Compile and create the vertex shader
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "VSLight", "vs_5_0"))
                    vertexShader = ToDispose(new VertexShader(device, bytecode));
                // Compile pixel shaders
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSAmbientLight", "ps_5_0"))
                    psAmbientLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSDirectionalLight", "ps_5_0"))
                    psDirectionalLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSPointLight", "ps_5_0"))
                    psPointLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSSpotLight", "ps_5_0"))
                    psSpotLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\LightsMS.hlsl", "PSDebugLight", "ps_5_0"))
                    psDebugLight = ToDispose(new PixelShader(device, bytecode));
            }
            else
            {
                // Compile and create the vertex shader
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "VSLight", "vs_5_0"))
                    vertexShader = ToDispose(new VertexShader(device, bytecode));
                // Compile pixel shaders
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSAmbientLight", "ps_5_0"))
                    psAmbientLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSDirectionalLight", "ps_5_0"))
                    psDirectionalLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSPointLight", "ps_5_0"))
                    psPointLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSSpotLight", "ps_5_0"))
                    psSpotLight = ToDispose(new PixelShader(device, bytecode));
                using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\Lights.hlsl", "PSDebugLight", "ps_5_0"))
                    psDebugLight = ToDispose(new PixelShader(device, bytecode));
            }
        }
        public override void Run()
        {
            #region Create renderers

            // Note: the renderers take care of creating their own
            // device resources and listen for DeviceManager.OnInitialize

            // Create a axis-grid renderer
            var axisGrid = ToDispose(new AxisGridRenderer());
            axisGrid.Initialize(this);

            // Create and initialize the mesh renderer
            var loadedMesh = Common.Mesh.LoadFromFile("Tree.cmo");
            loadedMesh.AddRange(Common.Mesh.LoadFromFile("Plane.cmo"));
            loadedMesh.AddRange(Common.Mesh.LoadFromFile("Cube.cmo"));

            List <DisplacedMeshRenderer> meshes = new List <DisplacedMeshRenderer>();
            meshes.AddRange((from mesh in loadedMesh
                             select ToDispose(new DisplacedMeshRenderer(mesh))));
            foreach (var m in meshes)
            {
                m.Initialize(this);
                m.World = Matrix.Identity;
            }

            // Set the first animation as the current animation and start clock
            foreach (var m in meshes)
            {
                if (m.Mesh.Animations != null && m.Mesh.Animations.Any())
                {
                    m.CurrentAnimation = m.Mesh.Animations.First().Value;
                }
                m.Clock.Start();
            }

            var triangle = new TriangleRenderer();
            triangle.Initialize(this);

            // Create and initialize a Direct2D FPS text renderer
            var fps = ToDispose(new Common.FpsRenderer("Calibri", Color.CornflowerBlue, new Point(8, 8), 16));
            fps.Initialize(this);

            // Create and initialize a general purpose Direct2D text renderer
            // This will display some instructions and the current view and rotation offsets
            var textRenderer = ToDispose(new Common.TextRenderer("Calibri", Color.CornflowerBlue, new Point(8, 40), 12));
            textRenderer.Initialize(this);

            #endregion

            // Initialize the world matrix
            var worldMatrix = Matrix.Identity;

            // Set the camera position
            var cameraPosition = new Vector3(0, 0, 2);
            var cameraTarget   = Vector3.Zero;  // Looking at the origin 0,0,0
            var cameraUp       = Vector3.UnitY; // Y+ is Up

            // Prepare matrices
            // Create the view matrix from our camera position, look target and up direction
            var viewMatrix = Matrix.LookAtRH(cameraPosition, cameraTarget, cameraUp);
            viewMatrix.TranslationVector += new Vector3(0, -0.98f, 0);

            // Create the projection matrix
            /* FoV 60degrees = Pi/3 radians */
            // Aspect ratio (based on window size), Near clip, Far clip
            var projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);

            // Maintain the correct aspect ratio on resize
            Window.Resize += (s, e) =>
            {
                projectionMatrix = Matrix.PerspectiveFovRH((float)Math.PI / 3f, Width / (float)Height, 0.1f, 100f);
            };

            #region Rotation and window event handlers

            // Create a rotation vector to keep track of the rotation
            // around each of the axes
            var rotation              = new Vector3(0.0f, 0.0f, 0.0f);
            var tessellationFactor    = 2f; // default to 5
            var tessellationPartition = "Integer";
            var tessellationMethod    = "Phong";
            var displacementScale     = 0.02f;
            // We will call this action to update text
            // for the text renderer
            Action updateText = () =>
            {
                textRenderer.Text =
                    String.Format("Tessellation Factor: {0:#0.0} (+/- to change)"
                                  + "\nPartitioning: {1} (F1,F2,F3,F4 to change)"
                                  + "\nTessellation: {2} (F5,F6,F7)"
                                  + "\nDisplacement: {3:#0.000} (Shift +/- to change)"
                                  + "\nPress F to toggle wireframe | Shift+N toggle Normal Map | N show normals"
                                  + "\nPress 1-4 to switch pixel shaders | Backspace to cycle meshes",
                                  tessellationFactor,
                                  tessellationPartition,
                                  tessellationMethod,
                                  displacementScale,
                                  DeviceManager.Direct3DDevice.NativePointer);
            };

            Dictionary <Keys, bool> keyToggles = new Dictionary <Keys, bool>();
            keyToggles[Keys.Z] = false;
            keyToggles[Keys.F] = false;

            // Support keyboard/mouse input to rotate or move camera view
            var moveFactor             = 0.02f; // how much to change on each keypress
            var shiftKey               = false;
            var ctrlKey                = false;
            var background             = Color.White;
            var activeTriTessellator   = tessellateTriIntegerShader;
            var activePnTriTessellator = pnTriIntegerShader;
            var usePhongTessellation   = true;
            var usePNTessellation      = false;
            var showNormals            = false;
            var enableNormalMap        = true;
            var meshIndex              = 0;
            Window.KeyDown += (s, e) =>
            {
                var context = DeviceManager.Direct3DContext;

                shiftKey = e.Shift;
                ctrlKey  = e.Control;

                switch (e.KeyCode)
                {
                // WASD -> pans view
                case Keys.A:
                    viewMatrix.TranslationVector += new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.D:
                    viewMatrix.TranslationVector -= new Vector3(moveFactor * 2, 0f, 0f);
                    break;

                case Keys.S:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                case Keys.W:
                    if (shiftKey)
                    {
                        viewMatrix.TranslationVector -= new Vector3(0f, moveFactor * 2, 0f);
                    }
                    else
                    {
                        viewMatrix.TranslationVector += new Vector3(0f, 0f, 1) * moveFactor * 2;
                    }
                    break;

                // Up/Down and Left/Right - rotates around X / Y respectively
                // (Mouse wheel rotates around Z)
                case Keys.Down:
                    worldMatrix *= Matrix.RotationX(moveFactor);
                    rotation    += new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Up:
                    worldMatrix *= Matrix.RotationX(-moveFactor);
                    rotation    -= new Vector3(moveFactor, 0f, 0f);
                    break;

                case Keys.Left:
                    worldMatrix *= Matrix.RotationY(moveFactor);
                    rotation    += new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.Right:
                    worldMatrix *= Matrix.RotationY(-moveFactor);
                    rotation    -= new Vector3(0f, moveFactor, 0f);
                    break;

                case Keys.T:
                    fps.Show          = !fps.Show;
                    textRenderer.Show = !textRenderer.Show;
                    break;

                case Keys.B:
                    if (background == Color.White)
                    {
                        background = new Color(30, 30, 34);
                    }
                    else
                    {
                        background = Color.White;
                    }
                    break;

                case Keys.G:
                    axisGrid.Show = !axisGrid.Show;
                    break;

                case Keys.P:
                    // Pause or resume mesh animation
                    meshes.ForEach(m => {
                        if (m.Clock.IsRunning)
                        {
                            m.Clock.Stop();
                        }
                        else
                        {
                            m.Clock.Start();
                        }
                    });
                    break;

                case Keys.X:
                    // To test for correct resource recreation
                    // Simulate device reset or lost.
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    DeviceManager.Initialize(DeviceManager.Dpi);
                    System.Diagnostics.Debug.WriteLine(SharpDX.Diagnostics.ObjectTracker.ReportActiveObjects());
                    break;

                case Keys.Z:
                    keyToggles[Keys.Z] = !keyToggles[Keys.Z];
                    if (keyToggles[Keys.Z])
                    {
                        context.PixelShader.Set(depthPixelShader);
                    }
                    else
                    {
                        context.PixelShader.Set(pixelShader);
                    }
                    break;

                case Keys.F:
                    keyToggles[Keys.F] = !keyToggles[Keys.F];
                    RasterizerStateDescription rasterDesc;
                    if (context.Rasterizer.State != null)
                    {
                        rasterDesc = context.Rasterizer.State.Description;
                    }
                    else
                    {
                        rasterDesc = new RasterizerStateDescription()
                        {
                            CullMode = CullMode.None,
                            FillMode = FillMode.Solid
                        }
                    };
                    if (keyToggles[Keys.F])
                    {
                        rasterDesc.FillMode      = FillMode.Wireframe;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    else
                    {
                        rasterDesc.FillMode      = FillMode.Solid;
                        context.Rasterizer.State = ToDispose(new RasterizerState(context.Device, rasterDesc));
                    }
                    break;

                case Keys.N:
                    if (!shiftKey)
                    {
                        showNormals = !showNormals;
                    }
                    else
                    {
                        enableNormalMap = !enableNormalMap;
                    }

                    break;

                case Keys.D1:
                    context.PixelShader.Set(pixelShader);
                    break;

                case Keys.D2:
                    context.PixelShader.Set(lambertShader);
                    break;

                case Keys.D3:
                    context.PixelShader.Set(phongShader);
                    break;

                case Keys.D4:
                    context.PixelShader.Set(blinnPhongShader);
                    break;

                case Keys.Add:
                    var multiple = 1.0f;
                    if (ctrlKey)
                    {
                        multiple = 3.0f;
                    }
                    if (!shiftKey)
                    {
                        tessellationFactor += 0.2f * multiple;
                        tessellationFactor  = Math.Min(tessellationFactor, 64);
                    }
                    else
                    {
                        displacementScale += 0.005f * multiple;
                    }
                    break;

                case Keys.Subtract:
                    multiple = 1.0f;
                    if (ctrlKey)
                    {
                        multiple = 3.0f;
                    }
                    if (!shiftKey)
                    {
                        tessellationFactor -= 0.2f * multiple;
                        tessellationFactor  = Math.Max(tessellationFactor, 0);
                    }
                    else
                    {
                        displacementScale -= 0.005f * multiple;
                    }
                    break;

                case Keys.F1:
                    tessellationPartition  = "Integer";
                    activeTriTessellator   = tessellateTriIntegerShader;
                    activePnTriTessellator = pnTriIntegerShader;
                    break;

                case Keys.F2:
                    tessellationPartition  = "Pow2";
                    activeTriTessellator   = tessellateTriPow2Shader;
                    activePnTriTessellator = pnTriPow2Shader;
                    break;

                case Keys.F3:
                    tessellationPartition  = "Fractional Even";
                    activeTriTessellator   = tessellateTriFractionalEvenShader;
                    activePnTriTessellator = pnTriFractionalEvenShader;
                    break;

                case Keys.F4:
                    tessellationPartition  = "Fractional Odd";
                    activeTriTessellator   = tessellateTriFractionalOddShader;
                    activePnTriTessellator = pnTriFractionalOddShader;
                    break;

                case Keys.F5:
                    usePhongTessellation = false;
                    usePNTessellation    = false;
                    tessellationMethod   = "Tri + displacement";
                    break;

                case Keys.F6:
                    usePhongTessellation = true;
                    usePNTessellation    = false;
                    tessellationMethod   = "Phong + displacement";
                    break;

                case Keys.F7:
                    usePhongTessellation = false;
                    usePNTessellation    = true;
                    tessellationMethod   = "PN-Triangle + displacement";
                    break;

                case Keys.Back:
                    meshIndex = (meshIndex + 1) % meshes.Count;
                    break;
                }

                updateText();
            };
            Window.KeyUp += (s, e) =>
            {
                // Clear the shift/ctrl keys so they aren't sticky
                if (e.KeyCode == Keys.ShiftKey)
                {
                    shiftKey = false;
                }
                if (e.KeyCode == Keys.ControlKey)
                {
                    ctrlKey = false;
                }
            };
            Window.MouseWheel += (s, e) =>
            {
                if (shiftKey)
                {
                    // Zoom in/out
                    viewMatrix.TranslationVector += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor * 2);
                }
                else
                {
                    // rotate around Z-axis
                    viewMatrix *= Matrix.RotationZ((e.Delta / 120f) * moveFactor);
                    rotation   += new Vector3(0f, 0f, (e.Delta / 120f) * moveFactor);
                }
                updateText();
            };

            var lastX = 0;
            var lastY = 0;

            Window.MouseDown += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    lastX = e.X;
                    lastY = e.Y;
                }
            };

            Window.MouseMove += (s, e) =>
            {
                if (e.Button == MouseButtons.Left)
                {
                    var yRotate = lastX - e.X;
                    var xRotate = lastY - e.Y;
                    lastY = e.Y;
                    lastX = e.X;

                    // Mouse move changes
                    viewMatrix *= Matrix.RotationX(-xRotate * moveFactor);
                    viewMatrix *= Matrix.RotationY(-yRotate * moveFactor);

                    updateText();
                }
            };

            // Display instructions with initial values
            updateText();

            #endregion

            var clock = new System.Diagnostics.Stopwatch();
            clock.Start();

            #region Render loop

            // Create and run the render loop
            RenderLoop.Run(Window, () =>
            {
                // Start of frame:

                // Retrieve immediate context
                var context = DeviceManager.Direct3DContext;

                // Clear depth stencil view
                context.ClearDepthStencilView(DepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
                // Clear render target view
                context.ClearRenderTargetView(RenderTargetView, background);

                // Create viewProjection matrix
                var viewProjection = Matrix.Multiply(viewMatrix, projectionMatrix);

                // Extract camera position from view
                var camPosition = Matrix.Transpose(Matrix.Invert(viewMatrix)).Column4;
                cameraPosition  = new Vector3(camPosition.X, camPosition.Y, camPosition.Z);

                // If Keys.CtrlKey is down, auto rotate viewProjection based on time
                var time = clock.ElapsedMilliseconds / 1000.0f;

                var perFrame                = new ConstantBuffers.PerFrame();
                perFrame.Light.Color        = new Color(0.8f, 0.8f, 0.8f, 1.0f);
                var lightDir                = Vector3.Transform(new Vector3(1f, -1f, -1f), worldMatrix);
                perFrame.Light.Direction    = new Vector3(lightDir.X, lightDir.Y, lightDir.Z);// new Vector3(Vector3.Transform(new Vector3(1f, -1f, 1f), worldMatrix * worldRotation).ToArray().Take(3).ToArray());
                perFrame.CameraPosition     = cameraPosition;
                perFrame.TessellationFactor = tessellationFactor;
                context.UpdateSubresource(ref perFrame, perFrameBuffer);

                // Set decal shader resource views
                //context.PixelShader.SetShaderResources(3, decalDiffuse, decalNormal);
                context.DomainShader.SetShaderResource(2, decalDisplacement);

                // Render each object

                var perMaterial           = new ConstantBuffers.PerMaterial();
                perMaterial.Ambient       = new Color4(0.2f);
                perMaterial.Diffuse       = Color.White;
                perMaterial.Emissive      = new Color4(0);
                perMaterial.Specular      = Color.White;
                perMaterial.SpecularPower = 20f;
                perMaterial.HasTexture    = 0;
                perMaterial.UVTransform   = Matrix.Identity;
                context.UpdateSubresource(ref perMaterial, perMaterialBuffer);

                var perObject = new ConstantBuffers.PerObject();

                // MESH
                context.VertexShader.Set(tessellateVertexShader);
                context.HullShader.Set(activeTriTessellator);
                if (usePhongTessellation)
                {
                    context.DomainShader.Set(tessellatePhongDomainShader);
                }
                else if (usePNTessellation)
                {
                    context.HullShader.Set(activePnTriTessellator);
                    context.DomainShader.Set(pnTriDomainShader);
                }
                else
                {
                    context.DomainShader.Set(tessellateTriDomainShader);
                }

                var m = meshes[meshIndex];
                //meshes.ForEach((m) =>
                //{

                // Assign decal textures
                m.TextureViews[3] = decalDiffuse;
                m.TextureViews[4] = decalNormal;

                // Apply decal
                var decal = new ConstantBuffers.DecalBuffer();
                decal.DecalDisplaceScale = 0.10f;
                var decalVectors         = new Vector3[3];
                if (meshIndex != 1)
                {
                    Vector3.Orthonormalize(decalVectors, new[] { new Vector3(0, 0.5f, 0.5f), Vector3.UnitX, -Vector3.UnitY });
                    decal.DecalPosition = new Vector3(0, 1, 1);
                }
                else
                {
                    Vector3.Orthonormalize(decalVectors, new[] { new Vector3(0, 0.5f, 0.2f), Vector3.UnitX, Vector3.UnitZ });
                    decal.DecalPosition = new Vector3(0, 0, 0);
                }
                decal.DecalNormal    = decalVectors[0];
                decal.DecalTangent   = decalVectors[1]; // U-axis of tex
                decal.DecalBitangent = decalVectors[2]; // V-axis of tex

                decal.DecalRadius = 0.5f;
                context.UpdateSubresource(ref decal, decalBuffer);
                // TODO: set decal buffer on mouse click using "Picking"



                // Provide the material constant buffer to the mesh renderer
                perObject.World = m.World * worldMatrix;
                perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                perObject.WorldViewProjection   = perObject.World * viewProjection;
                perObject.ViewProjection        = viewProjection;
                perObject.Transpose();
                context.UpdateSubresource(ref perObject, perObjectBuffer);

                m.EnableNormalMap   = enableNormalMap;
                m.DisplacementScale = displacementScale;
                m.DisplaceMidLevel  = 0.5f;
                m.PerMaterialBuffer = perMaterialBuffer;
                m.PerArmatureBuffer = perArmatureBuffer;
                m.Render();

                if (showNormals)
                {
                    using (var prevPixelShader = context.PixelShader.Get())
                    {
                        perMaterial.HasTexture  = 0;
                        perMaterial.UVTransform = Matrix.Identity;
                        context.UpdateSubresource(ref perMaterial, perMaterialBuffer);
                        context.PixelShader.Set(pixelShader);

                        context.GeometryShader.Set(debugNormals);

                        m.Render();

                        context.PixelShader.Set(prevPixelShader);
                        context.GeometryShader.Set(null);
                    }
                }

                //});

                // TRIANGLE
                //triangle.Render();

                //// QUAD
                //context.VertexShader.Set(tessellateVertexShader);
                //context.HullShader.Set(activeQuadTessellator);
                //context.DomainShader.Set(tessellateQuadDomainShader);

                //quad.Render();

                // BEZIER
                //context.VertexShader.Set(tessellateVertexShader);
                //context.HullShader.Set(activeBezierTessellator);
                //context.DomainShader.Set(tessellateBezierDomainShader);

                //bezier.Render();


                // AXIS GRID
                context.VertexShader.Set(vertexShader);
                context.HullShader.Set(null);
                context.DomainShader.Set(null);
                context.GeometryShader.Set(null);

                using (var prevPixelShader = context.PixelShader.Get())
                {
                    perMaterial.HasTexture  = 0;
                    perMaterial.UVTransform = Matrix.Identity;
                    context.UpdateSubresource(ref perMaterial, perMaterialBuffer);
                    context.PixelShader.Set(pixelShader);
                    perObject       = new ConstantBuffers.PerObject();
                    perObject.World = worldMatrix;
                    perObject.WorldInverseTranspose = Matrix.Transpose(Matrix.Invert(perObject.World));
                    perObject.WorldViewProjection   = perObject.World * viewProjection;
                    perObject.ViewProjection        = viewProjection;
                    perObject.Transpose();
                    context.UpdateSubresource(ref perObject, perObjectBuffer);
                    axisGrid.Render();
                    context.PixelShader.Set(prevPixelShader);
                }

                // Render FPS
                fps.Render();

                // Render instructions + position changes
                textRenderer.Render();

                // Present the frame
                Present();
            });
            #endregion
        }
        internal static RasterizerId CreateRasterizerState(RasterizerStateDescription description)
        {
            var id = new RasterizerId { Index = RasterizerStates.Allocate() };
            MyArrayHelpers.Reserve(ref RasterizerObjects, id.Index + 1);

            RasterizerStates.Data[id.Index] = description;

            InitRasterizerState(id);
            RasterizerIndices.Add(id);

            return id;
        }
Example #42
0
        public void LoadDirect3D(SharpDX.Direct3D11.Device device)
        {
            // Set up description of swap chain

            /*SwapChainDescription scd = new SwapChainDescription();
             * scd.BufferCount = 1;
             * scd.ModeDescription = new ModeDescription(Width, Height, new Rational(60, 1), Format.B8G8R8A8_UNorm);
             * scd.Usage = Usage.RenderTargetOutput;
             * scd.OutputHandle = Handle;
             * scd.SampleDescription.Count = 1;
             * scd.SampleDescription.Quality = 0;
             * scd.IsWindowed = true;
             * scd.ModeDescription.Width = Width;
             * scd.ModeDescription.Height = Height;*/

            // Create device and swap chain according to the description above
            //SharpDX.Direct3D11.Device d;
            //SwapChain sc;
            //DeviceCreationFlags flags = DeviceCreationFlags.BgraSupport | DeviceCreationFlags.SingleThreaded;
#if DEBUG
            //flags |= DeviceCreationFlags.Debug;
#endif
            //SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, flags, scd, out d, out sc);
            //this.SwapChain = sc; // we have to use these temp variables
            //this.Device = new SharpDX.Direct3D11.Device(DriverType.Hardware, flags);
            //this.Device = d; // because properties can't be passed as out parameters. =(

            // Set up the rendering context and buffers and stuff
            this.Device      = device;
            ImmediateContext = Device.ImmediateContext;
            //BuildBuffers();

            // Build a custom rasterizer state that doesn't cull backfaces
            RasterizerStateDescription frs = new RasterizerStateDescription();
            frs.CullMode        = CullMode.None;
            frs.FillMode        = FillMode.Solid;
            FillRasterizerState = new RasterizerState(Device, frs);
            ImmediateContext.Rasterizer.State = FillRasterizerState;
            // Build a custom rasterizer state for wireframe drawing
            RasterizerStateDescription wrs = new RasterizerStateDescription();
            wrs.CullMode = CullMode.None;
            wrs.FillMode = FillMode.Wireframe;
            wrs.IsAntialiasedLineEnabled = false;
            wrs.DepthBias            = -10;
            WireframeRasterizerState = new RasterizerState(Device, wrs);

            // Set texture sampler state
            SamplerStateDescription ssd = new SamplerStateDescription();
            ssd.AddressU          = TextureAddressMode.Wrap;
            ssd.AddressV          = TextureAddressMode.Wrap;
            ssd.AddressW          = TextureAddressMode.Wrap;
            ssd.Filter            = Filter.MinMagMipLinear;
            ssd.MaximumAnisotropy = 1;
            SampleState           = new SamplerState(Device, ssd);
            ImmediateContext.PixelShader.SetSampler(0, SampleState);

            // Load the default texture
            var path = Path.Combine(App.ExecFolder, "Default.bmp");
            System.Drawing.Bitmap deftex = new System.Drawing.Bitmap(path);
            DefaultTexture = LoadTexture(deftex);
            deftex.Dispose();
            DefaultTextureView = new ShaderResourceView(Device, DefaultTexture);

            // Load the default position-texture shader
            DefaultEffect = new Effect <WorldConstants, WorldVertex>(Device, Properties.Resources.StandardShader);

            TextureCache = new PreviewTextureCache(Device);
        }
Example #43
0
        private void SetRasterizerState()
        {
            var rasterizerState = new RasterizerStateDescription
            {
                CullMode = CullMode.Back,
                FillMode = FillMode.Solid,
                IsFrontCounterclockwise = false,
                DepthBias = 0,
                DepthBiasClamp = 0,
                SlopeScaledDepthBias = 0,
                IsDepthClipEnabled = true,
                IsScissorEnabled = false,
                IsMultisampleEnabled = false,
                IsAntialiasedLineEnabled = true,
            };

            Device.Rasterizer.State = RasterizerState.FromDescription(Device, rasterizerState);
        }
Example #44
0
        public VoroniRenderer2d(String title)
        {
            m_scenes = new List <Scene>();

            cameras_ = new List <Camera>();

            samplerStates_ = new Dictionary <string, SamplerState>();

            lastTime_ = DateTime.Now;

            form_        = new RenderForm(title);
            form_.Width  = 1024;
            form_.Height = 768;

            var desc = new SwapChainDescription()
            {
                BufferCount       = 1,
                ModeDescription   = new ModeDescription(form_.ClientSize.Width, form_.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm),
                IsWindowed        = true,
                OutputHandle      = form_.Handle,
                SampleDescription = new SampleDescription(1, 0),
                SwapEffect        = SwapEffect.Discard,
                Usage             = Usage.RenderTargetOutput
            };

            Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device_, out swapChain_);

            Factory factory = swapChain_.GetParent <Factory>();

            factory.SetWindowAssociation(form_.Handle, WindowAssociationFlags.IgnoreAll);

            backBuffer_ = Texture2D.FromSwapChain <Texture2D>(swapChain_, 0);
            renderView_ = new RenderTargetView(device_, backBuffer_);


            var depthDesc = new Texture2DDescription()
            {
                Width             = form_.Width,
                Height            = form_.Height,
                MipLevels         = 1,
                ArraySize         = 1,
                Format            = Format.D24_UNorm_S8_UInt,
                SampleDescription = new SampleDescription()
                {
                    Count   = 1,
                    Quality = 0
                },
                Usage          = ResourceUsage.Default,
                BindFlags      = BindFlags.DepthStencil,
                CpuAccessFlags = 0,
                OptionFlags    = 0
            };

            m_depthBuffer = new Texture2D(device_, depthDesc);

            device_.ImmediateContext.Rasterizer.SetViewports(new Viewport(0, 0, form_.ClientSize.Width, form_.ClientSize.Height, 0.1f, 1.0f));

            RasterizerStateDescription descRast = new RasterizerStateDescription()
            {
                FillMode           = FillMode.Solid,
                CullMode           = CullMode.None,
                IsDepthClipEnabled = true
            };

            m_rasterizerState = RasterizerState.FromDescription(device_, descRast);

            DepthStencilStateDescription dsStateDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled  = true,
                DepthWriteMask  = DepthWriteMask.All,
                DepthComparison = Comparison.Less,

                IsStencilEnabled = true,
                StencilReadMask  = 0xFF,
                StencilWriteMask = 0xFF,

                FrontFace = new DepthStencilOperationDescription()
                {
                    Comparison         = Comparison.Always,
                    DepthFailOperation = StencilOperation.Increment,
                    FailOperation      = StencilOperation.Keep,
                    PassOperation      = StencilOperation.Keep
                },

                BackFace = new DepthStencilOperationDescription()
                {
                    Comparison         = Comparison.Always,
                    DepthFailOperation = StencilOperation.Increment,
                    FailOperation      = StencilOperation.Keep,
                    PassOperation      = StencilOperation.Keep
                },
            };

            DepthStencilState dsState = DepthStencilState.FromDescription(device_, dsStateDesc);

            device_.ImmediateContext.OutputMerger.DepthStencilState = dsState;
            device_.ImmediateContext.Rasterizer.State = m_rasterizerState;

            DepthStencilViewDescription DSVDesc = new DepthStencilViewDescription()
            {
                Format    = Format.D24_UNorm_S8_UInt,
                Dimension = DepthStencilViewDimension.Texture2D,
                MipSlice  = 0
            };

            m_depthView = new DepthStencilView(device_, m_depthBuffer, DSVDesc);

            dsState.Dispose();

            device_.ImmediateContext.OutputMerger.SetTargets(m_depthView, renderView_);

            CreateSamplers();
        }
Example #45
0
		private void InitalizeGraphics()
		{
			if (Window.RenderCanvasHandle == IntPtr.Zero)
				throw new InvalidOperationException();

			SwapChainDescription swapChainDesc = new SwapChainDescription()
			{
				BufferCount = 1,
				Flags = SwapChainFlags.None,
				IsWindowed = true,
				OutputHandle = Window.RenderCanvasHandle,
				SwapEffect = SwapEffect.Discard,
				Usage = Usage.RenderTargetOutput,
				ModeDescription = new ModeDescription()
				{
					Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm,
					//Format = SlimDX.DXGI.Format.B8G8R8A8_UNorm,
					Width = (int)Window.RenderCanvasSize.Width,
					Height = (int)Window.RenderCanvasSize.Height,
					RefreshRate = new Rational(60, 1),
					Scaling = DisplayModeScaling.Unspecified,
					ScanlineOrdering = DisplayModeScanlineOrdering.Unspecified
				},
				SampleDescription = new SampleDescription(1, 0)
			};

			var giFactory = new SlimDX.DXGI.Factory();
			var adapter = giFactory.GetAdapter(0);

			Device device;
			SwapChain swapChain;
			Device.CreateWithSwapChain(adapter, DriverType.Hardware, DeviceCreationFlags.Debug, swapChainDesc, out device, out swapChain);
			_swapChain = swapChain;
			GraphicsDevice = device;

			// create a view of our render target, which is the backbuffer of the swap chain we just created
			using (var resource = SlimDX.Direct3D10.Resource.FromSwapChain<Texture2D>(swapChain, 0))
			{
				_backBuffer = new RenderTargetView(device, resource);
			}

			// setting a viewport is required if you want to actually see anything
			var viewport = new Viewport(0, 0, (int)Window.RenderCanvasSize.Width, (int)Window.RenderCanvasSize.Height);
			device.OutputMerger.SetTargets(_backBuffer);
			device.Rasterizer.SetViewports(viewport);

			CreateDepthStencil();
			LoadVisualizationEffect();

			// Allocate a large buffer to write the PhysX visualization vertices into
			// There's more optimized ways of doing this, but for this sample a large buffer will do
			_userPrimitivesBuffer = new SlimDX.Direct3D10.Buffer(GraphicsDevice, VertexPositionColor.SizeInBytes * 50000, ResourceUsage.Dynamic, BindFlags.VertexBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None);

			var elements = new[]
			{
				new InputElement("Position", 0, Format.R32G32B32A32_Float, 0, 0),
				new InputElement("Color", 0, Format.R32G32B32A32_Float, 16, 0)
			};
			_inputLayout = new InputLayout(GraphicsDevice, _visualizationEffect.RenderScenePass0.Description.Signature, elements);

			// States
			var blendDesc = new BlendStateDescription()
			{
				SourceBlend = BlendOption.One,
				DestinationBlend = BlendOption.Zero,
				BlendOperation = BlendOperation.Add,
				SourceAlphaBlend = BlendOption.One,
				DestinationAlphaBlend = BlendOption.Zero,
				AlphaBlendOperation = BlendOperation.Add
			};
			blendDesc.SetBlendEnable(0, true);
			_blendState = BlendState.FromDescription(device, blendDesc);

			var rasterDesc = new RasterizerStateDescription()
			{
				IsAntialiasedLineEnabled = false,
				IsMultisampleEnabled = false,
				FillMode = FillMode.Solid,
				CullMode = CullMode.None
			};
			_rasterizerState = RasterizerState.FromDescription(device, rasterDesc);
		}
Example #46
0
        /// <summary>
        /// Compute the parameters and store them in the material.
        /// </summary>
        /// <param name="log">The logger.</param>
        /// <returns>A boolean stating that the parameters were incorrectly created.</returns>
        public bool CreateParameterCollectionData(Logger log = null)
        {
            Parameters.Clear();

            var hasErrors = false;

            var materialShaderCreator = new MaterialTreeShaderCreator(Material);
            var shaders = materialShaderCreator.GenerateModelShaders();

            if (log != null)
            {
                (materialShaderCreator.Logger).CopyTo(log);
            }

            foreach (var keyValue in Material.Parameters)
            {
                // NOTE: cheap way to activate alpha blending
                Parameters.Set(keyValue.Key, keyValue.Value);
                if (keyValue.Key == MaterialParameters.UseTransparent && Material.GetParameter(MaterialParameters.UseTransparent))
                {
                    // using non premultiply alpha blending
                    var blendStateDescr = new BlendStateDescription(Blend.SourceAlpha, Blend.InverseSourceAlpha);
                    var blendState      = new FakeBlendState(blendStateDescr);
                    Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.BlendStateKey, ContentReference.Create((BlendState)blendState));

                    // disable face culling
                    // TODO: make this programmable
                    var rasterizerStateDescr = new RasterizerStateDescription(CullMode.None);
                    var rasterizerState      = new FakeRasterizerState(rasterizerStateDescr);
                    Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.RasterizerStateKey, ContentReference.Create((RasterizerState)rasterizerState));

                    // disable depth write
                    var depthStencilStateDescr = new DepthStencilStateDescription(true, false);
                    var depthStencilState      = new FakeDepthStencilState(depthStencilStateDescr);
                    Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.DepthStencilStateKey, ContentReference.Create((DepthStencilState)depthStencilState));
                }
                else if (keyValue.Key == MaterialParameters.UseTransparentMask && Material.GetParameter(MaterialParameters.UseTransparentMask))
                {
                    // disable face culling
                    // TODO: make this programmable
                    var rasterizerStateDescr = new RasterizerStateDescription(CullMode.None);
                    var rasterizerState      = new FakeRasterizerState(rasterizerStateDescr);
                    Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.RasterizerStateKey, ContentReference.Create((RasterizerState)rasterizerState));

                    // enable depth write
                    var depthStencilStateDescr = new DepthStencilStateDescription(true, true);
                    var depthStencilState      = new FakeDepthStencilState(depthStencilStateDescr);
                    Parameters.Set(SiliconStudio.Paradox.Graphics.Effect.DepthStencilStateKey, ContentReference.Create((DepthStencilState)depthStencilState));
                }
            }

            var textureVisitor = new MaterialTextureVisitor(Material);
            var allTextures    = textureVisitor.GetAllModelTextureValuesWithGenerics();

            foreach (var texture in allTextures)
            {
                if (texture.TextureReference == null || (texture.TextureReference.Id == Guid.Empty && String.IsNullOrEmpty(texture.TextureReference.Location)))
                {
                    if (log != null)
                    {
                        log.Error("[Material] Material {0} is missing a texture", materialUrl);
                    }
                    hasErrors = true;
                }
                else
                {
                    Parameters.Set(texture.UsedParameterKey, new ContentReference <Graphics.Texture>(texture.TextureReference.Id, texture.TextureReference.Location));
                    AddSampler(texture.Sampler);
                }
            }

            var allSamplers = textureVisitor.GetAllSamplerValues();

            foreach (var sampler in allSamplers)
            {
                AddSampler(sampler);
            }

            var parameterVisitor = new MaterialParametersVisitor(Material);
            var parameters       = parameterVisitor.GetParameters();

            foreach (var keyValue in parameters)
            {
                // The code is separated from the previous code since the key is not generated the same way.
                if (keyValue.Value is MaterialTextureNode)
                {
                    var textureNode = (MaterialTextureNode)keyValue.Value;
                    if (textureNode != null)
                    {
                        if (textureNode.TextureReference == null || textureNode.TextureReference.Id == Guid.Empty || String.IsNullOrEmpty(textureNode.TextureReference.Location))
                        {
                            if (log != null)
                            {
                                log.Error("[Material] Material {0} is missing a texture", materialUrl);
                            }
                            hasErrors = true;
                        }
                        else
                        {
                            Parameters.Set(keyValue.Key, new ContentReference <Graphics.Texture>(textureNode.TextureReference.Id, textureNode.TextureReference.Location));
                        }
                    }
                }
                else if (keyValue.Value is NodeParameterSampler)
                {
                    var sampler = (NodeParameterSampler)keyValue.Value;
                    if (sampler.SamplerParameterKey == null && keyValue.Key is ParameterKey <SamplerState> )
                    {
                        sampler.SamplerParameterKey = (ParameterKey <SamplerState>)keyValue.Key;
                    }
                    AddSampler(sampler);
                }
                else
                {
                    Parameters.Set(keyValue.Key, keyValue.Value);
                }
            }

            // NOTE: this can set the shader uniforms and potentially override what was in Material.SharedParameters
            foreach (var keyValue in shaders)
            {
                if (log != null && (keyValue.Key == MaterialParameters.BumpMap || keyValue.Key == MaterialParameters.EmissiveMap || keyValue.Key == MaterialParameters.ReflectionMap))
                {
                    log.Warning("[Material] Material {0} contains the key {1} which is not yet handled by the engine.", materialUrl, keyValue.Key);
                }

                Parameters.Set(keyValue.Key, keyValue.Value);
            }

            return(hasErrors);
        }
        private Texture2D CreateTexture(int width, int height, bool multiSampling)
        {
            var description = new SlimDX.Direct3D10.Texture2DDescription();
            description.ArraySize = 1;
            description.BindFlags = SlimDX.Direct3D10.BindFlags.RenderTarget | SlimDX.Direct3D10.BindFlags.ShaderResource;
            description.CpuAccessFlags = CpuAccessFlags.None;
            description.Format = Format.B8G8R8A8_UNorm;
            description.MipLevels = 1;
            //description.MiscellaneousResourceOptions = D3D10.MiscellaneousResourceOptions.Shared;
 
            // Multi-sample anti-aliasing
            //description.MiscellaneousResourceOptions = D3D10.MiscellaneousResourceOptions.Shared;
            int count;
            if (multiSampling) count = 8; else count = 1;
            int quality = device.CheckMultisampleQualityLevels(description.Format, count);
            if (count == 1) quality = 1;
            // Multi-sample anti-aliasing
            SampleDescription sampleDesc = new SampleDescription(count, 0);
            description.SampleDescription = sampleDesc;

            RasterizerStateDescription rastDesc = new RasterizerStateDescription();
            rastDesc.CullMode = CullMode.Back;
            rastDesc.FillMode = FillMode.Solid;
            rastDesc.IsMultisampleEnabled = false;
            rastDesc.IsAntialiasedLineEnabled = false;
            //rastDesc.DepthBias = 0;
            //rastDesc.DepthBiasClamp = 0;
            //rastDesc.IsDepthClipEnabled = true;
            //rastDesc.IsFrontCounterclockwise = false;
            //rastDesc.IsScissorEnabled = true;
            //rastDesc.SlopeScaledDepthBias = 0;

            device.Rasterizer.State = RasterizerState.FromDescription(device, rastDesc);

            description.Usage = ResourceUsage.Default;
            description.OptionFlags = ResourceOptionFlags.Shared;
            description.Height = (int)height;
            description.Width = (int)width;

            return new Texture2D(device, description);
        }
        public override void Attach(IRenderHost host)
        {
            /// --- attach
            this.renderTechnique = Techniques.RenderCubeMap;
            base.Attach(host);

            /// --- get variables               
            this.vertexLayout = EffectsManager.Instance.GetLayout(this.renderTechnique);
            this.effectTechnique = effect.GetTechniqueByName(this.renderTechnique.Name);
            this.effectTransforms = new EffectTransformVariables(this.effect);

            /// -- attach cube map 
            if (this.Filename != null)
            {
                /// -- attach texture
                using (var texture = Texture2D.FromFile<Texture2D>(this.Device, this.Filename))
                {
                    this.texCubeMapView = new ShaderResourceView(this.Device, texture);
                }
                this.texCubeMap = effect.GetVariableByName("texCubeMap").AsShaderResource();
                this.texCubeMap.SetResource(this.texCubeMapView);
                this.bHasCubeMap = effect.GetVariableByName("bHasCubeMap").AsScalar();
                this.bHasCubeMap.Set(true);

                /// --- set up geometry
                var sphere = new MeshBuilder(false,true,false);
                sphere.AddSphere(new Vector3(0, 0, 0));
                this.geometry = sphere.ToMeshGeometry3D();

                /// --- set up vertex buffer
                this.vertexBuffer = Device.CreateBuffer(BindFlags.VertexBuffer, CubeVertex.SizeInBytes, this.geometry.Positions.Select((x, ii) => new CubeVertex() { Position = new Vector4(x, 1f) }).ToArray());

                /// --- set up index buffer
                this.indexBuffer = Device.CreateBuffer(BindFlags.IndexBuffer, sizeof(int), geometry.Indices.Array);

                /// --- set up rasterizer states
                var rasterStateDesc = new RasterizerStateDescription()
                {
                    FillMode = FillMode.Solid,
                    CullMode = CullMode.Back,
                    IsMultisampleEnabled = true,
                    IsAntialiasedLineEnabled = true,
                    IsFrontCounterClockwise = false,
                };
                this.rasterState = new RasterizerState(this.Device, rasterStateDesc);

                /// --- set up depth stencil state
                var depthStencilDesc = new DepthStencilStateDescription()
                {
                    DepthComparison = Comparison.LessEqual,
                    DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All,
                    IsDepthEnabled = true,
                };
                this.depthStencilState = new DepthStencilState(this.Device, depthStencilDesc);
            }

            /// --- flush
            this.Device.ImmediateContext.Flush();
        }
Example #49
0
        private void BeginScene()
        {
            // make sure buffers are initialized with current size
            EnsureOutputBuffers();

            // bind the views to the output merger stage
            _dxDevice.OutputMerger.SetTargets(_dxDepthStencilView, _dxRenderView);

            // clear buffers
            _dxDevice.ClearDepthStencilView(_dxDepthStencilView, DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
            _dxDevice.ClearRenderTargetView(_dxRenderView, new Color4(0f, 0, 0, 0)); // uses transparent color

            // set rasterization parameters
            var rsd = new RasterizerStateDescription
            {
                //IsAntialiasedLineEnabled = true,
                IsFrontCounterclockwise = false,
                CullMode = CullMode.None,
                FillMode = (_wireframe) ? FillMode.Wireframe : FillMode.Solid
            };

            RasterizerState rsdState = RasterizerState.FromDescription(_dxDevice, rsd);
            _dxDevice.Rasterizer.State = rsdState;

            // set viewport
            _dxDevice.Rasterizer.SetViewports(new Viewport(0, 0, ClientWidth, ClientHeight, 0.0f, 1.0f));
        }
Example #50
0
        private static void Main()
        {
            // Device creation
            var form = new RenderForm("Stereo test")
                           {
                               ClientSize = size,
                               //FormBorderStyle = System.Windows.Forms.FormBorderStyle.None,
                               //WindowState = FormWindowState.Maximized
                           };

            form.KeyDown += new KeyEventHandler(form_KeyDown);
               // form.Resize += new EventHandler(form_Resize);

            ModeDescription mDesc = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height,
                                                        new Rational(120000, 1000), Format.R8G8B8A8_UNorm);
            mDesc.ScanlineOrdering = DisplayModeScanlineOrdering.Progressive;
            mDesc.Scaling = DisplayModeScaling.Unspecified;

            var desc = new SwapChainDescription()
                           {
                               BufferCount = 1,
                               ModeDescription = mDesc,
                                   Flags = SwapChainFlags.AllowModeSwitch,
                               IsWindowed = false,
                               OutputHandle = form.Handle,
                               SampleDescription = new SampleDescription(1, 0),
                               SwapEffect = SwapEffect.Discard,
                               Usage = Usage.RenderTargetOutput
                           };

            Device.CreateWithSwapChain(null, DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device,
                                       out swapChain);

            //Stops Alt+enter from causing fullscreen skrewiness.
            factory = swapChain.GetParent<Factory>();
            factory.SetWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll);

            backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0);
            renderView = new RenderTargetView(device, backBuffer);

            ImageLoadInformation info = new ImageLoadInformation()
                                            {
                                                BindFlags = BindFlags.None,
                                                CpuAccessFlags = CpuAccessFlags.Read,
                                                FilterFlags = FilterFlags.None,
                                                Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm,
                                                MipFilterFlags = FilterFlags.None,
                                                OptionFlags = ResourceOptionFlags.None,
                                                Usage = ResourceUsage.Staging,
                                                MipLevels = 1
                                            };

            // Make texture 3D
            sourceTexture = Texture2D.FromFile(device, "medusa.jpg", info);
            ImageLoadInformation info2 = new ImageLoadInformation()
                                            {
                                                BindFlags = BindFlags.ShaderResource,
                                                CpuAccessFlags = CpuAccessFlags.None,
                                                FilterFlags = FilterFlags.None,
                                                Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm,
                                                MipFilterFlags = FilterFlags.None,
                                                OptionFlags = ResourceOptionFlags.None,
                                                Usage = ResourceUsage.Default,
                                                MipLevels = 1
                                            };
            Texture2D tShader = Texture2D.FromFile(device, "medusa.jpg", info2);
            srv = new ShaderResourceView(device, tShader);
            //ResizeDevice(new Size(1920, 1080), true);
            // Create a quad that fills the whole screen

            BuildQuad();
            // Create world view (ortho) projection matrices
            //QuaternionCam qCam = new QuaternionCam();

            // Load effect from file. It is a basic effect that renders a full screen quad through
            // an ortho projectio=n matrix
            effect = Effect.FromFile(device, "Texture.fx", "fx_4_0", ShaderFlags.Debug, EffectFlags.None);
            EffectTechnique technique = effect.GetTechniqueByIndex(0);
            EffectPass pass = technique.GetPassByIndex(0);
            InputLayout layout = new InputLayout(device, pass.Description.Signature, new[]
                                                                                         {
                                                                                             new InputElement(
                                                                                                 "POSITION", 0,
                                                                                                 Format.
                                                                                                     R32G32B32A32_Float,
                                                                                                 0, 0),
                                                                                             new InputElement(
                                                                                                 "TEXCOORD", 0,
                                                                                                 Format.
                                                                                                     R32G32_Float,
                                                                                                 16, 0)
                                                                                         });
            //effect.GetVariableByName("mWorld").AsMatrix().SetMatrix(
            //    Matrix.Translation(Layout.OrthographicTransform(Vector2.Zero, 99, size)));
            //effect.GetVariableByName("mView").AsMatrix().SetMatrix(qCam.View);
            //effect.GetVariableByName("mProjection").AsMatrix().SetMatrix(qCam.OrthoProjection);
            //effect.GetVariableByName("tDiffuse").AsResource().SetResource(srv);

            // Set RT and Viewports
            device.OutputMerger.SetTargets(renderView);
            device.Rasterizer.SetViewports(new Viewport(0, 0, size.Width, size.Height, 0.0f, 1.0f));

            // Create solid rasterizer state
            RasterizerStateDescription rDesc = new RasterizerStateDescription()
                                                   {
                                                       CullMode = CullMode.None,
                                                       IsDepthClipEnabled = true,
                                                       FillMode = FillMode.Solid,
                                                       IsAntialiasedLineEnabled = false,
                                                       IsFrontCounterclockwise = true,
                                                       //IsMultisampleEnabled = true,
                                                   };
            RasterizerState rState = RasterizerState.FromDescription(device, rDesc);
            device.Rasterizer.State = rState;

            Texture2DDescription rtDesc = new Texture2DDescription
                                              {
                                                  ArraySize = 1,
                                                  Width = size.Width,
                                                  Height = size.Height,
                                                  BindFlags = BindFlags.RenderTarget,
                                                  CpuAccessFlags = CpuAccessFlags.None,
                                                  Format = SlimDX.DXGI.Format.R8G8B8A8_UNorm,
                                                  OptionFlags = ResourceOptionFlags.None,
                                                  Usage = ResourceUsage.Default,
                                                  MipLevels = 1,
                                                  SampleDescription = new SampleDescription(1, 0)
                                              };
            rtTex = new Texture2D(device, rtDesc);

            rv = new RenderTargetView(device, rtTex);

            stereoizedTexture = Make3D(sourceTexture);
            //ResizeDevice(new Size(1920, 1080), true);
            Console.WriteLine(form.ClientSize);
            // Main Loop
            MessagePump.Run(form, () =>
            {
            device.ClearRenderTargetView(renderView, Color.Cyan);

            //device.InputAssembler.SetInputLayout(layout);
            //device.InputAssembler.SetPrimitiveTopology(PrimitiveTopology.TriangleList);
            //device.OutputMerger.SetTargets(rv);
            //device.InputAssembler.SetVertexBuffers(0,
            //                                new VertexBufferBinding(vertices, 24, 0));
            //device.InputAssembler.SetIndexBuffer(indices, Format.R16_UInt, 0);
            //for (int i = 0; i < technique.Description.PassCount; ++i)
            //{
            //    // Render the full screen quad
            //    pass.Apply();
            //    device.DrawIndexed(6, 0, 0);
            //}
            ResourceRegion stereoSrcBox = new ResourceRegion { Front = 0, Back = 1, Top = 0, Bottom = size.Height, Left = 0, Right = size.Width };
            device.CopySubresourceRegion(stereoizedTexture, 0, stereoSrcBox, backBuffer, 0, 0, 0, 0);
            //device.CopyResource(rv.Resource, backBuffer);

            swapChain.Present(0, PresentFlags.None);
            });

            // Dispose resources
            vertices.Dispose();
            layout.Dispose();
            effect.Dispose();
            renderView.Dispose();
            backBuffer.Dispose();
            device.Dispose();
            swapChain.Dispose();

            rState.Dispose();
            stereoizedTexture.Dispose();
            sourceTexture.Dispose();
            indices.Dispose();
            srv.Dispose();
        }
Example #51
0
        public override bool Init() {
            if (!base.Init()) {
                return false;
            }

            BuildGeometryBuffers();
            BuildFX();
            BuildVertexLayout();

            var wireFrameDesc = new RasterizerStateDescription {
                FillMode = FillMode.Wireframe,
                CullMode = CullMode.Back,
                IsFrontCounterclockwise = false,
                IsDepthClipEnabled = true
            };

            _wireframeRS = RasterizerState.FromDescription(Device, wireFrameDesc);

            return true;
        }
        private void BuildPSOs()
        {
            //
            // PSO for opaque objects.
            //

            var opaquePsoDesc = new GraphicsPipelineStateDescription
            {
                InputLayout           = _inputLayout,
                RootSignature         = _rootSignature,
                VertexShader          = _shaders["standardVS"],
                PixelShader           = _shaders["opaquePS"],
                RasterizerState       = RasterizerStateDescription.Default(),
                BlendState            = BlendStateDescription.Default(),
                DepthStencilState     = DepthStencilStateDescription.Default(),
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                SampleDescription     = new SampleDescription(MsaaCount, MsaaQuality),
                DepthStencilFormat    = DepthStencilFormat
            };

            opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat;

            _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc);

            //
            // PSO for transparent objects.
            //

            GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy();

            var transparencyBlendDesc = new RenderTargetBlendDescription
            {
                IsBlendEnabled        = true,
                LogicOpEnable         = false, // TODO: API suggestion: Rename to IsLogicOpEnabled similar to IsBlendEnabled.
                SourceBlend           = BlendOption.SourceAlpha,
                DestinationBlend      = BlendOption.InverseSourceAlpha,
                BlendOperation        = BlendOperation.Add,
                SourceAlphaBlend      = BlendOption.One,
                DestinationAlphaBlend = BlendOption.Zero,
                AlphaBlendOperation   = BlendOperation.Add,
                LogicOp = LogicOperation.Noop,
                RenderTargetWriteMask = ColorWriteMaskFlags.All
            };

            transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc;

            _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc);

            //
            // PSO for alpha tested objects.
            //

            GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy();

            alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"];
            alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None;

            _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc);
        }
Example #53
0
        private void AffectConstants()
        {
            // Texture
            Texture2D texture2D = Texture2D.FromFile(device11, "yoda.jpg");
            ShaderResourceView view = new ShaderResourceView(device11, texture2D);

            effect.GetVariableByName("yodaTexture").AsResource().SetResource(view);

            RasterizerStateDescription rasterizerStateDescription = new RasterizerStateDescription {CullMode = CullMode.None, FillMode = FillMode.Solid};

            device11.ImmediateContext.Rasterizer.State = RasterizerState.FromDescription(device11, rasterizerStateDescription);

            // Matrices
            Matrix worldMatrix = Matrix.RotationY(0.5f);
            Matrix viewMatrix = Matrix.Translation(0, 0, 5.0f);
            const float fov = 0.8f;
            Matrix projectionMatrix = Matrix.PerspectiveFovLH(fov, ClientSize.Width / (float)ClientSize.Height, 0.1f, 1000.0f);

            effect.GetVariableByName("finalMatrix").AsMatrix().SetMatrix(worldMatrix * viewMatrix * projectionMatrix);
        }
Example #54
0
        public void BuildPSO(Device3 device, GraphicsCommandList commandList)
        {
            Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000);
            View       = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY);
            World      = Matrix.Translation(-2.5f, -2.5f, -2.5f);

            DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _perPassViewHeap = device.CreateDescriptorHeap(cbvHeapDesc);

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.All, new RootDescriptor(0, 0), RootParameterType.ConstantBufferView) };


            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters);

            _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/Untextured.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout           = new InputLayoutDescription(inputElementDescs),
                RootSignature         = _rootSignature,
                VertexShader          = vertexShader,
                PixelShader           = pixelShader,
                RasterizerState       = RasterizerStateDescription.Default(),
                BlendState            = BlendStateDescription.Default(),
                DepthStencilFormat    = SharpDX.DXGI.Format.D24_UNorm_S8_UInt,
                DepthStencilState     = DepthStencilStateDescription.Default(),
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            _pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                //Front
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), Color = new Vector4(0, 0, 1, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), Color = new Vector4(0, 0, 1, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), Color = new Vector4(0, 0, 1, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), Color = new Vector4(0, 0, 1, 1)
                },

                //Back
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), Color = new Vector4(0, 0, 1, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), Color = new Vector4(0, 0, 1, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), Color = new Vector4(0, 0, 1, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), Color = new Vector4(0, 0, 1, 1)
                },

                //Left
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), Color = new Vector4(0, 1, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), Color = new Vector4(0, 1, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), Color = new Vector4(0, 1, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), Color = new Vector4(0, 1, 0, 1)
                },

                //Right
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), Color = new Vector4(0, 1, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), Color = new Vector4(0, 1, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), Color = new Vector4(0, 1, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), Color = new Vector4(0, 1, 0, 1)
                },

                //Top
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), Color = new Vector4(1, 0, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), Color = new Vector4(1, 0, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), Color = new Vector4(1, 0, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), Color = new Vector4(1, 0, 0, 1)
                },

                //Bottom
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), Color = new Vector4(1, 0, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), Color = new Vector4(1, 0, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), Color = new Vector4(1, 0, 0, 1)
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), Color = new Vector4(1, 0, 0, 1)
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = _vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            _vertexBuffer.Unmap(0);

            _indicies = new int[] { 0, 1, 2,
                                    3, 2, 1,
                                    6, 5, 4,
                                    5, 6, 7,

                                    10, 9, 8,
                                    9, 10, 11,
                                    12, 13, 14,
                                    15, 14, 13,

                                    18, 17, 16,
                                    17, 18, 19,
                                    20, 21, 22,
                                    23, 22, 21 };

            int indBufferSize = Utilities.SizeOf(_indicies);

            _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead);

            IntPtr pIndBegin = _indexBuffer.Map(0);
            Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length);
            _indexBuffer.Unmap(0);

            _indexBufferView = new IndexBufferView()
            {
                BufferLocation = _indexBuffer.GPUVirtualAddress,
                Format         = Format.R32_UInt,
                SizeInBytes    = indBufferSize
            };

            // Initialize the vertex buffer view.
            _vertexBufferView = new VertexBufferView
            {
                BufferLocation = _vertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = vertexBufferSize
            };

            _perPassBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <PerPass>()), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = _perPassBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <PerPass>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc, _perPassViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _perPassPointer = _perPassBuffer.Map(0);
            Utilities.Write(_perPassPointer, ref buffer);

            _resources = new[] { new GraphicsResource()
                                 {
                                     Resource = _perPassBuffer, Register = 0, type = ResourceType.ConstantBufferView
                                 } };
        }
Example #55
0
        public static void ResizeDevice(Size newSize, bool fullScreen)
        {
            //OnDeviceSuspend(EventArgs.Empty);

            backBuffer.Dispose();
            renderView.Dispose();
            vertices.Dispose();
            indices.Dispose();
            rv.Dispose();
            device.ClearState();

            SwapChainDescription swapChainDesc = swapChain.Description;
            Output output = factory.GetAdapter(0).GetOutput(0);

            var modes = output.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Scaling | DisplayModeEnumerationFlags.Interlaced);

            ModeDescription desc2 = modes[modes.Count - 1];
            ModeDescription result2;
            output.GetClosestMatchingMode(device, desc2, out result2);
            //swapChain.SetFullScreenState(true, null);

            Result result;

            //

            swapChain.ResizeTarget(new ModeDescription(result2.Width, result2.Height, result2.RefreshRate, result2.Format));
            swapChain.SetFullScreenState(fullScreen, null);
            result = swapChain.ResizeBuffers(swapChainDesc.BufferCount, result2.Width, result2.Height,
                result2.Format, SwapChainFlags.AllowModeSwitch);
            backBuffer = Resource.FromSwapChain<Texture2D>(swapChain, 0);

            renderView = new RenderTargetView(device, backBuffer);
            rv = new RenderTargetView(device, rtTex);
            //Console.WriteLine(device.Rasterizer.State.ToString());
            RasterizerStateDescription rDesc = new RasterizerStateDescription()
            {
                CullMode = CullMode.None,
                IsDepthClipEnabled = true,
                FillMode = FillMode.Solid,
                IsAntialiasedLineEnabled = false,
                IsFrontCounterclockwise = true,
                //IsMultisampleEnabled = true,
            };
            RasterizerState rState = RasterizerState.FromDescription(device, rDesc);
            device.Rasterizer.State = rState;
            device.Rasterizer.SetViewports(new Viewport(0, 0, size.Width, size.Height, 0.0f, 1.0f));
            //stereoizedTexture = Make3D(sourceTexture);
            //srv.Dispose();
            //srv = new ShaderResourceView(device, stereoizedTexture);

            //effect.GetVariableByName("tDiffuse").AsResource().SetResource(srv);
            device.OutputMerger.SetTargets(renderView);
            BuildQuad();
            //OnDeviceResize(new ResizeEventArgs(previousSize, newSize, fullScreen));

            //OnDeviceResume(EventArgs.Empty);
            Console.WriteLine("here");
        }
Example #56
0
        public void BuildPSO(Device3 device, GraphicsCommandList commandList)
        {
            buffer[0].World = Matrix.Translation(-2.5f, -2.5f, -2.5f);
            buffer[1].World = Matrix.Translation(2.5f, 2.5f, 2.5f);
            light           = new Lighting
            {
                GlobalAmbientX = 1,
                GlobalAmbientY = 1,
                GlobalAmbientZ = 1,
                KaX            = .1f,
                KaY            = .1f,
                KaZ            = .1f,
                KdX            = .5f,
                KdY            = .5f,
                KdZ            = .5f,
                KeX            = .25f,
                KeY            = .25f,
                KeZ            = .25f,
                KsX            = .1f,
                KsY            = .1f,
                KsZ            = .1f,
                LightColorX    = 1,
                LightColorY    = 1,
                LightColorZ    = 1,
                LightPositionX = 10,
                LightPositionY = 10,
                LightPositionZ = 10,
                shininess      = 5
            };

            DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc);

            //setup descriptor ranges
            DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange()
                                                               {
                                                                   RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0
                                                               } };

            //Get sampler state setup
            StaticSamplerDescription sampler = new StaticSamplerDescription()
            {
                Filter           = Filter.MinimumMinMagMipPoint,
                AddressU         = TextureAddressMode.Border,
                AddressV         = TextureAddressMode.Border,
                AddressW         = TextureAddressMode.Border,
                MipLODBias       = 0,
                MaxAnisotropy    = 0,
                ComparisonFunc   = Comparison.Never,
                BorderColor      = StaticBorderColor.TransparentBlack,
                MinLOD           = 0.0f,
                MaxLOD           = float.MaxValue,
                ShaderRegister   = 0,
                RegisterSpace    = 0,
                ShaderVisibility = ShaderVisibility.Pixel,
            };

            Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000);
            View       = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY);
            World      = Matrix.Translation(-2.5f, -2.5f, -2.5f);

            DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Flags           = DescriptorHeapFlags.ShaderVisible,
                Type            = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView
            };

            _objectViewHeap   = device.CreateDescriptorHeap(cbvHeapDesc);
            _lightingViewHeap = device.CreateDescriptorHeap(cbvHeapDesc);

            RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges),
                                                                   new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView),
                                                                   new RootParameter(ShaderVisibility.All, new RootDescriptor(2, 0), RootParameterType.ConstantBufferView) };


            // Create an empty root signature.
            RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler });

            _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize());

            // Create the pipeline state, which includes compiling and loading shaders.

#if DEBUG
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "VSMain", "vs_5_0"));
#endif

#if DEBUG
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug));
#else
            var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitPixel.hlsl", "PSMain", "ps_5_0"));
#endif

            // Define the vertex input layout.
            InputElement[] inputElementDescs = new InputElement[]
            {
                new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0)
            };

            // Describe and create the graphics pipeline state object (PSO).
            GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription()
            {
                InputLayout           = new InputLayoutDescription(inputElementDescs),
                RootSignature         = _rootSignature,
                VertexShader          = vertexShader,
                PixelShader           = pixelShader,
                RasterizerState       = RasterizerStateDescription.Default(),
                BlendState            = BlendStateDescription.Default(),
                DepthStencilFormat    = SharpDX.DXGI.Format.D24_UNorm_S8_UInt,
                DepthStencilState     = DepthStencilStateDescription.Default(),
                SampleMask            = int.MaxValue,
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                Flags             = PipelineStateFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                StreamOutput      = new StreamOutputDescription()
            };
            psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm;

            _pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            // Define the geometry for a triangle.
            Vertex[] triangleVertices = new Vertex[]
            {
                //Front
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitZ
                },

                //Back
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitZ
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitZ
                },

                //Left
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitX
                },

                //Right
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitX
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitX
                },

                //Top
                new Vertex()
                {
                    Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitY
                },

                //Bottom
                new Vertex()
                {
                    Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitY
                },
                new Vertex()
                {
                    Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitY
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            // Note: using upload heaps to transfer static data like vert buffers is not
            // recommended. Every time the GPU needs it, the upload heap will be marshalled
            // over. Please read up on Default Heap usage. An upload heap is used here for
            // code simplicity and because there are very few verts to actually transfer.
            _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);

            // Copy the triangle data to the vertex buffer.
            IntPtr pVertexDataBegin = _vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            _vertexBuffer.Unmap(0);

            _indicies = new int[] { 0, 1, 2,
                                    3, 2, 1,
                                    6, 5, 4,
                                    5, 6, 7,

                                    10, 9, 8,
                                    9, 10, 11,
                                    12, 13, 14,
                                    15, 14, 13,

                                    18, 17, 16,
                                    17, 18, 19,
                                    20, 21, 22,
                                    23, 22, 21 };

            int indBufferSize = Utilities.SizeOf(_indicies);

            _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead);

            IntPtr pIndBegin = _indexBuffer.Map(0);
            Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length);
            _indexBuffer.Unmap(0);

            _indexBufferView = new IndexBufferView()
            {
                BufferLocation = _indexBuffer.GPUVirtualAddress,
                Format         = Format.R32_UInt,
                SizeInBytes    = indBufferSize
            };

            // Initialize the vertex buffer view.
            _vertexBufferView = new VertexBufferView
            {
                BufferLocation = _vertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = vertexBufferSize
            };

            _objectBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(((Utilities.SizeOf <ObjectData>() + 255) & ~255) * 2), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = _objectBuffer.GPUVirtualAddress,
                SizeInBytes    = ((Utilities.SizeOf <ObjectData>() + 255) & ~255) * 2
            };
            device.CreateConstantBufferView(cbvDesc, _objectViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _objectPointer = _objectBuffer.Map(0);

            _lightingBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <Lighting>()), ResourceStates.GenericRead);

            //// Describe and create a constant buffer view.
            ConstantBufferViewDescription cbvDesc2 = new ConstantBufferViewDescription()
            {
                BufferLocation = _objectBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <Lighting>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbvDesc2, _lightingViewHeap.CPUDescriptorHandleForHeapStart);

            // Initialize and map the constant buffers. We don't unmap this until the
            // app closes. Keeping things mapped for the lifetime of the resource is okay.
            _lightingPointer = _lightingBuffer.Map(0);
            Utilities.Write(_lightingPointer, ref light);

            Resource textureUploadHeap;

            // Create the texture.
            // Describe and create a Texture2D.
            ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight);
            _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination);

            long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1);

            // Create the GPU upload buffer.
            textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = GenerateTextureData();

            GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
            textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length);
            handle.Free();

            commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null);

            commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource);

            // Describe and create a SRV for the texture.
            ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription()
            {
                Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3),
                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
            };
            srvDesc.Texture2D.MipLevels = 1;

            device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart);

            _resources = new[] { new GraphicsResource()
                                 {
                                     Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _objectBuffer, Register = 2, type = ResourceType.ConstantBufferView
                                 },
                                 new GraphicsResource()
                                 {
                                     Resource = _lightingBuffer, Register = 1, type = ResourceType.ConstantBufferView
                                 } };
        }
Example #57
0
        public bool Initialize(DSystemConfiguration configuration, IntPtr windowHandle)
        {
            try
            {
                #region Environment Configuration
                // Store the vsync setting.
                VerticalSyncEnabled = DSystemConfiguration.VerticalSyncEnabled;

                // Create a DirectX graphics interface factory.
                var factory = new Factory1();

                // Use the factory to create an adapter for the primary graphics interface (video card).
                var adapter = factory.GetAdapter1(0);

                // Get the primary adapter output (monitor).
                var monitor = adapter.GetOutput(0);

                // Get modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor).
                var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced);

                // Now go through all the display modes and find the one that matches the screen width and height.
                // When a match is found store the the refresh rate for that monitor, if vertical sync is enabled.
                // Otherwise we use maximum refresh rate.
                var rational = new Rational(0, 1);
                if (VerticalSyncEnabled)
                {
                    foreach (var mode in modes)
                    {
                        if (mode.Width == configuration.Width && mode.Height == configuration.Height)
                        {
                            rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator);
                            break;
                        }
                    }
                }

                // Get the adapter (video card) description.
                var adapterDescription = adapter.Description;

                // Store the dedicated video card memory in megabytes.
                VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10;

                // Convert the name of the video card to a character array and store it.
                VideoCardDescription = adapterDescription.Description.Trim('\0');

                // Release the adapter output.
                monitor.Dispose();
                // Release the adapter.
                adapter.Dispose();
                // Release the factory.
                factory.Dispose();
                #endregion

                #region Initialize swap chain and d3d device
                // Initialize the swap chain description.
                var swapChainDesc = new SwapChainDescription()
                {
                    // Set to a single back buffer.
                    BufferCount = 1,
                    // Set the width and height of the back buffer.
                    ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm)
                    {
                        Scaling = DisplayModeScaling.Unspecified, ScanlineOrdering = DisplayModeScanlineOrder.Unspecified
                    },
                    // Set the usage of the back buffer.
                    Usage = Usage.RenderTargetOutput,
                    // Set the handle for the window to render to.
                    OutputHandle = windowHandle,
                    // Turn multisampling off.
                    SampleDescription = new SampleDescription(1, 0),
                    // Set to full screen or windowed mode.
                    IsWindowed = !DSystemConfiguration.FullScreen,
                    // Don't set the advanced flags.
                    Flags = SwapChainFlags.None,
                    // Discard the back buffer content after presenting.
                    SwapEffect = SwapEffect.Discard
                };

                // Create the swap chain, Direct3D device, and Direct3D device context.
                SharpDX.Direct3D11.Device device;
                SwapChain swapChain;
                SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain);

                Device        = device;
                SwapChain     = swapChain;
                DeviceContext = device.ImmediateContext;
                #endregion

                #region Initialize buffers
                // Get the pointer to the back buffer.
                var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0);

                // Create the render target view with the back buffer pointer.
                RenderTargetView = new RenderTargetView(device, backBuffer);

                // Release pointer to the back buffer as we no longer need it.
                backBuffer.Dispose();

                // Initialize and set up the description of the depth buffer.
                var depthBufferDesc = new Texture2DDescription()
                {
                    Width             = configuration.Width,
                    Height            = configuration.Height,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    Format            = Format.D24_UNorm_S8_UInt,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    BindFlags         = BindFlags.DepthStencil,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    OptionFlags       = ResourceOptionFlags.None
                };

                // Create the texture for the depth buffer using the filled out description.
                DepthStencilBuffer = new Texture2D(device, depthBufferDesc);
                #endregion

                #region Initialize Depth Enabled Stencil
                // Initialize and set up the description of the stencil state.
                var depthStencilDesc = new DepthStencilStateDescription()
                {
                    IsDepthEnabled   = true,
                    DepthWriteMask   = DepthWriteMask.All,
                    DepthComparison  = Comparison.Less,
                    IsStencilEnabled = true,
                    StencilReadMask  = 0xFF,
                    StencilWriteMask = 0xFF,
                    // Stencil operation if pixel front-facing.
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    },
                    // Stencil operation if pixel is back-facing.
                    BackFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    }
                };

                // Create the depth stencil state.
                DepthStencilState = new DepthStencilState(Device, depthStencilDesc);

                // Set the depth stencil state.
                DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1);
                #endregion

                #region Initialize Output Merger
                // Initialize and set up the depth stencil view.
                var depthStencilViewDesc = new DepthStencilViewDescription()
                {
                    Format    = Format.D24_UNorm_S8_UInt,
                    Dimension = DepthStencilViewDimension.Texture2D,
                    Texture2D = new DepthStencilViewDescription.Texture2DResource()
                    {
                        MipSlice = 0
                    }
                };

                // Create the depth stencil view.
                DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc);

                // Bind the render target view and depth stencil buffer to the output render pipeline.
                DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView);
                #endregion

                #region Initialize Raster State
                // Setup the raster description which will determine how and what polygon will be drawn.
                var rasterDesc = new RasterizerStateDescription()
                {
                    IsAntialiasedLineEnabled = false,
                    CullMode                = CullMode.Back,
                    DepthBias               = 0,
                    DepthBiasClamp          = .0f,
                    IsDepthClipEnabled      = true,
                    FillMode                = FillMode.Solid,
                    IsFrontCounterClockwise = false,
                    IsMultisampleEnabled    = false,
                    IsScissorEnabled        = false,
                    SlopeScaledDepthBias    = .0f
                };

                // Create the rasterizer state from the description we just filled out.
                RasterState = new RasterizerState(Device, rasterDesc);

                // Now set the rasterizer state.
                DeviceContext.Rasterizer.State = RasterState;

                // Setup a raster description which turns off back face culling.
                var rasterNoCullDesc = new RasterizerStateDescription()
                {
                    IsAntialiasedLineEnabled = false,
                    CullMode                = CullMode.None,
                    DepthBias               = 0,
                    DepthBiasClamp          = .0f,
                    IsDepthClipEnabled      = true,
                    FillMode                = FillMode.Solid,
                    IsFrontCounterClockwise = false,
                    IsMultisampleEnabled    = false,
                    IsScissorEnabled        = false,
                    SlopeScaledDepthBias    = .0f
                };

                // Create the no culling rasterizer state.
                RasterStateNoCulling = new RasterizerState(Device, rasterNoCullDesc);
                #endregion

                #region Initialize Rasterizer

                ViewPort = new ViewportF(0.0f, 0.0f, (float)configuration.Width, (float)configuration.Height, 0.0f, 1.0f);

                // Setup and create the viewport for rendering.
                DeviceContext.Rasterizer.SetViewport(ViewPort);
                #endregion

                #region Initialize matrices
                // Setup and create the projection matrix.
                ProjectionMatrix = Matrix.PerspectiveFovLH((float)(Math.PI / 4), ((float)configuration.Width / configuration.Height), DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth);

                // Initialize the world matrix to the identity matrix.
                WorldMatrix = Matrix.Identity;

                // Create an orthographic projection matrix for 2D rendering.
                OrthoMatrix = Matrix.OrthoLH(configuration.Width, configuration.Height, DSystemConfiguration.ScreenNear, DSystemConfiguration.ScreenDepth);
                #endregion

                #region Initialize Depth Disabled Stencil
                // Now create a second depth stencil state which turns off the Z buffer for 2D rendering. Added in Tutorial 11
                // The difference is that DepthEnable is set to false.
                // All other parameters are the same as the other depth stencil state.
                var depthDisabledStencilDesc = new DepthStencilStateDescription()
                {
                    IsDepthEnabled   = false,
                    DepthWriteMask   = DepthWriteMask.All,
                    DepthComparison  = Comparison.Less,
                    IsStencilEnabled = true,
                    StencilReadMask  = 0xFF,
                    StencilWriteMask = 0xFF,
                    // Stencil operation if pixel front-facing.
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    },
                    // Stencil operation if pixel is back-facing.
                    BackFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    }
                };

                // Create the depth stencil state.
                DepthDisabledStencilState = new DepthStencilState(Device, depthDisabledStencilDesc);
                #endregion

                #region Initialize Blend States
                // Create an alpha enabled blend state description.
                var blendStateDesc = new BlendStateDescription();
                blendStateDesc.RenderTarget[0].IsBlendEnabled        = true;
                blendStateDesc.RenderTarget[0].SourceBlend           = BlendOption.One;
                blendStateDesc.RenderTarget[0].DestinationBlend      = BlendOption.InverseSourceAlpha;
                blendStateDesc.RenderTarget[0].BlendOperation        = BlendOperation.Add;
                blendStateDesc.RenderTarget[0].SourceAlphaBlend      = BlendOption.One;
                blendStateDesc.RenderTarget[0].DestinationAlphaBlend = BlendOption.Zero;
                blendStateDesc.RenderTarget[0].AlphaBlendOperation   = BlendOperation.Add;
                blendStateDesc.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All;

                // Create the blend state using the description.
                AlphaEnableBlendingState = new BlendState(device, blendStateDesc);

                // Modify the description to create an disabled blend state description.
                blendStateDesc.RenderTarget[0].IsBlendEnabled = false;

                // Create the blend state using the description.
                AlphaDisableBlendingState = new BlendState(device, blendStateDesc);
                #endregion

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
Example #58
0
        internal static void Modify(RasterizerId id, RasterizerStateDescription desc)
        {
            RasterizerStates.Data[id.Index] = desc;

            InitRasterizerState(id);
        }
Example #59
0
        // Methods
        public bool Initialize(DSystemConfiguration configuration, IntPtr windowHandle)
        {
            try
            {
                // Store the vsync setting.
                VerticalSyncEnabled = DSystemConfiguration.VerticalSyncEnabled;

                // Create a DirectX graphics interface factory.
                var factory = new Factory1();

                // Use the factory to create an adapter for the primary graphics interface (video card).
                var adapter = factory.GetAdapter1(0);

                // Get the primary adapter output (monitor).
                var monitor = adapter.GetOutput(0);

                // Get modes that fit the DXGI_FORMAT_R8G8B8A8_UNORM display format for the adapter output (monitor).
                var modes = monitor.GetDisplayModeList(Format.R8G8B8A8_UNorm, DisplayModeEnumerationFlags.Interlaced);

                // Now go through all the display modes and find the one that matches the screen width and height.
                // When a match is found store the the refresh rate for that monitor, if vertical sync is enabled.
                // Otherwise we use maximum refresh rate.
                var rational = new Rational(0, 1);
                if (VerticalSyncEnabled)
                {
                    foreach (var mode in modes)
                    {
                        if (mode.Width == configuration.Width && mode.Height == configuration.Height)
                        {
                            rational = new Rational(mode.RefreshRate.Numerator, mode.RefreshRate.Denominator);
                            break;
                        }
                    }
                }

                // Get the adapter (video card) description.
                var adapterDescription = adapter.Description;

                // Store the dedicated video card memory in megabytes.
                VideoCardMemory = adapterDescription.DedicatedVideoMemory >> 10 >> 10;

                // Convert the name of the video card to a character array and store it.
                VideoCardDescription = adapterDescription.Description;

                // Release the adapter output.
                monitor.Dispose();
                // Release the adapter.
                adapter.Dispose();
                // Release the factory.
                factory.Dispose();

                // Initialize the swap chain description.
                var swapChainDesc = new SwapChainDescription()
                {
                    // Set to a single back buffer.
                    BufferCount = 1,
                    // Set the width and height of the back buffer.
                    ModeDescription = new ModeDescription(configuration.Width, configuration.Height, rational, Format.R8G8B8A8_UNorm),
                    // Set the usage of the back buffer.
                    Usage = Usage.RenderTargetOutput,
                    // Set the handle for the window to render to.
                    OutputHandle = windowHandle,
                    // Turn multisampling off.
                    SampleDescription = new SampleDescription(1, 0),
                    // Set to full screen or windowed mode.
                    IsWindowed = !DSystemConfiguration.FullScreen,
                    // Don't set the advanced flags.
                    Flags = SwapChainFlags.None,
                    // Discard the back buffer content after presenting.
                    SwapEffect = SwapEffect.Discard
                };

                // Create the swap chain, Direct3D device, and Direct3D device context.
                SharpDX.Direct3D11.Device device;
                SwapChain swapChain;
                SharpDX.Direct3D11.Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, swapChainDesc, out device, out swapChain);

                Device        = device;
                SwapChain     = swapChain;
                DeviceContext = device.ImmediateContext;

                // Get the pointer to the back buffer.
                var backBuffer = Texture2D.FromSwapChain <Texture2D>(SwapChain, 0);

                // Create the render target view with the back buffer pointer.
                RenderTargetView = new RenderTargetView(device, backBuffer);

                // Release pointer to the back buffer as we no longer need it.
                backBuffer.Dispose();

                // Initialize and set up the description of the depth buffer.
                var depthBufferDesc = new Texture2DDescription()
                {
                    Width             = configuration.Width,
                    Height            = configuration.Height,
                    MipLevels         = 1,
                    ArraySize         = 1,
                    Format            = Format.D24_UNorm_S8_UInt,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default,
                    BindFlags         = BindFlags.DepthStencil,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    OptionFlags       = ResourceOptionFlags.None
                };

                // Create the texture for the depth buffer using the filled out description.
                DepthStencilBuffer = new Texture2D(device, depthBufferDesc);

                // Initialize and set up the description of the stencil state.
                var depthStencilDesc = new DepthStencilStateDescription()
                {
                    IsDepthEnabled   = true,
                    DepthWriteMask   = DepthWriteMask.All,
                    DepthComparison  = Comparison.Less,
                    IsStencilEnabled = true,
                    StencilReadMask  = 0xFF,
                    StencilWriteMask = 0xFF,
                    // Stencil operation if pixel front-facing.
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    },
                    // Stencil operation if pixel is back-facing.
                    BackFace = new DepthStencilOperationDescription()
                    {
                        FailOperation      = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement,
                        PassOperation      = StencilOperation.Keep,
                        Comparison         = Comparison.Always
                    }
                };

                // Create the depth stencil state.
                DepthStencilState = new DepthStencilState(Device, depthStencilDesc);

                // Set the depth stencil state.
                DeviceContext.OutputMerger.SetDepthStencilState(DepthStencilState, 1);

                // Initialize and set up the depth stencil view.
                var depthStencilViewDesc = new DepthStencilViewDescription()
                {
                    Format    = Format.D24_UNorm_S8_UInt,
                    Dimension = DepthStencilViewDimension.Texture2D,
                    Texture2D = new DepthStencilViewDescription.Texture2DResource()
                    {
                        MipSlice = 0
                    }
                };

                // Create the depth stencil view.
                DepthStencilView = new DepthStencilView(Device, DepthStencilBuffer, depthStencilViewDesc);

                // Bind the render target view and depth stencil buffer to the output render pipeline.
                DeviceContext.OutputMerger.SetTargets(DepthStencilView, RenderTargetView);

                // Setup the raster description which will determine how and what polygon will be drawn.
                var rasterDesc = new RasterizerStateDescription()
                {
                    IsAntialiasedLineEnabled = false,
                    CullMode                = CullMode.Back,
                    DepthBias               = 0,
                    DepthBiasClamp          = .0f,
                    IsDepthClipEnabled      = true,
                    FillMode                = FillMode.Solid,
                    IsFrontCounterClockwise = false,
                    IsMultisampleEnabled    = false,
                    IsScissorEnabled        = false,
                    SlopeScaledDepthBias    = .0f
                };

                // Create the rasterizer state from the description we just filled out.
                RasterState = new RasterizerState(Device, rasterDesc);

                // Now set the rasterizer state.
                DeviceContext.Rasterizer.State = RasterState;

                // Setup and create the viewport for rendering.
                DeviceContext.Rasterizer.SetViewport(0, 0, configuration.Width, configuration.Height, 0, 1);
                return(true);
            }
            catch
            {
                return(false);
            }
        }
Example #60
0
        private void BuildPSOs()
        {
            //
            // PSO for opaque objects.
            //

            var opaquePsoDesc = new GraphicsPipelineStateDescription
            {
                InputLayout           = _inputLayout,
                RootSignature         = _rootSignature,
                VertexShader          = _shaders["standardVS"],
                PixelShader           = _shaders["opaquePS"],
                RasterizerState       = RasterizerStateDescription.Default(),
                BlendState            = BlendStateDescription.Default(),
                DepthStencilState     = DepthStencilStateDescription.Default(),
                SampleMask            = unchecked ((int)uint.MaxValue),
                PrimitiveTopologyType = PrimitiveTopologyType.Triangle,
                RenderTargetCount     = 1,
                SampleDescription     = new SampleDescription(MsaaCount, MsaaQuality),
                DepthStencilFormat    = DepthStencilFormat
            };

            opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat;
            _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc);

            //
            // PSO for shadow map pass.
            //

            var smapPsoDesc = opaquePsoDesc.Copy();

            smapPsoDesc.RasterizerState.DepthBias            = 100000;
            smapPsoDesc.RasterizerState.DepthBiasClamp       = 0.0f;
            smapPsoDesc.RasterizerState.SlopeScaledDepthBias = 1.0f;
            smapPsoDesc.VertexShader = _shaders["shadowVS"];
            smapPsoDesc.PixelShader  = _shaders["shadowOpaquePS"];
            // Shadow map pass does not have a render target.
            smapPsoDesc.RenderTargetFormats[0] = Format.Unknown;
            smapPsoDesc.RenderTargetCount      = 0;
            _psos["shadow_opaque"]             = Device.CreateGraphicsPipelineState(smapPsoDesc);

            //
            // PSO for debug layer.
            //

            var debugPsoDesc = opaquePsoDesc.Copy();

            debugPsoDesc.VertexShader = _shaders["debugVS"];
            debugPsoDesc.PixelShader  = _shaders["debugPS"];
            _psos["debug"]            = Device.CreateGraphicsPipelineState(debugPsoDesc);

            //
            // PSO for sky.
            //

            GraphicsPipelineStateDescription skyPsoDesc = opaquePsoDesc.Copy();

            // The camera is inside the sky sphere, so just turn off culling.
            skyPsoDesc.RasterizerState.CullMode = CullMode.None;
            // Make sure the depth function is LESS_EQUAL and not just LESS.
            // Otherwise, the normalized depth values at z = 1 (NDC) will
            // fail the depth test if the depth buffer was cleared to 1.
            skyPsoDesc.DepthStencilState.DepthComparison = Comparison.LessEqual;
            skyPsoDesc.VertexShader = _shaders["skyVS"];
            skyPsoDesc.PixelShader  = _shaders["skyPS"];
            _psos["sky"]            = Device.CreateGraphicsPipelineState(skyPsoDesc);
        }