JacobTech 06bc325fbe Window Matrix
Instead of calculating the int position to the OpenGL float of -1 to 1 in the code, we hand this responsibility to the shaders using a matrix to scale and translate everything.
2024-04-10 21:31:23 -04:00

154 lines
4.4 KiB
C#

using GraphicsManager.Enums;
using GraphicsManager.Interfaces;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Mathematics;
using OpenTK.Windowing.Common;
namespace GraphicsManager.Objects.Core;
public abstract class ParentBase : Rectangle, IParent
{
protected ParentBase(Texture? texture = null)
: base(texture)
{
}
public ControlList Controls { get; } = new();
public bool BlockDraw { get; set; }
public Vector3i Position => Location;
public void TryDraw()
{
if (!BlockDraw && Parent is not null) Parent.TryDraw();
}
public virtual void ParentResize(ResizeEventArgs e)
{
bool PastBlockState = BlockDraw;
BlockDraw = true;
if (e.Width == 0 && e.Height == 0) return;
for (int i = 0; i < Controls.Length; i++)
{
if (!Controls[i].Loaded) continue;
bool top = (Controls[i].Anchor & ObjectAnchor.Top) == ObjectAnchor.Top;
bool left = (Controls[i].Anchor & ObjectAnchor.Left) == ObjectAnchor.Left;
bool right = (Controls[i].Anchor & ObjectAnchor.Right) == ObjectAnchor.Right;
bool bottom = (Controls[i].Anchor & ObjectAnchor.Bottom) == ObjectAnchor.Bottom;
if (!top && !bottom) { Controls[i].Anchor |= ObjectAnchor.Top; top = true; }
if (!left && !right) { Controls[i].Anchor |= ObjectAnchor.Left; left = true; }
int lx = (left ? Controls[i].Location.X : Size.X - Controls[i].Distance.X - Controls[i].Size.X);
int ly = (top ? Controls[i].Location.Y : Size.Y - Controls[i].Distance.Y - Controls[i].Size.Y);
int sy = (bottom ? Size.Y - Controls[i].Distance.Y - ly : Controls[i].Size.Y);
int sx = (right ? Size.X - Controls[i].Distance.X - lx : Controls[i].Size.X);
Controls[i].Size = new(sx, sy);
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
if (Controls[i] is IParent parent)
{
parent.ParentResize(e);
}
}
Parent!.TryDraw();
BlockDraw = PastBlockState;
}
public virtual void ReportSizeUpdate(IRenderObject Control)
{
}
public override void Draw(int x, int y, int w, int h)
{
if (Loaded && Visible && Location.X > 0 - Size.X && Location.Y > 0 - Size.Y)
{
int nx = x, ny = y, nw = w, nh = h;
if (Location.X > nw)
return;
else
{
nx += Location.X;
nw -= Location.X;
if (Size.X < nw)
nw = Size.X;
}
if (Location.Y > nh)
return;
else
{
ny += Location.Y;
nh -= Location.Y;
if (Size.Y < nh)
nh = Size.Y;
}
if (nw == 0 || nh == 0) return;
GL.Scissor(nx, Window!.ClientSize.Y - ny - nh, nw, nh);
base.Draw(nx,ny,nw,nh);
IEnumerable<IRenderObject> needload = Controls.Where(a => a.Loaded == false);
if (needload.Any())
{
BlockDraw = true;
foreach (IRenderObject Control in needload)
{
Control.LoadToParent(this, Window!);
}
if (this is IFlow flow) flow.ForceScrollUpdate();
BlockDraw = false;
}
for (int i = 0; i < Controls.Length; i++)
{
if (Controls[i].Location.X > Size.X || Controls[i].Location.Y > Size.Y) continue;
GL.Scissor(nx, Window!.ClientSize.Y - ny - nh, nw, nh);
Controls[i].Draw(nx, ny, nw, nh);
}
}
}
public override void Clean()
{
for (int i = 0; i < Controls.Length; i++)
{
Controls[i].Clean();
}
base.Clean();
}
public override void LoadToParent(IParent Parent, IWindow Window)
{
if (Loaded) return;
bool PastBlockState = BlockDraw;
BlockDraw = true;
base.LoadToParent(Parent, Window);
for (int i = 0; i < Controls.Length; i++)
{
if (Controls[i].Loaded) continue;
Controls[i].LoadToParent(this, Window);
if (Controls[i] is IFlow flow) flow.ForceScrollUpdate();
}
BlockDraw = PastBlockState;
}
public override Vector3i Location
{
get => base.Location;
set
{
BlockDraw = true;
base.Location = value;
for (int i = 0; i < Controls.Length; i++)
{
Controls[i].Location = Controls[i].Location;
}
ParentResize(new());
if (Parent is not null) Parent.TryDraw();
BlockDraw = false;
}
}
public float IntToWindow(float p, bool Y = false)
{
return Parent!.IntToWindow((Y ? this.Location.Y : Location.X), Y) + p;
}
}