168 lines
5.1 KiB
C#
168 lines
5.1 KiB
C#
using System.Drawing;
|
|
using System.Numerics;
|
|
using Dashboard.Drawing;
|
|
using Dashboard.Pal;
|
|
using Dashboard.Windowing;
|
|
using OpenTK.Graphics.OpenGL;
|
|
using OpenTK.Graphics.Wgl;
|
|
using OpenTK.Mathematics;
|
|
using ColorBuffer = OpenTK.Graphics.OpenGL.ColorBuffer;
|
|
using Vector2 = System.Numerics.Vector2;
|
|
|
|
namespace Dashboard.OpenGL.Drawing
|
|
{
|
|
public class DeviceContextBase : IDeviceContextBase
|
|
{
|
|
private readonly Stack<Matrix4x4> _transforms = new Stack<Matrix4x4>();
|
|
private readonly Stack<Box2d> _clipRegions = new Stack<Box2d>();
|
|
private readonly Stack<Box2d> _scissorRegions = new Stack<Box2d>();
|
|
private int _z = 0;
|
|
|
|
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 Box2d ClipRegion => _clipRegions.Peek();
|
|
public Box2d ScissorRegion => _scissorRegions.Peek();
|
|
public Matrix4x4 Transforms => _transforms.Peek();
|
|
public float Scale => ScaleOverride > 0 ? ScaleOverride : (Context.Window as IDpiAwareWindow)?.Scale ?? 1;
|
|
public float ScaleOverride { get; set; } = -1f;
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
|
|
public void Require(DeviceContext context)
|
|
{
|
|
Context = context;
|
|
|
|
ResetClip();
|
|
ResetScissor();
|
|
ResetTransforms();
|
|
}
|
|
|
|
|
|
void IContextExtensionBase.Require(IContextBase context) => Require((DeviceContext)context);
|
|
|
|
public void ResetClip()
|
|
{
|
|
_clipRegions.Clear();
|
|
|
|
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
|
_clipRegions.Push(new Box2d(Vector2.Zero, size));
|
|
|
|
SetClip(ClipRegion);
|
|
}
|
|
|
|
public void PushClip(Box2d clipRegion)
|
|
{
|
|
clipRegion = new Box2d(ClipRegion.Min.X + clipRegion.Min.X, ClipRegion.Min.Y + clipRegion.Min.Y,
|
|
Math.Min(ClipRegion.Max.X, ClipRegion.Min.X + clipRegion.Max.X),
|
|
Math.Min(ClipRegion.Max.Y, ClipRegion.Max.Y + clipRegion.Max.Y));
|
|
_clipRegions.Push(clipRegion);
|
|
|
|
SetClip(clipRegion);
|
|
}
|
|
|
|
public void PopClip()
|
|
{
|
|
_clipRegions.Pop();
|
|
SetClip(ClipRegion);
|
|
}
|
|
|
|
public void ResetScissor()
|
|
{
|
|
GL.Disable(EnableCap.ScissorTest);
|
|
_scissorRegions.Clear();
|
|
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
|
_scissorRegions.Push(new Box2d(Vector2.Zero, size));
|
|
}
|
|
|
|
public void PushScissor(Box2d scissorRegion)
|
|
{
|
|
GL.Enable(EnableCap.ScissorTest);
|
|
|
|
// scissorRegion = new RectangleF(scissorRegion.X + scissorRegion.X, scissorRegion.Y + scissorRegion.Y,
|
|
// Math.Min(ScissorRegion.Right - scissorRegion.X, scissorRegion.Width),
|
|
// Math.Min(ScissorRegion.Bottom - scissorRegion.Y, scissorRegion.Height));
|
|
_scissorRegions.Push(scissorRegion);
|
|
|
|
SetScissor(scissorRegion);
|
|
}
|
|
|
|
public void PopScissor()
|
|
{
|
|
if (_scissorRegions.Count == 1)
|
|
GL.Disable(EnableCap.ScissorTest);
|
|
|
|
_scissorRegions.Pop();
|
|
SetScissor(ClipRegion);
|
|
}
|
|
|
|
private void SetClip(Box2d rect)
|
|
{
|
|
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
|
GL.Viewport(
|
|
(int)Math.Round(rect.Min.X),
|
|
(int)Math.Round(size.Y - rect.Min.Y - rect.Size.Y),
|
|
(int)Math.Round(rect.Size.X),
|
|
(int)Math.Round(rect.Size.Y));
|
|
}
|
|
|
|
void SetScissor(Box2d rect)
|
|
{
|
|
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
|
GL.Scissor(
|
|
(int)Math.Round(rect.Min.X),
|
|
(int)Math.Round(size.Y - rect.Min.Y - rect.Size.Y),
|
|
(int)Math.Round(rect.Size.X),
|
|
(int)Math.Round(rect.Size.Y));
|
|
}
|
|
|
|
public void ResetTransforms()
|
|
{
|
|
Vector2 size = ((GLDeviceContext)Context).GLContext.FramebufferSize;
|
|
Matrix4x4 m = Matrix4x4.CreateOrthographicOffCenterLeftHanded(0, size.X, size.Y, 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();
|
|
}
|
|
|
|
public void ClearColor(Color color)
|
|
{
|
|
GL.ClearColor(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
|
|
GL.Clear(ClearBufferMask.ColorBufferBit);
|
|
}
|
|
|
|
public void ClearDepth()
|
|
{
|
|
GL.Clear(ClearBufferMask.DepthBufferBit);
|
|
}
|
|
|
|
public int IncrementZ()
|
|
{
|
|
return ++_z;
|
|
}
|
|
|
|
public int DecrementZ()
|
|
{
|
|
return --_z;
|
|
}
|
|
}
|
|
}
|