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.
This commit is contained in:
JacobTech 2024-04-10 21:31:23 -04:00
parent 46c7244dd1
commit 06bc325fbe
14 changed files with 100 additions and 133 deletions

View File

@ -48,6 +48,12 @@ public class FPSWindow : GameWindow , IWindow
ClientRectangle = new Box2i(num, num2, num + Size.X, num2 + Size.Y);
}
public Matrix4 WindowSizeMatrix { get; private set; }
public float IntToWindow(float Point, bool Y = false)
{
return Point;
}
public IParent? Parent { get; } = null;
public MouseCursor HoverMouse { get; set; } = MouseCursor.Default;
public Vector2 LocationAsFloat { get; } = new Vector2(0f, 0f);

View File

@ -10,7 +10,7 @@
<IncludeSymbols>False</IncludeSymbols>
<RepositoryUrl>https://git.jacobtech.com/JacobTech.com/GraphicsManager</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>1.0.9-alpha29</Version>
<Version>1.0.9-alpha66</Version>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

View File

@ -12,12 +12,9 @@ public interface IParent
public IParent? Parent { get; }
public Vector2i Size { get; }
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);
public float IntToFloat(float p, bool Invert = false);
public float IntToWindow(float p, bool Y = false);
public void TryDraw();
public void ReportSizeUpdate(IRenderObject Control);
public float FloatToInt(float p, bool Invert = false);
public Vector3i Position { get; }
public MouseCursor HoverMouse { get; set; }
}

View File

@ -10,6 +10,8 @@ public interface IWindow : IParent
public IGLFWGraphicsContext Context { get; }
public bool ShowMissingChar { get; }
public Matrix4 WindowSizeMatrix { get; }
public Vector2i ClientSize { get; }
public event Action<MouseButtonEventArgs> MouseDown;

View File

@ -83,7 +83,7 @@ public abstract class ParentBase : Rectangle, IParent
nh = Size.Y;
}
if (nw == 0 || nh == 0) return;
GL.Scissor(nx, Window!.Size.Y - ny - nh, nw, nh);
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);
@ -100,7 +100,7 @@ public abstract class ParentBase : Rectangle, IParent
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!.Size.Y - ny - nh, nw, nh);
GL.Scissor(nx, Window!.ClientSize.Y - ny - nh, nw, nh);
Controls[i].Draw(nx, ny, nw, nh);
}
}
@ -147,98 +147,8 @@ public abstract class ParentBase : Rectangle, IParent
}
}
#region Cool Math Things
public float[] RctToFloat(int x, int y, int Width, int Height, bool hasTexture = false, float z = 0.0f)
public float IntToWindow(float p, bool Y = false)
{
if (hasTexture)
{
return new [] {
IntToFloat(x + Width), IntToFloat(y, true), z, 1.0f, 1.0f,// top r
IntToFloat(x + Width), IntToFloat(y + Height, true), z, 1.0f, 0.0f,//b r
IntToFloat(x), IntToFloat(y + Height, true), z, 0.0f, 0.0f,//bot l
IntToFloat(x), IntToFloat(y, true), z, 0.0f, 1.0f// top l
};
}
else
{
return new [] {
IntToFloat(x + Width), IntToFloat(y, true), z,// top r
IntToFloat(x + Width), IntToFloat(y + Height, true), z, //b r
IntToFloat(x), IntToFloat(y + Height, true), z, //bot l
IntToFloat(x), IntToFloat(y, true), z,// top l
};
}
return Parent!.IntToWindow((Y ? this.Location.Y : Location.X), Y) + p;
}
public Vector3 PointToVector(float x, float y, float z = 0.0f)
{
return new Vector3(IntToFloat(x), IntToFloat(y, true), z);
}
public float IntToFloat(float p, bool Invert = false)
{
p += (Invert ? Location.Y : Location.X);
IParent? TempParentObject = Parent;
while (TempParentObject is not null)
{
p += (Invert ? TempParentObject.Position.Y : TempParentObject.Position.X);
TempParentObject = TempParentObject.Parent;
}
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
double half = Math.Round((double)Size / (double)2, 1);
double Per = Math.Round((double)1 / half, 15);
if (p == half) return 0.0f;
if (Invert)
{
if (p > half) return (float)(((double)(p - half) * Per) * -1);
else return (float)(1 - (p * Per));
}
else
{
if (p > half) return (float)((double)(p - half) * Per);
else return (float)((1 - (p * Per)) * -1);
}
}
public float FloatToInt(float p, bool Invert = false)
{
p += (Invert ? LocationAsFloat.Y : LocationAsFloat.X);
IParent? tempp = Parent;
while (tempp is not null)
{
p += (Invert ? tempp.LocationAsFloat.Y : tempp.LocationAsFloat.X);
tempp = tempp.Parent;
}
float Size = (Invert ? Window!.Size.Y : Window!.Size.X);
double half = Math.Round((double)Size / (double)2, 15);
if (p == 0) return (int)half;
if (Invert)
{
if (p < 0)
{
p *= -1;
p++;
return (float)(half * p);
}
else
{
return (float)(half - (p * half));
}
}
else
{
if (p < 0)
{
p *= -1;
p++;
return (float)(Size - (half * p));
}
else
{
return (float)(p * half + half);
}
}
}
#endregion
}

