using System; using SharpDX.D3DCompiler; using SharpDX.Direct3D; using SharpDX.Direct3D11; using SharpDX.Mathematics.Interop; namespace Intromat.Pipelines { public class DisplayMeshPipeline { private readonly VertexShader _vs; private readonly PixelShader _ps; private readonly DeviceContext _context; private readonly SamplerState _sampler; private ShaderResourceView? _srv; private readonly RasterizerState _rs; private readonly DepthStencilState _dss; private const string _vertexShader = "void main(in uint i : SV_VertexID, out float2 uv : TEXCOORD, out float4 pos : SV_Position) { uv = float2(i % 2, i / 2); pos = float4(uv * 2 - 1, 0.5, 1); }"; private const string _pixelShader = "Texture2D t; SamplerState s; float4 main(in float2 uv : TEXCOORD) : SV_Target0 { return float4(t.Sample(s, uv).xyz, 1); }"; public DisplayMeshPipeline(Device device, DeviceContext context) { var flags = ShaderFlags.None; #if DEBUG flags |= ShaderFlags.Debug; #endif _vs = new VertexShader(device, ShaderBytecode.Compile(_vertexShader, "main", "vs_5_0", flags).Bytecode.Data); _ps = new PixelShader(device, ShaderBytecode.Compile(_pixelShader, "main", "ps_5_0", flags).Bytecode.Data); _context = context; var samplerDesc = new SamplerStateDescription { Filter = Filter.MinMagMipLinear, AddressU = TextureAddressMode.Clamp, AddressV = TextureAddressMode.Clamp, AddressW = TextureAddressMode.Clamp }; _sampler = new SamplerState(device, samplerDesc); var rasterizerDesc = RasterizerStateDescription.Default(); rasterizerDesc.CullMode = CullMode.None; rasterizerDesc.IsDepthClipEnabled = false; _rs = new RasterizerState(device, rasterizerDesc); var depthStencilStateDesc = DepthStencilStateDescription.Default(); depthStencilStateDesc.IsDepthEnabled = false; _dss = new DepthStencilState(device, depthStencilStateDesc); } public void Apply() { var viewport = _context.Rasterizer.GetViewports()[0]; var dim = Math.Min(viewport.Width, viewport.Height); var offsetX = dim < viewport.Width ? (viewport.Width - dim) / 2 : 0; var offsetY = dim < viewport.Height ? (viewport.Height - dim) / 2 : 0; _context.Rasterizer.SetViewport(offsetX, offsetY, dim, dim); _context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleStrip; _context.VertexShader.Set(_vs); _context.PixelShader.Set(_ps); _context.PixelShader.SetShaderResources(0, _srv); _context.PixelShader.SetSampler(0, _sampler); _context.Rasterizer.State = _rs; _context.OutputMerger.DepthStencilState = _dss; _context.Draw(4, 0); _context.PixelShader.SetShaderResources(0, (ShaderResourceView?)null); } public ShaderResourceView? ShaderResourceView { get => _srv; set => _srv = value; } } }