Exemple #1
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (disposing)
                {
                    // Disassociate any shaders after we've destroyed them.
                    if (Graphics.Shaders.GeometryShader.Current == this)
                    {
                        Graphics.Shaders.GeometryShader.Current = null;
                    }

                    if (D3DShader != null)
                    {
                        D3DShader.Dispose();
                    }

                    D3DShader = null;
                }

                _disposed = true;
            }

            base.Dispose(disposing);
        }
Exemple #2
0
        public PathShader(Device device)
        {
            var vertexShaderByteCode = ShaderBytecode.CompileFromFile(FileName, "VS", "vs_4_0", ShaderFlags);
            var pixelShaderByteCode = ShaderBytecode.CompileFromFile(FileName, "PS", "ps_4_0", ShaderFlags);
            var geometryShaderByteCode = ShaderBytecode.CompileFromFile(FileName, "GS", "gs_4_0", ShaderFlags);

            VertexShader = new VertexShader(device, vertexShaderByteCode);
            PixelShader = new PixelShader(device, pixelShaderByteCode);
            GeometryShader = new GeometryShader(device, geometryShaderByteCode);
            Layout = VertexDefinition.Path.GetInputLayout(device, vertexShaderByteCode);

            vertexShaderByteCode.Dispose();
            pixelShaderByteCode.Dispose();
            geometryShaderByteCode.Dispose();

            ConstantMatrixBuffer = new Buffer(device, MatrixBufferDesription);
            ConstantPathDataBuffer = new Buffer(device,
                new BufferDescription
                {
                    Usage = ResourceUsage.Dynamic,
                    SizeInBytes = Utilities.SizeOf<PathData>(),
                    BindFlags = BindFlags.ConstantBuffer,
                    CpuAccessFlags = CpuAccessFlags.Write,
                    OptionFlags = ResourceOptionFlags.None,
                    StructureByteStride = 0
                });
            SamplerState = new SamplerState(device, WrapSamplerStateDescription);
        }
        /// <summary>
        /// Function to convert this geometry shader to use a stream output.
        /// </summary>
        /// <param name="streamOutLayout">The stream output layout for the shader.</param>
        /// <param name="strides">[Optional] A list of strides that define the size of an element for each buffer.</param>
        /// <returns>A new <see cref="GorgonGeometryShader"/> that is capable of stream output.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="streamOutLayout"/> parameter is <b>null</b>.</exception>
        /// <remarks>
        /// <para>
        /// A base geometry shader must be converted to use stream output if an application wants to send data from the shader into a buffer.
        /// </para>
        /// <para>
        /// If the <paramref name="strides"/> parameter is supplied, then it will be limited to 4 items at most, any more than that and the list will be truncated.
        /// </para>
        /// </remarks>
        public GorgonGeometryShader ToStreamOut(GorgonStreamOutLayout streamOutLayout, IEnumerable <int> strides = null)
        {
            if (streamOutLayout == null)
            {
                throw new ArgumentNullException(nameof(streamOutLayout));
            }

            int[] strideList = strides?.Take(4).ToArray() ?? Array.Empty <int>();
            // Clone the byte code just in case we decide to destroy the original.
            var byteCode = new ShaderBytecode(D3DByteCode.Data);

            Graphics.Log.Print($"Converting '{Name}' to Stream-Out.", LoggingLevel.Verbose);

            var shader = new D3D11.GeometryShader(Graphics.D3DDevice, byteCode, streamOutLayout.Native, strideList, 0)
            {
                DebugName = $"{Name}_ID3D11GeometryShader (SO)"
            };
            var result = new GorgonGeometryShader(Graphics, Name + " (SO)", IsDebug, byteCode, shader)
            {
                StreamOutLayout = streamOutLayout
            };

            result.RegisterDisposable(Graphics);

            return(result);
        }
        private Shader(GraphicsDevice device, ShaderStage shaderStage, byte[] shaderBytecode)
            : base(device)
        {
            this.stage = shaderStage;

            switch (shaderStage)
            {
                case ShaderStage.Vertex:
                    NativeDeviceChild = new VertexShader(device.NativeDevice, shaderBytecode);
                    NativeInputSignature = shaderBytecode;
                    break;
                case ShaderStage.Hull:
                    NativeDeviceChild = new HullShader(device.NativeDevice, shaderBytecode);
                    break;
                case ShaderStage.Domain:
                    NativeDeviceChild = new DomainShader(device.NativeDevice, shaderBytecode);
                    break;
                case ShaderStage.Geometry:
                    NativeDeviceChild = new GeometryShader(device.NativeDevice, shaderBytecode);
                    break;
                case ShaderStage.Pixel:
                    NativeDeviceChild = new PixelShader(device.NativeDevice, shaderBytecode);
                    break;
                case ShaderStage.Compute:
                    NativeDeviceChild = new ComputeShader(device.NativeDevice, shaderBytecode);
                    break;
                default:
                    throw new ArgumentOutOfRangeException("shaderStage");
            }
        }
        public ProjectiveTexturingShader(Device device)
        {
            var shaderByteCode = new ShaderBytecode(File.ReadAllBytes("Content/DepthAndProjectiveTextureVS.cso"));
            vertexShader = new VertexShader(device, shaderByteCode);
            geometryShader = new GeometryShader(device, new ShaderBytecode(File.ReadAllBytes("Content/DepthAndColorGS.cso")));
            pixelShader = new PixelShader(device, new ShaderBytecode(File.ReadAllBytes("Content/DepthAndColorPS.cso")));

            // depth stencil state
            var depthStencilStateDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                DepthComparison = Comparison.LessEqual,
                IsStencilEnabled = false,
            };
            depthStencilState = new DepthStencilState(device, depthStencilStateDesc);

            // rasterizer states
            var rasterizerStateDesc = new RasterizerStateDescription()
            {
                CullMode = CullMode.None,
                FillMode = FillMode.Solid,
                IsDepthClipEnabled = true,
                IsFrontCounterClockwise = true,
                IsMultisampleEnabled = true,
            };
            rasterizerState = new RasterizerState(device, rasterizerStateDesc);

            // constant buffer
            var constantBufferDesc = new BufferDescription()
            {
                Usage = ResourceUsage.Dynamic,
                BindFlags = BindFlags.ConstantBuffer,
                SizeInBytes = Constants.size,
                CpuAccessFlags = CpuAccessFlags.Write,
                StructureByteStride = 0,
                OptionFlags = 0,
            };
            constantBuffer = new SharpDX.Direct3D11.Buffer(device, constantBufferDesc);

            // user view sampler state
            var colorSamplerStateDesc = new SamplerStateDescription()
            {
                Filter = Filter.MinMagMipLinear,
                AddressU = TextureAddressMode.Border,
                AddressV = TextureAddressMode.Border,
                AddressW = TextureAddressMode.Border,
                //BorderColor = new SharpDX.Color4(0.5f, 0.5f, 0.5f, 1.0f),
                BorderColor = new SharpDX.Color4(0, 0, 0, 1.0f),
            };
            colorSamplerState = new SamplerState(device, colorSamplerStateDesc);

            vertexInputLayout = new InputLayout(device, shaderByteCode.Data, new[]
            {
                new InputElement("SV_POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
            });

        }
        /// <summary>
        ///
        /// </summary>
        void SetupShadersAndLayouts()
        {
            ps = PixelShader == null ? null : new D3DPixelShader(device.Device, PixelShader.Bytecode);
            vs = VertexShader == null ? null : new D3DVertexShader(device.Device, VertexShader.Bytecode);
            gs = GeometryShader == null ? null : new D3DGeometryShader(device.Device, GeometryShader.Bytecode);
            hs = HullShader == null ? null : new D3DHullShader(device.Device, HullShader.Bytecode);
            ds = DomainShader == null ? null : new D3DDomainShader(device.Device, DomainShader.Bytecode);
            cs = ComputeShader == null ? null : new D3DComputeShader(device.Device, ComputeShader.Bytecode);

            if (cs != null)
            {
                if (ps != null || vs != null || gs != null || hs != null || ds != null)
                {
                    throw new InvalidOperationException("If ComputeShader is set, other shader must be set null.");
                }
            }
            else
            {
                if (vs == null)
                {
                    throw new InvalidOperationException("Vertex shader must be set.");
                }
            }



            if (VertexInputElements == null)
            {
                inputLayout = null;
            }
            else
            {
                inputLayout = new InputLayout(device.Device, VertexShader.Bytecode, VertexInputElement.Convert(VertexInputElements));
            }



            if (VertexOutputElements != null)
            {
                if (GeometryShader == null)
                {
                    throw new InvalidOperationException("Geometry shader is required for vertex output.");
                }

                var outputElements  = VertexOutputElement.Convert(VertexOutputElements);
                int maxBuffers      = outputElements.Max(oe => oe.OutputSlot) + 1;
                var bufferedStrides = new int[maxBuffers];

                for (int i = 0; i < maxBuffers; i++)
                {
                    bufferedStrides[i] = outputElements
                                         .Where(oe1 => oe1.OutputSlot == i)
                                         .Sum(oe2 => oe2.ComponentCount) * 4;
                }

                gs = new D3DGeometryShader(device.Device, GeometryShader.Bytecode, outputElements, bufferedStrides, RasterizedStream);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="GorgonGeometryShader" /> class.
 /// </summary>
 /// <param name="graphics">The graphics interface that owns this object.</param>
 /// <param name="name">The name for this shader.</param>
 /// <param name="isDebug"><b>true</b> if debug information is included in the byte code, <b>false</b> if not.</param>
 /// <param name="byteCode">The byte code for the shader.</param>
 internal GorgonGeometryShader(GorgonGraphics graphics, string name, bool isDebug, ShaderBytecode byteCode)
     : base(graphics, name, isDebug, byteCode)
 {
     graphics.Log.Print($"Creating {ShaderType} '{name}' ({ID})", LoggingLevel.Verbose);
     _shader = new D3D11.GeometryShader(graphics.D3DDevice, byteCode)
     {
         DebugName = name + "_ID3D11GeometryShader"
     };
 }
        private void CreateShaders()
        {
            foreach (var shaderBytecode in effectBytecode.Stages)
            {
                var bytecodeRaw = shaderBytecode.Data;
                var reflection = effectBytecode.Reflection;

                // TODO CACHE Shaders with a bytecode hash
                switch (shaderBytecode.Stage)
                {
                    case ShaderStage.Vertex:
                        vertexShader = new VertexShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        // Note: input signature can be reused when reseting device since it only stores non-GPU data,
                        // so just keep it if it has already been created before.
                        if (inputSignature == null)
                            inputSignature = EffectInputSignature.GetOrCreateLayout(new EffectInputSignature(shaderBytecode.Id, bytecodeRaw));
                        break;
                    case ShaderStage.Domain:
                        domainShader = new DomainShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                    case ShaderStage.Hull:
                        hullShader = new HullShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                    case ShaderStage.Geometry:
                        if (reflection.ShaderStreamOutputDeclarations != null && reflection.ShaderStreamOutputDeclarations.Count > 0)
                        {
                            // Calculate the strides
                            var soStrides = new List<int>();
                            foreach (var streamOutputElement in reflection.ShaderStreamOutputDeclarations)
                            {
                                for (int i = soStrides.Count; i < (streamOutputElement.Stream + 1); i++)
                                {
                                    soStrides.Add(0);
                                }

                                soStrides[streamOutputElement.Stream] += streamOutputElement.ComponentCount * sizeof(float);
                            }
                            var soElements = new StreamOutputElement[0]; // TODO CREATE StreamOutputElement from bytecode.Reflection.ShaderStreamOutputDeclarations
                            geometryShader = new GeometryShader(GraphicsDevice.NativeDevice, bytecodeRaw, soElements, soStrides.ToArray(), reflection.StreamOutputRasterizedStream);
                        }
                        else
                        {
                            geometryShader = new GeometryShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        }
                        break;
                    case ShaderStage.Pixel:
                        pixelShader = new PixelShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                    case ShaderStage.Compute:
                        computeShader = new ComputeShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                }
            }
        }
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public override void Dispose()
        {
            D3D11.GeometryShader shader = Interlocked.Exchange(ref _shader, null);

            if (shader != null)
            {
                Graphics.Log.Print($"Destroying {ShaderType} '{Name}' ({ID})", LoggingLevel.Verbose);
                shader.Dispose();
            }

            base.Dispose();
        }
Exemple #10
0
        public override void Preload(Renderer renderer)
        {
            if (_geometryShader.Get(renderer) == null)
            {
                SharpDX.Direct3D11.GeometryShader shader;

                if (_streamOutType == null)
                {
                    shader = new SharpDX.Direct3D11.GeometryShader(renderer.Device, _shaderByteCode);
                }
                else
                {
                    FieldInfo[]           infos    = _streamOutType.GetFields(BindingFlags.Public | BindingFlags.Instance);
                    StreamOutputElement[] elements = new StreamOutputElement[infos.Length];
                    int[] strides = new int[1] {
                        0
                    };

                    for (int i = 0; i < infos.Length; i++)
                    {
                        FieldInfo info = infos[i];
                        elements[i] = new StreamOutputElement();
                        elements[i].SemanticName = info.Name;

                        if (info.FieldType == typeof(float))
                        {
                            elements[i].ComponentCount = 1;
                        }
                        else if (info.FieldType == typeof(Vector2))
                        {
                            elements[i].ComponentCount = 2;
                        }
                        else if (info.FieldType == typeof(Vector3))
                        {
                            elements[i].ComponentCount = 3;
                        }
                        else if (info.FieldType == typeof(Vector4))
                        {
                            elements[i].ComponentCount = 4;
                        }
                        else
                        {
                            throw new Exception("Unknown element type: " + info.FieldType.ToString());
                        }

                        strides[0] += sizeof(float) * elements[i].ComponentCount; // TODO ...
                    }

                    shader = new SharpDX.Direct3D11.GeometryShader(renderer.Device, _shaderByteCode, elements, strides, 0);
                }
                _geometryShader.Set(renderer, shader, _shaderByteCode.Data.LongLength);
            }
        }
Exemple #11
0
        /// <summary>
        /// Function to create the shader.
        /// </summary>
        /// <param name="byteCode">Byte code for the shader.</param>
        protected override void CreateShader(Compiler.ShaderBytecode byteCode)
        {
            if (D3DShader != null)
            {
                D3DShader.Dispose();
            }

            D3DShader = new D3D.GeometryShader(Graphics.D3DDevice, byteCode)
            {
#if DEBUG
                DebugName = string.Format("Gorgon Geometry Shader '{0}'", Name)
#endif
            };
        }
Exemple #12
0
        public CGeometryShader(ICDevice device, CShaderReflection reflection)
            : base(device, reflection)
        {
            Profile = ParseProfile(reflection.Profile);
            MaxVertexCount = reflection.GetMaxVertexCount();
            InputPrimitiveType = reflection.GetGeometryInputPrimitiveType();
            OutputPrimitiveType = reflection.GetGeometryOutputPrimitiveType();

            var text = GenerateText<CGeometryShader>(WriteIOAndCode);
            CompilationResult bytecode;
            try
            {
                bytecode = ShaderBytecode.Compile(text, "main", ProfileToString(Profile),
                    ShaderFlags.PackMatrixColumnMajor | ShaderFlags.OptimizationLevel3, EffectFlags.None, Name);
            }
            catch (Exception e)
            {
                throw new ArgumentException(string.Format("Failed to compile a geometry shader '{0}'\r\n--- Code ---\r\n{1}\r\n--- Errors ---\r\n{2}", Name, text, e.Message), e);
            }
            D3DGeometryShader = new GeometryShader(device.D3DDevice, bytecode);
        }
Exemple #13
0
        public Shader(string file, D3D11.Device device, D3D11.DeviceContext context, params D3D11.InputElement[] inputElements)
        {
            if (File.Exists(file + "_vs.cso"))
            {
                using (var byteCode = ShaderBytecode.FromFile(file + "_vs.cso")) {
                    Signature    = ShaderSignature.GetInputSignature(byteCode);
                    VertexShader = new D3D11.VertexShader(device, byteCode);
                    InputLayout  = new D3D11.InputLayout(device, Signature, inputElements);
                }
            }

            if (File.Exists(file + "_ps.cso"))
            {
                using (var byteCode = ShaderBytecode.FromFile(file + "_ps.cso"))
                    PixelShader = new D3D11.PixelShader(device, byteCode);
            }

            if (File.Exists(file + "_gs.cso"))
            {
                using (var byteCode = ShaderBytecode.FromFile(file + "_gs.cso"))
                    GeometryShader = new D3D11.GeometryShader(device, byteCode);
            }
        }
Exemple #14
0
 internal DeviceChild GetOrCompileShader(EffectShaderType shaderType, int index)
 {
     DeviceChild shader = null;
     lock (sync)
     {
         shader = compiledShaders[index];
         if (shader == null)
         {
             var bytecodeRaw = dataGroup.Shaders[index].Bytecode;
             switch (shaderType)
             {
                 case EffectShaderType.Vertex:
                     shader = new VertexShader(graphicsDevice, bytecodeRaw);
                     break;
                 case EffectShaderType.Domain:
                     shader = new DomainShader(graphicsDevice, bytecodeRaw);
                     break;
                 case EffectShaderType.Hull:
                     shader = new HullShader(graphicsDevice, bytecodeRaw);
                     break;
                 case EffectShaderType.Geometry:
                     shader = new GeometryShader(graphicsDevice, bytecodeRaw);
                     break;
                 case EffectShaderType.Pixel:
                     shader = new PixelShader(graphicsDevice, bytecodeRaw);
                     break;
                 case EffectShaderType.Compute:
                     shader = new ComputeShader(graphicsDevice, bytecodeRaw);
                     break;
             }
             compiledShaders[index] = shader;
         }
     }
     return shader;
 }
        protected override void CreateDeviceDependentResources()
        {
            RemoveAndDispose(ref vertexShader);
            RemoveAndDispose(ref vertexShaderInstanced);
            RemoveAndDispose(ref geomShader);
            RemoveAndDispose(ref pixelShader);

            RemoveAndDispose(ref blendState);
            RemoveAndDispose(ref linearSampler);

            RemoveAndDispose(ref perComputeBuffer);
            RemoveAndDispose(ref perFrame);

            // Dispose of any loaded particle textures
            particleTextureSRVs.ForEach(srv => RemoveAndDispose(ref srv));
            particleTextureSRVs.Clear();

            // Dispose of any compute shaders
            computeShaders.Select(kv => kv.Value).ToList().ForEach(cs => RemoveAndDispose(ref cs));
            computeShaders.Clear();

            var device = this.DeviceManager.Direct3DDevice;

            #region Compile Vertex/Pixel/Geometry shaders

            // Compile and create the vertex shader
            using (var vsBytecode = HLSLCompiler.CompileFromFile(@"Shaders\ParticleVS.hlsl", "VSMain", "vs_5_0"))
            using (var vsInstance = HLSLCompiler.CompileFromFile(@"Shaders\ParticleVS.hlsl", "VSMainInstance", "vs_5_0"))
            // Compile and create the pixel shader
            using (var psBytecode = HLSLCompiler.CompileFromFile(@"Shaders\ParticlePS.hlsl", "PSMain", "ps_5_0"))
            // Compile and create the geometry shader
            using (var gsBytecode = HLSLCompiler.CompileFromFile(@"Shaders\ParticleGS.hlsl", "PointToQuadGS", "gs_5_0"))
            {
                vertexShader = ToDispose(new VertexShader(device, vsBytecode));
                vertexShaderInstanced = ToDispose(new VertexShader(device, vsInstance));
                pixelShader = ToDispose(new PixelShader(device, psBytecode));
                geomShader = ToDispose(new GeometryShader(device, gsBytecode));
            }
            #endregion

            #region Blend States
            var blendDesc = new BlendStateDescription() {
                IndependentBlendEnable = false,
                AlphaToCoverageEnable = false,
            };
            // Additive blend state that darkens
            blendDesc.RenderTarget[0] = new RenderTargetBlendDescription
            {
                IsBlendEnabled = true,
                BlendOperation = BlendOperation.Add,
                AlphaBlendOperation = BlendOperation.Add,
                SourceBlend = BlendOption.SourceAlpha,
                DestinationBlend = BlendOption.InverseSourceAlpha,
                SourceAlphaBlend = BlendOption.One,
                DestinationAlphaBlend = BlendOption.Zero,
                RenderTargetWriteMask = ColorWriteMaskFlags.All
            };
            blendState = ToDispose(new BlendState(device, blendDesc));

            // Additive blend state that lightens
            // (needs a dark background)
            blendDesc.RenderTarget[0].DestinationBlend = BlendOption.One;

            blendStateLight = ToDispose(new BlendState(device, blendDesc));
            #endregion

            // depth stencil state to disable Z-buffer
            disableDepthWrite = ToDispose(new DepthStencilState(device, new DepthStencilStateDescription {
                DepthComparison = Comparison.Less,
                DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.Zero,
                IsDepthEnabled = true,
                IsStencilEnabled = false
            }));

            // Create a linear sampler
            linearSampler = ToDispose(new SamplerState(device, new SamplerStateDescription
            {
                AddressU = TextureAddressMode.Wrap,
                AddressV = TextureAddressMode.Wrap,
                AddressW = TextureAddressMode.Wrap,
                Filter = Filter.MinMagMipLinear, // Bilinear
                MaximumLod = float.MaxValue,
                MinimumLod = 0,
            }));

            // Create the per compute shader constant buffer
            perComputeBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ParticleConstants>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));
            // Create the particle frame buffer
            perFrame = ToDispose(new Buffer(device, Utilities.SizeOf<ParticleFrame>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            particleTextureSRVs.Add(ToDispose(ShaderResourceView.FromFile(device, "Particle.png")));
            particleTextureSRVs.Add(ToDispose(ShaderResourceView.FromFile(device, "Snowflake.png")));
            particleTextureSRVs.Add(ToDispose(ShaderResourceView.FromFile(device, "Square.png")));
            activeParticleTextureIndex = 0;

            // Reinitialize particles if > 0
            if (this.Constants.MaxParticles > 0)
            {
                InitializeParticles(this.Constants.MaxParticles, this.Constants.MaxLifetime);
            }
        }
        protected override void CreateDeviceDependentResources(DeviceManager deviceManager)
        {
            base.CreateDeviceDependentResources(deviceManager);

            // Release all resources
            RemoveAndDispose(ref vertexShader);

            RemoveAndDispose(ref pixelShader);
            RemoveAndDispose(ref depthPixelShader);
            RemoveAndDispose(ref lambertShader);
            RemoveAndDispose(ref blinnPhongShader);
            RemoveAndDispose(ref phongShader);

            RemoveAndDispose(ref tessellateVertexShader);
            RemoveAndDispose(ref tessellateTriIntegerShader);
            RemoveAndDispose(ref tessellateTriPow2Shader);
            RemoveAndDispose(ref tessellateTriFractionalEvenShader);
            RemoveAndDispose(ref tessellateTriFractionalOddShader);
            RemoveAndDispose(ref tessellateTriDomainShader);

            RemoveAndDispose(ref tessellatePhongDomainShader);

            RemoveAndDispose(ref debugNormals);

            RemoveAndDispose(ref vertexLayout);
            RemoveAndDispose(ref perObjectBuffer);
            RemoveAndDispose(ref perFrameBuffer);
            RemoveAndDispose(ref perMaterialBuffer);
            RemoveAndDispose(ref perArmatureBuffer);

            RemoveAndDispose(ref depthStencilState);

            // Get a reference to the Device1 instance and immediate context
            var device = deviceManager.Direct3DDevice;
            var context = deviceManager.Direct3DContext;

            // Compile and create the vertex shader and input layout
            using (var vertexShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\VS.hlsl", "VSMain", "vs_5_0"))
            using (var vertexTessBytecode = HLSLCompiler.CompileFromFile(@"Shaders\VS.hlsl", "VSPassThruTessellate", "vs_5_0"))
            {
                vertexShader = ToDispose(new VertexShader(device, vertexShaderBytecode));
                tessellateVertexShader = ToDispose(new VertexShader(device, vertexTessBytecode));

                // Layout from VertexShader input signature
                vertexLayout = ToDispose(new InputLayout(device,
                    vertexShaderBytecode.GetPart(ShaderBytecodePart.InputSignatureBlob),
                    new[]
                {
                    // "SV_Position" = vertex coordinate in object space
                    new InputElement("SV_Position", 0, Format.R32G32B32_Float, 0, 0),
                    // "NORMAL" = the vertex normal
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                    // "COLOR"
                    new InputElement("COLOR", 0, Format.R8G8B8A8_UNorm, 24, 0),
                    // "UV"
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 28, 0),
                    // "BLENDINDICES"
                    new InputElement("BLENDINDICES", 0, Format.R32G32B32A32_UInt, 36, 0),
                    // "BLENDWEIGHT"
                    new InputElement("BLENDWEIGHT", 0, Format.R32G32B32A32_Float, 52, 0),
                }));
            }

            // Compile and create the pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\SimplePS.hlsl", "PSMain", "ps_5_0"))
                pixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the depth vertex and pixel shaders
            // This shader is for checking what the depth buffer would look like
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DepthPS.hlsl", "PSMain", "ps_5_0"))
                depthPixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DiffusePS.hlsl", "PSMain", "ps_5_0"))
                lambertShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\BlinnPhongPS.hlsl", "PSMain", "ps_5_0"))
                blinnPhongShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\PhongPS.hlsl", "PSMain", "ps_5_0"))
                phongShader = ToDispose(new PixelShader(device, bytecode));

            #region Tessellation Shaders

            using (var triIntegerBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellateTri.hlsl", "HS_TrianglesInteger", "hs_5_0", null))
            using (var triPow2Bytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellateTri.hlsl", "HS_TrianglesPow2", "hs_5_0", null))
            using (var triFractionalEvenBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellateTri.hlsl", "HS_TrianglesFractionalEven", "hs_5_0", null))
            using (var triFractionalOddBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellateTri.hlsl", "HS_TrianglesFractionalOdd", "hs_5_0", null))
            using (var triDomainShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellateTri.hlsl", "DS_Triangles", "ds_5_0", null))
            {
                tessellateTriIntegerShader = ToDispose(new HullShader(device, triIntegerBytecode));
                tessellateTriPow2Shader = ToDispose(new HullShader(device, triPow2Bytecode));
                tessellateTriFractionalEvenShader = ToDispose(new HullShader(device, triFractionalEvenBytecode));
                tessellateTriFractionalOddShader = ToDispose(new HullShader(device, triFractionalOddBytecode));
                tessellateTriDomainShader = ToDispose(new DomainShader(device, triDomainShaderBytecode));
            }

            using (var phongDomainShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellatePhong.hlsl", "DS_PhongTessellation", "ds_5_0", null))
            {
                tessellatePhongDomainShader = ToDispose(new DomainShader(device, phongDomainShaderBytecode));
            }

            using (var pnTriIntegerBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellatePNTri.hlsl", "HS_PNTrianglesInteger", "hs_5_0", null))
            using (var pnTriPow2Bytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellatePNTri.hlsl", "HS_PNTrianglesPow2", "hs_5_0", null))
            using (var pnTriFractionalEvenBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellatePNTri.hlsl", "HS_PNTrianglesFractionalEven", "hs_5_0", null))
            using (var pnTriFractionalOddBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellatePNTri.hlsl", "HS_PNTrianglesFractionalOdd", "hs_5_0", null))
            using (var pnTriDomainShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\TessellatePNTri.hlsl", "DS_PNTriangles", "ds_5_0", null))
            {
                pnTriIntegerShader = ToDispose(new HullShader(device, pnTriIntegerBytecode));
                pnTriPow2Shader = ToDispose(new HullShader(device, pnTriPow2Bytecode));
                pnTriFractionalEvenShader = ToDispose(new HullShader(device, pnTriFractionalEvenBytecode));
                pnTriFractionalOddShader = ToDispose(new HullShader(device, pnTriFractionalOddBytecode));
                pnTriDomainShader = ToDispose(new DomainShader(device, pnTriDomainShaderBytecode));
            }

            using (var geomShaderByteCode = HLSLCompiler.CompileFromFile(@"Shaders\GS_DebugNormals.hlsl", "GSMain", "gs_5_0", null))
            {
                debugNormals = ToDispose(new GeometryShader(device, geomShaderByteCode));
            }

            #endregion

            // IMPORTANT: A constant buffer's size must be a multiple of 16-bytes
            // use LayoutKind.Explicit and an explicit Size= to force this for structures
            // or alternatively add padding fields and use a LayoutKind.Sequential and Pack=1

            // Create the constant buffer that will
            // store our worldViewProjection matrix
            perObjectBuffer = ToDispose(new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf<ConstantBuffers.PerObject>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per frame constant buffer
            // lighting / camera position
            perFrameBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerFrame>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per material constant buffer
            perMaterialBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerMaterial>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per armature/skeletong constant buffer
            perArmatureBuffer = ToDispose(new Buffer(device, ConstantBuffers.PerArmature.Size(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Configure the depth buffer to discard pixels that are
            // further than the current pixel.
            depthStencilState = ToDispose(new DepthStencilState(device,
                new DepthStencilStateDescription()
                {
                    IsDepthEnabled = true, // enable depth?
                    DepthComparison = Comparison.Less,
                    DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,
                    IsStencilEnabled = false,// enable stencil?
                    StencilReadMask = 0xff, // 0xff (no mask)
                    StencilWriteMask = 0xff,// 0xff (no mask)
                    // Configure FrontFace depth/stencil operations
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment
                    },
                    // Configure BackFace depth/stencil operations
                    BackFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement
                    },
                }));

            // Tell the IA what the vertices will look like
            // in this case two 4-component 32bit floats
            // (32 bytes in total)
            context.InputAssembler.InputLayout = vertexLayout;

            // Set our constant buffer (to store worldViewProjection)
            context.VertexShader.SetConstantBuffer(0, perObjectBuffer);
            context.VertexShader.SetConstantBuffer(1, perFrameBuffer);
            context.VertexShader.SetConstantBuffer(2, perMaterialBuffer);
            context.VertexShader.SetConstantBuffer(3, perArmatureBuffer);

            // Set the vertex shader to run
            context.VertexShader.Set(vertexShader);

            // Set our hull shader constant buffers
            context.HullShader.SetConstantBuffer(0, perObjectBuffer);
            context.HullShader.SetConstantBuffer(1, perFrameBuffer);

            // Set default Hull Shader
            context.HullShader.Set(tessellateTriIntegerShader);

            context.DomainShader.SetConstantBuffer(0, perObjectBuffer);
            context.DomainShader.SetConstantBuffer(1, perFrameBuffer);
            context.DomainShader.Set(tessellateTriDomainShader);

            // Set gemoetry shader buffers
            context.GeometryShader.SetConstantBuffer(0, perObjectBuffer);
            context.GeometryShader.SetConstantBuffer(1, perFrameBuffer);

            // Set our pixel constant buffers
            context.PixelShader.SetConstantBuffer(1, perFrameBuffer);
            context.PixelShader.SetConstantBuffer(2, perMaterialBuffer);

            // Set the pixel shader to run
            context.PixelShader.Set(blinnPhongShader);

            // Set our depth stencil state
            context.OutputMerger.DepthStencilState = depthStencilState;

            // No culling
            context.Rasterizer.State = ToDispose(new RasterizerState(device, new RasterizerStateDescription()
            {
                FillMode = FillMode.Solid,
                CullMode = CullMode.None
            }));
        }
        protected override void CreateDeviceDependentResources(DeviceManager deviceManager)
        {
            base.CreateDeviceDependentResources(deviceManager);

            // Release all resources
            RemoveAndDispose(ref vertexShader);

            //RemoveAndDispose(ref depthPixelShader);
            //RemoveAndDispose(ref depthPixelShaderBytecode);
            //RemoveAndDispose(ref lambertShader);

            RemoveAndDispose(ref blinnPhongShader);

            RemoveAndDispose(ref envMapVSShader);
            RemoveAndDispose(ref envMapGSShader);
            RemoveAndDispose(ref envMapPSShader);

            RemoveAndDispose(ref vertexLayout);
            RemoveAndDispose(ref perObjectBuffer);
            RemoveAndDispose(ref perFrameBuffer);
            RemoveAndDispose(ref perMaterialBuffer);
            RemoveAndDispose(ref perArmatureBuffer);

            RemoveAndDispose(ref depthStencilState);

            RemoveAndDispose(ref rasterizerState);

            // Get a reference to the Device1 instance and immediate context
            var device = deviceManager.Direct3DDevice;
            var context = deviceManager.Direct3DContext;

            // Compile and create the vertex shader and input layout
            using (var vertexShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\VS.hlsl", "VSMain", "vs_5_0"))
            {
                vertexShader = ToDispose(new VertexShader(device, vertexShaderBytecode));
                // Layout from VertexShader input signature
                vertexLayout = ToDispose(new InputLayout(device,
                    vertexShaderBytecode.GetPart(ShaderBytecodePart.InputSignatureBlob),
                new[]
                {
                    // "SV_Position" = vertex coordinate in object space
                    new InputElement("SV_Position", 0, Format.R32G32B32_Float, 0, 0),
                    // "NORMAL" = the vertex normal
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                    // "COLOR"
                    new InputElement("COLOR", 0, Format.R8G8B8A8_UNorm, 24, 0),
                    // "UV"
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 28, 0),
                    // "SkinIndices"
                    new InputElement("BLENDINDICES", 0, Format.R32G32B32A32_UInt, 36, 0),
                    // "SkinWeights"
                    new InputElement("BLENDWEIGHT", 0, Format.R32G32B32A32_Float, 52, 0),
                }));
            }

            // Compile and create the pixel shader
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\SimplePS.hlsl", "PSMain", "ps_5_0"))
            //    pixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the depth vertex and pixel shaders
            // This shader is for checking what the depth buffer would look like
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DepthPS.hlsl", "PSMain", "ps_5_0"))
            //    depthPixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DiffusePS.hlsl", "PSMain", "ps_5_0"))
            //    lambertShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the blinn phong pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\BlinnPhongPS.hlsl", "PSMain", "ps_5_0"))
                blinnPhongShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            //using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\PhongPS.hlsl", "PSMain", "ps_5_0"))
            //    phongShader = ToDispose(new PixelShader(device, bytecode));

            // Compile CubeMap VS and GS shaders
            using (var vsBytecode = HLSLCompiler.CompileFromFile(@"Shaders\CubeMap.hlsl", "VS_CubeMap", "vs_5_0", null))
            using (var gsBytecode = HLSLCompiler.CompileFromFile(@"Shaders\CubeMap.hlsl", "GS_CubeMap", "gs_5_0", null))
            using (var psBytecode = HLSLCompiler.CompileFromFile(@"Shaders\CubeMap.hlsl", "PS_CubeMap", "ps_5_0", null))
            {
                envMapVSShader = ToDispose(new VertexShader(device, vsBytecode));
                envMapGSShader = ToDispose(new GeometryShader(device, gsBytecode));
                envMapPSShader = ToDispose(new PixelShader(device, psBytecode));
            }

            // IMPORTANT: A constant buffer's size must be a multiple of 16-bytes
            // use LayoutKind.Explicit and an explicit Size= to force this for structures
            // or alternatively add padding fields and use a LayoutKind.Sequential and Pack=1

            // Create the constant buffer that will
            // store our worldViewProjection matrix
            perObjectBuffer = ToDispose(new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf<ConstantBuffers.PerObject>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per frame constant buffer
            // lighting / camera position
            perFrameBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerFrame>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per material constant buffer
            perMaterialBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerMaterial>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per armature/skeletong constant buffer
            perArmatureBuffer = ToDispose(new Buffer(device, ConstantBuffers.PerArmature.Size(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Configure the depth buffer to discard pixels that are
            // further than the current pixel.
            depthStencilState = ToDispose(new DepthStencilState(device,
                new DepthStencilStateDescription()
                {
                    IsDepthEnabled = true, // enable depth?
                    DepthComparison = Comparison.Less,
                    DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,
                    IsStencilEnabled = false,// enable stencil?
                    StencilReadMask = 0xff, // 0xff (no mask)
                    StencilWriteMask = 0xff,// 0xff (no mask)
                    // Configure FrontFace depth/stencil operations
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment
                    },
                    // Configure BackFace depth/stencil operations
                    BackFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement
                    },
                }));

            rasterizerState = ToDispose(new RasterizerState(this.DeviceManager.Direct3DDevice, new RasterizerStateDescription()
            {
                FillMode = FillMode.Solid,
                CullMode = CullMode.Back,
            }));

            // Initialize the ImmediateContext pipeline stages
            //InitializeContext(context, true);
        }
        /// <summary>
        /// Creates device-based resources to store a constant buffer, cube
        /// geometry, and vertex and pixel shaders. In some cases this will also
        /// store a geometry shader.
        /// </summary>
        public async void CreateDeviceDependentResourcesAsync()
        {
            ReleaseDeviceDependentResources();

            usingVprtShaders = deviceResources.D3DDeviceSupportsVprt;

            var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;

            // On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
            // VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
            // we can avoid using a pass-through geometry shader to set the render
            // target array index, thus avoiding any overhead that would be
            // incurred by setting the geometry shader stage.
            var vertexShaderFileName = usingVprtShaders ? "Content\\Shaders\\VPRTVertexShader.cso" : "Content\\Shaders\\VertexShader.cso";

            // Load the compiled vertex shader.
            var vertexShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync(vertexShaderFileName));

            // After the vertex shader file is loaded, create the shader and input layout.
            vertexShader = this.ToDispose(new SharpDX.Direct3D11.VertexShader(
                                              deviceResources.D3DDevice,
                                              vertexShaderByteCode));

            SharpDX.Direct3D11.InputElement[] vertexDesc =
            {
                new SharpDX.Direct3D11.InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float,  0, 0, SharpDX.Direct3D11.InputClassification.PerVertexData, 0),
                new SharpDX.Direct3D11.InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float,    12, 0, SharpDX.Direct3D11.InputClassification.PerVertexData, 0),
            };

            inputLayout = this.ToDispose(new SharpDX.Direct3D11.InputLayout(
                                             deviceResources.D3DDevice,
                                             vertexShaderByteCode,
                                             vertexDesc));

            if (!usingVprtShaders)
            {
                // Load the compiled pass-through geometry shader.
                var geometryShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync("Content\\Shaders\\GeometryShader.cso"));

                // After the pass-through geometry shader file is loaded, create the shader.
                geometryShader = this.ToDispose(new SharpDX.Direct3D11.GeometryShader(
                                                    deviceResources.D3DDevice,
                                                    geometryShaderByteCode));
            }

            // Load the compiled pixel shader.
            var pixelShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync("Content\\Shaders\\PixelShader.cso"));

            // After the pixel shader file is loaded, create the shader.
            pixelShader = this.ToDispose(new SharpDX.Direct3D11.PixelShader(
                                             deviceResources.D3DDevice,
                                             pixelShaderByteCode));

            var texture = TextureLoader.CreateTexture2DFromBitmap(deviceResources.D3DDevice, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), _file));

            _textureView = new ShaderResourceView(deviceResources.D3DDevice, texture);

            // Load mesh vertices. Each vertex has a position and a color.
            // Note that the cube size has changed from the default DirectX app
            // template. Windows Holographic is scaled in meters, so to draw the
            // cube at a comfortable size we made the cube width 0.2 m (20 cm).

            TexturedVertex[] vertices =
            {
                new TexturedVertex(new Vector3(0.0f,   0.0f, 0.0f), new Vector2(0, 1)),
                new TexturedVertex(new Vector3(_size,  0.0f, 0.0f), new Vector2(1, 1)),
                new TexturedVertex(new Vector3(_size, _size, 0.0f), new Vector2(1, 0)),
                new TexturedVertex(new Vector3(0.0f,  _size, 0.0f), new Vector2(0, 0)),
            };

            vertexBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create(
                                              deviceResources.D3DDevice,
                                              SharpDX.Direct3D11.BindFlags.VertexBuffer,
                                              vertices));

            // Load mesh indices. Each trio of indices represents
            // a triangle to be rendered on the screen.
            // For example: 0,2,1 means that the vertices with indexes
            // 0, 2 and 1 from the vertex buffer compose the
            // first triangle of this mesh.
            ushort[] cubeIndices =
            {
                2, 1, 0,
                0, 3, 2,
            };

            indexCount = cubeIndices.Length;

            indexBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create(
                                             deviceResources.D3DDevice,
                                             SharpDX.Direct3D11.BindFlags.IndexBuffer,
                                             cubeIndices));

            // Create a constant buffer to store the model matrix.
            modelConstantBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create(
                                                     deviceResources.D3DDevice,
                                                     SharpDX.Direct3D11.BindFlags.ConstantBuffer,
                                                     ref modelConstantBufferData));

            // Once the cube is loaded, the object is ready to be rendered.
            loadingComplete = true;
        }
 internal void SetGS(GeometryShader gs)
 {
     if (State.m_gs != gs)
     {
         State.m_gs = gs;
         Context.GeometryShader.Set(gs);
         Stats.SetGS++;
     }
 }
        internal void Clear()
        {
            if (m_VBs == null)
            {
                m_VBs = new Buffer[8];
                m_strides = new int[8];
                m_CBs = new Buffer[8];

                m_bindings = new SortedDictionary<int, MyBinding>();
                m_srvBindings = new SortedSet<Tuple<int, int>>();

                m_RTVs = new RenderTargetView[8];
                m_SRVs = new ShaderResourceView[8];

                m_constantsVersion = new Dictionary<Buffer, int>();
                m_constantBindings = new Dictionary<MyStageBinding, Buffer>();
                m_srvTableBindings = new Dictionary<MyStageSrvBinding, int>();
                m_srvBindings1 = new List<MyStageSrvBinding>();
            }

            m_IB = null;

            m_inputLayout = null;
            m_ps = null;
            m_vs = null;
            m_gs = null;

            m_RS = null;
            m_BS = null;
            m_DS = null;
            m_stencilRef = 0;

            Array.Clear(m_VBs, 0, m_VBs.Length);
            Array.Clear(m_CBs, 0, m_CBs.Length);

            m_bindings.Clear();
            m_srvBindings.Clear();

            m_constantsVersion.Clear();
            m_constantBindings.Clear();
            m_srvTableBindings.Clear();
            m_srvBindings1.Clear();
        }
		/// <summary>
		/// 
		/// </summary>
		void SetupShadersAndLayouts ()
		{
			ps	=	PixelShader		== null ? null : new D3DPixelShader		( device.Device, PixelShader	.Bytecode );
			vs	=	VertexShader	== null ? null : new D3DVertexShader	( device.Device, VertexShader	.Bytecode );
			gs	=	GeometryShader	== null ? null : new D3DGeometryShader	( device.Device, GeometryShader	.Bytecode );
			hs	=	HullShader		== null ? null : new D3DHullShader		( device.Device, HullShader		.Bytecode );
			ds	=	DomainShader	== null ? null : new D3DDomainShader	( device.Device, DomainShader	.Bytecode );
			cs	=	ComputeShader	== null ? null : new D3DComputeShader	( device.Device, ComputeShader	.Bytecode );

			if (cs!=null) {
				if ( ps!=null || vs!=null || gs!=null || hs!=null || ds!=null ) {
					throw new InvalidOperationException("If ComputeShader is set, other shader must be set null.");
				}
			} else {
				if ( vs==null ) {
					throw new InvalidOperationException("Vertex shader must be set.");
				}
			}


			
			if (VertexInputElements==null) {
				inputLayout =	null ;
			} else {
				inputLayout	=	new InputLayout( device.Device, VertexShader.Bytecode, VertexInputElement.Convert( VertexInputElements ) );
			}



			if (VertexOutputElements!=null) {

				if (GeometryShader==null) {
					throw new InvalidOperationException("Geometry shader is required for vertex output.");
				}

				var outputElements	=	VertexOutputElement.Convert( VertexOutputElements );
				int maxBuffers		=	outputElements.Max( oe => oe.OutputSlot ) + 1;
				var bufferedStrides	=	new int[ maxBuffers ];

				for (int i=0; i<maxBuffers; i++) {
					bufferedStrides[i] = outputElements	
										.Where( oe1 => oe1.OutputSlot==i )
										.Sum( oe2 => oe2.ComponentCount	) * 4;
				}

				gs	=	new D3DGeometryShader( device.Device, GeometryShader.Bytecode, outputElements, bufferedStrides, RasterizedStream ); 
			}
		}
        internal override void ClearState()
        {
            base.ClearState();

            m_geometryShader = null;
        }
        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 cubemap for each mesh that contains "reflector" in its name
            List<DynamicCubeMap> envMaps = new List<DynamicCubeMap>();

            // 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 DynamicCubeMap(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 an axis-grid renderer
            var axisGrid = ToDispose(new AxisGridRenderer());
            axisGrid.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, 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)"
                    + "\n(G) Build in GS (single pass): {4}"
                    ,
                        threadCount,
                        maxReflectors,
                        additionalCPULoad,
                        meshRows * meshColumns,
                        buildCubeMapGeometryInstancing);
            };

            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;
                            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.G:
                        buildCubeMapGeometryInstancing = !buildCubeMapGeometryInstancing;
                        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, DynamicCubeMap> 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 a cubemap we must set the
                            // per environment map buffer.
                            if (envMap != null)
                                renderContext.GeometryShader.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;

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

                // 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 cubemap once every third frame
                //{
                #region Update environment maps

                // Update each of the cubemaps
                if (buildCubeMapGeometryInstancing)
                {
                    activeVertexShader = envMapVSShader;
                    activeGeometryShader = envMapGSShader;
                    activePixelShader = envMapPSShader;
                }
                else
                {
                    activeVertexShader = vertexShader;
                    activeGeometryShader = null;
                    activePixelShader = blinnPhongShader;
                }

                // 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));
                        if (buildCubeMapGeometryInstancing)
                        {
                            // Render cubemap in single full render pass using
                            // geometry shader instancing.
                            envMap.UpdateSinglePass(context, renderScene);
                        }
                        else
                        {
                            // Render cubemap in 6 full render passes
                            envMap.Update(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
        }
        protected override void CreateDeviceDependentResources(DeviceManager deviceManager)
        {
            base.CreateDeviceDependentResources(deviceManager);

            // Release all resources
            RemoveAndDispose(ref vertexShader);

            RemoveAndDispose(ref pixelShader);
            RemoveAndDispose(ref depthPixelShader);
            RemoveAndDispose(ref blinnPhongShader);

            RemoveAndDispose(ref debugNormals);

            RemoveAndDispose(ref vertexLayout);
            RemoveAndDispose(ref perObjectBuffer);
            RemoveAndDispose(ref perFrameBuffer);
            RemoveAndDispose(ref perMaterialBuffer);
            RemoveAndDispose(ref perArmatureBuffer);

            RemoveAndDispose(ref depthStencilState);

            DebugGBuffer.ForEach(ps => RemoveAndDispose(ref ps));
            DebugGBuffer.Clear();

            DebugGBufferMS.ForEach(ps => RemoveAndDispose(ref ps));
            DebugGBufferMS.Clear();

            // Get a reference to the Device1 instance and immediate context
            var device = deviceManager.Direct3DDevice;
            var context = deviceManager.Direct3DContext;

            // Compile and create the vertex shader and input layout
            using (var vertexShaderBytecode = HLSLCompiler.CompileFromFile(@"Shaders\VS.hlsl", "VSMain", "vs_5_0"))
            {
                vertexShader = ToDispose(new VertexShader(device, vertexShaderBytecode));

                // Layout from VertexShader input signature
                vertexLayout = ToDispose(new InputLayout(device,
                    vertexShaderBytecode.GetPart(ShaderBytecodePart.InputSignatureBlob),
                    new[]
                {
                    // "SV_Position" = vertex coordinate in object space
                    new InputElement("SV_Position", 0, Format.R32G32B32_Float, 0, 0),
                    // "NORMAL" = the vertex normal
                    new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0),
                    // "COLOR"
                    new InputElement("COLOR", 0, Format.R8G8B8A8_UNorm, 24, 0),
                    // "UV"
                    new InputElement("TEXCOORD", 0, Format.R32G32_Float, 28, 0),
                    // "BLENDINDICES"
                    new InputElement("BLENDINDICES", 0, Format.R32G32B32A32_UInt, 36, 0),
                    // "BLENDWEIGHT"
                    new InputElement("BLENDWEIGHT", 0, Format.R32G32B32A32_Float, 52, 0),
                    // "TANGENT"
                    new InputElement("TANGENT", 0, Format.R32G32B32A32_Float, 68, 0),
                }));
            }

            // Compile and create the pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\SimplePS.hlsl", "PSMain", "ps_5_0"))
                pixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the depth vertex and pixel shaders
            // This shader is for checking what the depth buffer would look like
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\DepthPS.hlsl", "PSMain", "ps_5_0"))
                depthPixelShader = ToDispose(new PixelShader(device, bytecode));

            // Compile and create the Lambert pixel shader
            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\BlinnPhongPS.hlsl", "PSMain", "ps_5_0"))
                blinnPhongShader = ToDispose(new PixelShader(device, bytecode));

            using (var geomShaderByteCode = HLSLCompiler.CompileFromFile(@"Shaders\GS_DebugNormals.hlsl", "GSMain", "gs_5_0"))
                debugNormals = ToDispose(new GeometryShader(device, geomShaderByteCode));

            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\FillGBuffer.hlsl", "VSFillGBuffer", "vs_5_0"))
                fillGBufferVS = ToDispose(new VertexShader(device, bytecode));

            using (var bytecode = HLSLCompiler.CompileFromFile(@"Shaders\FillGBuffer.hlsl", "PSFillGBuffer", "ps_5_0"))
            {
                fillGBufferPS = ToDispose(new PixelShader(device, bytecode));
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferDiffuse", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferDiffuse";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferNormalPacked", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferNormalPacked";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferEmissive", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferEmissive";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferSpecularPower", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferSpecularPower";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferSpecularInt", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferSpecularInt";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferDepth", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferDepth";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBuffer.hlsl", "GBufferPosition", "ps_5_0"))
            {
                DebugGBuffer.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBuffer.Last().DebugName = "GBufferPosition";
            }

            #region Debug GBuffer for multisampling

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferDiffuse", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferDiffuse";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferNormalPacked", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferNormalPacked";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferEmissive", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferEmissive";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferSpecularPower", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferSpecularPower";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferSpecularInt", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferSpecularInt";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferDepth", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferDepth";
            }

            using (var bc = HLSLCompiler.CompileFromFile(@"Shaders\DebugGBufferMS.hlsl", "GBufferPosition", "ps_5_0"))
            {
                DebugGBufferMS.Add(ToDispose(new PixelShader(device, bc)));
                DebugGBufferMS.Last().DebugName = "GBufferPosition";
            }
            #endregion

            // IMPORTANT: A constant buffer's size must be a multiple of 16-bytes
            // use LayoutKind.Explicit and an explicit Size= to force this for structures
            // or alternatively add padding fields and use a LayoutKind.Sequential and Pack=1

            // Create the constant buffer that will
            // store our worldViewProjection matrix
            perObjectBuffer = ToDispose(new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf<ConstantBuffers.PerObject>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per frame constant buffer
            // lighting / camera position
            perFrameBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerFrame>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per material constant buffer
            perMaterialBuffer = ToDispose(new Buffer(device, Utilities.SizeOf<ConstantBuffers.PerMaterial>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Create the per armature/skeletong constant buffer
            perArmatureBuffer = ToDispose(new Buffer(device, ConstantBuffers.PerArmature.Size(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0));

            // Configure the depth buffer to discard pixels that are
            // further than the current pixel.
            depthStencilState = ToDispose(new DepthStencilState(device,
                new DepthStencilStateDescription()
                {
                    IsDepthEnabled = true, // enable depth?
                    DepthComparison = Comparison.Less,
                    DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All,
                    IsStencilEnabled = false,// enable stencil?
                    StencilReadMask = 0xff, // 0xff (no mask)
                    StencilWriteMask = 0xff,// 0xff (no mask)
                    // Configure FrontFace depth/stencil operations
                    FrontFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Increment
                    },
                    // Configure BackFace depth/stencil operations
                    BackFace = new DepthStencilOperationDescription()
                    {
                        Comparison = Comparison.Always,
                        PassOperation = StencilOperation.Keep,
                        FailOperation = StencilOperation.Keep,
                        DepthFailOperation = StencilOperation.Decrement
                    },
                }));

            // Tell the IA what the vertices will look like
            context.InputAssembler.InputLayout = vertexLayout;

            // Set our constant buffer (to store worldViewProjection)
            context.VertexShader.SetConstantBuffer(0, perObjectBuffer);
            context.VertexShader.SetConstantBuffer(1, perFrameBuffer);
            context.VertexShader.SetConstantBuffer(2, perMaterialBuffer);
            context.VertexShader.SetConstantBuffer(3, perArmatureBuffer);

            // Set the vertex shader to run
            context.VertexShader.Set(vertexShader);

            // Set gemoetry shader buffers
            context.GeometryShader.SetConstantBuffer(0, perObjectBuffer);
            context.GeometryShader.SetConstantBuffer(1, perFrameBuffer);

            // Set our pixel constant buffers
            context.PixelShader.SetConstantBuffer(1, perFrameBuffer);
            context.PixelShader.SetConstantBuffer(2, perMaterialBuffer);

            // Set the pixel shader to run
            context.PixelShader.Set(blinnPhongShader);

            // Set our depth stencil state
            context.OutputMerger.DepthStencilState = depthStencilState;

            // Back-face culling
            context.Rasterizer.State = ToDispose(new RasterizerState(device, new RasterizerStateDescription()
            {
                FillMode = FillMode.Solid,
                CullMode = CullMode.Back,
            }));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="GorgonGeometryShader" /> class.
 /// </summary>
 /// <param name="graphics">The graphics interface that owns this object.</param>
 /// <param name="name">The name for this shader.</param>
 /// <param name="isDebug"><b>true</b> if debug information is included in the byte code, <b>false</b> if not.</param>
 /// <param name="byteCode">The byte code for the shader.</param>
 /// <param name="soShader">The stream out shader.</param>
 private GorgonGeometryShader(GorgonGraphics graphics, string name, bool isDebug, ShaderBytecode byteCode, D3D11.GeometryShader soShader)
     : base(graphics, name, isDebug, byteCode)
 {
     graphics.Log.Print($"Creating {ShaderType} '{name}' ({ID})", LoggingLevel.Verbose);
     _shader = soShader;
 }
        public DepthAndColorShader(Device device)
        {
            shaderByteCode = new ShaderBytecode(File.ReadAllBytes("Content/DepthAndColorFloatVS.cso"));
            depthAndColorVS = new VertexShader(device, shaderByteCode);
            depthAndColorGS = new GeometryShader(device, new ShaderBytecode(File.ReadAllBytes("Content/DepthAndColorGS.cso")));
            depthAndColorPS = new PixelShader(device, new ShaderBytecode(File.ReadAllBytes("Content/DepthAndColorPS.cso")));

            // depth stencil state
            var depthStencilStateDesc = new DepthStencilStateDescription()
            {
                IsDepthEnabled = true,
                DepthWriteMask = DepthWriteMask.All,
                DepthComparison = Comparison.LessEqual,
                IsStencilEnabled = false,
            };
            depthStencilState = new DepthStencilState(device, depthStencilStateDesc);

            // rasterizer state
            var rasterizerStateDesc = new RasterizerStateDescription()
            {
                CullMode = CullMode.None,
                FillMode = FillMode.Solid,
                IsDepthClipEnabled = true,
                IsFrontCounterClockwise = true,
                IsMultisampleEnabled = true,
            };
            rasterizerState = new RasterizerState(device, rasterizerStateDesc);

            // color sampler state
            var colorSamplerStateDesc = new SamplerStateDescription()
            {
                Filter = Filter.MinMagMipLinear,
                AddressU = TextureAddressMode.Border,
                AddressV = TextureAddressMode.Border,
                AddressW = TextureAddressMode.Border,
                //BorderColor = new SharpDX.Color4(0.5f, 0.5f, 0.5f, 1.0f),
                BorderColor = new SharpDX.Color4(0, 0, 0, 1.0f),
            };
            colorSamplerState = new SamplerState(device, colorSamplerStateDesc);

            //// Kinect depth image
            //var depthImageTextureDesc = new Texture2DDescription()
            //{
            //    Width = depthImageWidth,
            //    Height = depthImageHeight,
            //    MipLevels = 1,
            //    ArraySize = 1,
            //    Format = SharpDX.DXGI.Format.R16_UInt, // R32_Float
            //    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
            //    Usage = ResourceUsage.Dynamic,
            //    BindFlags = BindFlags.ShaderResource,
            //    CpuAccessFlags = CpuAccessFlags.Write,
            //};
            //depthImageTexture = new Texture2D(device, depthImageTextureDesc);
            //depthImageTextureRV = new ShaderResourceView(device, depthImageTexture);

            // filtered depth image
            var filteredDepthImageTextureDesc = new Texture2DDescription()
            {
                Width = Kinect2Calibration.depthImageWidth * 3,
                Height = Kinect2Calibration.depthImageHeight * 3,
                MipLevels = 1,
                ArraySize = 1,
                Format = SharpDX.DXGI.Format.R32G32_Float,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
                Usage = ResourceUsage.Default,
                BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
                CpuAccessFlags = CpuAccessFlags.None,
            };
            filteredDepthImageTexture = new Texture2D(device, filteredDepthImageTextureDesc);
            filteredRenderTargetView = new RenderTargetView(device, filteredDepthImageTexture);
            filteredDepthImageSRV = new ShaderResourceView(device, filteredDepthImageTexture);

            filteredDepthImageTexture2 = new Texture2D(device, filteredDepthImageTextureDesc);
            filteredRenderTargetView2 = new RenderTargetView(device, filteredDepthImageTexture2);
            filteredDepthImageSRV2 = new ShaderResourceView(device, filteredDepthImageTexture2);

            //// Kinect color image
            //var colorImageStagingTextureDesc = new Texture2DDescription()
            //{
            //    Width = colorImageWidth,
            //    Height = colorImageHeight,
            //    MipLevels = 1,
            //    ArraySize = 1,
            //    Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
            //    //Format = SharpDX.DXGI.Format.YUY2
            //    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
            //    Usage = ResourceUsage.Dynamic,
            //    BindFlags = BindFlags.ShaderResource,
            //    CpuAccessFlags = CpuAccessFlags.Write
            //};
            //colorImageStagingTexture = new Texture2D(device, colorImageStagingTextureDesc);

            //var colorImageTextureDesc = new Texture2DDescription()
            //{
            //    Width = colorImageWidth,
            //    Height = colorImageHeight,
            //    MipLevels = 0,
            //    ArraySize = 1,
            //    Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
            //    SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
            //    Usage = ResourceUsage.Default,
            //    BindFlags = BindFlags.ShaderResource | BindFlags.RenderTarget,
            //    CpuAccessFlags = CpuAccessFlags.None,
            //    OptionFlags = ResourceOptionFlags.GenerateMipMaps
            //};
            //colorImageTexture = new Texture2D(device, colorImageTextureDesc);
            //colorImageTextureRV = new ShaderResourceView(device, colorImageTexture);

            // constant buffer
            var constantBufferDesc = new BufferDescription()
            {
                Usage = ResourceUsage.Dynamic,
                BindFlags = BindFlags.ConstantBuffer,
                SizeInBytes = ConstantBuffer.size,
                CpuAccessFlags = CpuAccessFlags.Write,
                StructureByteStride = 0,
                OptionFlags = 0,
            };
            constantBuffer = new SharpDX.Direct3D11.Buffer(device, constantBufferDesc);

            bilateralFilter = new BilateralFilter(device, Kinect2Calibration.depthImageWidth, Kinect2Calibration.depthImageHeight);

            vertexInputLayout = new InputLayout(device, shaderByteCode.Data, new[]
            {
                new InputElement("SV_POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
            });
        }
Exemple #27
0
        /// <summary>
        /// Creates device-based resources to store a constant buffer, cube
        /// geometry, and vertex and pixel shaders. In some cases this will also
        /// store a geometry shader.
        /// </summary>
        public async void CreateDeviceDependentResourcesAsync()
        {
            ReleaseDeviceDependentResources();

            usingVprtShaders = deviceResources.D3DDeviceSupportsVprt;

            var folder = Windows.ApplicationModel.Package.Current.InstalledLocation;

            // On devices that do support the D3D11_FEATURE_D3D11_OPTIONS3::
            // VPAndRTArrayIndexFromAnyShaderFeedingRasterizer optional feature
            // we can avoid using a pass-through geometry shader to set the render
            // target array index, thus avoiding any overhead that would be
            // incurred by setting the geometry shader stage.
            var vertexShaderFileName =
                usingVprtShaders ? "Content\\Shaders\\VPRTVertexShader.cso" :
                "Content\\Shaders\\VertexShader.cso";

            // Load the compiled vertex shader.
            var vertexShaderByteCode = await DirectXHelper.ReadDataAsync(
                await folder.GetFileAsync(vertexShaderFileName));

            // After the vertex shader file is loaded, create the shader and input layout.
            vertexShader = this.ToDispose(
                new SharpDX.Direct3D11.VertexShader(
                    deviceResources.D3DDevice,
                    vertexShaderByteCode));

            SharpDX.Direct3D11.InputElement[] vertexDesc =
            {
                new SharpDX.Direct3D11.InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float,  0, 0, SharpDX.Direct3D11.InputClassification.PerVertexData, 0),
                new SharpDX.Direct3D11.InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float,    12, 0, SharpDX.Direct3D11.InputClassification.PerVertexData, 0)
            };

            inputLayout = this.ToDispose(new SharpDX.Direct3D11.InputLayout(
                                             deviceResources.D3DDevice,
                                             vertexShaderByteCode,
                                             vertexDesc));

            if (!usingVprtShaders)
            {
                // Load the compiled pass-through geometry shader.
                var geometryShaderByteCode = await DirectXHelper.ReadDataAsync(await folder.GetFileAsync("Content\\Shaders\\GeometryShader.cso"));

                // After the pass-through geometry shader file is loaded, create the shader.
                geometryShader = this.ToDispose(new SharpDX.Direct3D11.GeometryShader(
                                                    deviceResources.D3DDevice,
                                                    geometryShaderByteCode));
            }

            // Load the compiled pixel shader.
            var pixelShaderByteCode = await DirectXHelper.ReadDataAsync(
                await folder.GetFileAsync("Content\\Shaders\\TexturePixelShader.cso"));

            // After the pixel shader file is loaded, create the shader.
            pixelShader = this.ToDispose(new SharpDX.Direct3D11.PixelShader(
                                             deviceResources.D3DDevice,
                                             pixelShaderByteCode));

            // Load mesh vertices. Each vertex has a position, a texture-coord and a colour.
            VertexPositionTextureColor[] quadVertices =
            {
                new VertexPositionTextureColor(new Vector3(-(QUAD_SIZE / 2.0f), -(QUAD_SIZE / 2.0f), 0f), new Vector2(0, 1), Vector3.Zero),
                new VertexPositionTextureColor(new Vector3(-(QUAD_SIZE / 2.0f), (QUAD_SIZE / 2.0f),  0f), new Vector2(0, 0), Vector3.Zero),
                new VertexPositionTextureColor(new Vector3((QUAD_SIZE / 2.0f),  (QUAD_SIZE / 2.0f),  0f), new Vector2(1, 0), Vector3.Zero),
                new VertexPositionTextureColor(new Vector3((QUAD_SIZE / 2.0f),  -(QUAD_SIZE / 2.0f), 0f), new Vector2(1, 1), Vector3.Zero)
            };

            vertexBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create(
                                              deviceResources.D3DDevice,
                                              SharpDX.Direct3D11.BindFlags.VertexBuffer,
                                              quadVertices));

            // Load mesh indices. Each trio of indices represents
            // a triangle to be rendered on the screen.
            // For example: 0,2,1 means that the vertices with indexes
            // 0, 2 and 1 from the vertex buffer compose the
            // first triangle of this mesh.
            ushort[] cubeIndices =
            {
                0, 1, 2,
                0, 2, 3
            };

            indexCount = cubeIndices.Length;

            indexBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create(
                                             deviceResources.D3DDevice,
                                             SharpDX.Direct3D11.BindFlags.IndexBuffer,
                                             cubeIndices));

            // Create a constant buffer to store the model matrix.
            modelConstantBuffer = this.ToDispose(SharpDX.Direct3D11.Buffer.Create(
                                                     deviceResources.D3DDevice,
                                                     SharpDX.Direct3D11.BindFlags.ConstantBuffer,
                                                     ref modelConstantBufferData));

            this.samplerState = this.ToDispose(
                new SamplerState(
                    this.deviceResources.D3DDevice,
                    new SamplerStateDescription()
            {
                AddressU           = TextureAddressMode.Clamp,
                AddressV           = TextureAddressMode.Clamp,
                AddressW           = TextureAddressMode.Clamp,
                ComparisonFunction = Comparison.Never,
                MaximumAnisotropy  = 16,
                MipLodBias         = 0,
                MinimumLod         = -float.MaxValue,
                MaximumLod         = float.MaxValue
            }
                    )
                );

            Texture2DDescription desc = new Texture2DDescription()
            {
                Width             = TEXTURE_SIZE,
                Height            = TEXTURE_SIZE,
                ArraySize         = 1,
                MipLevels         = 1,
                Usage             = ResourceUsage.Default,
                Format            = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
                CpuAccessFlags    = CpuAccessFlags.None,
                SampleDescription = new SampleDescription(1, 0),
                BindFlags         = BindFlags.RenderTarget | BindFlags.ShaderResource
            };

            this.texture2D = this.ToDispose(new Texture2D(this.deviceResources.D3DDevice, desc));

            this.shaderResourceView = this.ToDispose(new ShaderResourceView(
                                                         this.deviceResources.D3DDevice, texture2D));

            this.renderTargetView = this.ToDispose(new RenderTargetView(
                                                       this.deviceResources.D3DDevice, texture2D));

            using (var surface = texture2D.QueryInterface <Surface>())
            {
                this.renderTarget = this.ToDispose(
                    new RenderTarget(
                        this.deviceResources.D2DFactory,
                        surface,
                        new RenderTargetProperties()
                {
                    DpiX        = 96,
                    DpiY        = 96,
                    Type        = RenderTargetType.Default,
                    Usage       = RenderTargetUsage.None,
                    MinLevel    = FeatureLevel.Level_DEFAULT,
                    PixelFormat = new PixelFormat(Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied)
                }
                        )
                    );
            }
            this.redBrush = this.ToDispose(new SolidColorBrush(renderTarget, new RawColor4(255, 0, 0, 255)));

            this.whiteBrush = this.ToDispose(new SolidColorBrush(renderTarget, new RawColor4(255, 255, 255, 255)));

            this.textFormat = this.ToDispose(new TextFormat(this.deviceResources.DWriteFactory, "Consolas", 24));

            this.ellipse = new Ellipse(new RawVector2(TEXTURE_SIZE / 2, TEXTURE_SIZE / 2), TEXTURE_SIZE / 4, TEXTURE_SIZE / 4);

            this.fillRectangle = new RawRectangleF(0, 0, TEXTURE_SIZE, TEXTURE_SIZE);
            this.textRectangle = new RawRectangleF(24, 24, 240, 60); // magic numbers, hard-coded to fit.

            // Once the cube is loaded, the object is ready to be rendered.
            loadingComplete = true;
        }
 internal GeometryShader(GraphicsDevice device, string bytecode) : base(bytecode)
 {
     Shader = new D3D11.GeometryShader(device.Device, Misc.HexStringToByte(bytecode));
 }
        internal Engine_Material(string _shaderFileName, string _imageFileName, bool _includeGeometryShader = false)
        {
            #region //Get Instances
            m_d3d = Engine_Renderer.Instance;
            #endregion

            #region //Create InputLayout
            var inputElements = new D3D11.InputElement[] {
                new D3D11.InputElement("POSITION", 0, DXGI.Format.R32G32B32_Float, 0, 0),
                new D3D11.InputElement("TEXCOORD", 0, DXGI.Format.R32G32_Float, D3D11.InputElement.AppendAligned, 0),
                new D3D11.InputElement("NORMAL", 0, DXGI.Format.R32G32B32_Float, D3D11.InputElement.AppendAligned, 0)
            };
            #endregion

            #region //Create VertexShader
            CompilationResult vsResult;
            using (vsResult = ShaderBytecode.CompileFromFile(_shaderFileName, "VS", "vs_4_0", ShaderFlags.None))
            {
                m_vertexShader = new D3D11.VertexShader(m_d3d.m_device, vsResult.Bytecode.Data);
                m_inputLayout  = new D3D11.InputLayout(m_d3d.m_device, vsResult.Bytecode, inputElements);
            }
            #endregion

            #region //Create PixelShader
            using (var psResult = ShaderBytecode.CompileFromFile(_shaderFileName, "PS", "ps_4_0", ShaderFlags.None))
                m_pixelShader = new D3D11.PixelShader(m_d3d.m_device, psResult.Bytecode.Data);
            #endregion

            #region //Create GeometryShader
            if (_includeGeometryShader)
            {
                using (var psResult = ShaderBytecode.CompileFromFile(_shaderFileName, "GS", "gs_4_0", ShaderFlags.None))
                    m_geometryShader = new D3D11.GeometryShader(m_d3d.m_device, psResult.Bytecode.Data);
            }
            #endregion

            #region //Create ConstantBuffers for Model
            SPerModelConstantBuffer cbModel = new SPerModelConstantBuffer();

            D3D11.BufferDescription bufferDescription = new D3D11.BufferDescription
            {
                BindFlags      = D3D11.BindFlags.ConstantBuffer,
                CpuAccessFlags = D3D11.CpuAccessFlags.Write,
                Usage          = D3D11.ResourceUsage.Dynamic,
            };

            m_model = D3D11.Buffer.Create(m_d3d.m_device, D3D11.BindFlags.ConstantBuffer, ref cbModel);
            #endregion

            #region //Create Texture and Sampler
            var texture = Engine_ImgLoader.CreateTexture2DFromBitmap(m_d3d.m_device, Engine_ImgLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), _imageFileName));
            m_resourceView = new D3D11.ShaderResourceView(m_d3d.m_device, texture);

            D3D11.SamplerStateDescription samplerStateDescription = new D3D11.SamplerStateDescription
            {
                Filter             = D3D11.Filter.Anisotropic,
                AddressU           = D3D11.TextureAddressMode.Clamp,
                AddressV           = D3D11.TextureAddressMode.Clamp,
                AddressW           = D3D11.TextureAddressMode.Clamp,
                ComparisonFunction = D3D11.Comparison.Always,
                MaximumAnisotropy  = 16,
                MinimumLod         = 0,
                MaximumLod         = float.MaxValue,
            };

            m_sampler = new D3D11.SamplerState(m_d3d.m_device, samplerStateDescription);
            #endregion
        }
Exemple #30
0
 internal GeometryShader( GraphicsDevice device, string bytecode )
     : base(bytecode)
 {
     Shader = new D3D11.GeometryShader( device.Device, Misc.HexStringToByte(bytecode) );
 }
        public void CompileShader(string vertexProfile, string pixelProfile)
        {
            string vertexShaderText = GetVertexShaderSource(vertexProfile);
            vertexShaderBytecode = ShaderLibrary.Instance.getShaderBytecode(Key, vertexShaderText, "VS", vertexProfile);
            vertexShader = new VertexShader(RenderContext11.PrepDevice, vertexShaderBytecode);

            string pixelShaderText = GetPixelShaderSource(pixelProfile);
            pixelShaderBytecode = ShaderLibrary.Instance.getShaderBytecode(Key, pixelShaderText, "PS", pixelProfile);
            pixelShader = new PixelShader(RenderContext11.PrepDevice, pixelShaderBytecode);

            string geometryShaderProfile = "gs_4_0";
            string geometryShaderText = GetGeometryShaderSource(geometryShaderProfile);
            if (geometryShaderText != null)
            {
                geometryShaderBytecode = ShaderLibrary.Instance.getShaderBytecode(Key, geometryShaderText, "GS", geometryShaderProfile);
                geometryShader = new GeometryShader(RenderContext11.PrepDevice, geometryShaderBytecode);
            }
        }
Exemple #32
0
        internal DeviceChild GetOrCompileShader(EffectShaderType shaderType, int index, int soRasterizedStream, StreamOutputElement[] soElements, out string profileError)
        {
            DeviceChild shader = null;
            profileError = null;
            lock (sync)
            {
                shader = compiledShadersGroup[(int)shaderType][index];
                if (shader == null)
                {
                    if (RegisteredShaders[index].Level > graphicsDevice.Features.Level)
                    {
                        profileError = string.Format("{0}", RegisteredShaders[index].Level);
                        return null;
                    }

                    var bytecodeRaw = RegisteredShaders[index].Bytecode;
                    switch (shaderType)
                    {
                        case EffectShaderType.Vertex:
                            shader = new VertexShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Domain:
                            shader = new DomainShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Hull:
                            shader = new HullShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Geometry:
                            if (soElements != null)
                            {
                                // Calculate the strides
                                var soStrides = new List<int>();
                                foreach (var streamOutputElement in soElements)
                                {
                                    for (int i = soStrides.Count; i < (streamOutputElement.Stream+1); i++)
                                    {
                                        soStrides.Add(0);
                                    }

                                    soStrides[streamOutputElement.Stream] += streamOutputElement.ComponentCount * sizeof(float);
                                }
                                shader = new GeometryShader(graphicsDevice, bytecodeRaw, soElements, soStrides.ToArray(), soRasterizedStream);
                            }
                            else
                            {
                                shader = new GeometryShader(graphicsDevice, bytecodeRaw);
                            }
                            break;
                        case EffectShaderType.Pixel:
                            shader = new PixelShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Compute:
                            shader = new ComputeShader(graphicsDevice, bytecodeRaw);
                            break;
                    }
                    compiledShadersGroup[(int)shaderType][index] = ToDispose(shader);
                }
            }
            return shader;
        }
Exemple #33
0
        public ShaderSolution(string _name, Device Device, ByteCodeBind[] _shaders_bytecode)
        {
            shaders_bytecode = new Dictionary<Shaders, ShaderBytecode>();
            shaders_buffers = new Dictionary<Shaders, SharpDX.Direct3D11.Buffer[]>();
            //shaders_bound_values = new Dictionary<Shaders, NonNullable<SharpDX.DataStream>[]>();
            name = _name;
            for (int i = 0; i < _shaders_bytecode.Length; i++)
            {
                shaders_bytecode.Add(_shaders_bytecode[i].shaderType, _shaders_bytecode[i].byteCode);

                switch (_shaders_bytecode[i].shaderType)
                {
                    case Shaders.VertexShader:
                        vs = new VertexShader(Device, _shaders_bytecode[i].byteCode);
                        break;
                    case Shaders.HullShader:
                        hs = new HullShader(Device, _shaders_bytecode[i].byteCode);
                        break;
                    case Shaders.DomainShader:
                        ds = new DomainShader(Device, _shaders_bytecode[i].byteCode);
                        break;
                    case Shaders.GeometryShader:
                        gs = new GeometryShader(Device, _shaders_bytecode[i].byteCode);
                        break;
                    case Shaders.PixelShader:
                        ps = new PixelShader(Device, _shaders_bytecode[i].byteCode);
                        break;
                    default:
                        break;
                }
            }
        }
Exemple #34
-1
 internal void Set(GeometryShader shader)
 {
     if (shader == m_geometryShader)
         return;
     m_geometryShader = shader;
     m_deviceContext.GeometryShader.Set(shader);
     m_statistics.SetGeometryShaders++;
 }