View File

@ -1,5 +1,6 @@
using OpenTK.Graphics.OpenGL4;
using System.Reflection;
using OpenTK.Mathematics;
namespace GraphicsManager.Objects.Core;
@ -85,6 +86,33 @@ public class Shader : IDisposable
GL.DetachShader(Handle, FragmentShader);
GL.DeleteShader(FragmentShader);
GL.DeleteShader(VertexShader);
GL.GetProgram(Handle, GetProgramParameterName.ActiveUniforms, out var numberOfUniforms);
// Next, allocate the dictionary to hold the locations.
_uniformLocations = new Dictionary<string, int>();
// Loop over all the uniforms,
for (var i = 0; i < numberOfUniforms; i++)
{
// get the name of this uniform,
var key = GL.GetActiveUniform(Handle, i, out _, out _);
// get the location,
var location = GL.GetUniformLocation(Handle, key);
// and then add it to the dictionary.
_uniformLocations.Add(key, location);
}
}
private readonly Dictionary<string, int> _uniformLocations;
public void SetMatrix4(string name, Matrix4 data)
{
GL.UseProgram(Handle);
GL.UniformMatrix4(_uniformLocations[name], true, ref data);
}
public void Use()

View File

@ -350,6 +350,7 @@ public class Label : ILabel
GL.Enable(EnableCap.Blend);
GL.Uniform4(Shader.GetUniformLocation("textColor"), Color);
Matrix4 projectionM = Matrix4.CreateOrthographicOffCenter(0, Window!.Size.X, Window!.Size.Y, 0, -1.0f, 1.0f);
projectionM = this.Window.WindowSizeMatrix;
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
GL.BlendFunc(0, BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
GL.UniformMatrix4(1, false, ref projectionM);
@ -358,7 +359,7 @@ public class Label : ILabel
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 * Scale) + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f));
Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Parent!.IntToWindow(0), loc_.Y + (Font.PixelHeight * Scale) + Parent!.IntToWindow(0, true), 0f));
float char_x = 0.0f;
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);

View File

@ -239,7 +239,7 @@ public class RainbowLabel : ILabel
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 * Scale) + Window.FloatToInt(Parent!.IntToFloat(0, true), true), 0f));
Matrix4 transOriginM = Matrix4.CreateTranslation(new Vector3(loc_.X + Parent!.IntToWindow(0), loc_.Y + (Font.PixelHeight * Scale) + Parent!.IntToWindow(0, true), 0f));
float char_x = 0.0f;
GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);

View File

