/// <summary>
        /// Renders all given lines with the given parameters.
        /// </summary>
        /// <param name="renderState">The render state to be used.</param>
        /// <param name="worldViewProj">Current world-view-project transformation.</param>
        /// <param name="lineColor">The color for the line.</param>
        /// <param name="lineVertexBuffer">The vertex buffer containing all line vertices.</param>
        /// <param name="vertexCount">Total count of vertices.</param>
        internal void RenderLines(RenderState renderState, Matrix4x4 worldViewProj, Color4 lineColor, D3D11.Buffer lineVertexBuffer, int vertexCount)
        {
            D3D11.DeviceContext deviceContext = renderState.Device.DeviceImmediateContextD3D11;

            //Apply constant buffer data
            ConstantBufferData constantData = new ConstantBufferData();

            constantData.DiffuseColor  = lineColor;
            constantData.WorldViewProj = worldViewProj;
            m_constantBuffer.SetData(deviceContext, constantData);

            //Apply vertex buffer and draw lines
            deviceContext.VertexShader.SetConstantBuffer(4, m_constantBuffer.ConstantBuffer);
            deviceContext.PixelShader.SetConstantBuffer(4, m_constantBuffer.ConstantBuffer);
            deviceContext.InputAssembler.SetVertexBuffers(0, new D3D11.VertexBufferBinding(lineVertexBuffer, LineVertex.Size, 0));
            deviceContext.Draw(vertexCount, 0);
        }
        private void BuildTerrainResouces()
        {
            float[] HeightMapData = new float[100 * 100];
            for (int i = 0; i < 100; i++)
                for (int j = 0; j < 100; j++)
                    HeightMapData[i * 100 + j] = Convert.ToSingle(Math.Cos(Math.PI * 2 * i) * Math.Sin(Math.PI * 2 * j));
            var Tex = Texture.LoadFromFile("../../", "Terrain.jpg");

            ResourceDescription HeighMapDesc = ResourceDescription.Texture2D(Format.R32_Float, 100, 100, 1);
            ResourceDescription TerrainTextureDesc = ResourceDescription.Texture2D(Tex[0].ColorFormat, Tex[0].Width, Tex[0].Height, 1);
            HeightMap = device.CreateCommittedResource(
                        new HeapProperties(HeapType.Upload),
                        HeapFlags.None,
                        HeighMapDesc,
                        ResourceStates.GenericRead, null);
            TerrainTexture = device.CreateCommittedResource(
                        new HeapProperties(HeapType.Upload),
                        HeapFlags.None,
                        HeighMapDesc,
                        ResourceStates.GenericRead, null);
            TerrainCBF = device.CreateCommittedResource(
                        new HeapProperties(HeapType.Upload),
                        HeapFlags.None,
                        ResourceDescription.Buffer(1024 * 64),
                        ResourceStates.GenericRead);

            GCHandle handle = GCHandle.Alloc(HeightMapData, GCHandleType.Pinned);
            IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(HeightMapData, 0);
            HeightMap.WriteToSubresource(0, null, ptr, 100 * 4, HeightMapData.Length);
            handle.Free();

            handle = GCHandle.Alloc(Tex[0].Data, GCHandleType.Pinned);
            ptr = Marshal.UnsafeAddrOfPinnedArrayElement(Tex[0].Data, 0);
            TerrainTexture.WriteToSubresource(0, null, ptr, Tex[0].Width * Tex[0].PixelWdith, Tex[0].Data.Length);
            handle.Free();

            device.CreateShaderResourceView(
             HeightMap,
             new ShaderResourceViewDescription
             {
                 Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                 Format = HeighMapDesc.Format,
                 Dimension = ShaderResourceViewDimension.Texture2D,
                 Texture2D =
                 {
                     MipLevels = 1,
                     MostDetailedMip = 0,
                     PlaneSlice = 0,
                     ResourceMinLODClamp = 0.0f
                 }
             },
             terrainHeap.CPUDescriptorHandleForHeapStart);

            device.CreateShaderResourceView(
             TerrainTexture,
             new ShaderResourceViewDescription
             {
                 Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                 Format = HeighMapDesc.Format,
                 Dimension = ShaderResourceViewDimension.Texture2D,
                 Texture2D =
                 {
                     MipLevels = 1,
                     MostDetailedMip = 0,
                     PlaneSlice = 0,
                     ResourceMinLODClamp = 0.0f
                 }
             },
             terrainHeap.CPUDescriptorHandleForHeapStart +
              device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));

            //==========
            TerrainCBF = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);
            device.CreateConstantBufferView(
                new ConstantBufferViewDescription()
                {
                    BufferLocation = TerrainCBF.GPUVirtualAddress,
                    SizeInBytes = (Utilities.SizeOf<ConstantBufferData>() + 255) & ~255
                },
                 terrainHeap.CPUDescriptorHandleForHeapStart +
              device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView) * 2);

            TerrainCBFData = new ConstantBufferData
            {
                World = Matrix.Identity,
                View = Matrix.Identity,
                Project = Matrix.Identity,
                TexsCount = 1
            };

            TerrainCBFPointer = TerrainCBF.Map(0);

            Vertex[] TerrainVertex = new Vertex[100 * 100];
            for (int i = 0; i < 100; i++)
                for (int j = 0; j < 100; j++)
                {
                    TerrainVertex[i * 100 + j].Position = new Vector3(i, 0, j);
                    TerrainVertex[i * 100 + j].TexCoord = new Vector2(i/2 == 0? 0 : 1, j/2==0? 0 : 1);
                }
            TerrainVertexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(TerrainVertex)),
                    ResourceStates.GenericRead);
            Utilities.Write(TerrainVertexBuffer.Map(0), TerrainVertex, 0, TerrainVertex.Length);
            vertexBuffer.Unmap(0);

            TerrainVertexBufferView = new VertexBufferView()
            {
                BufferLocation = TerrainVertexBuffer.GPUVirtualAddress,
                StrideInBytes = Utilities.SizeOf<Vertex>(),
                SizeInBytes = Utilities.SizeOf(TerrainVertex)
            };
        }
        private void BuildModelResources()
        {
            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = (Utilities.SizeOf<ConstantBufferData>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            constantBufferData = new ConstantBufferData
            {
                World = Matrix.Identity,
                View = Matrix.Identity,
                Project = Matrix.Identity,
                TexsCount = 1
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            //build mesh controll buffer

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

            cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = meshCtrBuffer.GPUVirtualAddress,
                SizeInBytes = (Utilities.SizeOf<MeshCtrBufferData>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbDesc, meshCtrBufferViewHeap.CPUDescriptorHandleForHeapStart);

            meshCtrBufferData = new MeshCtrBufferData
            {
                TexsCount = 1
            };

            meshCtrBufferPointer = meshCtrBuffer.Map(0);
            Utilities.Write(meshCtrBufferPointer, ref meshCtrBufferData);

            //model test
            var modePath = "../../models/MikuDeepSea/";
            Model model = Model.LoadFromFile(modePath + "DeepSeaGirl.x");

            Vertex[] triangleVertices;
            int[] triangleIndexes;
            List<Texture> texs;
            byte[] textureData;
            GCHandle handle;
            IntPtr ptr;
            ResourceDescription textureDesc;
            //int viewStep = 0;
            int viewStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            bufferViews = new List<BufferView>();

            foreach (ModelComponent m in model.Components)
            {
                if (m.TexturePath != null)
                {
                    texs = Texture.LoadFromFile(modePath, m.TexturePath);
                }
                else
                {
                    continue;
                    //texs = Texture.LoadFromFile(modePath, "tex/jacket.png");
                }

                int texsCount = 0;
                foreach (Texture tex in texs)
                {
                    textureData = tex.Data;
                    textureDesc = ResourceDescription.Texture2D(tex.ColorFormat, tex.Width, tex.Height, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
                    // Create the texture.
                    // Describe and create a Texture2D.
                    texture = device.CreateCommittedResource(
                        new HeapProperties(HeapType.Upload),
                        HeapFlags.None,
                        textureDesc,
                        ResourceStates.GenericRead, null);

                    // Copy data to the intermediate upload heap and then schedule a copy
                    // from the upload heap to the Texture2D.

                    handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
                    ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
                    texture.WriteToSubresource(0, null, ptr, tex.Width * tex.PixelWdith, textureData.Length);
                    handle.Free();

                    // Describe and create a SRV for the texture.
                    device.CreateShaderResourceView(
                        texture,
                        new ShaderResourceViewDescription
                        {
                            Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                            Format = textureDesc.Format,
                            Dimension = ShaderResourceViewDimension.Texture2D,
                            Texture2D =
                            {
                                MipLevels = 1,
                                MostDetailedMip = 0,
                                PlaneSlice = 0,
                                ResourceMinLODClamp = 0.0f
                            }
                        },
                        shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + viewStep + texsCount * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));

                    texsCount++;
                    //break;
                }

                triangleVertices = (new Func<Vertex[]>(() =>
                {
                    var v = new Vertex[m.Vertices.Length];
                    for (int i = 0; i < m.Vertices.Length; i++)
                    {
                        v[i].Position = m.Vertices[i];
                        v[i].TexCoord = m.UV[i];
                        v[i].Normal = m.Normals[i];
                        //v[i].Tangent = m.Tangents[i];
                        //v[i].BiTangent = m.BiTangents[i];
                        v[i].Diffuse = m.Diffuse;
                        v[i].emissive = m.Emissive;
                        v[i].Specular = m.Specular;
                    }
                    return v;
                }))();
                triangleIndexes = m.Indices;

                // build vertex buffer
                vertexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(triangleVertices)),
                    ResourceStates.GenericRead);
                Utilities.Write(vertexBuffer.Map(0), triangleVertices, 0, triangleVertices.Length);
                vertexBuffer.Unmap(0);

                // build index buffer
                indexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(triangleIndexes)),
                    ResourceStates.GenericRead);
                Utilities.Write(indexBuffer.Map(0), triangleIndexes, 0, triangleIndexes.Length);
                indexBuffer.Unmap(0);

                bufferViews.Add(new BufferView()
                {
                    vertexBufferView = new VertexBufferView()
                    {
                        BufferLocation = vertexBuffer.GPUVirtualAddress,
                        StrideInBytes = Utilities.SizeOf<Vertex>(),
                        SizeInBytes = Utilities.SizeOf(triangleVertices)
                    },
                    indexBufferView = new IndexBufferView()
                    {
                        BufferLocation = indexBuffer.GPUVirtualAddress,
                        SizeInBytes = Utilities.SizeOf(triangleIndexes),
                        Format = Format.R32_UInt
                    },
                    IndexCount = triangleIndexes.Length,
                    ViewStep = viewStep,
                    TexsCount = texsCount
                });

                viewStep += texsCount * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            }

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter = Filter.MinMagMipLinear,
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
                MaximumAnisotropy = 0,
                MaximumLod = float.MaxValue,
                MinimumLod = -float.MaxValue,
                MipLodBias = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);
        }
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(

                RootSignatureFlags.AllowInputAssemblerInputLayout,
                // Root Parameters
                new[]
            {
                new RootParameter(ShaderVisibility.All,
                                  new []
                {
                    new DescriptorRange()
                    {
                        RangeType       = DescriptorRangeType.ShaderResourceView,
                        DescriptorCount = 1,
                        OffsetInDescriptorsFromTableStart = int.MinValue,
                        BaseShaderRegister = 0
                    },
                    new DescriptorRange()
                    {
                        RangeType       = DescriptorRangeType.ConstantBufferView,
                        DescriptorCount = 1,
                        OffsetInDescriptorsFromTableStart = int.MinValue + 1,
                        BaseShaderRegister = 0
                    }
                }),
                new RootParameter(ShaderVisibility.Pixel,
                                  new DescriptorRange()
                {
                    RangeType       = DescriptorRangeType.Sampler,
                    DescriptorCount = 1,
                    OffsetInDescriptorsFromTableStart = int.MinValue,
                    BaseShaderRegister = 0
                }),
            });

            //// Samplers
            //new[]
            //{
            //    new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
            //    {
            //        Filter = Filter.MinimumMinMagMipPoint,
            //        AddressUVW = TextureAddressMode.Border,
            //    }
            //});

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

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

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

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

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

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

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);
            commandList.Close();

            // build vertex buffer

            var triangleVertices = new[]
            {
                //TOP
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                //BOTTOM
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                //LEFT
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, 1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, -1f), TexCoord = new Vector2(1f, 1f)
                },
                //RIGHT
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, 1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, -1f), TexCoord = new Vector2(0f, 1f)
                },
                //FRONT
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, 1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, 1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, 1f), TexCoord = new Vector2(0f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, 1f), TexCoord = new Vector2(1f, 1f)
                },
                //BACK
                new Vertex()
                {
                    Position = new Vector3(-1f, 1f, -1f), TexCoord = new Vector2(0f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, 1f, -1f), TexCoord = new Vector2(1f, 0f)
                },
                new Vertex()
                {
                    Position = new Vector3(1f, -1f, -1f), TexCoord = new Vector2(1f, 1f)
                },
                new Vertex()
                {
                    Position = new Vector3(-1f, -1f, -1f), TexCoord = new Vector2(0f, 1f)
                }
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes  = Utilities.SizeOf <Vertex>();
            vertexBufferView.SizeInBytes    = vertexBufferSize;

            // build index buffer

            var triangleIndexes = new uint[]
            {
                0, 1, 2,
                0, 2, 3,

                4, 6, 5,
                4, 7, 6,

                8, 9, 10,
                8, 10, 11,

                12, 14, 13,
                12, 15, 14,

                16, 18, 17,
                16, 19, 18,

                20, 21, 22,
                20, 22, 23
            };

            int indexBufferSize = Utilities.SizeOf(triangleIndexes);

            indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead);
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(pIndexDataBegin, triangleIndexes, 0, triangleIndexes.Length);
            indexBuffer.Unmap(0);

            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.SizeInBytes    = indexBufferSize;
            indexBufferView.Format         = Format.R32_UInt;

            // Create the texture.
            // Describe and create a Texture2D.
            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, textureDesc, ResourceStates.GenericRead, null);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = Utilities.ReadStream(new FileStream("../../texture1.dds", FileMode.Open));

            texture.Name = "Texture";

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

            // Describe and create a SRV for the texture.
            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),

                Format    = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                },
            };

            device.CreateShaderResourceView(texture, srvDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart);

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter             = Filter.MinMagMipLinear,
                AddressU           = TextureAddressMode.Clamp,
                AddressV           = TextureAddressMode.Clamp,
                AddressW           = TextureAddressMode.Clamp,
                MaximumAnisotropy  = 0,
                MaximumLod         = float.MaxValue,
                MinimumLod         = -float.MaxValue,
                MipLodBias         = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);

            // build constant buffer

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

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBufferData>() + 255) & ~255
            };
            var srvCbvStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            device.CreateConstantBufferView(cbDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart + srvCbvStep);

            constantBufferData = new ConstantBufferData
            {
                Project = Matrix.Identity
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            // build depth buffer

            DescriptorHeapDescription descDescriptorHeapDSB = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Type            = DescriptorHeapType.DepthStencilView,
                Flags           = DescriptorHeapFlags.None
            };

            DescriptorHeap      descriptorHeapDSB = device.CreateDescriptorHeap(descDescriptorHeapDSB);
            ResourceDescription descDepth         = new ResourceDescription()
            {
                Dimension         = ResourceDimension.Texture2D,
                DepthOrArraySize  = 1,
                MipLevels         = 0,
                Flags             = ResourceFlags.AllowDepthStencil,
                Width             = (int)viewport.Width,
                Height            = (int)viewport.Height,
                Format            = Format.R32_Typeless,
                Layout            = TextureLayout.Unknown,
                SampleDescription = new SampleDescription()
                {
                    Count = 1
                }
            };

            ClearValue dsvClearValue = new ClearValue()
            {
                Format       = Format.D32_Float,
                DepthStencil = new DepthStencilValue()
                {
                    Depth   = 1.0f,
                    Stencil = 0
                }
            };

            Resource renderTargetDepth = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, descDepth, ResourceStates.GenericRead, dsvClearValue);

            DepthStencilViewDescription depthDSV = new DepthStencilViewDescription()
            {
                Dimension = DepthStencilViewDimension.Texture2D,
                Format    = Format.D32_Float,
                Texture2D = new DepthStencilViewDescription.Texture2DResource()
                {
                    MipSlice = 0
                }
            };

            device.CreateDepthStencilView(renderTargetDepth, depthDSV, descriptorHeapDSB.CPUDescriptorHandleForHeapStart);
            handleDSV = descriptorHeapDSB.CPUDescriptorHandleForHeapStart;

            fence      = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;
            fenceEvent = new AutoResetEvent(false);
        }
        private void BuildModelResources()
        {
            constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBufferData>() + 255) & ~255
            };

            device.CreateConstantBufferView(cbDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart);

            constantBufferData = new ConstantBufferData
            {
                World     = Matrix.Identity,
                View      = Matrix.Identity,
                Project   = Matrix.Identity,
                TexsCount = 1
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            //build mesh controll buffer

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

            cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = meshCtrBuffer.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <MeshCtrBufferData>() + 255) & ~255
            };
            device.CreateConstantBufferView(cbDesc, meshCtrBufferViewHeap.CPUDescriptorHandleForHeapStart);

            meshCtrBufferData = new MeshCtrBufferData
            {
                TexsCount = 1
            };

            meshCtrBufferPointer = meshCtrBuffer.Map(0);
            Utilities.Write(meshCtrBufferPointer, ref meshCtrBufferData);

            //model test
            var   modePath = "../../models/MikuDeepSea/";
            Model model    = Model.LoadFromFile(modePath + "DeepSeaGirl.x");

            Vertex[]       triangleVertices;
            int[]          triangleIndexes;
            List <Texture> texs;

            byte[]              textureData;
            GCHandle            handle;
            IntPtr              ptr;
            ResourceDescription textureDesc;
            //int viewStep = 0;
            int viewStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);

            bufferViews = new List <BufferView>();

            foreach (ModelComponent m in model.Components)
            {
                if (m.TexturePath != null)
                {
                    texs = Texture.LoadFromFile(modePath, m.TexturePath);
                }
                else
                {
                    continue;
                    //texs = Texture.LoadFromFile(modePath, "tex/jacket.png");
                }

                int texsCount = 0;
                foreach (Texture tex in texs)
                {
                    textureData = tex.Data;
                    textureDesc = ResourceDescription.Texture2D(tex.ColorFormat, tex.Width, tex.Height, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
                    // Create the texture.
                    // Describe and create a Texture2D.
                    texture = device.CreateCommittedResource(
                        new HeapProperties(HeapType.Upload),
                        HeapFlags.None,
                        textureDesc,
                        ResourceStates.GenericRead, null);

                    // Copy data to the intermediate upload heap and then schedule a copy
                    // from the upload heap to the Texture2D.

                    handle = GCHandle.Alloc(textureData, GCHandleType.Pinned);
                    ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0);
                    texture.WriteToSubresource(0, null, ptr, tex.Width * tex.PixelWdith, textureData.Length);
                    handle.Free();

                    // Describe and create a SRV for the texture.
                    device.CreateShaderResourceView(
                        texture,
                        new ShaderResourceViewDescription
                    {
                        Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                        Format    = textureDesc.Format,
                        Dimension = ShaderResourceViewDimension.Texture2D,
                        Texture2D =
                        {
                            MipLevels           = 1,
                            MostDetailedMip     = 0,
                            PlaneSlice          = 0,
                            ResourceMinLODClamp = 0.0f
                        }
                    },
                        shaderRenderViewHeap.CPUDescriptorHandleForHeapStart + viewStep + texsCount * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));

                    texsCount++;
                    //break;
                }

                triangleVertices = (new Func <Vertex[]>(() =>
                {
                    var v = new Vertex[m.Vertices.Length];
                    for (int i = 0; i < m.Vertices.Length; i++)
                    {
                        v[i].Position = m.Vertices[i];
                        v[i].TexCoord = m.UV[i];
                        v[i].Normal = m.Normals[i];
                        //v[i].Tangent = m.Tangents[i];
                        //v[i].BiTangent = m.BiTangents[i];
                        v[i].Diffuse = m.Diffuse;
                        v[i].emissive = m.Emissive;
                        v[i].Specular = m.Specular;
                    }
                    return(v);
                }))();
                triangleIndexes = m.Indices;

                // build vertex buffer
                vertexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(triangleVertices)),
                    ResourceStates.GenericRead);
                Utilities.Write(vertexBuffer.Map(0), triangleVertices, 0, triangleVertices.Length);
                vertexBuffer.Unmap(0);

                // build index buffer
                indexBuffer = device.CreateCommittedResource(
                    new HeapProperties(HeapType.Upload),
                    HeapFlags.None,
                    ResourceDescription.Buffer(Utilities.SizeOf(triangleIndexes)),
                    ResourceStates.GenericRead);
                Utilities.Write(indexBuffer.Map(0), triangleIndexes, 0, triangleIndexes.Length);
                indexBuffer.Unmap(0);

                bufferViews.Add(new BufferView()
                {
                    vertexBufferView = new VertexBufferView()
                    {
                        BufferLocation = vertexBuffer.GPUVirtualAddress,
                        StrideInBytes  = Utilities.SizeOf <Vertex>(),
                        SizeInBytes    = Utilities.SizeOf(triangleVertices)
                    },
                    indexBufferView = new IndexBufferView()
                    {
                        BufferLocation = indexBuffer.GPUVirtualAddress,
                        SizeInBytes    = Utilities.SizeOf(triangleIndexes),
                        Format         = Format.R32_UInt
                    },
                    IndexCount = triangleIndexes.Length,
                    ViewStep   = viewStep,
                    TexsCount  = texsCount
                });

                viewStep += texsCount * device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            }

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter             = Filter.MinMagMipLinear,
                AddressU           = TextureAddressMode.Clamp,
                AddressV           = TextureAddressMode.Clamp,
                AddressW           = TextureAddressMode.Clamp,
                MaximumAnisotropy  = 0,
                MaximumLod         = float.MaxValue,
                MinimumLod         = -float.MaxValue,
                MipLodBias         = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);
        }
        private void BuildTerrainResouces()
        {
            float[] HeightMapData = new float[100 * 100];
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    HeightMapData[i * 100 + j] = Convert.ToSingle(Math.Cos(Math.PI * 2 * i) * Math.Sin(Math.PI * 2 * j));
                }
            }
            var Tex = Texture.LoadFromFile("../../", "Terrain.jpg");

            ResourceDescription HeighMapDesc       = ResourceDescription.Texture2D(Format.R32_Float, 100, 100, 1);
            ResourceDescription TerrainTextureDesc = ResourceDescription.Texture2D(Tex[0].ColorFormat, Tex[0].Width, Tex[0].Height, 1);

            HeightMap = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                HeighMapDesc,
                ResourceStates.GenericRead, null);
            TerrainTexture = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                HeighMapDesc,
                ResourceStates.GenericRead, null);
            TerrainCBF = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(1024 * 64),
                ResourceStates.GenericRead);

            GCHandle handle = GCHandle.Alloc(HeightMapData, GCHandleType.Pinned);
            IntPtr   ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(HeightMapData, 0);

            HeightMap.WriteToSubresource(0, null, ptr, 100 * 4, HeightMapData.Length);
            handle.Free();

            handle = GCHandle.Alloc(Tex[0].Data, GCHandleType.Pinned);
            ptr    = Marshal.UnsafeAddrOfPinnedArrayElement(Tex[0].Data, 0);
            TerrainTexture.WriteToSubresource(0, null, ptr, Tex[0].Width * Tex[0].PixelWdith, Tex[0].Data.Length);
            handle.Free();

            device.CreateShaderResourceView(
                HeightMap,
                new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                Format    = HeighMapDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                }
            },
                terrainHeap.CPUDescriptorHandleForHeapStart);

            device.CreateShaderResourceView(
                TerrainTexture,
                new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) | (((1) & 0x7) << 3) | (((2) & 0x7) << (3 * 2)) | (((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),
                Format    = HeighMapDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels           = 1,
                    MostDetailedMip     = 0,
                    PlaneSlice          = 0,
                    ResourceMinLODClamp = 0.0f
                }
            },
                terrainHeap.CPUDescriptorHandleForHeapStart +
                device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView));

            //==========
            TerrainCBF = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead);
            device.CreateConstantBufferView(
                new ConstantBufferViewDescription()
            {
                BufferLocation = TerrainCBF.GPUVirtualAddress,
                SizeInBytes    = (Utilities.SizeOf <ConstantBufferData>() + 255) & ~255
            },
                terrainHeap.CPUDescriptorHandleForHeapStart +
                device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView) * 2);

            TerrainCBFData = new ConstantBufferData
            {
                World     = Matrix.Identity,
                View      = Matrix.Identity,
                Project   = Matrix.Identity,
                TexsCount = 1
            };

            TerrainCBFPointer = TerrainCBF.Map(0);

            Vertex[] TerrainVertex = new Vertex[100 * 100];
            for (int i = 0; i < 100; i++)
            {
                for (int j = 0; j < 100; j++)
                {
                    TerrainVertex[i * 100 + j].Position = new Vector3(i, 0, j);
                    TerrainVertex[i * 100 + j].TexCoord = new Vector2(i / 2 == 0? 0 : 1, j / 2 == 0? 0 : 1);
                }
            }
            TerrainVertexBuffer = device.CreateCommittedResource(
                new HeapProperties(HeapType.Upload),
                HeapFlags.None,
                ResourceDescription.Buffer(Utilities.SizeOf(TerrainVertex)),
                ResourceStates.GenericRead);
            Utilities.Write(TerrainVertexBuffer.Map(0), TerrainVertex, 0, TerrainVertex.Length);
            vertexBuffer.Unmap(0);

            TerrainVertexBufferView = new VertexBufferView()
            {
                BufferLocation = TerrainVertexBuffer.GPUVirtualAddress,
                StrideInBytes  = Utilities.SizeOf <Vertex>(),
                SizeInBytes    = Utilities.SizeOf(TerrainVertex)
            };
        }
        private void LoadAssets()
        {
            // Create the root signature description.
            var rootSignatureDesc = new RootSignatureDescription(

                RootSignatureFlags.AllowInputAssemblerInputLayout,
                // Root Parameters
                new[]
                {
                    new RootParameter(ShaderVisibility.All,
                        new []
                        {
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ShaderResourceView,
                                DescriptorCount = 1,
                                OffsetInDescriptorsFromTableStart = int.MinValue,
                                BaseShaderRegister = 0
                            },
                            new DescriptorRange()
                            {
                                RangeType = DescriptorRangeType.ConstantBufferView,
                                DescriptorCount = 1,
                                OffsetInDescriptorsFromTableStart = int.MinValue + 1,
                                BaseShaderRegister = 0
                            }
                        }),
                    new RootParameter(ShaderVisibility.Pixel,
                        new DescriptorRange()
                        {
                            RangeType = DescriptorRangeType.Sampler,
                            DescriptorCount = 1,
                            OffsetInDescriptorsFromTableStart = int.MinValue,
                            BaseShaderRegister = 0
                        }),
                });
                //// Samplers
                //new[]
                //{
                //    new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0)
                //    {
                //        Filter = Filter.MinimumMinMagMipPoint,
                //        AddressUVW = TextureAddressMode.Border,
                //    }
                //});

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

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

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

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

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

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

            pipelineState = device.CreateGraphicsPipelineState(psoDesc);

            commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState);
            commandList.Close();

            // build vertex buffer

            var triangleVertices = new[]
            {
                //TOP
                new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                //BOTTOM
                new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                //LEFT
                new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,1f)} ,
                //RIGHT
                new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,1f)} ,
                //FRONT
                new Vertex() {Position = new Vector3(-1f , 1f , 1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(1f , 1f , 1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f , 1f) , TexCoord = new Vector2(0f ,1f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f , 1f) , TexCoord = new Vector2(1f ,1f)} ,
                //BACK
                new Vertex() {Position = new Vector3(-1f , 1f ,-1f) , TexCoord = new Vector2(0f ,0f)} ,
                new Vertex() {Position = new Vector3(1f , 1f ,-1f) , TexCoord = new Vector2(1f ,0f)} ,
                new Vertex() {Position = new Vector3(1f ,-1f ,-1f) , TexCoord = new Vector2(1f ,1f)} ,
                new Vertex() {Position = new Vector3(-1f ,-1f ,-1f) , TexCoord = new Vector2(0f ,1f)}
            };

            int vertexBufferSize = Utilities.SizeOf(triangleVertices);

            vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead);
            IntPtr pVertexDataBegin = vertexBuffer.Map(0);
            Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length);
            vertexBuffer.Unmap(0);

            vertexBufferView = new VertexBufferView();
            vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress;
            vertexBufferView.StrideInBytes = Utilities.SizeOf<Vertex>();
            vertexBufferView.SizeInBytes = vertexBufferSize;

            // build index buffer

            var triangleIndexes = new uint[]
            {
                0,1,2,
                0,2,3,

                4,6,5,
                4,7,6,

                8,9,10,
                8,10,11,

                12,14,13,
                12,15,14,

                16,18,17,
                16,19,18,

                20,21,22,
                20,22,23
            };

            int indexBufferSize = Utilities.SizeOf(triangleIndexes);

            indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead);
            IntPtr pIndexDataBegin = indexBuffer.Map(0);
            Utilities.Write(pIndexDataBegin, triangleIndexes, 0, triangleIndexes.Length);
            indexBuffer.Unmap(0);

            indexBufferView = new IndexBufferView();
            indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress;
            indexBufferView.SizeInBytes = indexBufferSize;
            indexBufferView.Format = Format.R32_UInt;

            // Create the texture.
            // Describe and create a Texture2D.
            var textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight, 1, 1, 1, 0, ResourceFlags.None, TextureLayout.Unknown, 0);
            texture = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, textureDesc, ResourceStates.GenericRead, null);

            // Copy data to the intermediate upload heap and then schedule a copy
            // from the upload heap to the Texture2D.
            byte[] textureData = Utilities.ReadStream(new FileStream("../../texture1.dds", FileMode.Open));

            texture.Name = "Texture";

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

            // Describe and create a SRV for the texture.
            var srvDesc = new ShaderResourceViewDescription
            {
                Shader4ComponentMapping = ((((0) & 0x7) |(((1) & 0x7) << 3) |(((2) & 0x7) << (3 * 2)) |(((3) & 0x7) << (3 * 3)) | (1 << (3 * 4)))),

                Format = textureDesc.Format,
                Dimension = ShaderResourceViewDimension.Texture2D,
                Texture2D =
                {
                    MipLevels = 1,
                    MostDetailedMip = 0,
                    PlaneSlice = 0,
                    ResourceMinLODClamp = 0.0f
                },
            };

            device.CreateShaderResourceView(texture, srvDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart);

            SamplerStateDescription samplerDesc = new SamplerStateDescription
            {
                Filter = Filter.MinMagMipLinear,
                AddressU = TextureAddressMode.Clamp,
                AddressV = TextureAddressMode.Clamp,
                AddressW = TextureAddressMode.Clamp,
                MaximumAnisotropy = 0,
                MaximumLod = float.MaxValue,
                MinimumLod = -float.MaxValue,
                MipLodBias = 0,
                ComparisonFunction = Comparison.Never
            };

            device.CreateSampler(samplerDesc, samplerViewHeap.CPUDescriptorHandleForHeapStart);

            // build constant buffer

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

            var cbDesc = new ConstantBufferViewDescription()
            {
                BufferLocation = constantBuffer.GPUVirtualAddress,
                SizeInBytes = (Utilities.SizeOf<ConstantBufferData>() + 255) & ~255
            };
            var srvCbvStep = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView);
            device.CreateConstantBufferView(cbDesc, srvCbvHeap.CPUDescriptorHandleForHeapStart + srvCbvStep);

            constantBufferData = new ConstantBufferData
            {
                Project = Matrix.Identity
            };

            constantBufferPointer = constantBuffer.Map(0);
            Utilities.Write(constantBufferPointer, ref constantBufferData);

            // build depth buffer

            DescriptorHeapDescription descDescriptorHeapDSB = new DescriptorHeapDescription()
            {
                DescriptorCount = 1,
                Type = DescriptorHeapType.DepthStencilView,
                Flags = DescriptorHeapFlags.None
            };

            DescriptorHeap descriptorHeapDSB = device.CreateDescriptorHeap(descDescriptorHeapDSB);
            ResourceDescription descDepth = new ResourceDescription()
            {
                Dimension = ResourceDimension.Texture2D,
                DepthOrArraySize = 1,
                MipLevels = 0,
                Flags = ResourceFlags.AllowDepthStencil,
                Width = (int)viewport.Width,
                Height = (int)viewport.Height,
                Format = Format.R32_Typeless,
                Layout = TextureLayout.Unknown,
                SampleDescription = new SampleDescription() { Count = 1 }
            };

            ClearValue dsvClearValue = new ClearValue()
            {
                Format = Format.D32_Float,
                DepthStencil = new DepthStencilValue()
                {
                    Depth = 1.0f,
                    Stencil = 0
                }
            };

            Resource renderTargetDepth = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, descDepth, ResourceStates.GenericRead, dsvClearValue);

            DepthStencilViewDescription depthDSV = new DepthStencilViewDescription()
            {
                Dimension = DepthStencilViewDimension.Texture2D,
                Format = Format.D32_Float,
                Texture2D = new DepthStencilViewDescription.Texture2DResource()
                {
                    MipSlice = 0
                }
            };

            device.CreateDepthStencilView(renderTargetDepth, depthDSV, descriptorHeapDSB.CPUDescriptorHandleForHeapStart);
            handleDSV = descriptorHeapDSB.CPUDescriptorHandleForHeapStart;

            fence = device.CreateFence(0, FenceFlags.None);
            fenceValue = 1;
            fenceEvent = new AutoResetEvent(false);
        }