private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat, StreamOutput = new StreamOutputDescription() //find out how this should actually be done later }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for opaque wireframe objects. // var opaqueWireframePsoDesc = opaquePsoDesc; opaqueWireframePsoDesc.RasterizerState.FillMode = FillMode.Wireframe; _psos["opaque_wireframe"] = Device.CreateGraphicsPipelineState(opaqueWireframePsoDesc); }
private BlendState CreateBlendState(bool isBlendEnabled, Blend sourceBlend, Blend destinationBlend, BlendOperation blendOperation, Blend sourceAlphaBlend, Blend destinationAlphaBlend, BlendOperation blendOperationAlpha) { var blendStateDescription = BlendStateDescription.Default(); for (var i = 0; i < 8; i++) { blendStateDescription.RenderTarget[i].IsBlendEnabled = true; blendStateDescription.RenderTarget[i].SourceBlend = sourceBlend.ToSharpDX(); blendStateDescription.RenderTarget[i].DestinationBlend = destinationBlend.ToSharpDX(); blendStateDescription.RenderTarget[i].BlendOperation = blendOperation.ToSharpDX(); blendStateDescription.RenderTarget[i].SourceAlphaBlend = sourceAlphaBlend.ToSharpDX(); blendStateDescription.RenderTarget[i].DestinationAlphaBlend = destinationAlphaBlend.ToSharpDX(); blendStateDescription.RenderTarget[i].AlphaBlendOperation = blendOperationAlpha.ToSharpDX(); blendStateDescription.RenderTarget[i].RenderTargetWriteMask = ColorWriteMaskFlags.All; } var blendState = new BlendState(_graphicsDevice, blendStateDescription); return(blendState); }
public Device(RenderForm form, bool debug = false) { View = form; // SwapChain description var desc = new SwapChainDescription() { BufferCount = 1,//buffer count ModeDescription = new ModeDescription(View.ClientSize.Width, View.ClientSize.Height, new Rational(60, 1), Format.B8G8R8A8_UNorm), IsWindowed = true, OutputHandle = View.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; FeatureLevel[] levels = new FeatureLevel[] { FeatureLevel.Level_11_1 }; //create device and swapchain DeviceCreationFlags flag = DeviceCreationFlags.None | DeviceCreationFlags.BgraSupport; if (debug) { flag = DeviceCreationFlags.Debug; } Device11.CreateWithSwapChain(DriverType.Hardware, flag, levels, desc, out var nativeDevice, out swapChain); NativeDevice = nativeDevice; //get context to device NativeDeviceContext = NativeDevice.ImmediateContext; //Ignore all windows events var factory = swapChain.GetParent <Factory>(); factory.MakeWindowAssociation(View.Handle, WindowAssociationFlags.IgnoreAll); //Setup handler on resize form View.UserResized += (sender, args) => ResizeBuffers = true; { Utilities.Dispose(ref rasterizerState); RasterizerStateDescription rasterDescription = RasterizerStateDescription.Default(); //rasterDescription.CullMode = CullMode.Back; rasterizerState = new RasterizerState(NativeDevice, rasterDescription); NativeDeviceContext.Rasterizer.State = rasterizerState; } { Utilities.Dispose(ref blendState); BlendStateDescription description = BlendStateDescription.Default(); blendState = new BlendState(NativeDevice, description); } { Utilities.Dispose(ref depthStencilState); DepthStencilStateDescription description = DepthStencilStateDescription.Default(); description.DepthComparison = Comparison.LessEqual; description.IsDepthEnabled = true; depthStencilState = new DepthStencilState(NativeDevice, description); } { Utilities.Dispose(ref samplerState); SamplerStateDescription description = SamplerStateDescription.Default(); description.Filter = Filter.MinMagMipLinear; description.AddressU = TextureAddressMode.Wrap; description.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(NativeDevice, description); } { NativeDeviceContext.Rasterizer.State = rasterizerState; NativeDeviceContext.PixelShader.SetSampler(0, samplerState); NativeDeviceContext.PixelShader.SetSampler(1, samplerState); NativeDeviceContext.PixelShader.SetSampler(2, samplerState); NativeDeviceContext.PixelShader.SetSampler(3, samplerState); NativeDeviceContext.PixelShader.SetSampler(4, samplerState); NativeDeviceContext.PixelShader.SetSampler(5, samplerState); NativeDeviceContext.PixelShader.SetSampler(6, samplerState); NativeDeviceContext.OutputMerger.SetBlendState(blendState); NativeDeviceContext.OutputMerger.SetDepthStencilState(depthStencilState); } Canvas = new Canvas(this); Resize(); }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat, StreamOutput = new StreamOutputDescription() //find out how this should actually be done later }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); // // PSO for drawing waves. // GraphicsPipelineStateDescription wavesRenderPSO = transparentPsoDesc.Copy(); wavesRenderPSO.VertexShader = _shaders["wavesVS"]; _psos["wavesRender"] = Device.CreateGraphicsPipelineState(wavesRenderPSO); // // PSO for compositing post process. // GraphicsPipelineStateDescription compositePSO = opaquePsoDesc.Copy(); compositePSO.RootSignature = _postProcessRootSignature; // Disable depth test. compositePSO.DepthStencilState.IsDepthEnabled = false; compositePSO.DepthStencilState.DepthWriteMask = DepthWriteMask.Zero; compositePSO.DepthStencilState.DepthComparison = Comparison.Always; compositePSO.VertexShader = _shaders["compositeVS"]; compositePSO.PixelShader = _shaders["compositePS"]; _psos["composite"] = Device.CreateGraphicsPipelineState(compositePSO); // // PSO for disturbing waves. // var wavesDisturbPSO = new ComputePipelineStateDescription { RootSignaturePointer = _wavesRootSignature, ComputeShader = _shaders["wavesDisturbCS"], Flags = PipelineStateFlags.None }; _psos["wavesDisturb"] = Device.CreateComputePipelineState(wavesDisturbPSO); // // PSO for updating waves. // var wavesUpdatePSO = new ComputePipelineStateDescription { RootSignaturePointer = _wavesRootSignature, ComputeShader = _shaders["wavesUpdateCS"], Flags = PipelineStateFlags.None }; _psos["wavesUpdate"] = Device.CreateComputePipelineState(wavesUpdatePSO); // // PSO for sobel. // var sobelPSO = new ComputePipelineStateDescription { RootSignaturePointer = _postProcessRootSignature, ComputeShader = _shaders["sobelCS"], Flags = PipelineStateFlags.None }; _psos["sobel"] = Device.CreateComputePipelineState(sobelPSO); }
public void BuildPSO(Device3 device, GraphicsCommandList commandList) { World = Matrix.Translation(-2.5f, -2.5f, -2.5f); buffer.World = World; light = new Lighting { GlobalAmbientX = 1, GlobalAmbientY = 1, GlobalAmbientZ = 1, KaX = .1f, KaY = .1f, KaZ = .1f, KdX = .5f, KdY = .5f, KdZ = .5f, KeX = .25f, KeY = .25f, KeZ = .25f, KsX = .1f, KsY = .1f, KsZ = .1f, LightColorX = 1, LightColorY = 1, LightColorZ = 1, LightPositionX = 10, LightPositionY = 10, LightPositionZ = 10, shininess = 5 }; DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc); //setup descriptor ranges DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } }; //Get sampler state setup StaticSamplerDescription sampler = new StaticSamplerDescription() { Filter = Filter.MinimumMinMagMipPoint, AddressU = TextureAddressMode.Border, AddressV = TextureAddressMode.Border, AddressW = TextureAddressMode.Border, MipLODBias = 0, MaxAnisotropy = 0, ComparisonFunc = Comparison.Never, BorderColor = StaticBorderColor.TransparentBlack, MinLOD = 0.0f, MaxLOD = float.MaxValue, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.Pixel, }; Projection = Matrix.PerspectiveFovLH((float)Math.PI / 3f, 4f / 3f, 1, 1000); View = Matrix.LookAtLH(new Vector3(10 * (float)Math.Sin(rotation), 5, 10 * (float)Math.Cos(rotation)), Vector3.Zero, Vector3.UnitY); World = Matrix.Translation(-2.5f, -2.5f, -2.5f); DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _objectViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); _lightingViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges), new RootParameter(ShaderVisibility.All, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.All, new RootDescriptor(2, 0), RootParameterType.ConstantBufferView) }; // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler }); _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/LitVertex.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 24, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = _rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D24_UNorm_S8_UInt, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; _pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { //Front new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitZ }, //Back new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitZ }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitZ }, //Left new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitX }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitX }, //Right new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitX }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitX }, //Top new Vertex() { Position = new Vector3(0, 0, 0), TexCoord = new Vector2(1, 1), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(0, 0, 5), TexCoord = new Vector2(1, 0), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 0, 0), TexCoord = new Vector2(0, 1), Normal = -Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 0, 5), TexCoord = new Vector2(0, 0), Normal = -Vector3.UnitY }, //Bottom new Vertex() { Position = new Vector3(0, 5, 0), TexCoord = new Vector2(1, 1), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(0, 5, 5), TexCoord = new Vector2(1, 0), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 5, 0), TexCoord = new Vector2(0, 1), Normal = Vector3.UnitY }, new Vertex() { Position = new Vector3(5, 5, 5), TexCoord = new Vector2(0, 0), Normal = Vector3.UnitY } }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = _vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); _vertexBuffer.Unmap(0); _indicies = new int[] { 0, 1, 2, 3, 2, 1, 6, 5, 4, 5, 6, 7, 10, 9, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 18, 17, 16, 17, 18, 19, 20, 21, 22, 23, 22, 21 }; int indBufferSize = Utilities.SizeOf(_indicies); _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead); IntPtr pIndBegin = _indexBuffer.Map(0); Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length); _indexBuffer.Unmap(0); _indexBufferView = new IndexBufferView() { BufferLocation = _indexBuffer.GPUVirtualAddress, Format = Format.R32_UInt, SizeInBytes = indBufferSize }; // Initialize the vertex buffer view. _vertexBufferView = new VertexBufferView { BufferLocation = _vertexBuffer.GPUVirtualAddress, StrideInBytes = Utilities.SizeOf <Vertex>(), SizeInBytes = vertexBufferSize }; _objectBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <ObjectData>()), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = _objectBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <ObjectData>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc, _objectViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _objectPointer = _objectBuffer.Map(0); Utilities.Write(_objectPointer, ref buffer); _lightingBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(Utilities.SizeOf <Lighting>()), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc2 = new ConstantBufferViewDescription() { BufferLocation = _objectBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <Lighting>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc2, _lightingViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _lightingPointer = _lightingBuffer.Map(0); Utilities.Write(_lightingPointer, ref light); Resource textureUploadHeap; // Create the texture. // Describe and create a Texture2D. ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight); _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1); // Create the GPU upload buffer. textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, }; srvDesc.Texture2D.MipLevels = 1; device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart); _resources = new[] { new GraphicsResource() { Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable }, new GraphicsResource() { Resource = _objectBuffer, Register = 2, type = ResourceType.ConstantBufferView }, new GraphicsResource() { Resource = _lightingBuffer, Register = 1, type = ResourceType.ConstantBufferView } }; }
/// <summary> /// Setup resources for rendering /// </summary> void LoadAssets() { // Create the main command list commandList = Collect(device.CreateCommandList(CommandListType.Direct, commandListAllocator, pipelineState)); // Create the descriptor heap for the render target view descriptorHeapRT = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.RenderTargetView, DescriptorCount = 1 })); #if USE_DEPTH descriptorHeapDS = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.DepthStencilView, DescriptorCount = 1 })); #endif #if USE_TEXTURE descriptorHeapCB = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, DescriptorCount = 2, Flags = DescriptorHeapFlags.ShaderVisible, })); descriptorHeapS = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.Sampler, DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, })); descriptorsHeaps[0] = descriptorHeapCB; descriptorsHeaps[1] = descriptorHeapS; #else descriptorHeapCB = Collect(device.CreateDescriptorHeap(new DescriptorHeapDescription() { Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, })); descriptorsHeaps[0] = descriptorHeapCB; #endif #if true // root signature in code var rsparams = new RootParameter[] { new RootParameter(ShaderVisibility.Vertex, new RootDescriptor(), RootParameterType.ConstantBufferView), new RootParameter(ShaderVisibility.Vertex, new DescriptorRange { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 1, DescriptorCount = 1, }), #if USE_TEXTURE new RootParameter(ShaderVisibility.Pixel, new DescriptorRange { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, DescriptorCount = 1, }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange { RangeType = DescriptorRangeType.Sampler, BaseShaderRegister = 0, DescriptorCount = 1, }), #endif }; var rs = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rsparams); rootSignature = Collect(device.CreateRootSignature(rs.Serialize())); #else var rootSignatureByteCode = Utilities.ReadStream(assembly.GetManifestResourceStream("Shaders.Cube" + shaderNameSuffix + ".rs")); using (var bufferRootSignature = DataBuffer.Create(rootSignatureByteCode)) rootSignature = Collect(device.CreateRootSignature(bufferRootSignature)); #endif byte[] vertexShaderByteCode = GetResourceBytes("Cube" + shaderNameSuffix + ".vso"); byte[] pixelShaderByteCode = GetResourceBytes("Cube" + shaderNameSuffix + ".pso"); var layout = new InputLayoutDescription(new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 0), #if USE_INSTANCES new InputElement("OFFSET", 0, Format.R32G32B32_Float, 0, 1, InputClassification.PerInstanceData, 1), #endif }); #region pipeline state var psd = new GraphicsPipelineStateDescription { InputLayout = layout, VertexShader = vertexShaderByteCode, PixelShader = pixelShaderByteCode, RootSignature = rootSignature, DepthStencilState = DepthStencilStateDescription.Default(), DepthStencilFormat = Format.Unknown, BlendState = BlendStateDescription.Default(), RasterizerState = RasterizerStateDescription.Default(), SampleDescription = new SampleDescription(1, 0), RenderTargetCount = 1, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, SampleMask = -1, StreamOutput = new StreamOutputDescription() }; psd.RenderTargetFormats[0] = Format.R8G8B8A8_UNorm; #if USE_DEPTH psd.DepthStencilFormat = Format.D32_Float; #else psd.DepthStencilState.IsDepthEnabled = false; #endif //psd.RasterizerState.CullMode = CullMode.None; pipelineState = Collect(device.CreateGraphicsPipelineState(psd)); #endregion pipeline state #region vertices var vertices = new[] { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Front -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // BACK -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // BACK 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Top -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Top -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Bottom -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Bottom 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Left -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Left -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Right 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // Right 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, }; #endregion vertices #region vertex buffer // Instantiate Vertex buiffer from vertex data int sizeOfFloat = sizeof(float); int sizeInBytes = vertices.Length * sizeOfFloat; vertexBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); vertexBufferView = new[] { new VertexBufferView { BufferLocation = vertexBuffer.GPUVirtualAddress, SizeInBytes = sizeInBytes, StrideInBytes = sizeOfFloat * 8, } }; var ptr = vertexBuffer.Map(0); Utilities.Write(ptr, vertices, 0, vertices.Length); vertexBuffer.Unmap(0); #endregion vertex buffer #region instances #if USE_INSTANCES int instanceSizeInBytes = sizeOfFloat * instances.Length; instancesBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, instanceSizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); instancesBufferView = new[] { new VertexBufferView { BufferLocation = instancesBuffer.GPUVirtualAddress, SizeInBytes = instanceSizeInBytes, StrideInBytes = sizeOfFloat * 3, } }; ptr = instancesBuffer.Map(0); Utilities.Write(ptr, instances, 0, instances.Length); instancesBuffer.Unmap(0); #endif #endregion instances #region indices #if USE_INDICES var indexData = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 }; sizeInBytes = indexData.Length * sizeof(int); indexBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, sizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); ptr = indexBuffer.Map(0); Utilities.Write(ptr, indexData, 0, indexData.Length); indexBuffer.Unmap(0); indexBufferView = new IndexBufferView { BufferLocation = indexBuffer.GPUVirtualAddress, SizeInBytes = sizeInBytes, Format = Format.R32_UInt }; #endif #endregion indices #region transform transWorld = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, 16 * sizeOfMatrix, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); transWorldPtr = transWorld.Map(0); transViewProj = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription(ResourceDimension.Buffer, 0, sizeOfMatrix, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead)); device.CreateConstantBufferView(new ConstantBufferViewDescription { BufferLocation = transViewProj.GPUVirtualAddress, SizeInBytes = sizeOfMatrix, }, descriptorHeapCB.CPUDescriptorHandleForHeapStart); var view = Matrix.LookAtLH(new Vector3(5, 5, -5), Vector3.Zero, Vector3.UnitY); var proj = Matrix.PerspectiveFovLH(MathUtil.Pi / 4, (float)width / height, 0.1f, 100); var vpT = view * proj; vpT.Transpose(); ptr = transViewProj.Map(0); Utilities.Write(ptr, ref vpT); transViewProj.Unmap(0); #endregion transform #if USE_TEXTURE #region texture Resource buf; using (var tl = new TextureLoader("GeneticaMortarlessBlocks.jpg")) { int w = tl.Width, h = tl.Height; var descrs = new[] { new ResourceDescription(ResourceDimension.Texture2D, 0, w, h, 1, 1, Format.B8G8R8A8_UNorm, 1, 0, TextureLayout.Unknown, ResourceFlags.None), }; texture = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Default), HeapFlags.None, descrs[0], ResourceStates.CopyDestination) ); var resAllocInfo = device.GetResourceAllocationInfo(1, 1, descrs); buf = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, new ResourceDescription( ResourceDimension.Buffer, 0, resAllocInfo.SizeInBytes, 1, 1, 1, Format.Unknown, 1, 0, TextureLayout.RowMajor, ResourceFlags.None), ResourceStates.GenericRead); var ptrBuf = buf.Map(0); int rowPitch = tl.CopyImageData(ptrBuf); buf.Unmap(0); var src = new TextureCopyLocation(buf, new PlacedSubResourceFootprint { Offset = 0, Footprint = new SubResourceFootprint { Format = Format.B8G8R8A8_UNorm_SRgb, Width = w, Height = h, Depth = 1, RowPitch = rowPitch } } ); var dst = new TextureCopyLocation(texture, 0); // record copy commandList.CopyTextureRegion(dst, 0, 0, 0, src, null); commandList.ResourceBarrierTransition(texture, ResourceStates.CopyDestination, ResourceStates.GenericRead); } descrOffsetCB = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); device.CreateShaderResourceView(texture, null, descriptorHeapCB.CPUDescriptorHandleForHeapStart + descrOffsetCB); #endregion texture #region sampler device.CreateSampler(new SamplerStateDescription { AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, Filter = Filter.MaximumMinMagMipLinear, }, descriptorHeapS.CPUDescriptorHandleForHeapStart); #endregion sampler #endif // Get the backbuffer and creates the render target view renderTarget = Collect(swapChain.GetBackBuffer <Resource>(0)); device.CreateRenderTargetView(renderTarget, null, descriptorHeapRT.CPUDescriptorHandleForHeapStart); #if USE_DEPTH depthBuffer = Collect(device.CreateCommittedResource( new HeapProperties(HeapType.Default), HeapFlags.None, new ResourceDescription(ResourceDimension.Texture2D, 0, width, height, 1, 1, Format.D32_Float, 1, 0, TextureLayout.Unknown, ResourceFlags.AllowDepthStencil), ResourceStates.Present, new ClearValue { Format = Format.D32_Float, DepthStencil = new DepthStencilValue { Depth = 1, Stencil = 0, } })); device.CreateDepthStencilView(depthBuffer, null, descriptorHeapDS.CPUDescriptorHandleForHeapStart); #endif // Create the viewport viewPort = new ViewportF(0, 0, width, height); // Create the scissor scissorRectangle = new Rectangle(0, 0, width, height); // Create a fence to wait for next frame fence = Collect(device.CreateFence(0, FenceFlags.None)); currentFence = 1; // Close command list commandList.Close(); commandQueue.ExecuteCommandList(commandList); // Create an event handle use for VTBL CreateWaitEvent(); // Wait the command list to complete WaitForPrevFrame(); #if USE_TEXTURE buf.Dispose(); #endif }
//创建资源 private void LoadAssets() { //创建一个空的根签名 var rootSignatureDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, //根常量 new[] { new RootParameter(ShaderVisibility.All, //指定可以访问根签名绑定的内容的着色器,这里设置为顶点着色器 new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, //指定描述符范围,这里的参数是CBV BaseShaderRegister = 0, //指定描述符范围内的基本着色器 OffsetInDescriptorsFromTableStart = int.MinValue, //描述符从根签名开始的偏移量 DescriptorCount = 1 //描述符范围内的描述符数 }) }); //表示该根签名需要一组顶点缓冲区来绑定 rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); //创建流水线状态,负责编译和加载着色器 #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VS", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VS", "vs_5_0")); #endif //#if DEBUG // var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PS", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); //#else // var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PS", "ps_5_0")); //#endif //描述输入装配器阶段的输入元素,这里定义顶点输入布局 var inputElementDescs = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0) }; //创建流水线状态对象(PSO) var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), //描述输入缓冲器 RootSignature = rootSignature, //根签名 VertexShader = vertexShader, //顶点着色器 //PixelShader = pixelShader,//像素着色器 RasterizerState = RasterizerStateDescription.Default(), //描述光栅器状态 BlendState = BlendStateDescription.Default(), //描述混合状态 DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, //描述深度/模板格式(纹理资源) DepthStencilState = DepthStencilStateDescription.Default(), //描述深度模板状态 SampleMask = int.MaxValue, //混合状态的样本掩码 PrimitiveTopologyType = PrimitiveTopologyType.Triangle, //定义该管道的几何或外壳着色器的输入类型,这里是三角 RenderTargetCount = 1, //RTVFormat成员中的渲染目标格式数 Flags = PipelineStateFlags.None, //用于控制管道状态的标志,这里表示没有标志 SampleDescription = new SampleDescription(1, 0), //描述资源的多采样参数 StreamOutput = new StreamOutputDescription() //描述输出缓冲器 }; psoDesc.RenderTargetFormats[0] = Format.R8G8B8A8_UNorm; //描述渲染目标格式的数组 //设置管道 pipelineState = device.CreateGraphicsPipelineState(psoDesc); //创建命令列表 commandList = device.CreateCommandList( CommandListType.Direct, //指定命令列表的创建类型,Direct命令列表不会继承任何GPU状态 commandAllocator, //指向设备创建的命令列表对象的指针 pipelineState); //指向(管道)内存块的指针 commandList.Close(); float aspectRatio = viewPort.Width / viewPort.Height; //定义待绘制图形的几何形状 string bitmapPath = @"C:\Users\yulanli\Desktop\TerrainForm\heightMap.BMP"; Bitmap bitmap = new Bitmap(bitmapPath); xCount = (bitmap.Width - 1) / 2; yCount = (bitmap.Height - 1) / 2; cellWidth = bitmap.Width / xCount; cellHeight = bitmap.Height / yCount; var vertices = new PositionTextured[(xCount + 1) * (yCount + 1)];//定义顶点 for (int i = 0; i < yCount + 1; i++) { for (int j = 0; j < xCount + 1; j++) { System.Drawing.Color color = bitmap.GetPixel((int)(j * cellWidth), (int)(i * cellHeight)); float height = float.Parse(color.R.ToString()) + float.Parse(color.G.ToString()) + float.Parse(color.B.ToString()); height /= 10; vertices[j + i * (xCount + 1)].Position = new Vector3(j * cellWidth, height, i * cellHeight); vertices[j + i * (xCount + 1)].Texcoord = new Vector2((float)j / (xCount + 1), (float)i / (yCount + 1)); } } texture = TextureLoader.TextureLoader.CreateTextureFromDDS(device, @"C:\Users\yulanli\Desktop\TerrainForm\colorMapDDS.DDS"); //创建待绘制图形的顶点索引 indices = new int[6 * xCount * yCount]; for (int i = 0; i < yCount; i++) { for (int j = 0; j < xCount; j++) { indices[6 * (j + i * xCount)] = j + i * (xCount + 1); indices[6 * (j + i * xCount) + 1] = j + (i + 1) * (xCount + 1); indices[6 * (j + i * xCount) + 2] = j + i * (xCount + 1) + 1; indices[6 * (j + i * xCount) + 3] = j + i * (xCount + 1) + 1; indices[6 * (j + i * xCount) + 4] = j + (i + 1) * (xCount + 1); indices[6 * (j + i * xCount) + 5] = j + (i + 1) * (xCount + 1) + 1; } } //创建视锥体 //创建摄像机 CamTarget = new Vector3(bitmap.Width / 2, 0f, bitmap.Height / 2); view = Matrix.LookAtLH( CamPostion, //摄像机原点 CamTarget, //摄像机观察目标点 Vector3.UnitY); //当前世界的向上方向的向量,通常为(0,1,0),即这里的UnitY参数 proj = Matrix.Identity; proj = Matrix.PerspectiveFovLH( (float)Math.PI / 4.0f, //用弧度制表示垂直视场角,这里是45°角 aspectRatio, //纵横比 0.3f, //到近平面的距离 500.0f //到远平面的距离 ); var worldViewProj = Matrix.Multiply(proj, view); //使用上传堆来传递顶点缓冲区的数据 /*--------------------------------------------------* * 不推荐使用上传堆来传递像顶点缓冲区这样的静态数据 * * 这里使用上载堆是为了代码的简洁性,并且还因为需要 * * 传递的资源很少 * *--------------------------------------------------*/ var vertexBufferSize = Utilities.SizeOf(vertices); vertexBuffer = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); //将顶点的数据复制到顶点缓冲区 IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write( pVertexDataBegin, vertices, 0, vertices.Length); vertexBuffer.Unmap(0); //初始化顶点缓冲区视图 vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <PositionTextured>(); vertexBufferView.SizeInBytes = vertexBufferSize; //使用上传堆来传递索引缓冲区的数据 int indexBufferSize = Utilities.SizeOf(indices); indexBuffer = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead); //将索引的数据复制到索引缓冲区 IntPtr pIndexDataBegin = indexBuffer.Map(0); Utilities.Write( pIndexDataBegin, indices, 0, indices.Length); indexBuffer.Unmap(0); //初始化索引缓冲区视图 indexBufferView = new IndexBufferView(); indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress; indexBufferView.SizeInBytes = indexBufferSize; indexBufferView.Format = Format.R32_UInt; //创建bundle bundle = device.CreateCommandList( 0, CommandListType.Bundle, bundleAllocator, pipelineState); bundle.SetGraphicsRootSignature(rootSignature); bundle.PrimitiveTopology = SharpDX.Direct3D.PrimitiveTopology.TriangleList; bundle.SetVertexBuffer(0, vertexBufferView); bundle.SetIndexBuffer(indexBufferView); //bundle.DrawInstanced( // vertices.Length,//VertexCountPerInstance,要绘制的顶点数 // 1,//InstanceCount,要绘制的实例数,这里是1个 // 0,//StartVertexLocation,第一个顶点的索引,这里是0 // 0);//StartInstanceLocation,在从顶点缓冲区读取每个实例数据之前添加到每个索引的值 bundle.DrawIndexedInstanced( indices.Length, //IndexCountPerInstance,要绘制的索引数 1, //InstanceCount,要绘制的实例数,这里是1个 0, //StartIndexLocation,第一个顶点的索引,这里是0 0, //BaseVertexLocation,,从顶点缓冲区读取顶点之前添加到每个索引的值 0); //StartInstanceLocation,在从顶点缓冲区读取每个实例数据之前添加到每个索引的值 bundle.Close(); //使用上传堆来传递常量缓冲区的数据 /*--------------------------------------------------* * 不推荐使用上传堆来传递像垂直缓冲区这样的静态数据 * * 这里使用上载堆是为了代码的简洁性,并且还因为需要 * * 传递的资源很少 * *--------------------------------------------------*/ constantBuffer = device.CreateCommittedResource( new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); //创建SRV视图 var srvDesc = new ShaderResourceViewDescription(); srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; device.CreateShaderResourceView(texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart); //创建常量缓冲区视图(CBV) var cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <ConstantBuffer>() + 255) & ~255 }; device.CreateConstantBufferView( cbvDesc, constantBufferViewHeap.CPUDescriptorHandleForHeapStart); //初始化并映射常量缓冲区 /*--------------------------------------------------* * 直到应用程序关闭,我们才会取消映射,因此在资源的 * * 生命周期中保持映射是可以的 * *------------------------------------------------- */ constantBufferPointer = constantBuffer.Map(0); Utilities.Write(constantBufferPointer, ref worldViewProj); //创建同步对象 //创建围栏 fence = device.CreateFence( 0, //围栏的初始值 FenceFlags.None); //指定围栏的类型,None表示没有指定的类型 fenceValue = 1; //创建用于帧同步的事件句柄 fenceEvent = new AutoResetEvent(false); }
static void Main() { using (var form = new RenderForm()) using (var factory = new Factory4()) { Device11 device; SwapChain swapChain; Device11.CreateWithSwapChain( DriverType.Hardware, DeviceCreationFlags.None, new SwapChainDescription { IsWindowed = true, BufferCount = 1, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), ModeDescription = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(60, 1), Format.B8G8R8A8_UNorm), Usage = Usage.RenderTargetOutput, SwapEffect = SwapEffect.Discard, Flags = SwapChainFlags.None }, out device, out swapChain); var context = device.ImmediateContext; var backBuffer = swapChain.GetBackBuffer <Texture2D>(0); var backBufferView = new RenderTargetView(device, backBuffer); backBuffer.Dispose(); var depthBuffer = new Texture2D(device, new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }); var depthBufferView = new DepthStencilView(device, depthBuffer); depthBuffer.Dispose(); //Indices var indices = new int[] { 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 }; //Vertices var vertices = new[] { ////TOP new ColoredVertex(new Vector3(-5, 5, 5), new Vector4(0, 1, 0, 0)), new ColoredVertex(new Vector3(5, 5, 5), new Vector4(0, 1, 0, 0)), new ColoredVertex(new Vector3(5, 5, -5), new Vector4(0, 1, 0, 0)), new ColoredVertex(new Vector3(-5, 5, -5), new Vector4(0, 1, 0, 0)), //BOTTOM new ColoredVertex(new Vector3(-5, -5, 5), new Vector4(1, 0, 1, 1)), new ColoredVertex(new Vector3(5, -5, 5), new Vector4(1, 0, 1, 1)), new ColoredVertex(new Vector3(5, -5, -5), new Vector4(1, 0, 1, 1)), new ColoredVertex(new Vector3(-5, -5, -5), new Vector4(1, 0, 1, 1)), //LEFT new ColoredVertex(new Vector3(-5, -5, 5), new Vector4(1, 0, 0, 1)), new ColoredVertex(new Vector3(-5, 5, 5), new Vector4(1, 0, 0, 1)), new ColoredVertex(new Vector3(-5, 5, -5), new Vector4(1, 0, 0, 1)), new ColoredVertex(new Vector3(-5, -5, -5), new Vector4(1, 0, 0, 1)), //RIGHT new ColoredVertex(new Vector3(5, -5, 5), new Vector4(1, 1, 0, 1)), new ColoredVertex(new Vector3(5, 5, 5), new Vector4(1, 1, 0, 1)), new ColoredVertex(new Vector3(5, 5, -5), new Vector4(1, 1, 0, 1)), new ColoredVertex(new Vector3(5, -5, -5), new Vector4(1, 1, 0, 1)), //FRONT new ColoredVertex(new Vector3(-5, 5, 5), new Vector4(0, 1, 1, 1)), new ColoredVertex(new Vector3(5, 5, 5), new Vector4(0, 1, 1, 1)), new ColoredVertex(new Vector3(5, -5, 5), new Vector4(0, 1, 1, 1)), new ColoredVertex(new Vector3(-5, -5, 5), new Vector4(0, 1, 1, 1)), //BACK new ColoredVertex(new Vector3(-5, 5, -5), new Vector4(0, 0, 1, 1)), new ColoredVertex(new Vector3(5, 5, -5), new Vector4(0, 0, 1, 1)), new ColoredVertex(new Vector3(5, -5, -5), new Vector4(0, 0, 1, 1)), new ColoredVertex(new Vector3(-5, -5, -5), new Vector4(0, 0, 1, 1)) }; var vertexBuffer = Buffer11.Create(device, BindFlags.VertexBuffer, vertices); var indexBuffer = Buffer11.Create(device, BindFlags.IndexBuffer, indices); var vertexBufferBinding = new VertexBufferBinding(vertexBuffer, Utilities.SizeOf <ColoredVertex>(), 0); var source = @" cbuffer data :register(b0) { float4x4 worldViewProj; }; struct VS_IN { float4 position : POSITION; float4 color : COLOR; }; struct PS_IN { float4 position : SV_POSITION; float4 color : COLOR; }; PS_IN VS( VS_IN input) { PS_IN output = (PS_IN)0; output.position = mul(worldViewProj,input.position); output.color=input.color; return output; } float4 PS( PS_IN input ) : SV_Target { return input.color; } "; var vertexShaderByteCode = ShaderBytecode.Compile(source, "VS", "vs_5_0"); var vertexShader = new VertexShader(device, vertexShaderByteCode); var pixelShader = new PixelShader(device, ShaderBytecode.Compile(source, "PS", "ps_5_0")); var layout = new InputLayout(device, ShaderSignature.GetInputSignature(vertexShaderByteCode), new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0) }); var worldViewProjectionBuffer = new Buffer11(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); var rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); var blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; var depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; var samplerState = new SamplerState(device, samplerStateDescription); var startTime = DateTime.Now; var frame = 0; var size = form.ClientSize; RenderLoop.Run(form, () => { if (form.ClientSize != size) { Utilities.Dispose(ref backBufferView); Utilities.Dispose(ref depthBufferView); if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0) { swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); backBuffer = swapChain.GetBackBuffer <Texture2D>(0); backBufferView = new RenderTargetView(device, backBuffer); backBuffer.Dispose(); depthBuffer = new Texture2D(device, new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }); depthBufferView = new DepthStencilView(device, depthBuffer); depthBuffer.Dispose(); } size = form.ClientSize; } var ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height; var projection = Matrix.PerspectiveFovLH(3.14F / 3.0F, ratio, 1, 1000); var view = Matrix.LookAtLH(new Vector3(0, 10, -50), Vector3.Zero, Vector3.UnitY); var world = Matrix.RotationY(Environment.TickCount / 1000.0F); var worldViewProjection = world * view * projection; //worldViewProjection = Matrix.Identity; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.Rasterizer.SetViewport(0, 0, form.ClientSize.Width, form.ClientSize.Height); context.OutputMerger.SetTargets(depthBufferView, backBufferView); context.ClearRenderTargetView(backBufferView, new RawColor4(0, 0, 0, 1)); context.ClearDepthStencilView(depthBufferView, DepthStencilClearFlags.Depth, 1.0f, 0); context.InputAssembler.InputLayout = layout; context.InputAssembler.SetVertexBuffers(0, vertexBufferBinding); context.InputAssembler.SetIndexBuffer(indexBuffer, Format.R32_UInt, 0); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.VertexShader.Set(vertexShader); context.PixelShader.Set(pixelShader); context.GeometryShader.Set(null); context.DomainShader.Set(null); context.HullShader.Set(null); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); context.DrawIndexed(indices.Length, 0, 0); swapChain.Present(0, PresentFlags.None); frame++; }); MessageBox.Show((frame / DateTime.Now.Subtract(startTime).TotalSeconds).ToString() + " FPS"); } }
/// <summary> /// Устанавливает параметры блендинга, растеризации, Буффера глубины и бледн фактор (влияет на то какой процент из цвета пикселя будет усачтвовать в блендинге) /// </summary> protected virtual void SetStates() { //Установка Сампрелар для текстуры. SamplerStateDescription description = SamplerStateDescription.Default(); description.Filter = Filter.MinMagMipLinear; description.AddressU = TextureAddressMode.Wrap; description.AddressV = TextureAddressMode.Wrap; _drawer.Samplerdescription = description; //Устанавливаем параметры буффера глубины DepthStencilStateDescription DStateDescripshion = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthComparison = Comparison.Less, DepthWriteMask = SharpDX.Direct3D11.DepthWriteMask.All, IsStencilEnabled = false, 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 } }; _drawer.DepthStencilDescripshion = DStateDescripshion; //Устанавливаем параметры растеризации так чтобы обратная сторона объекта не спряталась. RasterizerStateDescription rasterizerStateDescription = RasterizerStateDescription.Default(); rasterizerStateDescription.CullMode = CullMode.None; rasterizerStateDescription.FillMode = FillMode.Solid; _drawer.RasterizerDescription = rasterizerStateDescription; //TODO: донастроить параметры блендинга для прозрачности. #region Формула бледнинга //(FC) - Final Color //(SP) - Source Pixel //(DP) - Destination Pixel //(SBF) - Source Blend Factor //(DBF) - Destination Blend Factor //(FA) - Final Alpha //(SA) - Source Alpha //(DA) - Destination Alpha //(+) - Binaray Operator described below //(X) - Cross Multiply Matrices //Формула для блендинга //(FC) = (SP)(X)(SBF)(+)(DP)(X)(DPF) //(FA) = (SA)(SBF)(+)(DA)(DBF) //ИСПОЛЬЗОВАНИЕ //_dx11DeviceContext.OutputMerger.SetBlendState( // _blendState, // new SharpDX.Mathematics.Interop.RawColor4(0.75f, 0.75f, 0.75f, 1f)); //ЭТО ДЛЯ НЕПРОЗРАЧНЫХ _dx11DeviceContext.OutputMerger.SetBlendState(null, null); #endregion RenderTargetBlendDescription targetBlendDescription = new RenderTargetBlendDescription() { IsBlendEnabled = new SharpDX.Mathematics.Interop.RawBool(true), SourceBlend = BlendOption.SourceColor, DestinationBlend = BlendOption.BlendFactor, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, RenderTargetWriteMask = ColorWriteMaskFlags.All }; BlendStateDescription blendDescription = BlendStateDescription.Default(); blendDescription.AlphaToCoverageEnable = new SharpDX.Mathematics.Interop.RawBool(false); blendDescription.RenderTarget[0] = targetBlendDescription; _drawer.BlendDescription = blendDescription; SharpDX.Mathematics.Interop.RawColor4 blenF = new SharpDX.Mathematics.Interop.RawColor4(0.3f, 0.3f, 0.3f, 0.3f); _drawer.BlendFactor = blenF; }
private void CreateTerrainBind() { var rootSignatureDesc = new RootSignatureDescription( RootSignatureFlags.AllowInputAssemblerInputLayout, // Root Parameters new[] { new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.All, new [] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 2, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 } }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = 0, BaseShaderRegister = 0 }), }); terrainRootSignature = device.CreateRootSignature(0, rootSignatureDesc.Serialize()); var inputElementDescs = new[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TANGENT", 0, Format.R32G32B32_Float, 24, 0), new InputElement("BITANGENT", 0, Format.R32G32B32_Float, 36, 0), new InputElement("DIFFUSE", 0, Format.R32G32B32_Float, 48, 0), new InputElement("EMISSIVE", 0, Format.R32G32B32_Float, 64, 0), new InputElement("SPECULAR", 0, Format.R32G32B32_Float, 80, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 96, 0) }; var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = terrainRootSignature, VertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../Terrain.hlsl"), "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)), PixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.Compile(SharpDX.IO.NativeFile.ReadAllText("../../Terrain.hlsl"), "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)), 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; pipelineState2 = device.CreateGraphicsPipelineState(psoDesc); }
public void InitRendering(UI ui) { lock (_drawLock) { if (ui == null) { return; } _ui = ui; ResizeRedraw = true; var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { throw new Exception("Not Available"); } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(UI.GameWidth, UI.GameHeight); leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var factory = new SharpDX.DXGI.Factory4()) { var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = windowSize.Width, Height = windowSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = this.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(this.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = windowSize.Width, Height = windowSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; leftEyeTexture = new Texture2D(device, eyeTextureDescription); rightEyeTexture = new Texture2D(device, eyeTextureDescription); leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; eyeDepth = new Texture2D(device, eyeTextureDescription); eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Normal.Load(device); Shaders.NormalTexture.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } shaderParameterBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Shaders.Parameters>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; //windowSize = ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); head = Matrix.Identity; _ui.ready = true; } } }
protected override void CreateState() { InputElement[] inputElements = new InputElement[] { new InputElement("SV_Position", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("COLOR", 0, Format.R8G8B8A8_UNorm, 24, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 28, 0) }; //Установка Сампрелар для текстуры. SamplerStateDescription description = SamplerStateDescription.Default(); description.Filter = Filter.MinMagMipLinear; description.AddressU = TextureAddressMode.Wrap; description.AddressV = TextureAddressMode.Wrap; //Устанавливаем параметры буффера глубины DepthStencilStateDescription DStateDescripshion = new DepthStencilStateDescription() { IsDepthEnabled = true, DepthComparison = Comparison.Less, DepthWriteMask = DepthWriteMask.All, IsStencilEnabled = false, 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 } }; //Устанавливаем параметры растеризации так чтобы обратная сторона объекта не спряталась. RasterizerStateDescription rasterizerStateDescription = RasterizerStateDescription.Default(); rasterizerStateDescription.CullMode = CullMode.None; rasterizerStateDescription.FillMode = FillMode.Solid; //TODO: донастроить параметры блендинга для прозрачности. #region Формула бледнинга //(FC) - Final Color //(SP) - Source Pixel //(DP) - Destination Pixel //(SBF) - Source Blend Factor //(DBF) - Destination Blend Factor //(FA) - Final Alpha //(SA) - Source Alpha //(DA) - Destination Alpha //(+) - Binaray Operator described below //(X) - Cross Multiply Matrices //Формула для блендинга //(FC) = (SP)(X)(SBF)(+)(DP)(X)(DPF) //(FA) = (SA)(SBF)(+)(DA)(DBF) //ИСПОЛЬЗОВАНИЕ //_dx11DeviceContext.OutputMerger.SetBlendState( // _blendState, // new SharpDX.Mathematics.Interop.RawColor4(0.75f, 0.75f, 0.75f, 1f)); //ЭТО ДЛЯ НЕПРОЗРАЧНЫХ _dx11DeviceContext.OutputMerger.SetBlendState(null, null); #endregion RenderTargetBlendDescription targetBlendDescription = new RenderTargetBlendDescription() { IsBlendEnabled = new RawBool(true), SourceBlend = BlendOption.SourceColor, DestinationBlend = BlendOption.BlendFactor, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.SourceAlpha, DestinationAlphaBlend = BlendOption.DestinationAlpha, AlphaBlendOperation = BlendOperation.Add, RenderTargetWriteMask = ColorWriteMaskFlags.All }; BlendStateDescription blendDescription = BlendStateDescription.Default(); blendDescription.AlphaToCoverageEnable = new RawBool(true); blendDescription.IndependentBlendEnable = new RawBool(true); // blendDescription.RenderTarget[0] = targetBlendDescription; InitDrawer("Shaders\\ShadedCube.hlsl", inputElements, "Textures\\lava.jpg", description, DStateDescripshion, rasterizerStateDescription, blendDescription ); }
static void Main() { var initError = EVRInitError.None; system = OpenVR.Init(ref initError); if (initError != EVRInitError.None) { return; } compositor = OpenVR.Compositor; compositor.CompositorBringToFront(); compositor.FadeGrid(5.0f, false); count = OpenVR.k_unMaxTrackedDeviceCount; currentPoses = new TrackedDevicePose_t[count]; nextPoses = new TrackedDevicePose_t[count]; controllers = new List <uint>(); controllerModels = new RenderModel_t[count]; controllerTextures = new RenderModel_TextureMap_t[count]; controllerTextureViews = new ShaderResourceView[count]; controllerVertexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerIndexBuffers = new SharpDX.Direct3D11.Buffer[count]; controllerVertexBufferBindings = new VertexBufferBinding[count]; for (uint device = 0; device < count; device++) { var deviceClass = system.GetTrackedDeviceClass(device); switch (deviceClass) { case ETrackedDeviceClass.HMD: headset = device; break; case ETrackedDeviceClass.Controller: controllers.Add(device); break; } } uint width = 0; uint height = 0; system.GetRecommendedRenderTargetSize(ref width, ref height); headsetSize = new Size((int)width, (int)height); windowSize = new Size(960, 540); var leftEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Left, 0.01f, 1000.0f)); var rightEyeProjection = Convert(system.GetProjectionMatrix(EVREye.Eye_Right, 0.01f, 1000.0f)); var leftEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Left)); var rightEyeView = Convert(system.GetEyeToHeadTransform(EVREye.Eye_Right)); foreach (var controller in controllers) { var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var texture = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = texture; break; } } } } int adapterIndex = 0; system.GetDXGIOutputInfo(ref adapterIndex); using (var form = new Form()) using (var factory = new Factory4()) { form.ClientSize = windowSize; var adapter = factory.GetAdapter(adapterIndex); var swapChainDescription = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription { Format = Format.B8G8R8A8_UNorm, Width = form.ClientSize.Width, Height = form.ClientSize.Height, RefreshRate = new Rational(60, 1) }, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; SharpDX.Direct3D11.Device.CreateWithSwapChain(adapter, DeviceCreationFlags.None, swapChainDescription, out device, out swapChain); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.None); context = device.ImmediateContext; using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); var depthBufferDescription = new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }; using (var depthBuffer = new Texture2D(device, depthBufferDescription)) depthStencilView = new DepthStencilView(device, depthBuffer); // Create Eye Textures var eyeTextureDescription = new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.RenderTarget, CpuAccessFlags = CpuAccessFlags.None, Format = Format.B8G8R8A8_UNorm, Width = headsetSize.Width, Height = headsetSize.Height, MipLevels = 1, OptionFlags = ResourceOptionFlags.None, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default }; var leftEyeTexture = new Texture2D(device, eyeTextureDescription); var rightEyeTexture = new Texture2D(device, eyeTextureDescription); var leftEyeTextureView = new RenderTargetView(device, leftEyeTexture); var rightEyeTextureView = new RenderTargetView(device, rightEyeTexture); // Create Eye Depth Buffer eyeTextureDescription.BindFlags = BindFlags.DepthStencil; eyeTextureDescription.Format = Format.D32_Float; var eyeDepth = new Texture2D(device, eyeTextureDescription); var eyeDepthView = new DepthStencilView(device, eyeDepth); Shapes.Cube.Load(device); Shapes.Sphere.Load(device); Shaders.Position.Load(device); Shaders.Normal.Load(device); Shaders.NormalTexture.Load(device); // Load Controller Models foreach (var controller in controllers) { var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); var texture = controllerTextures[controller]; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = texture.unWidth, Height = texture.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(texture.rubTextureMapData, texture.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); } worldViewProjectionBuffer = new SharpDX.Direct3D11.Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); blendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; blendStateDescription.RenderTarget[0].SourceBlend = BlendOption.SourceAlpha; blendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; blendStateDescription.RenderTarget[0].IsBlendEnabled = false; blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; samplerState = new SamplerState(device, samplerStateDescription); startTime = DateTime.Now; frame = 0; windowSize = form.ClientSize; backgroundColor = new RawColor4(0.1f, 0.1f, 0.1f, 1); var vrEvent = new VREvent_t(); var eventSize = (uint)Utilities.SizeOf <VREvent_t>(); head = Matrix.Identity; // Initialize Audio var audioSamples = 1024; var audioDevices = DirectSoundCapture.GetDevices(); //var audioCapture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid); var audioCapture = new DirectSoundCapture(audioDevices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid); var audioFormat = new WaveFormat(); var audioLength = audioFormat.ConvertLatencyToByteSize(24); var audioData = new byte[audioLength]; var audioPosition = 0; var leftWaveForm = new float[1024 * 8]; var rightWaveForm = new float[1024 * 8]; for (var sample = 0; sample < 1024; sample++) { leftWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f); rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / 512.0f); } var audioBuffer = new CaptureBuffer(audioCapture, new CaptureBufferDescription { BufferBytes = audioLength, Format = audioFormat }); audioBuffer.Start(true); var waveFormBufferDescription = new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = leftWaveForm.Length * sizeof(float), CpuAccessFlags = CpuAccessFlags.Write, Usage = ResourceUsage.Dynamic }; var leftWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, leftWaveForm, waveFormBufferDescription); var rightWaveFormVertexBuffer = SharpDX.Direct3D11.Buffer.Create(device, rightWaveForm, waveFormBufferDescription); var leftWaveFormVertexBufferBinding = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0); var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0); RenderLoop.Run(form, () => { if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition) { audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None); for (var sample = 0; sample < 1024; sample++) { leftWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue; rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue; } DataStream stream; context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(leftWaveForm); context.UnmapSubresource(leftWaveFormVertexBuffer, 0); stream.Dispose(); context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); stream.WriteRange(rightWaveForm); context.UnmapSubresource(rightWaveFormVertexBuffer, 0); stream.Dispose(); } audioPosition += 8; if (audioPosition >= leftWaveForm.Length) { audioPosition = 0; } while (system.PollNextEvent(ref vrEvent, eventSize)) { switch ((EVREventType)vrEvent.eventType) { case EVREventType.VREvent_TrackedDeviceActivated: var controller = vrEvent.trackedDeviceIndex; controllers.Add(controller); var modelName = new StringBuilder(255, 255); var propertyError = ETrackedPropertyError.TrackedProp_Success; var length = system.GetStringTrackedDeviceProperty(controller, ETrackedDeviceProperty.Prop_RenderModelName_String, modelName, 255, ref propertyError); if (propertyError == ETrackedPropertyError.TrackedProp_Success) { var modelName2 = modelName.ToString(); while (true) { var pointer = IntPtr.Zero; var modelError = EVRRenderModelError.None; modelError = OpenVR.RenderModels.LoadRenderModel_Async(modelName2, ref pointer); if (modelError == EVRRenderModelError.Loading) { continue; } if (modelError == EVRRenderModelError.None) { var renderModel = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_t>(pointer); controllerModels[controller] = renderModel; // Load Controller Model var model = controllerModels[controller]; controllerVertexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rVertexData, new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = (int)model.unVertexCount * 32 }); controllerVertexBufferBindings[controller] = new VertexBufferBinding(controllerVertexBuffers[controller], 32, 0); controllerIndexBuffers[controller] = new SharpDX.Direct3D11.Buffer(device, model.rIndexData, new BufferDescription { BindFlags = BindFlags.IndexBuffer, SizeInBytes = (int)model.unTriangleCount * 3 * 2 }); break; } } while (true) { var pointer = IntPtr.Zero; var textureError = EVRRenderModelError.None; textureError = OpenVR.RenderModels.LoadTexture_Async(controllerModels[controller].diffuseTextureId, ref pointer); if (textureError == EVRRenderModelError.Loading) { continue; } if (textureError == EVRRenderModelError.None) { var textureMap = System.Runtime.InteropServices.Marshal.PtrToStructure <RenderModel_TextureMap_t>(pointer); controllerTextures[controller] = textureMap; using (var texture2d = new Texture2D(device, new Texture2DDescription { ArraySize = 1, BindFlags = BindFlags.ShaderResource, Format = Format.R8G8B8A8_UNorm, Width = textureMap.unWidth, Height = textureMap.unHeight, MipLevels = 1, SampleDescription = new SampleDescription(1, 0) }, new DataRectangle(textureMap.rubTextureMapData, textureMap.unWidth * 4))) controllerTextureViews[controller] = new ShaderResourceView(device, texture2d); break; } } } break; case EVREventType.VREvent_TrackedDeviceDeactivated: controllers.RemoveAll(c => c == vrEvent.trackedDeviceIndex); break; default: System.Diagnostics.Debug.WriteLine((EVREventType)vrEvent.eventType); break; } } if (form.ClientSize != windowSize) { Utilities.Dispose(ref backBufferView); if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0) { swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); using (var backBuffer = swapChain.GetBackBuffer <Texture2D>(0)) backBufferView = new RenderTargetView(device, backBuffer); } windowSize = form.ClientSize; } // Update Device Tracking compositor.WaitGetPoses(currentPoses, nextPoses); if (currentPoses[headset].bPoseIsValid) { Convert(ref currentPoses[headset].mDeviceToAbsoluteTracking, ref head); } foreach (var controller in controllers) { var controllerMatrix = Matrix.Identity; Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref controllerMatrix); } // Render Left Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, leftEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(leftEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); var ratio = (float)headsetSize.Width / (float)headsetSize.Height; var projection = leftEyeProjection; var view = Matrix.Invert(leftEyeView * head); var world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Present Left Eye var texture = new Texture_t { eType = ETextureType.DirectX, eColorSpace = EColorSpace.Gamma, handle = leftEyeTextureView.Resource.NativePointer }; var bounds = new VRTextureBounds_t { uMin = 0.0f, uMax = 1.0f, vMin = 0.0f, vMax = 1.0f, }; var submitError = compositor.Submit(EVREye.Eye_Left, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Right Eye context.Rasterizer.SetViewport(0, 0, headsetSize.Width, headsetSize.Height); context.OutputMerger.SetTargets(eyeDepthView, rightEyeTextureView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(rightEyeTextureView, backgroundColor); context.ClearDepthStencilView(eyeDepthView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); projection = rightEyeProjection; view = Matrix.Invert(rightEyeView * head); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); context.PixelShader.SetShaderResource(0, controllerTextureViews[controller]); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Present Right Eye texture.handle = rightEyeTextureView.Resource.NativePointer; submitError = compositor.Submit(EVREye.Eye_Right, ref texture, ref bounds, EVRSubmitFlags.Submit_Default); if (submitError != EVRCompositorError.None) { System.Diagnostics.Debug.WriteLine(submitError); } // Render Window context.Rasterizer.SetViewport(0, 0, windowSize.Width, windowSize.Height); context.OutputMerger.SetTargets(depthStencilView, backBufferView); context.OutputMerger.SetDepthStencilState(depthStencilState); context.ClearRenderTargetView(backBufferView, backgroundColor); context.ClearDepthStencilView(depthStencilView, DepthStencilClearFlags.Depth, 1.0f, 0); Shaders.Normal.Apply(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height; projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000); view = Matrix.Invert(head); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.1f)) * Matrix.Translation(0, 1.0f, 0); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); //Shapes.Cube.Begin(context); //Shapes.Cube.Draw(context); Shapes.Sphere.Begin(context); Shapes.Sphere.Draw(context); // Draw Controllers context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; Shaders.NormalTexture.Apply(context); context.PixelShader.SetSampler(0, samplerState); foreach (var controller in controllers) { context.InputAssembler.SetVertexBuffers(0, controllerVertexBufferBindings[controller]); context.InputAssembler.SetIndexBuffer(controllerIndexBuffers[controller], Format.R16_UInt, 0); Convert(ref currentPoses[controller].mDeviceToAbsoluteTracking, ref world); world = Matrix.Scaling(1.0f + (Math.Abs(leftWaveForm[audioPosition + 1]) * 0.5f)) * world; worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.VertexShader.SetConstantBuffer(0, worldViewProjectionBuffer); context.DrawIndexed((int)controllerModels[controller].unTriangleCount * 3 * 4, 0, 0); } // Draw Waveforms Shaders.Position.Apply(context); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, 1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); context.Draw(1024, 0); world = Matrix.Scaling(100, 2.5f, 1) * Matrix.Translation(0, 1, -1); worldViewProjection = world * view * projection; context.UpdateSubresource(ref worldViewProjection, worldViewProjectionBuffer); context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); context.Draw(1024, 0); // Show Backbuffer swapChain.Present(0, PresentFlags.None); }); } }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat, StreamOutput = new StreamOutputDescription() //find out how this should actually be done later }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, // TODO: rename to IsLogicOpEnabled SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); // // PSO for horizontal blur. // var horzBlurPso = new ComputePipelineStateDescription { RootSignaturePointer = _postProcessRootSignature, ComputeShader = _shaders["horzBlurCS"], Flags = PipelineStateFlags.None }; _psos["horzBlur"] = Device.CreateComputePipelineState(horzBlurPso); // // PSO for vertical blur. // var vertBlurPso = new ComputePipelineStateDescription { RootSignaturePointer = _postProcessRootSignature, ComputeShader = _shaders["vertBlurCS"], Flags = PipelineStateFlags.None }; _psos["vertBlur"] = Device.CreateComputePipelineState(vertBlurPso); }
public Renderer(RenderSurface surface) { looper = new ParallelLooper(); Surface = surface; using (var stream = new MemoryStream(Resources.DemoRendererShaders)) { ShaderCache = ShaderCache.Load(stream); } Shapes = new ShapesExtractor(looper); SphereRenderer = new SphereRenderer(surface.Device, ShaderCache); Lines = new LineExtractor(looper); LineRenderer = new LineRenderer(surface.Device, ShaderCache); Background = new BackgroundRenderer(surface.Device, ShaderCache); CompressToSwap = new CompressToSwap(surface.Device, ShaderCache); GlyphRenderer = new GlyphRenderer(surface.Device, surface.Context, ShaderCache); TextBatcher = new TextBatcher(); UILineRenderer = new UILineRenderer(surface.Device, ShaderCache); UILineBatcher = new UILineBatcher(); OnResize(); var rasterizerStateDescription = RasterizerStateDescription.Default(); rasterizerStateDescription.IsFrontCounterClockwise = true; rasterizerStateDescription.CullMode = CullMode.None; rasterizerState = new RasterizerState(Surface.Device, rasterizerStateDescription); rasterizerState.DebugName = "Default Rasterizer State"; var opaqueDepthStencilDescription = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, //Note depth reversal. DepthComparison = Comparison.Greater, IsStencilEnabled = false }; opaqueDepthState = new DepthStencilState(Surface.Device, opaqueDepthStencilDescription); opaqueDepthState.DebugName = "Opaque Depth State"; var opaqueBlendStateDescription = BlendStateDescription.Default(); opaqueBlendState = new BlendState(Surface.Device, opaqueBlendStateDescription); opaqueBlendState.DebugName = "Opaque Blend State"; var uiDepthStateDescription = new DepthStencilStateDescription { IsDepthEnabled = false, DepthWriteMask = DepthWriteMask.Zero, //Note depth reversal. DepthComparison = Comparison.Greater, IsStencilEnabled = false }; uiDepthState = new DepthStencilState(Surface.Device, uiDepthStateDescription); uiDepthState.DebugName = "UI Depth State"; //The UI will use premultiplied alpha. var uiBlendStateDescription = BlendStateDescription.Default(); uiBlendStateDescription.RenderTarget[0].IsBlendEnabled = true; uiBlendStateDescription.RenderTarget[0].SourceBlend = BlendOption.One; uiBlendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.One; uiBlendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; uiBlendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.InverseSourceAlpha; uiBlendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; uiBlendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; uiBlendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; uiBlendState = new BlendState(Surface.Device, uiBlendStateDescription); uiBlendState.DebugName = "UI Blend State"; }
static void Main() { const int samples = 512; const int latency = 24; var devices = DirectSoundCapture.GetDevices(); //var capture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mic")).First().DriverGuid); var capture = new DirectSoundCapture(devices.OrderByDescending(d => d.Description.Contains("Mix")).First().DriverGuid); var audioFormat = new WaveFormat(); var audioBuffer = new CaptureBuffer(capture, new CaptureBufferDescription { BufferBytes = audioFormat.ConvertLatencyToByteSize(latency), Format = audioFormat }); audioBuffer.Start(true); using (var form = new Form()) using (var factory = new Factory4()) { form.Text = "AudioDX"; form.ClientSize = new System.Drawing.Size(1024, 768); form.StartPosition = FormStartPosition.CenterScreen; Device11 device; SwapChain swapChain; Device11.CreateWithSwapChain( DriverType.Hardware, DeviceCreationFlags.None, new SwapChainDescription { IsWindowed = true, BufferCount = 1, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), ModeDescription = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(60, 1), Format.B8G8R8A8_UNorm), Usage = Usage.RenderTargetOutput, SwapEffect = SwapEffect.Discard }, out device, out swapChain); var context = device.ImmediateContext; var backBuffer = swapChain.GetBackBuffer <Texture2D>(0); var backBufferView = new RenderTargetView(device, backBuffer); backBuffer.Dispose(); var depthBuffer = new Texture2D(device, new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), BindFlags = BindFlags.DepthStencil }); var depthBufferView = new DepthStencilView(device, depthBuffer); depthBuffer.Dispose(); Shapes.Sphere.Load(device); Shapes.Cube.Load(device); Shapes.Billboard.Load(device); Shaders.Normal.Load(device); Shaders.Color.Load(device); var rasterizerStateDescription = RasterizerStateDescription.Default(); //rasterizerStateDescription.FillMode = FillMode.Wireframe; //rasterizerStateDescription.IsFrontCounterClockwise = true; //rasterizerStateDescription.CullMode = CullMode.Back; var rasterizerState = new RasterizerState(device, rasterizerStateDescription); var blendStateDescription = BlendStateDescription.Default(); //blendStateDescription.RenderTarget[0] = new RenderTargetBlendDescription(true, BlendOption.SourceAlpha, BlendOption.InverseSourceAlpha, BlendOperation.Add, BlendOption.SourceAlpha, BlendOption.DestinationAlpha, BlendOperation.Add, ColorWriteMaskFlags.All); var blendState = new BlendState(device, blendStateDescription); var depthStateDescription = DepthStencilStateDescription.Default(); depthStateDescription.DepthComparison = Comparison.LessEqual; depthStateDescription.IsDepthEnabled = true; depthStateDescription.IsStencilEnabled = false; var depthStencilState = new DepthStencilState(device, depthStateDescription); var samplerStateDescription = SamplerStateDescription.Default(); samplerStateDescription.Filter = Filter.MinMagMipLinear; samplerStateDescription.AddressU = TextureAddressMode.Wrap; samplerStateDescription.AddressV = TextureAddressMode.Wrap; var samplerState = new SamplerState(device, samplerStateDescription); var startTime = DateTime.Now; var frame = 0; var size = form.ClientSize; var audioData = new byte[audioFormat.ConvertLatencyToByteSize(latency)]; var audioIndex = 0; var leftWaveForm = new float[samples * 8]; var rightWaveForm = new float[samples * 8]; for (var sample = 0; sample < samples; sample++) { leftWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / (samples - 1) * 2.0f); rightWaveForm[(sample * 8) + 0] = -1.0f + ((float)sample / (samples - 1) * 2.0f); } var waveFormBufferDescription = new BufferDescription { BindFlags = BindFlags.VertexBuffer, SizeInBytes = leftWaveForm.Length * sizeof(float), CpuAccessFlags = CpuAccessFlags.Write, Usage = ResourceUsage.Dynamic }; //var leftWaveFormVertexBuffer = Buffer11.Create(device, leftWaveForm, waveFormBufferDescription); //var rightWaveFormVertexBuffer = Buffer11.Create(device, rightWaveForm, waveFormBufferDescription); //var leftWaveFormVertexBufferBinding = new VertexBufferBinding(leftWaveFormVertexBuffer, 8 * sizeof(float), 0); //var rightWaveFormVertexBufferBinding = new VertexBufferBinding(rightWaveFormVertexBuffer, 8 * sizeof(float), 0); var leftFrequencies = new float[samples]; var rightFrequencies = new float[samples]; //var rotation = 0.0f; RenderLoop.Run(form, () => { if (audioBuffer.CurrentCapturePosition != audioBuffer.CurrentRealPosition) { audioBuffer.Read(audioData, 0, audioData.Length, 0, LockFlags.None); //for (var sample = 0; sample < samples; sample++) //{ // leftWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, sample * 4) / (float)short.MinValue; // rightWaveForm[(sample * 8) + 1] = -BitConverter.ToInt16(audioData, (sample * 4) + 2) / (float)short.MinValue; //} //DataStream stream; //context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); //stream.WriteRange(leftWaveForm); //context.UnmapSubresource(leftWaveFormVertexBuffer, 0); //stream.Dispose(); //context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); //stream.WriteRange(rightWaveForm); //context.UnmapSubresource(rightWaveFormVertexBuffer, 0); //stream.Dispose(); for (var sample = 0; sample < samples; sample++) { leftFrequencies[sample] = 0.0f; rightFrequencies[sample] = 0.0f; for (var sample2 = 0; sample2 < samples; sample2++) { var theta = -2.0f * MathUtil.Pi * (float)sample2 * (float)sample / (samples << 1); var value = (float)Math.Cos(theta); leftFrequencies[sample] += value * (-BitConverter.ToInt16(audioData, sample2 * 4) / (float)short.MinValue); rightFrequencies[sample] += value * (-BitConverter.ToInt16(audioData, (sample2 * 4) + 2) / (float)short.MinValue); } } //for (var sample = 0; sample < samples; sample++) //{ // leftWaveForm[(sample * 8) + 1] = Math.Abs(leftFrequencies[sample]); // rightWaveForm[(sample * 8) + 1] = Math.Abs(rightFrequencies[sample]); //var angle = ((float)sample / (float)samples) * MathUtil.TwoPi; //var sin = (float)Math.Sin(angle); //var cos = (float)Math.Cos(angle); //leftWaveForm[(sample * 8) + 0] = (Math.Abs(leftFrequencies[sample]) + 10.0f) * sin * -0.01f; //leftWaveForm[(sample * 8) + 1] = (Math.Abs(leftFrequencies[sample]) + 10.0f) * cos * -0.01f; //rightWaveForm[(sample * 8) + 0] = (Math.Abs(rightFrequencies[sample]) + 10.0f) * sin * 0.01f; //rightWaveForm[(sample * 8) + 1] = (Math.Abs(rightFrequencies[sample]) + 10.0f) * cos * -0.01f; //} //context.MapSubresource(leftWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); //stream.WriteRange(leftWaveForm); //context.UnmapSubresource(leftWaveFormVertexBuffer, 0); //stream.Dispose(); //context.MapSubresource(rightWaveFormVertexBuffer, 0, MapMode.WriteDiscard, SharpDX.Direct3D11.MapFlags.None, out stream); //stream.WriteRange(rightWaveForm); //context.UnmapSubresource(rightWaveFormVertexBuffer, 0); //stream.Dispose(); } if (form.ClientSize != size) { Utilities.Dispose(ref backBufferView); Utilities.Dispose(ref depthBufferView); if (form.ClientSize.Width != 0 && form.ClientSize.Height != 0) { swapChain.ResizeBuffers(1, form.ClientSize.Width, form.ClientSize.Height, Format.B8G8R8A8_UNorm, SwapChainFlags.None); backBuffer = swapChain.GetBackBuffer <Texture2D>(0); backBufferView = new RenderTargetView(device, backBuffer); backBuffer.Dispose(); depthBuffer = new Texture2D(device, new Texture2DDescription { Format = Format.D16_UNorm, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), BindFlags = BindFlags.DepthStencil }); depthBufferView = new DepthStencilView(device, depthBuffer); depthBuffer.Dispose(); } size = form.ClientSize; } var ratio = (float)form.ClientSize.Width / (float)form.ClientSize.Height; var projection = Matrix.PerspectiveFovRH(3.14f / 3.0f, ratio, 0.01f, 1000); var view = Matrix.LookAtRH(new Vector3(0, 2, 50), Vector3.Zero, Vector3.UnitY); //var world = Matrix.Scaling(1.0f + Math.Abs(((leftWaveForm[audioIndex + 1]) * 0.01f))) * Matrix.RotationY(Environment.TickCount / 2000.0f); //var world = Matrix.RotationY(rotation); //var world = Matrix.Scaling(1.0f + ((audioData[audioIndex] + audioData[audioIndex + 1] << 8) * 0.00001f)) * Matrix.RotationY(Environment.TickCount / 1000.0f); //audioIndex += 8; //if (audioIndex >= leftWaveForm.Length) // audioIndex = 0; //rotation += 0.01f; //var worldViewProjection = world * view * projection; //var diffuse = new Vector4(1, 0, 0, 0.5f); //Shaders.Color.WorldViewProjection(context, ref worldViewProjection); //Shaders.Color.Emissive(context, ref diffuse); context.Rasterizer.SetViewport(0, 0, form.ClientSize.Width, form.ClientSize.Height); context.OutputMerger.SetTargets(depthBufferView, backBufferView); context.ClearRenderTargetView(backBufferView, new RawColor4(0, 0, 0, 1)); context.ClearDepthStencilView(depthBufferView, DepthStencilClearFlags.Depth, 1.0f, 0); //Shaders.Color.Apply(context); //Shapes.Sphere.Begin(context); //Shapes.Cube.Begin(context); //Shapes.Billboard.Begin(context); context.Rasterizer.State = rasterizerState; context.OutputMerger.SetBlendState(blendState); context.OutputMerger.SetDepthStencilState(depthStencilState); context.PixelShader.SetSampler(0, samplerState); context.PixelShader.SetShaderResource(0, null); //Shapes.Sphere.Draw(context); //Shapes.Cube.Draw(context); //Shapes.Billboard.Draw(context); // Draw Waveforms //diffuse = new Vector4(0, 0, 1, 0.5f); //Shaders.Color.Apply(context); //worldViewProjection = Matrix.Scaling(1, 0.1f, 1) * Matrix.Translation(0, 0.1f, 0); //worldViewProjection = Matrix.Scaling(1, 1, 1) * Matrix.Translation(-0.5f, 0, 0); //Shaders.Color.WorldViewProjection(context, ref worldViewProjection); //Shaders.Color.Emissive(context, ref diffuse); //context.InputAssembler.PrimitiveTopology = PrimitiveTopology.LineStrip; //context.InputAssembler.SetVertexBuffers(0, leftWaveFormVertexBufferBinding); //context.Draw(samples, 0); //worldViewProjection = Matrix.Scaling(1, 0.1f, 1) * Matrix.Translation(0, -0.1f, 0); //Shaders.Color.WorldViewProjection(context, ref worldViewProjection); //context.InputAssembler.SetVertexBuffers(0, rightWaveFormVertexBufferBinding); //context.Draw(samples, 0); // Draw Frequencies Shapes.Billboard.Begin(context); Shaders.Color.Apply(context); var emissive = new Vector4(0.2f, 0.2f, 0.8f, 1); Shaders.Color.Emissive(context, ref emissive); for (var sample = 0; sample < samples; sample++) { var volume = 1 + (int)(Math.Abs(leftFrequencies[sample]) * 10.0f); for (var pixel = 0; pixel < volume; pixel++) { //var worldViewProjection = Matrix.Scaling(0.5f) * Matrix.Translation(-256.0f + sample, Math.Abs(leftFrequencies[sample]) * 10.0f, 0) * view * projection; var worldViewProjection = Matrix.Scaling(0.5f) * Matrix.Translation(-50.0f + sample, pixel, 0) * view * projection; Shaders.Color.WorldViewProjection(context, ref worldViewProjection); emissive = new Vector4(pixel * 0.06f, 0.0f, 0.8f - (pixel * 0.02f), 1); Shaders.Color.Emissive(context, ref emissive); Shapes.Billboard.Draw(context); } } swapChain.Present(1, PresentFlags.None); frame++; }); MessageBox.Show((frame / DateTime.Now.Subtract(startTime).TotalSeconds).ToString() + " FPS"); } }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = unchecked ((int)uint.MaxValue), PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for shadow map pass. // var smapPsoDesc = opaquePsoDesc.Copy(); smapPsoDesc.RasterizerState.DepthBias = 100000; smapPsoDesc.RasterizerState.DepthBiasClamp = 0.0f; smapPsoDesc.RasterizerState.SlopeScaledDepthBias = 1.0f; smapPsoDesc.VertexShader = _shaders["shadowVS"]; smapPsoDesc.PixelShader = _shaders["shadowOpaquePS"]; // Shadow map pass does not have a render target. smapPsoDesc.RenderTargetFormats[0] = Format.Unknown; smapPsoDesc.RenderTargetCount = 0; _psos["shadow_opaque"] = Device.CreateGraphicsPipelineState(smapPsoDesc); // // PSO for debug layer. // var debugPsoDesc = opaquePsoDesc.Copy(); debugPsoDesc.VertexShader = _shaders["debugVS"]; debugPsoDesc.PixelShader = _shaders["debugPS"]; _psos["debug"] = Device.CreateGraphicsPipelineState(debugPsoDesc); // // PSO for sky. // GraphicsPipelineStateDescription skyPsoDesc = opaquePsoDesc.Copy(); // The camera is inside the sky sphere, so just turn off culling. skyPsoDesc.RasterizerState.CullMode = CullMode.None; // Make sure the depth function is LESS_EQUAL and not just LESS. // Otherwise, the normalized depth values at z = 1 (NDC) will // fail the depth test if the depth buffer was cleared to 1. skyPsoDesc.DepthStencilState.DepthComparison = Comparison.LessEqual; skyPsoDesc.VertexShader = _shaders["skyVS"]; skyPsoDesc.PixelShader = _shaders["skyPS"]; _psos["sky"] = Device.CreateGraphicsPipelineState(skyPsoDesc); }
private void LoadAssets() { RootParameter parameter1 = new RootParameter(ShaderVisibility.All, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 }); RootParameter parameter2 = new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, DescriptorCount = 1 }); RootParameter parameter3 = new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.Sampler, BaseShaderRegister = 0, DescriptorCount = 1 }); // Create a root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter1, parameter2, parameter3 }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("NORMAL", 0, Format.R32G32B32_Float, 12, 0), new InputElement("TEXCOORD", 0, Format.R32G32B32_Float, 24, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; //constant Buffer int constantBufferSize = (Utilities.SizeOf <Transform>() + 255) & ~255; constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize), ResourceStates.GenericRead); constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); //constant buffer ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = constantBufferSize }; CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart; device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart); cbvDesc.BufferLocation += Utilities.SizeOf <Transform>(); cbHandleHeapStart += constantBufferDescriptorSize; LoadMesh(cbHandleHeapStart); // Create synchronization objects. { fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); } InitBundles(); }
public Renderer(RenderSurface surface) { looper = new ParallelLooper(); Surface = surface; using (var stream = GetType().Assembly.GetManifestResourceStream("DemoRenderer.DemoRenderer.shaderarchive")) { ShaderCache = ShaderCache.Load(stream); } pool = new BufferPool(); Shapes = new ShapesExtractor(Surface.Device, looper, pool); SphereRenderer = new RayTracedRenderer <SphereInstance>(surface.Device, ShaderCache, @"ShapeDrawing\RenderSpheres.hlsl"); CapsuleRenderer = new RayTracedRenderer <CapsuleInstance>(surface.Device, ShaderCache, @"ShapeDrawing\RenderCapsules.hlsl"); BoxRenderer = new BoxRenderer(surface.Device, ShaderCache); TriangleRenderer = new TriangleRenderer(surface.Device, ShaderCache); MeshRenderer = new MeshRenderer(surface.Device, Shapes.MeshCache, ShaderCache); Lines = new LineExtractor(pool, looper); LineRenderer = new LineRenderer(surface.Device, ShaderCache); Background = new BackgroundRenderer(surface.Device, ShaderCache); CompressToSwap = new CompressToSwap(surface.Device, ShaderCache); GlyphRenderer = new GlyphRenderer(surface.Device, surface.Context, ShaderCache); TextBatcher = new TextBatcher(); UILineRenderer = new UILineRenderer(surface.Device, ShaderCache); UILineBatcher = new UILineBatcher(); OnResize(); var rasterizerStateDescription = RasterizerStateDescription.Default(); rasterizerStateDescription.IsFrontCounterClockwise = true; rasterizerStateDescription.CullMode = CullMode.Back; rasterizerState = new RasterizerState(Surface.Device, rasterizerStateDescription); rasterizerState.DebugName = "Default Rasterizer State"; var opaqueDepthStencilDescription = new DepthStencilStateDescription { IsDepthEnabled = true, DepthWriteMask = DepthWriteMask.All, //Note depth reversal. DepthComparison = Comparison.Greater, IsStencilEnabled = false }; opaqueDepthState = new DepthStencilState(Surface.Device, opaqueDepthStencilDescription); opaqueDepthState.DebugName = "Opaque Depth State"; var opaqueBlendStateDescription = BlendStateDescription.Default(); opaqueBlendState = new BlendState(Surface.Device, opaqueBlendStateDescription); opaqueBlendState.DebugName = "Opaque Blend State"; var a2cBlendStateDescription = BlendStateDescription.Default(); a2cBlendStateDescription.AlphaToCoverageEnable = true; a2cBlendState = new BlendState(Surface.Device, a2cBlendStateDescription); a2cBlendState.DebugName = "A2C Blend State"; var uiDepthStateDescription = new DepthStencilStateDescription { IsDepthEnabled = false, DepthWriteMask = DepthWriteMask.Zero, //Note depth reversal. DepthComparison = Comparison.Greater, IsStencilEnabled = false }; uiDepthState = new DepthStencilState(Surface.Device, uiDepthStateDescription); uiDepthState.DebugName = "UI Depth State"; //The UI will use premultiplied alpha. var uiBlendStateDescription = BlendStateDescription.Default(); uiBlendStateDescription.RenderTarget[0].IsBlendEnabled = true; uiBlendStateDescription.RenderTarget[0].SourceBlend = BlendOption.One; uiBlendStateDescription.RenderTarget[0].SourceAlphaBlend = BlendOption.One; uiBlendStateDescription.RenderTarget[0].DestinationBlend = BlendOption.InverseSourceAlpha; uiBlendStateDescription.RenderTarget[0].DestinationAlphaBlend = BlendOption.InverseSourceAlpha; uiBlendStateDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; uiBlendStateDescription.RenderTarget[0].AlphaBlendOperation = BlendOperation.Add; uiBlendStateDescription.RenderTarget[0].RenderTargetWriteMask = ColorWriteMaskFlags.All; uiBlendState = new BlendState(Surface.Device, uiBlendStateDescription); uiBlendState.DebugName = "UI Blend State"; }
public void BuildPSO(Device3 device, GraphicsCommandList commandList) { buffer = new CBuffer() { Rows = 3, Columns = 5 }; DescriptorHeapDescription cbvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _constantBufferViewHeap = device.CreateDescriptorHeap(cbvHeapDesc); DescriptorHeapDescription srvHeapDesc = new DescriptorHeapDescription() { DescriptorCount = 1, Flags = DescriptorHeapFlags.ShaderVisible, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView }; _srvDescriptorHeap = device.CreateDescriptorHeap(srvHeapDesc); DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } }; //Get sampler state setup StaticSamplerDescription sampler = new StaticSamplerDescription() { Filter = Filter.MinimumMinMagMipPoint, AddressU = TextureAddressMode.Border, AddressV = TextureAddressMode.Border, AddressW = TextureAddressMode.Border, MipLODBias = 0, MaxAnisotropy = 0, ComparisonFunc = Comparison.Never, BorderColor = StaticBorderColor.TransparentBlack, MinLOD = 0.0f, MaxLOD = float.MaxValue, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.Pixel, }; RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges), new RootParameter(ShaderVisibility.Pixel, new RootDescriptor(1, 0), RootParameterType.ConstantBufferView) }; // Create an empty root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler }); _rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("Shaders/AtlasWalk.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = _rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; _pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { new Vertex() { position = new Vector3(-0.5f, -0.5f, 0.5f), texCoord = new Vector2(1.0f, 1.0f) }, new Vertex() { position = new Vector3(-0.5f, 0.5f, 0.5f), texCoord = new Vector2(1.0f, 0.0f) }, new Vertex() { position = new Vector3(0.5f, -0.5f, 0.5f), texCoord = new Vector2(0.0f, 1.0f) }, new Vertex() { position = new Vector3(0.5f, 0.5f, 0.5f), texCoord = new Vector2(0.0f, 0.0f) } }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. _vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = _vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); _vertexBuffer.Unmap(0); _indicies = new int[] { 0, 1, 2, 3, 2, 1 }; int indBufferSize = Utilities.SizeOf(_indicies); _indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indBufferSize), ResourceStates.GenericRead); IntPtr pIndBegin = _indexBuffer.Map(0); Utilities.Write(pIndBegin, _indicies, 0, _indicies.Length); _indexBuffer.Unmap(0); _indexBufferView = new IndexBufferView() { BufferLocation = _indexBuffer.GPUVirtualAddress, Format = Format.R32_UInt, SizeInBytes = indBufferSize }; // Initialize the vertex buffer view. _vertexBufferView = new VertexBufferView { BufferLocation = _vertexBuffer.GPUVirtualAddress, StrideInBytes = Utilities.SizeOf <Vertex>(), SizeInBytes = vertexBufferSize }; Resource textureUploadHeap; // Create the texture. // Describe and create a Texture2D. ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight); _texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(device, _texture, 0, 1); // Create the GPU upload buffer. textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, textureWidth, textureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, 4 * textureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(_texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(_texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = ComponentMapping(0, 1, 2, 3), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, }; srvDesc.Texture2D.MipLevels = 1; device.CreateShaderResourceView(_texture, srvDesc, _srvDescriptorHeap.CPUDescriptorHandleForHeapStart); _constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); //// Describe and create a constant buffer view. ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = _constantBuffer.GPUVirtualAddress, SizeInBytes = (Utilities.SizeOf <CBuffer>() + 255) & ~255 }; device.CreateConstantBufferView(cbvDesc, _constantBufferViewHeap.CPUDescriptorHandleForHeapStart); // Initialize and map the constant buffers. We don't unmap this until the // app closes. Keeping things mapped for the lifetime of the resource is okay. _constantBufferPointer = _constantBuffer.Map(0); Utilities.Write(_constantBufferPointer, ref buffer); _resources = new[] { new GraphicsResource() { Heap = _srvDescriptorHeap, Register = 0, type = ResourceType.DescriptorTable }, new GraphicsResource() { Resource = _constantBuffer, Register = 1, type = ResourceType.ConstantBufferView } }; }
private void LoadAssets() { DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, DescriptorCount = 1 } }; RootParameter parameter = new RootParameter(ShaderVisibility.Vertex, ranges); // Create a root signature. RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, new RootParameter[] { parameter }); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a cube. Vertex[] vertices = new[] { ////TOP new Vertex(new Vector3(-5, 5, 5), new Vector4(0, 1, 0, 0)), new Vertex(new Vector3(5, 5, 5), new Vector4(0, 1, 0, 0)), new Vertex(new Vector3(5, 5, -5), new Vector4(0, 1, 0, 0)), new Vertex(new Vector3(-5, 5, -5), new Vector4(0, 1, 0, 0)), //BOTTOM new Vertex(new Vector3(-5, -5, 5), new Vector4(1, 0, 1, 1)), new Vertex(new Vector3(5, -5, 5), new Vector4(1, 0, 1, 1)), new Vertex(new Vector3(5, -5, -5), new Vector4(1, 0, 1, 1)), new Vertex(new Vector3(-5, -5, -5), new Vector4(1, 0, 1, 1)), //LEFT new Vertex(new Vector3(-5, -5, 5), new Vector4(1, 0, 0, 1)), new Vertex(new Vector3(-5, 5, 5), new Vector4(1, 0, 0, 1)), new Vertex(new Vector3(-5, 5, -5), new Vector4(1, 0, 0, 1)), new Vertex(new Vector3(-5, -5, -5), new Vector4(1, 0, 0, 1)), //RIGHT new Vertex(new Vector3(5, -5, 5), new Vector4(1, 1, 0, 1)), new Vertex(new Vector3(5, 5, 5), new Vector4(1, 1, 0, 1)), new Vertex(new Vector3(5, 5, -5), new Vector4(1, 1, 0, 1)), new Vertex(new Vector3(5, -5, -5), new Vector4(1, 1, 0, 1)), //FRONT new Vertex(new Vector3(-5, 5, 5), new Vector4(0, 1, 1, 1)), new Vertex(new Vector3(5, 5, 5), new Vector4(0, 1, 1, 1)), new Vertex(new Vector3(5, -5, 5), new Vector4(0, 1, 1, 1)), new Vertex(new Vector3(-5, -5, 5), new Vector4(0, 1, 1, 1)), //BACK new Vertex(new Vector3(-5, 5, -5), new Vector4(0, 0, 1, 1)), new Vertex(new Vector3(5, 5, -5), new Vector4(0, 0, 1, 1)), new Vertex(new Vector3(5, -5, -5), new Vector4(0, 0, 1, 1)), new Vertex(new Vector3(-5, -5, -5), new Vector4(0, 0, 1, 1)) }; int vertexBufferSize = Utilities.SizeOf(vertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, vertices, 0, vertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; //Create Index Buffer //Indices int[] indices = new int[] { 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(indices); indexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(indexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pIndexDataBegin = indexBuffer.Map(0); Utilities.Write(pIndexDataBegin, indices, 0, indices.Length); indexBuffer.Unmap(0); // Initialize the index buffer view. indexBufferView = new IndexBufferView(); indexBufferView.BufferLocation = indexBuffer.GPUVirtualAddress; indexBufferView.Format = Format.R32_UInt; indexBufferView.SizeInBytes = indexBufferSize; //constant Buffer for each cubes constantBufferViewHeap = device.CreateDescriptorHeap(new DescriptorHeapDescription() { DescriptorCount = NumCubes, Type = DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView, Flags = DescriptorHeapFlags.ShaderVisible }); int constantBufferSize = (Utilities.SizeOf <Transform>() + 255) & ~255; constantBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(constantBufferSize * NumCubes), ResourceStates.GenericRead); constantBufferDescriptorSize = device.GetDescriptorHandleIncrementSize(DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); //First cube ConstantBufferViewDescription cbvDesc = new ConstantBufferViewDescription() { BufferLocation = constantBuffer.GPUVirtualAddress, SizeInBytes = constantBufferSize }; CpuDescriptorHandle cbHandleHeapStart = constantBufferViewHeap.CPUDescriptorHandleForHeapStart; for (int i = 0; i < NumCubes; i++) { device.CreateConstantBufferView(cbvDesc, cbHandleHeapStart); cbvDesc.BufferLocation += Utilities.SizeOf <Transform>(); cbHandleHeapStart += constantBufferDescriptorSize; } InitBundles(); }
public void SettingForPhysics() { //@TODO - temporary sampler StaticSamplerDescription pointClamp = new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0); pointClamp.Filter = Filter.ComparisonMinLinearMagMipPoint; pointClamp.AddressU = TextureAddressMode.Clamp; pointClamp.AddressV = TextureAddressMode.Clamp; pointClamp.AddressW = TextureAddressMode.Clamp; StaticSamplerDescription[] staticSamArray = new[] { pointClamp }; // create an empty root signature var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, // root parameters new[] { new RootParameter(ShaderVisibility.Vertex, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = 0, DescriptorCount = 1 }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = 0, DescriptorCount = 1 }) } , staticSamArray ); m_RootSignature = Device.CreateRootSignature(rootSignatureDesc.Serialize()); // create the pipeline state, which includes compiling and loading shader H1VertexFactoryType vertexFactoryType = ShaderManager.GetVertexFactoryType("H1LocalVertexFactory"); //H1VertexFactoryType vertexFactoryType = ShaderManager.GetVertexFactoryType("H1GpuSkinVertexFactory"); #if DEBUG //var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shader.hlsl", "VSMain", "vs_5_1", SharpDX.D3DCompiler.ShaderFlags.Debug)); var vertexShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassVertexShader", vertexFactoryType).ShaderByteCode; #else var vertexShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassVertexShader", vertexFactoryType).ShaderByteCode; #endif #if DEBUG //var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shader.hlsl", "PSMain", "ps_5_1", SharpDX.D3DCompiler.ShaderFlags.Debug)); var pixelShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassPixelShader", vertexFactoryType).ShaderByteCode; #else var pixelShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassPixelShader", vertexFactoryType).ShaderByteCode; #endif // set the seperate rasterizerstatedesc RasterizerStateDescription rasterizerStateDesc = RasterizerStateDescription.Default(); rasterizerStateDesc.FillMode = FillMode.Wireframe; rasterizerStateDesc.CullMode = CullMode.None; //rasterizerStateDesc.CullMode = CullMode.Front; //@TODO - what the f**k?!... need to solve this urgently~****** //rasterizerStateDesc.FillMode = FillMode.Solid; Vector3 position = new Vector3(); Vector3 size = new Vector3(1, 1, 1); H1RenderUtils.H1DynamicMeshBuilder meshBuilder = H1Global <H1VisualDebugger> .Instance.GetNewDynamicMeshBuilder(); { meshBuilder.AddLine(new Vector4(position + size * new Vector3(1, 0, 0), 1), new Vector4(position - size * new Vector3(1, 0, 0), 1), new Vector4(1)); meshBuilder.AddLine(new Vector4(position + size * new Vector3(0, 1, 0), 1), new Vector4(position - size * new Vector3(0, 1, 0), 1), new Vector4(1)); meshBuilder.AddLine(new Vector4(position + size * new Vector3(0, 0, 1), 1), new Vector4(position - size * new Vector3(0, 0, 1), 1), new Vector4(1)); } // generate vertex & index buffers and vertex declaration meshBuilder.GenerateVertexIndexBuffersAndVertexDeclaration(); // describe and create the graphics pipeline state object (PSO) var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = meshBuilder.VertexFactory.VertexDeclaration.InputLayout.Description, RootSignature = m_RootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = rasterizerStateDesc, BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = DepthStencilStateDescription.Default(), //DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; m_PipelineState = Device.CreateGraphicsPipelineState(psoDesc); // create the command list m_CommandList = new Direct3D12.H1CommandList(m_DeviceContext.Dx12Device, m_DeviceContext.MainCommandListPool); m_CommandList.Initialize(); // create the vertex buffer float aspectRatio = m_Viewport.Width / m_Viewport.Height; m_ConstantBuffer = Device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); var cbvDesc = new ConstantBufferViewDescription { BufferLocation = m_ConstantBuffer.GPUVirtualAddress, SizeInBytes = 256 * 256//(Utilities.SizeOf<TransformationCB>() + 255) & ~255 }; Device.CreateConstantBufferView(cbvDesc, m_ConstantBufferViewHeap.CPUDescriptorHandleForHeapStart); }
private void LoadAssets() { DescriptorRange[] ranges = new DescriptorRange[] { new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, DescriptorCount = 1, OffsetInDescriptorsFromTableStart = int.MinValue, BaseShaderRegister = 0 } }; StaticSamplerDescription sampler = new StaticSamplerDescription() { Filter = Filter.MinimumMinMagMipPoint, AddressU = TextureAddressMode.Border, AddressV = TextureAddressMode.Border, AddressW = TextureAddressMode.Border, MipLODBias = 0, MaxAnisotropy = 0, ComparisonFunc = Comparison.Never, BorderColor = StaticBorderColor.TransparentBlack, MinLOD = 0.0f, MaxLOD = float.MaxValue, ShaderRegister = 0, RegisterSpace = 0, ShaderVisibility = ShaderVisibility.Pixel, }; RootParameter[] rootParameters = new RootParameter[] { new RootParameter(ShaderVisibility.Pixel, ranges) }; RootSignatureDescription rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, rootParameters, new StaticSamplerDescription[] { sampler }); 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.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. InputElement[] inputElementDescs = new InputElement[] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). GraphicsPipelineStateDescription psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. Vertex[] triangleVertices = new Vertex[] { new Vertex() { position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), uv = new Vector2(0.5f, 0.0f) }, new Vertex() { position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), uv = new Vector2(1.0f, 1.0f) }, new Vertex() { position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), uv = new Vector2(0.0f, 1.0f) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; Resource textureUploadHeap; // Create the texture. // Describe and create a Texture2D. ResourceDescription textureDesc = ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight); texture = device.CreateCommittedResource(new HeapProperties(HeapType.Default), HeapFlags.None, textureDesc, ResourceStates.CopyDestination); long uploadBufferSize = GetRequiredIntermediateSize(this.texture, 0, 1); // Create the GPU upload buffer. textureUploadHeap = device.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None, ResourceDescription.Texture2D(Format.R8G8B8A8_UNorm, TextureWidth, TextureHeight), ResourceStates.GenericRead); // Copy data to the intermediate upload heap and then schedule a copy // from the upload heap to the Texture2D. byte[] textureData = GenerateTextureData(); GCHandle handle = GCHandle.Alloc(textureData, GCHandleType.Pinned); IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(textureData, 0); textureUploadHeap.WriteToSubresource(0, null, ptr, TexturePixelSize * TextureWidth, textureData.Length); handle.Free(); commandList.CopyTextureRegion(new TextureCopyLocation(texture, 0), 0, 0, 0, new TextureCopyLocation(textureUploadHeap, 0), null); commandList.ResourceBarrierTransition(this.texture, ResourceStates.CopyDestination, ResourceStates.PixelShaderResource); // Describe and create a SRV for the texture. ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = D3DXUtilities.DefaultComponentMapping(), Format = textureDesc.Format, Dimension = ShaderResourceViewDimension.Texture2D, }; srvDesc.Texture2D.MipLevels = 1; device.CreateShaderResourceView(this.texture, srvDesc, shaderRenderViewHeap.CPUDescriptorHandleForHeapStart); // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); commandQueue.ExecuteCommandList(commandList); // Create synchronization objects. fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); WaitForPreviousFrame(); //release temp texture textureUploadHeap.Dispose(); }
public void LoadAssets() { //@TODO - temporary sampler StaticSamplerDescription pointClamp = new StaticSamplerDescription(ShaderVisibility.Pixel, 0, 0); pointClamp.Filter = Filter.ComparisonMinLinearMagMipPoint; pointClamp.AddressU = TextureAddressMode.Clamp; pointClamp.AddressV = TextureAddressMode.Clamp; pointClamp.AddressW = TextureAddressMode.Clamp; StaticSamplerDescription[] staticSamArray = new[] { pointClamp }; // create an empty root signature var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout, // root parameters new[] { new RootParameter(ShaderVisibility.Vertex, new DescriptorRange() { RangeType = DescriptorRangeType.ConstantBufferView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = 0, DescriptorCount = 1 }), new RootParameter(ShaderVisibility.Pixel, new DescriptorRange() { RangeType = DescriptorRangeType.ShaderResourceView, BaseShaderRegister = 0, OffsetInDescriptorsFromTableStart = 0, DescriptorCount = 1 }) } , staticSamArray ); m_RootSignature = Device.CreateRootSignature(rootSignatureDesc.Serialize()); // create the pipeline state, which includes compiling and loading shader //H1VertexFactoryType vertexFactoryType = ShaderManager.GetVertexFactoryType("H1LocalVertexFactory"); H1VertexFactoryType vertexFactoryType = ShaderManager.GetVertexFactoryType("H1GpuSkinVertexFactory"); #if DEBUG //var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shader.hlsl", "VSMain", "vs_5_1", SharpDX.D3DCompiler.ShaderFlags.Debug)); var vertexShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassVertexShader", vertexFactoryType).ShaderByteCode; #else var vertexShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassVertexShader", vertexFactoryType).ShaderByteCode; #endif #if DEBUG //var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shader.hlsl", "PSMain", "ps_5_1", SharpDX.D3DCompiler.ShaderFlags.Debug)); var pixelShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassPixelShader", vertexFactoryType).ShaderByteCode; #else var pixelShader = H1Material.DefaultMaterial.MaterialResource.GetShader("H1BasePassPixelShader", vertexFactoryType).ShaderByteCode; #endif // set the seperate rasterizerstatedesc RasterizerStateDescription rasterizerStateDesc = RasterizerStateDescription.Default(); //rasterizerStateDesc.FillMode = FillMode.Wireframe; //rasterizerStateDesc.CullMode = CullMode.None; rasterizerStateDesc.CullMode = CullMode.Front; //@TODO - what the f**k?!... need to solve this urgently~****** rasterizerStateDesc.FillMode = FillMode.Solid; //H1StaticMeshLODResource resource = m_TempStaticMesh.StaticMeshData.GetLODResource(0); //H1StaticMeshLODResource resource = H1Global<H1World>.Instance.PersistentLevel.GetActor(0).GetActorComponent<H1StaticMeshComponent>().StaticMesh.StaticMeshData.GetLODResource(1); H1SkeletalMeshObjectGPUSkin skeletalMeshObject = H1Global <H1World> .Instance.PersistentLevel.GetActor(0).GetActorComponent <H1SkeletalMeshComponent>().SkeletalMeshObjectGPUSkin; // describe and create the graphics pipeline state object (PSO) var psoDesc = new GraphicsPipelineStateDescription() { //InputLayout = resource.LocalVertexFactory.VertexDeclaration.InputLayout, InputLayout = ((Gen2Layer.H1InputLayout)skeletalMeshObject.GetSkeletalMeshObjectLODByIndex(0).GPUSkinVertexFactories.VertexFactories[0].VertexDeclaration.InputLayout).Description, RootSignature = m_RootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = rasterizerStateDesc, BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = DepthStencilStateDescription.Default(), //DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; m_PipelineState = Device.CreateGraphicsPipelineState(psoDesc); // create the command list m_CommandList = new Direct3D12.H1CommandList(m_DeviceContext.Dx12Device, m_DeviceContext.MainCommandListPool); m_CommandList.Initialize(); // create the vertex buffer float aspectRatio = m_Viewport.Width / m_Viewport.Height; m_ConstantBuffer = Device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(1024 * 64), ResourceStates.GenericRead); var cbvDesc = new ConstantBufferViewDescription { BufferLocation = m_ConstantBuffer.GPUVirtualAddress, SizeInBytes = 256 * 256//(Utilities.SizeOf<TransformationCB>() + 255) & ~255 }; Device.CreateConstantBufferView(cbvDesc, m_ConstantBufferViewHeap.CPUDescriptorHandleForHeapStart); m_TransformationCBPointer = m_ConstantBuffer.Map(0); //Utilities.Write(m_TransformationCBPointer, ref m_TransformationCB); List <Matrix> dataToCopy = new List <Matrix>(); dataToCopy.Add(m_TransformationCB.viewProjectionMatrix); foreach (Matrix mtx in m_TransformationCB.BoneMatrices) { dataToCopy.Add(mtx); } Utilities.Write(m_TransformationCBPointer, dataToCopy.ToArray(), 0, 101); m_ConstantBuffer.Unmap(0); // @TODO - temporary so need to delete String path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Assets\\"); m_tempImageLoader = new H1ImageWrapper(path + "alduin.JPG"); //CpuDescriptorHandle hDescriptor = m_srvDescriptorHeap.CPUDescriptorHandleForHeapStart; CpuDescriptorHandle hDescriptor = m_ConstantBufferViewHeap.CPUDescriptorHandleForHeapStart; hDescriptor += m_ConstantBufferDescriptorSize; //Int32 sizeInBytes = (Utilities.SizeOf<TransformationCB>() + 255) & ~255; //hDescriptor += sizeInBytes; ShaderResourceViewDescription srvDesc = new ShaderResourceViewDescription() { Shader4ComponentMapping = 5768, //@TODO - temporary! Format = m_tempImageLoader.m_tempTextureObject.Resource.Description.Format, Dimension = ShaderResourceViewDimension.Texture2D }; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1;// m_tempImageLoader.m_tempTextureObject.Resource.Description.MipLevels; srvDesc.Texture2D.ResourceMinLODClamp = 0.0f; Device.CreateShaderResourceView(m_tempImageLoader.m_tempTextureObject.Resource, srvDesc, hDescriptor); }
private void SetBlendState() { blendState = new BlendState(Device, BlendStateDescription.Default()); }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = unchecked ((int)0xFFFFFFFF), PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat, StreamOutput = new StreamOutputDescription() //find out how this should actually be done later }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); // // PSO for tree sprites. // GraphicsPipelineStateDescription treeSpritePsoDesc = opaquePsoDesc.Copy(); treeSpritePsoDesc.VertexShader = _shaders["treeSpriteVS"]; treeSpritePsoDesc.GeometryShader = _shaders["treeSpriteGS"]; treeSpritePsoDesc.PixelShader = _shaders["treeSpritePS"]; treeSpritePsoDesc.PrimitiveTopologyType = PrimitiveTopologyType.Point; treeSpritePsoDesc.InputLayout = _treeSpriteInputLayout; treeSpritePsoDesc.RasterizerState.CullMode = CullMode.None; _psos["treeSprites"] = Device.CreateGraphicsPipelineState(treeSpritePsoDesc); }
private void BuildPSOs() { // // PSO for opaque objects. // var opaquePsoDesc = new GraphicsPipelineStateDescription { InputLayout = _inputLayout, RootSignature = _rootSignature, VertexShader = _shaders["standardVS"], PixelShader = _shaders["opaquePS"], RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilState = DepthStencilStateDescription.Default(), SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, SampleDescription = new SampleDescription(MsaaCount, MsaaQuality), DepthStencilFormat = DepthStencilFormat }; opaquePsoDesc.RenderTargetFormats[0] = BackBufferFormat; _psos["opaque"] = Device.CreateGraphicsPipelineState(opaquePsoDesc); // // PSO for transparent objects. // GraphicsPipelineStateDescription transparentPsoDesc = opaquePsoDesc.Copy(); var transparencyBlendDesc = new RenderTargetBlendDescription { IsBlendEnabled = true, LogicOpEnable = false, // TODO: API suggestion: Rename to IsLogicOpEnabled similar to IsBlendEnabled. SourceBlend = BlendOption.SourceAlpha, DestinationBlend = BlendOption.InverseSourceAlpha, BlendOperation = BlendOperation.Add, SourceAlphaBlend = BlendOption.One, DestinationAlphaBlend = BlendOption.Zero, AlphaBlendOperation = BlendOperation.Add, LogicOp = LogicOperation.Noop, RenderTargetWriteMask = ColorWriteMaskFlags.All }; transparentPsoDesc.BlendState.RenderTarget[0] = transparencyBlendDesc; _psos["transparent"] = Device.CreateGraphicsPipelineState(transparentPsoDesc); // // PSO for alpha tested objects. // GraphicsPipelineStateDescription alphaTestedPsoDesc = opaquePsoDesc.Copy(); alphaTestedPsoDesc.PixelShader = _shaders["alphaTestedPS"]; alphaTestedPsoDesc.RasterizerState.CullMode = CullMode.None; _psos["alphaTested"] = Device.CreateGraphicsPipelineState(alphaTestedPsoDesc); }
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 LoadAssets() { // Create an empty root signature. var rootSignatureDesc = new RootSignatureDescription(RootSignatureFlags.AllowInputAssemblerInputLayout); rootSignature = device.CreateRootSignature(rootSignatureDesc.Serialize()); // Create the pipeline state, which includes compiling and loading shaders. #if DEBUG var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var vertexShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "VSMain", "vs_5_0")); #endif #if DEBUG var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0", SharpDX.D3DCompiler.ShaderFlags.Debug)); #else var pixelShader = new ShaderBytecode(SharpDX.D3DCompiler.ShaderBytecode.CompileFromFile("shaders.hlsl", "PSMain", "ps_5_0")); #endif // Define the vertex input layout. var inputElementDescs = new [] { new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0), new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 12, 0) }; // Describe and create the graphics pipeline state object (PSO). var psoDesc = new GraphicsPipelineStateDescription() { InputLayout = new InputLayoutDescription(inputElementDescs), RootSignature = rootSignature, VertexShader = vertexShader, PixelShader = pixelShader, RasterizerState = RasterizerStateDescription.Default(), BlendState = BlendStateDescription.Default(), DepthStencilFormat = SharpDX.DXGI.Format.D32_Float, DepthStencilState = new DepthStencilStateDescription() { IsDepthEnabled = false, IsStencilEnabled = false }, SampleMask = int.MaxValue, PrimitiveTopologyType = PrimitiveTopologyType.Triangle, RenderTargetCount = 1, Flags = PipelineStateFlags.None, SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0), StreamOutput = new StreamOutputDescription() }; psoDesc.RenderTargetFormats[0] = SharpDX.DXGI.Format.R8G8B8A8_UNorm; pipelineState = device.CreateGraphicsPipelineState(psoDesc); // Create the command list. commandList = device.CreateCommandList(CommandListType.Direct, commandAllocator, pipelineState); // Create the vertex buffer. float aspectRatio = viewport.Width / viewport.Height; // Define the geometry for a triangle. var triangleVertices = new [] { new Vertex() { Position = new Vector3(0.0f, 0.25f * aspectRatio, 0.0f), Color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f) }, new Vertex() { Position = new Vector3(0.25f, -0.25f * aspectRatio, 0.0f), Color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f) }, new Vertex() { Position = new Vector3(-0.25f, -0.25f * aspectRatio, 0.0f), Color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f) }, }; int vertexBufferSize = Utilities.SizeOf(triangleVertices); // Note: using upload heaps to transfer static data like vert buffers is not // recommended. Every time the GPU needs it, the upload heap will be marshalled // over. Please read up on Default Heap usage. An upload heap is used here for // code simplicity and because there are very few verts to actually transfer. vertexBuffer = device.CreateCommittedResource(new HeapProperties(HeapType.Upload), HeapFlags.None, ResourceDescription.Buffer(vertexBufferSize), ResourceStates.GenericRead); // Copy the triangle data to the vertex buffer. IntPtr pVertexDataBegin = vertexBuffer.Map(0); Utilities.Write(pVertexDataBegin, triangleVertices, 0, triangleVertices.Length); vertexBuffer.Unmap(0); // Initialize the vertex buffer view. vertexBufferView = new VertexBufferView(); vertexBufferView.BufferLocation = vertexBuffer.GPUVirtualAddress; vertexBufferView.StrideInBytes = Utilities.SizeOf <Vertex>(); vertexBufferView.SizeInBytes = vertexBufferSize; // Command lists are created in the recording state, but there is nothing // to record yet. The main loop expects it to be closed, so close it now. commandList.Close(); // Create synchronization objects. fence = device.CreateFence(0, FenceFlags.None); fenceValue = 1; // Create an event handle to use for frame synchronization. fenceEvent = new AutoResetEvent(false); }
public Logic(Game game) : base(game) { int numGroups = (PARTICLES_COUNT % 768 != 0) ? ((PARTICLES_COUNT / 768) + 1) : (PARTICLES_COUNT / 768); double secondRoot = System.Math.Pow((double)numGroups, (double)(1.0 / 2.0)); secondRoot = System.Math.Ceiling(secondRoot); _groupSizeX = _groupSizeY = (int)secondRoot; game.Color = Color.Black; System.Random random = new System.Random(); GPUParticleData[] initialParticles = new GPUParticleData[PARTICLES_COUNT]; Vector3 min = new Vector3(-30f, -30f, -30f); Vector3 max = new Vector3(30f, 30f, 30f); for (int i = 0; i < PARTICLES_COUNT; i++) { initialParticles[i].Position = random.NextVector3(min, max); float angle = -(float)System.Math.Atan2(initialParticles[i].Position.X, initialParticles[i].Position.Z); initialParticles[i].Velocity = new Vector3((float)System.Math.Cos(angle), 0f, (float)System.Math.Sin(angle)) * 5f; } _particlesBuffer = new Buffer(game.DeviceContext.Device, Utilities.SizeOf <GPUParticleData>() * PARTICLES_COUNT, ResourceUsage.Default, BindFlags.ShaderResource | BindFlags.UnorderedAccess, CpuAccessFlags.None, ResourceOptionFlags.BufferStructured, Utilities.SizeOf <GPUParticleData>()); game.DeviceContext.UpdateSubresource(initialParticles, _particlesBuffer); #region Blend and Depth States var blendDesc = new BlendStateDescription() { IndependentBlendEnable = false, AlphaToCoverageEnable = false, }; // Additive blend state that darkens when overlapped 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 }; blendDesc.RenderTarget[0].DestinationBlend = BlendOption.One; BlendStateDescription blendDescription = BlendStateDescription.Default(); blendDescription.RenderTarget[0].IsBlendEnabled = true; blendDescription.RenderTarget[0].SourceBlend = BlendOption.One; blendDescription.RenderTarget[0].DestinationBlend = BlendOption.One; blendDescription.RenderTarget[0].BlendOperation = BlendOperation.Add; var depthDesc = new DepthStencilStateDescription { DepthComparison = Comparison.Less, DepthWriteMask = DepthWriteMask.Zero, IsDepthEnabled = true, IsStencilEnabled = false }; _DState = new DepthStencilState(game.DeviceContext.Device, depthDesc); _blendState = new BlendState(game.DeviceContext.Device, blendDescription); #endregion worldMatrix = Matrix.Identity; viewMatrix = Matrix.LookAtLH(new Vector3(0, 0, 100), Vector3.Zero, Vector3.Up); projectionMatrix = Matrix.PerspectiveFovLH(MathUtil.PiOverFour, game.ViewRatio, 1f, 1000); m = new Matrixes(); m.World = worldMatrix; m.View = viewMatrix; m.Proj = projectionMatrix; m.Size = 1f; m.Trans(); _perFrame = new Buffer(game.DeviceContext.Device, Utilities.SizeOf <Matrixes>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); game.DeviceContext.UpdateSubresource(ref m, _perFrame); _c = new Constants(); _c.GroupDim = _groupSizeX; _c.MaxParticles = PARTICLES_COUNT; _csConstants = new Buffer(game.DeviceContext.Device, Utilities.SizeOf <Constants>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); ShaderFlags shaderFlags = ShaderFlags.None; #if DEBUG shaderFlags = ShaderFlags.Debug; #endif using (var shaderByteCode = ShaderBytecode.CompileFromFile(@"Shaders\VS.hlsl", "VS", "vs_5_0", shaderFlags)) _vs = new VertexShader(game.DeviceContext.Device, shaderByteCode); using (var shaderByteCode = ShaderBytecode.CompileFromFile(@"Shaders\GS.hlsl", "GS", "gs_5_0", shaderFlags)) _gs = new GeometryShader(game.DeviceContext.Device, shaderByteCode); using (var shaderByteCode = ShaderBytecode.CompileFromFile(@"Shaders\PS.hlsl", "PS", "ps_5_0", shaderFlags)) _ps = new PixelShader(game.DeviceContext.Device, shaderByteCode); using (var shaderByteCode = ShaderBytecode.CompileFromFile(@"Shaders\CS.hlsl", "CS", "cs_5_0", shaderFlags)) _cs = new ComputeShader(game.DeviceContext.Device, shaderByteCode); _SRV = new ShaderResourceView(game.DeviceContext.Device, _particlesBuffer); UnorderedAccessViewDescription uavDesc = new UnorderedAccessViewDescription { Dimension = UnorderedAccessViewDimension.Buffer, Buffer = new UnorderedAccessViewDescription.BufferResource { FirstElement = 0 } }; uavDesc.Format = Format.Unknown; uavDesc.Buffer.Flags = UnorderedAccessViewBufferFlags.None; uavDesc.Buffer.ElementCount = _particlesBuffer.Description.SizeInBytes / _particlesBuffer.Description.StructureByteStride; _UAV = new UnorderedAccessView(game.DeviceContext.Device, _particlesBuffer, uavDesc); SamplerStateDescription samplerDecription = SamplerStateDescription.Default(); { samplerDecription.AddressU = TextureAddressMode.Clamp; samplerDecription.AddressV = TextureAddressMode.Clamp; samplerDecription.Filter = Filter.MinMagMipLinear; }; _particleSampler = new SamplerState(game.DeviceContext.Device, samplerDecription); _texture = StaticMetods.LoadTextureFromFile(game.DeviceContext, "smoke5.png"); game.DeviceContext.OutputMerger.DepthStencilState = _DState; }