@ -1,5 +1,6 @@
using System.Diagnostics;
using GraphicsManager.Enums;
using GraphicsManager.Globals;
using GraphicsManager.Interfaces;
using GraphicsManager.Objects.Core;
using OpenTK.Graphics.OpenGL4;
@ -105,6 +106,7 @@ public class Rectangle : ITextureObject
tex.Use();
}
Shader.Use();
Shader.SetMatrix4("windowMatrix", Window.WindowSizeMatrix);
if (!Textures.Any() || Shader.Handle == DefaultAlphaShader[Window!.Context].Handle)
{
GL.Uniform4(0, BackgroundColor);
@ -274,8 +276,9 @@ public class Rectangle : ITextureObject
add = 5;
GL.EnableVertexAttribArray(Textures.First().Location);
GL.VertexAttribPointer(Textures.First().Location, 2, VertexAttribPointerType.Float, false, 5 * sizeof(float), 3 * sizeof(float));
if (PrintPoints) EXT.PrintArray(value, "Points", 5);
}
else if (PrintPoints) EXT.PrintArray(value, "Points", 3);
GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, add * sizeof(float), 0);
GL.EnableVertexAttribArray(0);
GL.BindBuffer(BufferTarget.ArrayBuffer, BufferObject);
@ -284,6 +287,7 @@ public class Rectangle : ITextureObject
GL.BindBuffer(BufferTarget.ElementArrayBuffer, ElementBufferObject);
GL.BufferData(BufferTarget.ElementArrayBuffer, Indexs.Length * sizeof(ushort), Indexs, Hint);
if (Window is not null && Window.CanControleUpdate && Loaded) Parent!.TryDraw();
}
}
catch (AccessViolationException v)
@ -338,10 +342,10 @@ public class Rectangle : ITextureObject
if (Window is not null)
{
diff = Window.IntToFloat(Size.Y) + 1;
diff = Window.IntToWindow(Size.Y) + 1;
if (value == TextureDisplay.TextureHorizontalCenter)
{
diff = Window.IntToFloat(Textures[0].RawSize!.Value.Y);
diff = Window.IntToWindow(Textures[0].RawSize!.Value.Y);
}
}
Points = new float[]
@ -372,9 +376,9 @@ public class Rectangle : ITextureObject
if (Window is not null)
{
if (Size.X > Textures[0].RawSize!.Value.X)
diff = (Window.IntToFloat(Textures[0].RawSize!.Value.X) + 1) / 3;
diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3;
else
diff = (Window.IntToFloat(Size.X) + 1) / 3;
diff = (Window.IntToWindow(Size.X) + 1) / 3;
}
Points = new float[]
{
@ -423,6 +427,8 @@ public class Rectangle : ITextureObject
if (Parent is not null) Parent.TryDraw();
}
}
public bool PrintPoints = false;
private static void SetPoint(float[] temp, int start, float X, float Y, float Z, float Tx, float Ty)
{
@ -454,7 +460,7 @@ public class Rectangle : ITextureObject
TextureDisplay.Center => new float[80],
_ => new float[20]
};
saf = new Vector2(Parent.IntToFloat(value.X + loc_.X, false), Parent.IntToFloat(value.Y + loc_.Y, true));
saf = new Vector2(Parent.IntToWindow(value.X + loc_.X, false), Parent.IntToWindow(value.Y + loc_.Y, true));
temp[2] = Location.Z;
temp[(!Textures.Any() ? 5 : 7)] = Location.Z;
temp[(!Textures.Any() ? 8 : 12)] = Location.Z;
@ -472,16 +478,16 @@ public class Rectangle : ITextureObject
if (Textures.Count > 0)
{
Vector2i s = value;
float diff = Window.IntToFloat(s.Y) + 1;
float diff = Window.IntToWindow(s.Y) + 1;
float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X;
if (TextureDisplay == TextureDisplay.TextureHorizontalCenter)
diff = Window.IntToFloat(Textures[0].RawSize!.Value.Y);
diff = Window.IntToWindow(Textures[0].RawSize!.Value.Y);
if (TextureDisplay == TextureDisplay.Center)
{
if (s.X > Textures[0].RawSize!.Value.X)
diff = (Window.IntToFloat(Textures[0].RawSize!.Value.X) + 1) / 3;
diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3;
else
diff = (Window.IntToFloat(s.X) + 1) / 3;
diff = (Window.IntToWindow(s.X) + 1) / 3;
per = Textures[0].MaxText.X / 3;
}
@ -541,13 +547,13 @@ public class Rectangle : ITextureObject
if (dy > dx) dy = dx;
else dx = dy;
float diffy = (Window.IntToFloat(Window.Size.Y - dy, true) + 1) / 3;
diff = (Window.IntToFloat(dx) + 1) / 3;
float diffy = (dy + 1) / (float)3;
diff = (dx + 1) / (float)3;
per = Textures[0].MaxText.X / 3;
SetPoint(temp, 20, temp[0], temp[1] - diffy, temp[2], temp[3], temp[4] - (temp[4]*per));
SetPoint(temp, 25, temp[0], temp[6] + diffy, temp[2], temp[3], temp[4] * per);
SetPoint(temp, 20, temp[0], temp[1] + diffy, temp[2], temp[3], temp[4] - (temp[4]*per));
SetPoint(temp, 25, temp[0], temp[6] - diffy, temp[2], temp[3], temp[4] * per);
SetPoint(temp, 30, temp[5] - diff, temp[6], temp[2], temp[3] - (temp[3]*per), temp[9]);
SetPoint(temp, 35, temp[10] + diff, temp[6], temp[2], temp[3] * per, temp[9]);
SetPoint(temp, 40, temp[10], temp[26], temp[2], temp[13], temp[29]);
@ -683,7 +689,7 @@ public class Rectangle : ITextureObject
TextureDisplay.Center => new float[80],
_ => new float[20]
};
laf = new Vector2(Parent.IntToFloat(value.X, false), Parent.IntToFloat(value.Y, true));
laf = new Vector2(Parent.IntToWindow(value.X, false), Parent.IntToWindow(value.Y, true));
temp[2] = value.Z;
temp[(!Textures.Any() ? 5 : 7)] = value.Z;
temp[(!Textures.Any() ? 8 : 12)] = value.Z;
@ -693,7 +699,7 @@ public class Rectangle : ITextureObject
temp[(!Textures.Any() ? 9 : 15)] = laf.X;
temp[1] = laf.Y;
temp[(!Textures.Any() ? 10 : 16)] = laf.Y;
saf = new Vector2(Parent.IntToFloat(Size.X + value.X, false), Parent.IntToFloat(Size.Y + value.Y, true));
saf = new Vector2(Parent.IntToWindow(Size.X + value.X, false), Parent.IntToWindow(Size.Y + value.Y, true));
temp[0] = saf.X;
temp[(!Textures.Any() ? 3 : 5)] = saf.X;
temp[(!Textures.Any() ? 4 : 6)] = saf.Y;
@ -701,14 +707,14 @@ public class Rectangle : ITextureObject
if (Textures.Count > 0)
{
Vector2i s = Size;
float diff = Window.IntToFloat(s.Y) + 1;
float diff = Window.IntToWindow(s.Y) + 1;
float per = (float)Textures[0].RawSize!.Value.Y / Textures[0].RawSize!.Value.X;
if (TextureDisplay == TextureDisplay.Center)
{
if (s.X > Textures[0].RawSize!.Value.X)
diff = (Window.IntToFloat(Textures[0].RawSize!.Value.X) + 1) / 3;
diff = (Window.IntToWindow(Textures[0].RawSize!.Value.X) + 1) / 3;
else
diff = (Window.IntToFloat(s.X) + 1) / 3;
diff = (Window.IntToWindow(s.X) + 1) / 3;
per = Textures[0].MaxText.X / 3;
}
switch (TextureDisplay)
@ -767,11 +773,11 @@ public class Rectangle : ITextureObject
if (dy > dx) dy = dx;
else dx = dy;
float diffy = (Window.IntToFloat(Window.Size.Y - dy, true) + 1) / 3;
diff = (Window.IntToFloat(dx) + 1) / 3;
float diffy = (dy + 1) / (float)3;
diff = (dx + 1) / (float)3;
SetPoint(temp, 20, temp[0], temp[1] - diffy, temp[2], temp[3], temp[4] - (temp[4]*per));
SetPoint(temp, 25, temp[0], temp[6] + diffy, temp[2], temp[3], temp[4] * per);
SetPoint(temp, 20, temp[0], temp[1] + diffy, temp[2], temp[3], temp[4] - (temp[4]*per));
SetPoint(temp, 25, temp[0], temp[6] - diffy, temp[2], temp[3], temp[4] * per);
SetPoint(temp, 30, temp[5] - diff, temp[6], temp[2], temp[3] - (temp[3]*per), temp[9]);
SetPoint(temp, 35, temp[10] + diff, temp[6], temp[2], temp[3] * per, temp[9]);
SetPoint(temp, 40, temp[10], temp[26], temp[2], temp[13], temp[29]);

View File

@ -4,9 +4,12 @@ layout(location = 1) in vec2 aTexCoord;
out vec2 texCoord;
out vec4 vertexColor;
uniform vec4 objColor;
uniform mat4 windowMatrix;
void main(void)
{
texCoord = aTexCoord;
gl_Position = vec4(aPosition, 1.0);
gl_Position = vec4(aPosition, 1.0) * windowMatrix;
vertexColor = objColor;
}

View File

@ -2,8 +2,11 @@
layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec2 aTexCoord;
out vec2 texCoord;
uniform mat4 windowMatrix;
void main(void)
{
texCoord = aTexCoord;
gl_Position = vec4(aPosition, 1.0);
gl_Position = vec4(aPosition, 1.0) * windowMatrix;
}

View File

@ -3,8 +3,10 @@ layout (location = 0) in vec3 aPos;
uniform vec4 objColor;
out vec4 vertexColor;
uniform mat4 windowMatrix;
void main()
{
gl_Position = vec4(aPos, 1.0);
gl_Position = vec4(aPos, 1.0) * windowMatrix;
vertexColor = objColor;
}

View File

@ -2,8 +2,11 @@
layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec2 aTexCoord;
out vec2 texCoord;
uniform mat4 windowMatrix;
void main(void)
{
texCoord = aTexCoord;
gl_Position = vec4(aPosition, 1.0);
gl_Position = vec4(aPosition, 1.0) * windowMatrix;
}

View File

@ -74,6 +74,7 @@ public class Window : NativeWindow , IWindow
}
if (!Label._characters.ContainsKey(Context)) Label._characters.Add(Context, new());
last = WindowState;
WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, Size.X, Size.Y, 0, 1, -1);
KeyDown += OnKeyDownn;
}
@ -180,6 +181,11 @@ public class Window : NativeWindow , IWindow
else return (float)((1 - (p * Per)) * -1);
}
}
public float IntToWindow(float p, bool Y = false)
{
return p;
}
public float FloatToInt(float p, bool Invert = false)
{
@ -231,7 +237,7 @@ public class Window : NativeWindow , IWindow
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);
if (Controls[i].Size.X != sx || Controls[i].Size.Y != sy) Controls[i].Size = new(sx, sy);
Controls[i].Location = new(lx, ly, Controls[i].Location.Z);
if (Controls[i] is IParent parent)
{
@ -241,16 +247,16 @@ public class Window : NativeWindow , IWindow
DrawFrame();
BlockDraw = false;
}
public Matrix4 WindowSizeMatrix { get; set; }
public void ParentResize(ResizeEventArgs e)
{
base.OnResize(e);
if (e.Width == 0 && e.Height == 0 && WindowState != WindowState.Fullscreen) return;
WindowSizeMatrix = Matrix4.CreateOrthographicOffCenter(0.0f, e.Width, e.Height, 0, 1, -1);
GL.Viewport(0, 0, e.Width, e.Height);
Matrix4.CreateOrthographicOffCenter(0.0f, 800.0f, 0.0f, 600.0f, 0.1f, 100.0f);
ForceUpdate(e);
}
@ -442,7 +448,7 @@ public class Window : NativeWindow , IWindow
{
if (!Controls[i].Loaded) continue;
GL.Scissor(0, 0, Size.X, Size.Y);
Controls[i].Draw(0,0,Size.X, Size.Y);
Controls[i].Draw(0,0,Size.X, ClientSize.Y);
}
Context.SwapBuffers();