diff --git a/GraphicsManager/ContextMenu.cs b/GraphicsManager/ContextMenu.cs index bf56208..11d9c28 100644 --- a/GraphicsManager/ContextMenu.cs +++ b/GraphicsManager/ContextMenu.cs @@ -19,6 +19,7 @@ public class ContextMenu : Window StartFocused = false, Size = new OpenTK.Mathematics.Vector2i(400, 5), StartVisible = false, + SharedContext = null }; private FlowLayout fl; diff --git a/GraphicsManager/Globals/EXT.cs b/GraphicsManager/Globals/EXT.cs index d3ecebc..5c34a42 100644 --- a/GraphicsManager/Globals/EXT.cs +++ b/GraphicsManager/Globals/EXT.cs @@ -1,3 +1,9 @@ +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Drawing; +using SixLabors.ImageSharp.Drawing.Processing; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Processing; + namespace GraphicsManager.Globals; public static class EXT @@ -15,6 +21,63 @@ public static class EXT return dest; } + public static IImageProcessingContext ConvertToAvatar(this IImageProcessingContext context, int size, float cornerRadius) + { + return context.Resize(new ResizeOptions + { + Size = new Size(size), + Mode = ResizeMode.Crop + }).ApplyRoundedCorners(cornerRadius); + } + + + // This method can be seen as an inline implementation of an `IImageProcessor`: + // (The combination of `IImageOperations.Apply()` + this could be replaced with an `IImageProcessor`) + public static IImageProcessingContext ApplyRoundedCorners(this IImageProcessingContext context, float cornerRadius) + { + Size size = context.GetCurrentSize(); + IPathCollection corners = BuildCorners(size.Width, size.Height, cornerRadius); + + context.SetGraphicsOptions(new GraphicsOptions() + { + Antialias = true, + + // Enforces that any part of this shape that has color is punched out of the background + AlphaCompositionMode = PixelAlphaCompositionMode.DestOut + }); + + // Mutating in here as we already have a cloned original + // use any color (not Transparent), so the corners will be clipped + foreach (IPath path in corners) + { + context = context.Fill(Color.Red, path); + } + + return context; + } + + public static IPathCollection BuildCorners(int imageWidth, int imageHeight, float cornerRadius) + { + // First create a square + var rect = new RectangularPolygon(-0.5f, -0.5f, cornerRadius, cornerRadius); + + // Then cut out of the square a circle so we are left with a corner + IPath cornerTopLeft = rect.Clip(new EllipsePolygon(cornerRadius - 0.5f, cornerRadius - 0.5f, cornerRadius)); + + // Corner is now a corner shape positions top left + // let's make 3 more positioned correctly, we can do that by translating the original around the center of the image. + + float rightPos = imageWidth - cornerTopLeft.Bounds.Width + 1; + float bottomPos = imageHeight - cornerTopLeft.Bounds.Height + 1; + + // Move it across the width of the image - the width of the shape + IPath cornerTopRight = cornerTopLeft.RotateDegree(90).Translate(rightPos, 0); + IPath cornerBottomLeft = cornerTopLeft.RotateDegree(-90).Translate(0, bottomPos); + IPath cornerBottomRight = cornerTopLeft.RotateDegree(180).Translate(rightPos, bottomPos); + + return new PathCollection(cornerTopLeft, cornerBottomLeft, cornerTopRight, cornerBottomRight); + } + public static T[] Add(this T[] source, T Object) { T[] dest = new T[source.Length + 1]; diff --git a/GraphicsManager/GraphicsManager.csproj b/GraphicsManager/GraphicsManager.csproj index 881576d..efd6e32 100644 --- a/GraphicsManager/GraphicsManager.csproj +++ b/GraphicsManager/GraphicsManager.csproj @@ -10,7 +10,15 @@ False https://git.jacobtech.com/JacobTech.com/GraphicsManager git - 1.0.4-alpha09 + 1.0.5-alpha08 + + + + true + + + + true @@ -26,7 +34,8 @@ - + + diff --git a/GraphicsManager/Interfaces/IParent.cs b/GraphicsManager/Interfaces/IParent.cs index 1340e61..f447683 100755 --- a/GraphicsManager/Interfaces/IParent.cs +++ b/GraphicsManager/Interfaces/IParent.cs @@ -8,6 +8,7 @@ public interface IParent public Vector2 LocationAsFloat { get; } public IParent? Parent { get; } public Vector2i Size { get; } + public Vector2i GetParentRelLocPoint(); public void ParentResize(ResizeEventArgs e); public float[] RctToFloat(int x, int y, int Width, int Height, bool hastexture = false, float z = 0.0f); public Vector3 PointToVector(float x, float y, float z = 0.0f); diff --git a/GraphicsManager/Interfaces/IRenderObject.cs b/GraphicsManager/Interfaces/IRenderObject.cs index 26e9ea1..ab8dfb1 100755 --- a/GraphicsManager/Interfaces/IRenderObject.cs +++ b/GraphicsManager/Interfaces/IRenderObject.cs @@ -9,7 +9,7 @@ public interface IRenderObject public ObjectAnchor Anchor { get; set; } public bool Loaded { get; } public void LoadToParent(IParent Parent, Window Window); - public void Draw(); + public void Draw(int x, int y, int w, int h); public void Clean(); public void Focus(); public void UnFocus(); @@ -17,6 +17,7 @@ public interface IRenderObject public Vector2i Location { get; set; } public Vector2 SizeAsFloat { get; } public Vector2 LocationAsFloat { get; } + public Vector2i ScissorLocation { get; } public Vector2i Distance { get; } public IParent? Parent { get; } public Window? Window { get; } diff --git a/GraphicsManager/Objects/Core/Texture.cs b/GraphicsManager/Objects/Core/Texture.cs index 53e212a..4f2fd0f 100755 --- a/GraphicsManager/Objects/Core/Texture.cs +++ b/GraphicsManager/Objects/Core/Texture.cs @@ -1,4 +1,5 @@ -using GraphicsManager.Structs; +using GraphicsManager.Globals; +using GraphicsManager.Structs; using OpenTK.Graphics.ES30; using OpenTK.Mathematics; using OpenTK.Windowing.Desktop; @@ -27,31 +28,39 @@ public class Texture public static readonly Dictionary TextureShader = new (); public int handel; - internal Texture(byte[] File) + public int Location { get; set; } = 1; + + internal Texture(byte[] File, bool Rounded = false) { Image image = Image.Load(File); - image.Mutate(x => x.Flip(FlipMode.Vertical)); - - var pixels = new List(4 * image.Width * image.Height); - - for (int y = 0; y < image.Height; y++) + if (Rounded) { - var row = image.GetPixelRowSpan(y); - - for (int x = 0; x < image.Width; x++) + image.Mutate(x => { - pixels.Add(row[x].R); - pixels.Add(row[x].G); - pixels.Add(row[x].B); - pixels.Add(row[x].A); - } + x.Flip(FlipMode.Vertical); + if (image.Width <= image.Height) x.ConvertToAvatar(image.Width, image.Width/2); + else x.ConvertToAvatar(image.Height, image.Height/2); + }); } + else + { + image.Mutate(x => + { + x.Flip(FlipMode.Vertical); + }); + } + + Span pixels = new byte[4 * image.Width * image.Height].AsSpan(); + image.CopyPixelDataTo(pixels); handel = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, handel); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, image.Width, image.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels.ToArray()); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); + GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); } private Texture() @@ -224,7 +233,10 @@ public class Texture GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.R8, bitmap.Width, bitmap.Rows, 0, PixelFormat.Red, PixelType.UnsignedByte, bitmap.Buffer); - + GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); + GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); Character cha = new() { @@ -284,6 +296,10 @@ public class Texture GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.R8, bitmap2.Width, bitmap2.Rows, 0, PixelFormat.Red, PixelType.UnsignedByte, bitmap2.Buffer); + GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); + GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); Character cha2 = new() { Size = new Vector2(bitmap2.Width, bitmap2.Rows), @@ -321,7 +337,10 @@ public class Texture GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.R8, bitmap.Width, bitmap.Rows, 0, PixelFormat.Red, PixelType.UnsignedByte, bitmap.Buffer); - + GL.TextureParameter(t.handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); + GL.TextureParameter(t.handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); + GL.TextureParameter(t.handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); + GL.TextureParameter(t.handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); Character cha = new() { @@ -344,23 +363,6 @@ public class Texture } } - public void LoadText() - { - GL.TextureParameter(handel, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); - GL.TextureParameter(handel, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); - GL.TextureParameter(handel, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); - GL.TextureParameter(handel, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); - } - - public void Load(int loc) - { - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); - GL.EnableVertexAttribArray(loc); - GL.VertexAttribPointer(loc, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); - } - public void Use(TextureUnit unit = TextureUnit.Texture0) { GL.ActiveTexture(unit); diff --git a/GraphicsManager/Objects/Core/TextureManager.cs b/GraphicsManager/Objects/Core/TextureManager.cs index 2de58b9..568ecd5 100644 --- a/GraphicsManager/Objects/Core/TextureManager.cs +++ b/GraphicsManager/Objects/Core/TextureManager.cs @@ -41,12 +41,14 @@ public class TextureManager } } - public Texture AddTexture(byte[] Texture) + public Texture AddTexture(byte[] Texture, bool Rounded = false) { - byte[] hash = SHA256.HashData(Texture); + List hash2 = SHA256.HashData(Texture).ToList(); + hash2.Insert(0, Convert.ToByte(Rounded)); + byte[] hash = hash2.ToArray(); if (TextureHashMap.ContainsKey(hash)) return TextureHashMap[hash]; Context.MakeCurrent(); - TextureHashMap.Add(hash, new(Texture)); + TextureHashMap.Add(hash, new(Texture, Rounded)); return TextureHashMap[hash]; } } \ No newline at end of file diff --git a/GraphicsManager/Objects/FlowLayout.cs b/GraphicsManager/Objects/FlowLayout.cs index c1ee967..5ba5f66 100644 --- a/GraphicsManager/Objects/FlowLayout.cs +++ b/GraphicsManager/Objects/FlowLayout.cs @@ -217,6 +217,7 @@ public class FlowLayout : IRenderObject, IParent BlockDraw = false; } } + public Vector2i ScissorLocation { get => _bounds.ScissorLocation; } public Vector2i Position => Location; public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; } @@ -399,11 +400,11 @@ public class FlowLayout : IRenderObject, IParent } } - public void Draw() + public void Draw(int x, int y, int w, int h) { if (Loaded) { - _bounds.Draw(); + _bounds.Draw(x,y,w,h); IEnumerable needload = Controls.Where(a => a.Loaded == false); if (needload.Any()) @@ -418,10 +419,24 @@ public class FlowLayout : IRenderObject, IParent } for (int i = 0; i < Controls.Length; i++) { - Controls[i].Draw(); + Vector2i laff = new(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y); + Vector2i saff = new Vector2i(Controls[i].Size.X, Controls[i].Size.Y); + if (laff.X < ScissorLocation.X) laff = new(ScissorLocation.X, laff.Y); + if (laff.X < x) laff = new(x, laff.Y); + if (laff.Y < ScissorLocation.Y) laff = new(laff.X, ScissorLocation.Y); + if (laff.Y < y) laff = new(laff.X, y); + if (saff.X + laff.X > Size.X + ScissorLocation.X) saff = new(Size.X, saff.Y); + if (saff.Y + laff.Y > Size.Y + ScissorLocation.Y) saff = new(saff.X, Size.Y); + GL.Scissor(laff.X, laff.Y, saff.X, saff.Y); + Controls[i].Draw(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y); } } } + + public Vector2i GetParentRelLocPoint() + { + return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y)); + } public void Clean() { diff --git a/GraphicsManager/Objects/Label.cs b/GraphicsManager/Objects/Label.cs index 09b524e..a001f78 100755 --- a/GraphicsManager/Objects/Label.cs +++ b/GraphicsManager/Objects/Label.cs @@ -120,8 +120,23 @@ public class Label : IRenderObject Size = new((int)addx, (int)addy); if (Loaded) { - GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); - if (Window is not null && Window.CanControleUpdate) Parent!.TryDraw(); + + if (Window is not null && Window.CanControleUpdate) + { + if (!Window.Context.IsCurrent) + { + try + { + Window.Context.MakeCurrent(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); + Parent!.TryDraw(); + } } } } @@ -141,29 +156,56 @@ public class Label : IRenderObject { loc_ = value; if (Window is null || Parent is null) return; - if (Window.CanControleUpdate && Loaded) Parent!.TryDraw(); + if (Window.CanControleUpdate && Loaded) + { + ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y)); + Parent!.TryDraw(); + if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); + } + } + } + + private Vector2i _size; + public Vector2i Size { get => _size; + set + { + _size = value; + if (Loaded && Parent is not null) ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + Size.Y)); } } - public Vector2i Size { get; set; } public void Clean() { - GL.DeleteBuffer(VBO); + Tuple tup = GlobalBuffers[Window!.Context]; + if (tup.Item3 - 1 == 0) + { + //Broken, I may fix latter + + //if (!Window.Context.IsCurrent) Window.Context.MakeCurrent(); + //GL.DeleteBuffer(VBO); + //GL.DeleteVertexArray(VAO); + //GL.BindBuffer(BufferTarget.ArrayBuffer, 0); + //GlobalBuffers.Remove(Window!.Context); + } + else + { + GlobalBuffers[Window!.Context] = new(tup.Item1, tup.Item2, tup.Item3 - 1); + } Size = new(0, 0); - GL.DeleteVertexArray(VAO); - GL.BindBuffer(BufferTarget.ArrayBuffer, 0); Loaded = false; Visible = false; } + public Vector2i ScissorLocation { get; private set; } - public void Draw() + public void Draw(int x, int y, int ww, int hh) { if (Visible & Loaded) { + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); Shader.Use(); GL.Enable(EnableCap.Blend); GL.Uniform4(2, Color); - Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f); + Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GL.UniformMatrix4(1, false, ref projectionM); @@ -173,8 +215,7 @@ public class Label : IRenderObject float angle_rad = (float)Math.Atan2(DIR.Y, DIR.X); Matrix4 rotateM = Matrix4.CreateRotationZ(angle_rad); Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Window.FloatToInt(Parent!.IntToFloat(0)), loc_.Y + Font.PixelHeight + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f)); - - float char_x = 0.0f; + float char_x = 0.0f; GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); GL.ActiveTexture(TextureUnit.Texture0); @@ -191,7 +232,6 @@ public class Label : IRenderObject if (!_characters[Window!.Context][Font].ContainsKey(c) && !n) { var f = Texture.TextureForChar(Window!.Context, Font, c); - f.LoadText(); } int maxx = 0; @@ -226,7 +266,7 @@ public class Label : IRenderObject } } public Window? Window { get; private set; } - + private static Dictionary> GlobalBuffers = new(); public void LoadToParent(IParent window, Window win) { if (Loaded) return; @@ -237,18 +277,40 @@ public class Label : IRenderObject Window = win; Window.MouseMove += WindowOnMouseMove; Window.MouseDown += WindowOnMouseDown; + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1); GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); - float[] vquad = + if (!GlobalBuffers.ContainsKey(win.Context)) { - 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 0.0f, -1.0f, 0.0f, 0.0f, - 1.0f, 0.0f, 1.0f, 1.0f, - 1.0f, -1.0f, 1.0f, 0.0f - }; + float[] vquad = + { + 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 0.0f, -1.0f, 0.0f, 0.0f, + 1.0f, 0.0f, 1.0f, 1.0f, + 1.0f, -1.0f, 1.0f, 0.0f + }; + int _VBO = GL.GenBuffer(); + GL.BindBuffer(BufferTarget.ArrayBuffer, _VBO); + GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw); + int _VAO = GL.GenVertexArray(); + GL.BindVertexArray(_VAO); + GL.EnableVertexAttribArray(0); + GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0); + GL.EnableVertexAttribArray(1); + GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4); + GlobalBuffers.Add(win.Context, new(_VBO, _VAO, 0)); + } + Tuple tup = GlobalBuffers[win.Context]; + VBO = tup.Item1; + VAO = tup.Item2; + GlobalBuffers[win.Context] = new(VBO, VAO, tup.Item3 + 1); + + + +/* VBO = GL.GenBuffer(); GL.BindBuffer(BufferTarget.ArrayBuffer, VBO); GL.BufferData(BufferTarget.ArrayBuffer, 4 * 6 * 4, vquad, BufferUsageHint.StaticDraw); @@ -259,7 +321,7 @@ public class Label : IRenderObject GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 4 * 4, 0); GL.EnableVertexAttribArray(1); GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 4 * 4, 2 * 4); - +*/ GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(0); diff --git a/GraphicsManager/Objects/Rectangle.cs b/GraphicsManager/Objects/Rectangle.cs index 880999d..55556f7 100755 --- a/GraphicsManager/Objects/Rectangle.cs +++ b/GraphicsManager/Objects/Rectangle.cs @@ -15,7 +15,7 @@ public class Rectangle : ITextureObject public ObjectAnchor Anchor { get; set; } = ObjectAnchor.Left | ObjectAnchor.Top; - public Texture? Texture { get; private set; } + public Texture? Texture { get; set; } public ContextMenu? ContextMenu { get; set; } = null; public event Func? FilesDroped; @@ -67,13 +67,15 @@ public class Rectangle : ITextureObject } } - public void Draw() + public void Draw(int x, int y, int w, int h) { if (Visible && Loaded) { + + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); if (Texture is not null) Texture.Use(); Shader.Use(); - GL.Uniform4(0, BackgroundColor); + if (Texture is null) GL.Uniform4(0, BackgroundColor); if (Texture is not null) { GL.Enable(EnableCap.Blend); @@ -115,7 +117,6 @@ public class Rectangle : ITextureObject if (Texture is not null) { Shader = Texture.TextureShader[Window.Context]; - Texture.Load(Shader.GetAttribLocation("aTexCoord")); } GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); @@ -197,14 +198,19 @@ public class Rectangle : ITextureObject if (Loaded) { //Distance = new(Parent!.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y); - int add = 3; - if (Texture is not null) add = 5; GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); GL.BindVertexArray(ArrayObject); + int add = 3; + if (Texture is not null) + { + add = 5; + GL.VertexAttribPointer(Texture.Location, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float)); + GL.EnableVertexAttribArray(Texture.Location); + } GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0); GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, Points_.Length * sizeof(float), Points_, Hint); + GL.BufferData(BufferTarget.ArrayBuffer, value.Length * sizeof(float), value, Hint); GL.BindVertexArray(ArrayObject); GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject); GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint); @@ -248,6 +254,7 @@ public class Rectangle : ITextureObject temp[(Texture is null ? 3 : 5)] = saf.X; temp[(Texture is null ? 4 : 6)] = saf.Y; temp[(Texture is null ? 7 : 11)] = saf.Y; + ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y)); Points = temp; } } @@ -273,9 +280,14 @@ public class Rectangle : ITextureObject temp[(Texture is null ? 3 : 5)] = saf.X; temp[(Texture is null ? 4 : 6)] = saf.Y; temp[(Texture is null ? 7 : 11)] = saf.Y; + ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y));// new((int)Window.FloatToInt(Parent.IntToFloat(value.X)), + //ScissorLocation = new Vector2i(ScissorLocation.X, Window.Size.Y - ScissorLocation.Y); + //(int)Window.FloatToInt(Parent.IntToFloat(value.Y, true), true) + //); Points = temp; } } + public Vector2i ScissorLocation { get; private set; } private Vector2 laf = new(), saf = new(); public Vector2 LocationAsFloat { get { return laf; } } diff --git a/GraphicsManager/Objects/RoundedButton.cs b/GraphicsManager/Objects/RoundedButton.cs index 219ce77..3929bd8 100755 --- a/GraphicsManager/Objects/RoundedButton.cs +++ b/GraphicsManager/Objects/RoundedButton.cs @@ -73,6 +73,8 @@ public class RoundedButton : IRenderObject _label.Location = new( value.X + Border + (((Size.X - (Border * 2)) / 2) - (_label.Size.X / 2)), value.Y + Border + (((Size.Y - (Border * 2)) / 2) - (_label.Size.Y / 2))); } } + public Vector2i ScissorLocation { get => _bounds.ScissorLocation; } + public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; } public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; } public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value;} @@ -108,12 +110,12 @@ public class RoundedButton : IRenderObject _label.Clean(); } - public void Draw() + public void Draw(int x, int y, int w, int h) { if (!Visible || !Loaded) return; - _bounds.Draw(); - _inside.Draw(); - _label.Draw(); + _bounds.Draw(x,y,w,h); + _inside.Draw(x,y,w,h); + _label.Draw(x,y,w,h); } public void LoadToParent(IParent Parent, Window Window) diff --git a/GraphicsManager/Objects/RoundedRectangle.cs b/GraphicsManager/Objects/RoundedRectangle.cs index ecc2c35..0597a9d 100755 --- a/GraphicsManager/Objects/RoundedRectangle.cs +++ b/GraphicsManager/Objects/RoundedRectangle.cs @@ -4,7 +4,6 @@ using GraphicsManager.Objects.Core; using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using OpenTK.Windowing.GraphicsLibraryFramework; -using System.Runtime.Intrinsics.X86; using OpenTK.Windowing.Common; namespace GraphicsManager.Objects; @@ -18,7 +17,7 @@ public class RoundedRectangle : IRenderObject public RoundedRectangle() { - Points_ = new float[36 + (((sn - 1) * 4) * 3)]; + //Points_ = new float[36 + (((sn - 1) * 4) * 3)]; } public event Func? WindowLoaded; public event Func? MouseEnter; @@ -110,7 +109,7 @@ public class RoundedRectangle : IRenderObject } } - public void Draw() + public void Draw(int x, int y, int w, int h) { if (Visible && Loaded) { @@ -141,26 +140,13 @@ public class RoundedRectangle : IRenderObject this.Parent = Parent; this.Window = Window; if (Shader is null) Shader = Rectangle.DefaultShader[Window.Context]; - int pos = Points.Length - 3; - pos = 4; - BufferObject = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); ArrayObject = GL.GenVertexArray(); - GL.BindVertexArray(ArrayObject); - int add = 3; - GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0); - GL.EnableVertexAttribArray(0); - GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, Points.Length * sizeof(float), Points, Hint); - GL.BindVertexArray(ArrayObject); ElementBufferObject = GL.GenBuffer(); - GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject); - GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint); + Location = Location; Loaded = true; Window.MouseDown += Window_MouseDown; Window.MouseMove += WindowOnMouseMove; - Location = Location; Distance = new(Parent.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y); if (WindowLoaded is not null) WindowLoaded.Invoke(this); } @@ -212,30 +198,22 @@ public class RoundedRectangle : IRenderObject public int ElementBufferObject { get; private set; } public int BufferObject { get; private set; } public int ArrayObject { get; private set; } - private float[] Points_; private Vector2i size_ = new(), loc_ = new(); - public float[] Points + private float[] Points { - get - { - return Points_; - } set { - Points_ = value; try { if (Loaded) { - //Distance = new(Parent!.Size.X - Size.X - Location.X, Parent.Size.Y - Size.Y - Location.Y); - int add = 3; GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); GL.BindVertexArray(ArrayObject); - GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0); + GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0); GL.EnableVertexAttribArray(0); GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject); - GL.BufferData(BufferTarget.ArrayBuffer, Points_.Length * sizeof(float), Points_, Hint); + GL.BufferData(BufferTarget.ArrayBuffer, value.Length * sizeof(float), value, Hint); GL.BindVertexArray(ArrayObject); GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject); GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(uint), Indexs, Hint); @@ -290,6 +268,7 @@ public class RoundedRectangle : IRenderObject Parent.ReportSizeUpdate(this); Location = Location; saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true)); + ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (loc_.Y + value.Y)); } } @@ -348,9 +327,17 @@ public class RoundedRectangle : IRenderObject temp.Add(tri.Z); } } + //ScissorLocation = new((int)Window.FloatToInt(Parent.IntToFloat(value.X)), + //(int)Window.FloatToInt(Parent.IntToFloat(value.Y, true), true) + //); + //ScissorLocation = Parent.GetParentRelLocPoint() + value; + //ScissorLocation = Parent.GetParentRelLocPoint() + value;// new((int)Window.FloatToInt(Parent.IntToFloat(value.X)), + //ScissorLocation = new Vector2i(ScissorLocation.X, Window.Size.Y - ScissorLocation.Y); + ScissorLocation = Parent.GetParentRelLocPoint() + new Vector2i(value.X, Parent.Size.Y - (value.Y + Size.Y)); Points = temp.ToArray(); } } + public Vector2i ScissorLocation { get; private set; } private Vector2 laf = new(), saf = new(); public Vector2 LocationAsFloat { get { return laf; } } diff --git a/GraphicsManager/Objects/TabControl.cs b/GraphicsManager/Objects/TabControl.cs index 55fff57..bf4e469 100644 --- a/GraphicsManager/Objects/TabControl.cs +++ b/GraphicsManager/Objects/TabControl.cs @@ -1,6 +1,7 @@ using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects.Core; +using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using SixLabors.ImageSharp.Processing; @@ -126,6 +127,7 @@ public class TabControl : IRenderObject, IParent public ContextMenu? ContextMenu { get => _bounds.ContextMenu; set => _bounds.ContextMenu = value; } public Vector2i Distance { get => _bounds.Distance; internal set => _bounds.Distance = value; } public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; } + public Vector2i ScissorLocation { get => _bounds.ScissorLocation; } public Vector2 SizeAsFloat { get => _bounds.SizeAsFloat; } private uint pgi = 0; public uint PageIndex @@ -226,6 +228,7 @@ public class TabControl : IRenderObject, IParent this.Parent = Parent; this.Window = Window; BlockDraw = true; + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); Loaded = true; _bounds.LoadToParent(Parent, Window); for (int i = 0; i < Controls.Length; i++) @@ -241,18 +244,25 @@ public class TabControl : IRenderObject, IParent if (WindowLoaded is not null) WindowLoaded.Invoke(this); } - public void Draw() + public void Draw(int x, int y, int w, int h) { if (Loaded && Visible) { - _bounds.Draw(); + _bounds.Draw(x,y,w,h); if (!(Controls.Length >= (PageIndex))) return; if (!Controls[PageIndex].Loaded) return; - Controls[PageIndex].Draw(); + GL.Scissor(Controls[PageIndex].ScissorLocation.X, Controls[PageIndex].ScissorLocation.Y, Controls[PageIndex].Size.X, Controls[PageIndex].Size.Y); + Controls[PageIndex].Draw(x,y,w,h); + GL.Scissor(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y); for (int i = 0; i < Buttonts.Length; i++) - Buttonts[i].Draw(); + Buttonts[i].Draw(x,y,w,h); } } + + public Vector2i GetParentRelLocPoint() + { + return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y)); + } public void Clean() { diff --git a/GraphicsManager/Objects/Textbox.cs b/GraphicsManager/Objects/Textbox.cs index 23002a6..c144216 100755 --- a/GraphicsManager/Objects/Textbox.cs +++ b/GraphicsManager/Objects/Textbox.cs @@ -1,8 +1,10 @@ using System.Timers; +using System.Timers; using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects.Core; using OpenTK.Graphics.GL; +using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.GraphicsLibraryFramework; @@ -153,13 +155,34 @@ public class Textbox : IRenderObject _watermark.Clean(); } - public void Draw() + private Vector2i? l = null, s = null; + public Vector2i ScissorLocation { get => _bounds.ScissorLocation; } + + public void Draw(int x, int y, int w, int h) { if (!Visible || !Loaded) return; - _bounds.Draw(); - _inside.Draw(); - if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(); - else _watermark.Draw(); + _bounds.Draw(x,y,w,h); + _inside.Draw(x,y,w,h); + if (l is null || s is null) + { + l = new((int)Window.FloatToInt(Parent.IntToFloat(_inside.Location.X)), + (int)Window.FloatToInt(Parent.IntToFloat(_inside.Location.Y, true), true)); + s = new(_inside.Size.X - _label.Location.X + Location.X, + _inside.Size.Y); + Console.WriteLine(_inside.Location.Y); + Console.WriteLine($"x:{l.Value.X} y:{l.Value.Y} xx:{s.Value.X} yy:{s.Value.Y}"); + l = new(l.Value.X, 0); + s = new(s.Value.X, Window.Size.Y); + } + GL.Disable(EnableCap.ScissorTest); + GL.Enable(EnableCap.ScissorTest); + GL.Scissor(l.Value.X, + l.Value.Y, + s.Value.X, + s.Value.Y + ); + if (!string.IsNullOrEmpty(_label.Text)) _label.Draw(x,y,w,h); + else _watermark.Draw(x,y,w,h); } public void LoadToParent(IParent Parent, Window Window) @@ -171,6 +194,7 @@ public class Textbox : IRenderObject this.Window.KeyDown += Window_KeyDown; this.Window.TextInput += WindowOnTextInput; Loaded = true; + if (!Window!.Context.IsCurrent) Window.Context.MakeCurrent(); _bounds.LoadToParent(Parent, Window); _inside.LoadToParent(Parent, Window); _label.LoadToParent(Parent, Window); diff --git a/GraphicsManager/Objects/TitleBar.cs b/GraphicsManager/Objects/TitleBar.cs new file mode 100644 index 0000000..7f133a7 --- /dev/null +++ b/GraphicsManager/Objects/TitleBar.cs @@ -0,0 +1,13 @@ +using GraphicsManager.Interfaces; + +namespace GraphicsManager.Objects; + +public class TitleBar +{ + public bool Loaded { get; private set; } = false; + + public void Draw() + { + + } +} \ No newline at end of file diff --git a/GraphicsManager/Objects/UserControl.cs b/GraphicsManager/Objects/UserControl.cs index fb129bb..fbcb67f 100755 --- a/GraphicsManager/Objects/UserControl.cs +++ b/GraphicsManager/Objects/UserControl.cs @@ -1,6 +1,7 @@ using GraphicsManager.Enums; using GraphicsManager.Interfaces; using GraphicsManager.Objects.Core; +using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using OpenTK.Windowing.Common; @@ -92,6 +93,7 @@ public class UserControl : IRenderObject, IParent BlockDraw = false; } } + public Vector2i ScissorLocation { get => _bounds.ScissorLocation; } public Vector2i Position => Location; public Vector2 LocationAsFloat { get => _bounds.LocationAsFloat; } @@ -123,11 +125,12 @@ public class UserControl : IRenderObject, IParent if (WindowLoaded is not null) WindowLoaded.Invoke(this); } - public void Draw() + public void Draw(int x, int y, int w, int h) { if (Loaded) { - _bounds.Draw(); + _bounds.Draw(x,y,w,h); + IEnumerable needload = Controls.Where(a => a.Loaded == false); if (needload.Any()) @@ -142,11 +145,25 @@ public class UserControl : IRenderObject, IParent } for (int i = 0; i < Controls.Length; i++) { - Controls[i].Draw(); + Vector2i laff = new(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y); + Vector2i saff = new Vector2i(Controls[i].Size.X, Controls[i].Size.Y); + if (laff.X < ScissorLocation.X) laff = new(ScissorLocation.X, laff.Y); + if (laff.X < x) laff = new(x, laff.Y); + if (laff.Y < ScissorLocation.Y) laff = new(laff.X, ScissorLocation.Y); + if (laff.Y < y) laff = new(laff.X, y); + if (saff.X + laff.X > Size.X + ScissorLocation.X) saff = new(Size.X, saff.Y); + if (saff.Y + laff.Y > Size.Y + ScissorLocation.Y) saff = new(saff.X, Size.Y); + GL.Scissor(laff.X, laff.Y, saff.X, saff.Y); + Controls[i].Draw(ScissorLocation.X, ScissorLocation.Y, Size.X, Size.Y); } } } + public Vector2i GetParentRelLocPoint() + { + return Parent!.GetParentRelLocPoint() + new Vector2i(Location.X, Parent.Size.Y - (Location.Y + Size.Y)); + } + public void Clean() { for (int i = 0; i < Controls.Length; i++) diff --git a/GraphicsManager/Window.cs b/GraphicsManager/Window.cs index 4f6cc84..bd12fd1 100755 --- a/GraphicsManager/Window.cs +++ b/GraphicsManager/Window.cs @@ -15,15 +15,21 @@ public class Window : NativeWindow , IParent { protected override void Dispose(bool disposing) { - for (int i = 0; i < Controls.Length; i++) - { - Controls[i].Clean(); - } - Context.MakeNoneCurrent(); base.Dispose(disposing); } public TextureManager TextureManager { get; private set; } + private TitleBar? _tb = null; + + public TitleBar? CustomeTitleBar + { + get => _tb; + set + { + _tb = value; + //some setting/changeing code + } + } internal IRenderObject? focused; public void CenterWindow(int mon) @@ -51,15 +57,50 @@ public class Window : NativeWindow , IParent { TextureManager = TextureManager.GetTextureManager(Context); Context.MakeCurrent(); - Texture.TextureShader.Add(Context, new("RectangleTexture", true)); - Objects.Rectangle.DefaultShader.Add(Context, new("Rectangle", true)); - Label.DefaultTextShader.Add(Context, new("Label", true)); - Label._characters.Add(Context, new()); + if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true)); + if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true)); + if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true)); + if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new()); + last = WindowState; + KeyDown += OnKeyDownn; } - public Window() : base(new NativeWindowSettings()) +private WindowState last; +private bool fs = false; +private Vector2i os, loc; +private unsafe void OnKeyDownn(KeyboardKeyEventArgs obj) +{ + if (obj.Key != Keys.F11 || WindowBorder == WindowBorder.Fixed) return; + GLFW.WindowHint(WindowHintBool.AutoIconify, true); + if (WindowState != WindowState.Normal) last = WindowState; + Console.WriteLine(fs); + switch (fs) { + case false: + loc = Location; + os = Size; + WindowBorder = WindowBorder.Hidden; + Location = new(4090, 0); + fs = true; + break; + case true: + WindowBorder = WindowBorder.Resizable; + + Size = os; + Location = loc; + fs = false; + break; + } +} + + public Window() : this(new NativeWindowSettings()) + { + /* TextureManager = TextureManager.GetTextureManager(Context); + if (!Texture.TextureShader.ContainsKey(Context)) Texture.TextureShader.Add(Context, new("RectangleTexture", true)); + if (!Rectangle.DefaultShader.ContainsKey(Context)) Rectangle.DefaultShader.Add(Context, new("Rectangle", true)); + if (!Label.DefaultTextShader.ContainsKey(Context)) Label.DefaultTextShader.Add(Context, new("Label", true)); + if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());*/ } public Vector2i Position { get; } = new Vector2i(0, 0); public Color4 BackgroundColor { get; set; } = new Color4(0, 0, 0, 255); @@ -147,9 +188,10 @@ public class Window : NativeWindow , IParent public void ParentResize(ResizeEventArgs e) { - if (e.Width == 0 && e.Height == 0) return; - BlockDraw = true; base.OnResize(e); + if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return; + BlockDraw = true; + GL.Viewport(0, 0, e.Width, e.Height); for (int i = 0; i < Controls.Length; i++) { @@ -189,6 +231,7 @@ public class Window : NativeWindow , IParent protected override void OnClosing(CancelEventArgs e) { + Context.MakeCurrent(); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(0); GL.UseProgram(0); @@ -204,6 +247,12 @@ public class Window : NativeWindow , IParent public int FPS { get; set; } = 0; public event Func? WindowLoaded; + public List Windows = new(); + + public void ProcessEvent() + { + ProcessEvents(); + } public void StartRender() { Context.MakeCurrent(); @@ -214,6 +263,13 @@ public class Window : NativeWindow , IParent while (Exists && IsVisible && !IsExiting) { GLFW.PollEvents(); + if (Windows.Any()) + { + foreach (var win in Windows) + { + win.ProcessEvent(); + } + } if (invokes.Any()) { for (int i = 0; i < invokes.Count; i++) invokes.Dequeue().Invoke(); @@ -222,6 +278,12 @@ public class Window : NativeWindow , IParent } } + public void StartRenderAsync() + { + Thread t = new Thread(_ => StartRender()); + t.Start(); + } + public bool BlockDraw { get; set; } = false; public void TryDraw() @@ -245,12 +307,19 @@ public class Window : NativeWindow , IParent { invokes.Enqueue(A); } + + public Vector2i GetParentRelLocPoint() + { + return new(0); + } public void DrawFrame() { Context.MakeCurrent(); frame++; Console.WriteLine($"Drawing Frame: {frame}"); + GL.Enable(EnableCap.ScissorTest); + GL.Scissor(0, 0, Size.X, Size.Y); GL.ClearColor(BackgroundColor.R, BackgroundColor.G, BackgroundColor.B, (BackgroundColor.A * -1) + 1); IEnumerable needload = Controls.Where(a => a.Loaded == false); @@ -263,11 +332,26 @@ public class Window : NativeWindow , IParent } BlockDraw = false; } + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); for (int i = 0; i < Controls.Length; i++) { - if (Controls[i].Loaded) Controls[i].Draw(); + if (!Controls[i].Loaded) continue; + GL.Disable(EnableCap.ScissorTest); + if (Controls[i] is not Label) + { + GL.Enable(EnableCap.ScissorTest); + GL.Scissor(Controls[i].ScissorLocation.X, Controls[i].ScissorLocation.Y, Controls[i].Size.X, Controls[i].Size.Y); + Controls[i].Draw(0,0,Size.X, Size.Y); + } + else + { + GL.Enable(EnableCap.ScissorTest); + GL.Scissor(0, 0, Size.X, Size.Y); + Controls[i].Draw(0,0,Size.X, Size.Y); + } } + GL.Disable(EnableCap.ScissorTest); Context.SwapBuffers(); }