using System.Drawing; using System.Numerics; using Dashboard.Drawing; using Dashboard.Pal; using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.Wgl; using OpenTK.Mathematics; namespace Dashboard.OpenGL.Drawing { public class DeviceContextBase : IDeviceContextBase { private readonly Stack _transforms = new Stack(); private readonly Stack _clipRegions = new Stack(); public DeviceContext Context { get; private set; } = null!; IContextBase IContextExtensionBase.Context => Context; public string DriverName => "Dashboard OpenGL Device Context"; public string DriverVendor => "Dashboard"; public Version DriverVersion => new Version(0, 1); public RectangleF ClipRegion => _clipRegions.Peek(); public Matrix4x4 Transforms => _transforms.Peek(); public void Dispose() { } public void Require(DeviceContext context) { Context = context; ResetClip(); ResetTransforms(); } void IContextExtensionBase.Require(IContextBase context) => Require((DeviceContext)context); public void ResetClip() { _clipRegions.Clear(); SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; _clipRegions.Push(new RectangleF(0,0, size.Width, size.Height)); SetClip(ClipRegion); } public void PushClip(RectangleF clipRegion) { clipRegion = new RectangleF(ClipRegion.X + clipRegion.X, ClipRegion.Y + clipRegion.Y, Math.Min(ClipRegion.Right - clipRegion.X, clipRegion.Width), Math.Min(ClipRegion.Bottom - clipRegion.Y, clipRegion.Height)); _clipRegions.Push(clipRegion); SetClip(clipRegion); } public void PopClip() { _clipRegions.Pop(); SetClip(ClipRegion); } private void SetClip(RectangleF rect) { SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; GL.Viewport( (int)Math.Round(rect.X), (int)Math.Round(size.Height - rect.Y - rect.Height), (int)Math.Round(rect.Width), (int)Math.Round(rect.Height)); } public void ResetTransforms() { SizeF size = ((GLDeviceContext)Context).GLContext.FramebufferSize; Matrix4x4 m = Matrix4x4.CreateOrthographicOffCenterLeftHanded(0, size.Width, size.Height, 0, 1, -1); _transforms.Clear(); _transforms.Push(m); } public void PushTransforms(in Matrix4x4 matrix) { Matrix4x4 result = matrix * Transforms; _transforms.Push(result); } public void PopTransforms() { _transforms.Pop(); } } }