using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Numerics; namespace Dashboard.Drawing { public enum MeshPrimitive { Point, Line, Triangle, TriangleFan, TriangleStrip, } public enum WindingOrder { Clockwise, Counterclockwise, } public enum FaceCulling { None, Front, Back, Both, } public enum VertexAttributeType { UnsignedByte, UnsignedShort, UnsignedInt, Byte, Short, Int, Half, Float, Double, } public enum IndexType { UnsignedShort, UnsignedInt, UnsignedLong, Short, Int, } public enum BlendFunction { One, Zero, SourceAlpha, OneMinusSourceAlpha, DestinationAlpha, OneMinusDestinationAlpha, SourceColor, OneMinusSourceColor, DestinationColor, OneMinusDestinationColor, ConstantColor, OneMinusConstantColor, ConstantAlpha, OneMinusConstantAlpha, } public enum BlendEquation { Add, Subtract, ReverseSubtract, Min, Max, } public enum TestFunction { Never, LessThan, LessThanOrEqual, Equal, NotEqual, GreaterThanOrEqual, Greater, Always, } public enum StencilOperation { Keep, Zero, Replace, Increment, UncheckedIncrement, Decrement, UncheckedDecrement, Invert, } public enum UniformType { U1, U2, U3, U4, I1, I2, I3, I4, F1, F2, F3, F4, Mat2, Mat3, Mat4, Buffer, } public readonly record struct DepthMode(bool Test, bool Mask, TestFunction Function) { public static readonly DepthMode Off = new DepthMode(false, false, TestFunction.Always); public static readonly DepthMode WriteOnly = new DepthMode(false, true, TestFunction.LessThan); public static readonly DepthMode Equal = new DepthMode(true, false, TestFunction.Equal); public static readonly DepthMode Enabled = new DepthMode(true, true, TestFunction.LessThan); } public readonly record struct BlendFactor(BlendFunction Source, BlendFunction Destination) { public static readonly BlendFactor Default = new BlendFactor(BlendFunction.SourceAlpha, BlendFunction.OneMinusSourceAlpha); } public readonly record struct BlendMode(bool Enabled, BlendFactor Color, BlendFactor Alpha) { [MemberNotNullWhen(false, nameof(Unified), nameof(UnifiedEquation))] public bool IsSeparate => Color != Alpha; public BlendFactor? Unified => IsSeparate ? null : Color; public BlendEquation? UnifiedEquation => IsSeparate ? null : ColorEquation; public BlendEquation ColorEquation { get; init; } = BlendEquation.Add; public BlendEquation AlphaEquation { get; init; } = BlendEquation.Add; public Color Constant { get; init; } = System.Drawing.Color.Black; public BlendMode(BlendFunction source, BlendFunction destination) : this(true, new BlendFactor(source, destination), new BlendFactor(source, destination)) { } public static readonly BlendMode Off = new BlendMode(false, BlendFactor.Default, BlendFactor.Default); public static readonly BlendMode Normal = new BlendMode(true, BlendFactor.Default, BlendFactor.Default); } public readonly record struct StencilMode(bool Enabled, TestFunction Function) { public int Reference { get; init; } = 0; public int Mask { get; init; } = ~0; public StencilOperation Pass { get; init; } = StencilOperation.Keep; public StencilOperation DepthFail { get; init; } = StencilOperation.Keep; public StencilOperation Fail { get; init; } = StencilOperation.Keep; public static readonly StencilMode Off = new StencilMode(false, TestFunction.Always); } public record struct VertexAttribute( int Location, int Components, VertexAttributeType Type, long Offset, long Stride) { public int Divisor { get; init; } = 1; } public record struct UniformDescriptor(int Location, UniformType Type, long Offset, long Size); public struct DrawCall(MeshPrimitive primitive, IBuffer vertexBuffer, int first, int count) { public IShader? ShaderPipeline { get; init; } public Box2d ViewportRegion { get; init; } = new Box2d(Vector2.Zero, Vector2.PositiveInfinity); public Box2d ScissorRegion { get; init; } = new Box2d(Vector2.PositiveInfinity, Vector2.PositiveInfinity); public WindingOrder FrontFace { get; init; } = WindingOrder.Counterclockwise; public FaceCulling CullMode { get; init; } = FaceCulling.Back; public BlendMode BlendMode { get; init; } = BlendMode.Normal; public DepthMode DepthMode { get; init; } = DepthMode.Enabled; public StencilMode StencilMode { get; init; } = StencilMode.Off; public bool EnableRestart { get; init; } = false; public long RestartIndex { get; init; } = -1; public bool RedMask { get; init; } = true; public bool GreenMask { get; init; } = true; public bool BlueMask { get; init; } = true; public bool AlphaMask { get; init; } = true; public float PointSize { get; init; }= 1.0f; public float LineWidth { get; init; }= 1.0f; public MeshPrimitive Primitive { get; init; } = primitive; public List Textures { get; init; } = []; public List Attributes { get; init; } = []; public List Uniforms { get; init; } = []; public IndexType IndexType { get; init; } = IndexType.UnsignedShort; public int First { get; init; } = first; public int Count { get; init; } = count; public long Offset { get; init; } = 0; public int BaseVertex { get; init; } = 0; public IBuffer VertexBuffer { get; init; } = vertexBuffer; public IBuffer? ElementBuffer { get; init; } public ReadOnlyMemory UniformData { get; init; } = ReadOnlyMemory.Empty; public IBuffer? UniformBuffer { get; init; } } }