Files
bluflame/intromat/Intromat/Pipelines/DisplayMeshPipeline.cs
2026-04-18 22:31:51 +02:00

72 lines
3.2 KiB
C#

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<RawViewportF>()[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;
}
}
}