2021-15-03

+ GenericTransformation.InWorldSpace (Merges the object transformation and the last master transformation)
+ Ray class for Raycasting (may not work correctly)
+ Util.CallGarbageCollector() can call the garbage collector.
+ GLWindow.WindowFlags allow to easly switch between Window <-> Borderless Window (this will cause the window to fill the entire screen) <-> Exclusive Fullscreen.

~ Made the bloom-texture scale a constructor-parameter.

SM.OGL:
+ OpenGL-GarbageCollector integration.
+ BoundingBox.GetBounds(Matrix4, out Vector3,out Vector3) allows for easy transformation of the bounding box.
+ GLObjects can now marked as not compiled. Where it always returns false at WasCompiled.

SM2D:
~ Improved the Mouse2D.MouseOver Algorithm.
This commit is contained in:
Michel Fedde 2021-03-15 18:11:58 +01:00
parent 4efc47d75a
commit 5bb690e45f
18 changed files with 224 additions and 20 deletions

View file

@ -96,7 +96,7 @@ namespace SM.Base.Drawing
{ {
base.DrawContext(ref context); base.DrawContext(ref context);
Transform.LastMaster = context.ModelMatrix; Transform.LastMaster = context.ModelMatrix;
context.ModelMatrix = Transform.MergeMatrix(context.ModelMatrix); context.ModelMatrix = Transform.InWorldSpace;
} }
} }
} }

View file

@ -18,6 +18,8 @@ namespace SM.Base.Drawing
public Matrix4 LastMaster { get; internal set; } public Matrix4 LastMaster { get; internal set; }
public Matrix4 InWorldSpace => MergeMatrix(LastMaster);
/// <summary> /// <summary>
/// Contains the current model matrix. /// Contains the current model matrix.
/// </summary> /// </summary>

View file

@ -15,7 +15,9 @@ namespace SM.Base.PostEffects
{ {
private static BezierCurve _defaultCurve = new BezierCurve(Vector2.UnitY, new Vector2(0.32f, 1), new Vector2(0.432f, 0), new Vector2(1,0)); private static BezierCurve _defaultCurve = new BezierCurve(Vector2.UnitY, new Vector2(0.32f, 1), new Vector2(0.432f, 0), new Vector2(1,0));
private const float _textureScale = .75f; private const float _defaultTextureScale = .75f;
private float _textureScale = .75f;
private Framebuffer _bloomBuffer1; private Framebuffer _bloomBuffer1;
private Framebuffer _bloomBuffer2; private Framebuffer _bloomBuffer2;
@ -56,10 +58,11 @@ namespace SM.Base.PostEffects
public int WeightCurvePickAmount = 4; public int WeightCurvePickAmount = 4;
public BloomEffect(Framebuffer source = null, bool hdr = false) public BloomEffect(Framebuffer source = null, bool hdr = false, float? textureScale = null)
{ {
_source = source; _source = source;
_hdr = hdr; _hdr = hdr;
_textureScale = textureScale.GetValueOrDefault(_defaultTextureScale);
WeightCurve = _defaultCurve; WeightCurve = _defaultCurve;
} }

View file

@ -73,6 +73,7 @@
<Compile Include="Drawing\Particles\ParticleDrawingBasis.cs" /> <Compile Include="Drawing\Particles\ParticleDrawingBasis.cs" />
<Compile Include="Shaders\SimpleShader.cs" /> <Compile Include="Shaders\SimpleShader.cs" />
<Compile Include="Utility\IInitializable.cs" /> <Compile Include="Utility\IInitializable.cs" />
<Compile Include="Utility\Ray.cs" />
<Compile Include="Utility\Util.cs" /> <Compile Include="Utility\Util.cs" />
<Compile Include="Window\Contexts\DrawContext.cs" /> <Compile Include="Window\Contexts\DrawContext.cs" />
<Compile Include="Window\Contexts\UpdateContext.cs" /> <Compile Include="Window\Contexts\UpdateContext.cs" />
@ -116,6 +117,7 @@
<Compile Include="Window\ISetup.cs" /> <Compile Include="Window\ISetup.cs" />
<Compile Include="Window\RenderPipeline.cs" /> <Compile Include="Window\RenderPipeline.cs" />
<Compile Include="Window\WindowCode.cs" /> <Compile Include="Window\WindowCode.cs" />
<Compile Include="Window\WindowFlags.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Shaders\Extensions\vertex\basic.vert" /> <EmbeddedResource Include="Shaders\Extensions\vertex\basic.vert" />

View file

@ -0,0 +1,66 @@
using System;
using System.Windows;
using OpenTK;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM.OGL.Mesh;
namespace SM.Utility
{
public struct Ray
{
public Vector3 Position;
public Vector3 Direction;
public Ray(Vector3 position, Vector3 direction)
{
Position = position;
Direction = direction.Normalized();
}
public bool ObjectIntersection(BoundingBox box, Matrix4 modelMatrix, out float distance)
{
distance = 0.0f;
float tMin = 0.0f;
float tMax = 100000.0f;
Vector3 delta = modelMatrix.Row3.Xyz - Position;
for (int i = 0; i < 3; i++)
{
Vector3 axis = new Vector3(modelMatrix[i, 0], modelMatrix[i, 1], modelMatrix[i, 2]);
float e = Vector3.Dot(axis, delta);
float f = Vector3.Dot(Direction, axis);
if (Math.Abs(f) > 0.001f)
{
float t1 = (e + box.Min[i]) / f;
float t2 = (e + box.Max[i]) / f;
if (t1 > t2)
{
float w = t1;
t1 = t2;
t2 = w;
}
if (t2 < tMax) tMax = t2;
if (t1 > tMin) tMin = t1;
if (tMax < tMin)
return false;
}
else
{
if (-e + box.Min[i] > 0.0f || -e + box.Max[i] < 0.0f)
return false;
}
}
distance = tMin;
return true;
}
}
}

View file

@ -1,4 +1,6 @@
namespace SM.Utility using System;
namespace SM.Utility
{ {
public class Util public class Util
{ {
@ -11,5 +13,11 @@
} }
obj.Activate(); obj.Activate();
} }
public static void CallGarbageCollector()
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
} }
} }

View file

@ -1,4 +1,6 @@
using System; using System;
using System.Windows;
using System.Windows.Forms;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Input; using OpenTK.Input;
@ -11,6 +13,8 @@ namespace SM.Base.Windows
{ {
public class GLWindow : GameWindow, IGenericWindow public class GLWindow : GameWindow, IGenericWindow
{ {
private Vector2 _flagWindowSize;
public bool Loading { get; private set; } = true; public bool Loading { get; private set; } = true;
public float AspectRatio { get; set; } public float AspectRatio { get; set; }
@ -30,12 +34,17 @@ namespace SM.Base.Windows
public GenericScene CurrentScene { get; private set; } public GenericScene CurrentScene { get; private set; }
public RenderPipeline CurrentRenderPipeline { get; private set; } public RenderPipeline CurrentRenderPipeline { get; private set; }
public GLWindow() : this(1280, 720, "Generic OpenGL Title", GameWindowFlags.Default) {} public WindowFlags WindowFlags;
public GLWindow(int width, int height, string title, GameWindowFlags flags, VSyncMode vSync = VSyncMode.On) : public GLWindow() : this(1280, 720, "Generic OpenGL Title", WindowFlags.Window) {}
base(width, height, default, title, flags, DisplayDevice.Default, GLSettings.ForcedVersion.MajorVersion, GLSettings.ForcedVersion.MinorVersion, GraphicsContextFlags.Default)
public GLWindow(int width, int height, string title, WindowFlags flags, VSyncMode vSync = VSyncMode.On) :
base(width, height, default, title, (GameWindowFlags)flags, DisplayDevice.Default, GLSettings.ForcedVersion.MajorVersion, GLSettings.ForcedVersion.MinorVersion, GraphicsContextFlags.Default)
{ {
VSync = vSync; VSync = vSync;
_flagWindowSize = new Vector2(width, height);
ChangeWindowFlag(flags);
} }
protected override void OnLoad(EventArgs e) protected override void OnLoad(EventArgs e)
@ -52,6 +61,8 @@ namespace SM.Base.Windows
WindowCode.Resize(this); WindowCode.Resize(this);
if (WindowFlags == WindowFlags.Window) _flagWindowSize = WindowSize;
if (Loading) if (Loading)
{ {
Loading = false; Loading = false;
@ -125,5 +136,40 @@ namespace SM.Base.Windows
public void TriggerLoad() => Load?.Invoke(this); public void TriggerLoad() => Load?.Invoke(this);
public void TriggerResize() => Resize?.Invoke(this); public void TriggerResize() => Resize?.Invoke(this);
public void ChangeWindowFlag(WindowFlags newFlag)
{
WindowFlags = newFlag;
switch (newFlag)
{
case WindowFlags.Window:
Width = (int)_flagWindowSize.X;
Height = (int)_flagWindowSize.Y;
WindowBorder = WindowBorder.Resizable;
break;
case WindowFlags.BorderlessWindow:
WindowBorder = WindowBorder.Hidden;
X = Screen.PrimaryScreen.Bounds.Left;
Y = Screen.PrimaryScreen.Bounds.Top;
Width = Screen.PrimaryScreen.Bounds.Width;
Height = Screen.PrimaryScreen.Bounds.Height;
break;
case WindowFlags.ExclusiveFullscreen:
break;
default:
throw new ArgumentOutOfRangeException(nameof(newFlag), newFlag, null);
}
if (newFlag == WindowFlags.BorderlessWindow)
{
WindowBorder = WindowBorder.Hidden;
X = Screen.PrimaryScreen.Bounds.X;
Y = Screen.PrimaryScreen.Bounds.Y;
}
}
} }
} }

View file

@ -94,6 +94,8 @@ namespace SM.Base.Windows
SMRenderer.CurrentFrame++; SMRenderer.CurrentFrame++;
GLObject.DisposeMarkedObjects();
Deltatime.RenderDelta = deltatime; Deltatime.RenderDelta = deltatime;
var drawContext = new DrawContext() var drawContext = new DrawContext()
{ {

View file

@ -0,0 +1,9 @@
namespace SM.Base.Windows
{
public enum WindowFlags
{
Window = 0,
BorderlessWindow = 2,
ExclusiveFullscreen = 1
}
}

View file

@ -116,9 +116,11 @@ namespace SM.OGL.Framebuffer
/// <inheritdoc /> /// <inheritdoc />
public override void Dispose() public override void Dispose()
{ {
base.Dispose();
foreach (var attachment in ColorAttachments.Values) attachment.Dispose(); foreach (var attachment in ColorAttachments.Values) attachment.Dispose();
GL.DeleteFramebuffer(this); GL.DeleteFramebuffer(this);
base.Dispose();
} }
/// <summary> /// <summary>
@ -180,6 +182,7 @@ namespace SM.OGL.Framebuffer
Framebuffer buffer = new Framebuffer() Framebuffer buffer = new Framebuffer()
{ {
_canBeCompiled = false, _canBeCompiled = false,
ReportAsNotCompiled = true
}; };
switch (target) switch (target)
{ {

View file

@ -1,6 +1,9 @@
#region usings #region usings
using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion #endregion
@ -12,6 +15,10 @@ namespace SM.OGL
/// </summary> /// </summary>
public abstract class GLObject public abstract class GLObject
{ {
private static List<GLObject> _disposableObjects = new List<GLObject>();
protected bool ReportAsNotCompiled;
/// <summary> /// <summary>
/// Contains the OpenGL ID /// Contains the OpenGL ID
/// </summary> /// </summary>
@ -25,7 +32,7 @@ namespace SM.OGL
/// <summary> /// <summary>
/// Checks if the object was compiled. /// Checks if the object was compiled.
/// </summary> /// </summary>
public bool WasCompiled => _id > 0; public bool WasCompiled => _id > 0 && !ReportAsNotCompiled;
/// <summary> /// <summary>
/// Returns the id for this object. /// Returns the id for this object.
@ -64,7 +71,7 @@ namespace SM.OGL
/// </summary> /// </summary>
public virtual void Dispose() public virtual void Dispose()
{ {
_id = -1;
} }
/// <summary> /// <summary>
@ -87,6 +94,15 @@ namespace SM.OGL
if (GLSystem.Debugging) GL.ObjectLabel(TypeIdentifier, _id, name.Length, name); if (GLSystem.Debugging) GL.ObjectLabel(TypeIdentifier, _id, name.Length, name);
} }
public static void DisposeMarkedObjects()
{
foreach (GLObject o in _disposableObjects)
{
o.Dispose();
}
_disposableObjects.Clear();
}
/// <summary> /// <summary>
/// Returns the ID for the object. /// Returns the ID for the object.
/// </summary> /// </summary>
@ -95,5 +111,10 @@ namespace SM.OGL
{ {
return glo.ID; return glo.ID;
} }
~GLObject()
{
if (WasCompiled) _disposableObjects.Add(this);
}
} }
} }

View file

@ -65,6 +65,21 @@ namespace SM.OGL.Mesh
public Vector3 Get(Matrix4 transformation, bool xyz) => Get(transformation, xyz, xyz, xyz); public Vector3 Get(Matrix4 transformation, bool xyz) => Get(transformation, xyz, xyz, xyz);
public void GetBounds(Matrix4 transformation, out Vector3 min, out Vector3 max)
{
min = Get(transformation, false);
max = Get(transformation, true);
for (int i = 0; i < 3; i++)
{
float newmin = Math.Min(min[i], max[i]);
float newmax = Math.Max(min[i], max[i]);
min[i] = newmin;
max[i] = newmax;
}
}
public void Update(GenericMesh mesh) public void Update(GenericMesh mesh)
{ {
int pos = 0; int pos = 0;

View file

@ -99,5 +99,11 @@ namespace SM.OGL.Mesh
GL.BindVertexArray(0); GL.BindVertexArray(0);
} }
public override void Dispose()
{
GL.DeleteVertexArray(_id);
base.Dispose();
}
} }
} }

View file

@ -119,7 +119,8 @@ namespace SM.OGL.Shaders
public override void Dispose() public override void Dispose()
{ {
GL.DeleteShader(this); GL.DeleteProgram(this);
base.Dispose();
} }
/// <summary> /// <summary>

View file

@ -79,5 +79,12 @@ namespace SM.OGL.Shaders
for (var i = 0; i < GLSLExtensions.Count; i++) GLSLExtensions[i].Compile(shader, type); for (var i = 0; i < GLSLExtensions.Count; i++) GLSLExtensions[i].Compile(shader, type);
} }
public override void Dispose()
{
GL.DeleteShader(this);
base.Dispose();
}
} }
} }

View file

@ -46,8 +46,8 @@ namespace SM.OGL.Texture
public override void Dispose() public override void Dispose()
{ {
base.Dispose();
GL.DeleteTexture(_id); GL.DeleteTexture(_id);
base.Dispose();
} }
} }
} }

View file

@ -1,8 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Controls;
using OpenTK; using OpenTK;
using SM.Base.Controls; using SM.Base.Controls;
using SM.Base.Drawing; using SM.Base.Drawing;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Utility;
using SM2D.Scene; using SM2D.Scene;
using SM2D.Types; using SM2D.Types;
@ -43,21 +45,30 @@ namespace SM2D.Controls
where TObject : IModelItem, ITransformItem<Transformation> where TObject : IModelItem, ITransformItem<Transformation>
{ {
clickedObj = default; clickedObj = default;
bool success = false;
foreach (TObject obj in checkingObjects) float distance = -10;
foreach (TObject item in checkingObjects)
{ {
Vector3 min = obj.Mesh.BoundingBox.Get(obj.Transform.MergeMatrix(obj.Transform.LastMaster), false); Matrix4 worldPos = item.Transform.InWorldSpace;
Vector3 max = obj.Mesh.BoundingBox.Get(obj.Transform.MergeMatrix(obj.Transform.LastMaster), true); item.Mesh.BoundingBox.GetBounds(worldPos, out Vector3 min, out Vector3 max);
if (mousePos.X > min.X && mousePos.X < max.X && if (mousePos.X > min.X && mousePos.X < max.X &&
mousePos.Y > min.Y && mousePos.Y < max.Y) mousePos.Y > min.Y && mousePos.Y < max.Y)
{ {
clickedObj = obj; // if z is greater than distance
return true; if (worldPos[3, 2] > distance)
{
clickedObj = item;
distance = worldPos[3, 2];
}
success = true;
} }
} }
return false; return success;
} }
} }
} }

View file

@ -1,6 +1,7 @@
#region usings #region usings
using System; using System;
using System.Runtime.Serialization.Formatters;
using OpenTK; using OpenTK;
using SM.Base; using SM.Base;
using SM.Base.Scene; using SM.Base.Scene;
@ -14,6 +15,7 @@ namespace SM2D.Scene
public class Camera : GenericCamera public class Camera : GenericCamera
{ {
internal static int ResizeCounter = 0; internal static int ResizeCounter = 0;
internal static float Distance = 2F;
private int _resizeCounter = 0; private int _resizeCounter = 0;
private bool _updateWorldScale = false; private bool _updateWorldScale = false;
@ -38,7 +40,7 @@ namespace SM2D.Scene
protected override Matrix4 ViewCalculation(IGenericWindow window) protected override Matrix4 ViewCalculation(IGenericWindow window)
{ {
return Matrix4.LookAt(Position.X, Position.Y, 2f, Position.X, Position.Y, 0f, 0, 1, 0); return Matrix4.LookAt(Position.X, Position.Y, Distance, Position.X, Position.Y, 0f, 0, 1, 0);
} }
protected override bool WorldCalculation(IGenericWindow window, out Matrix4 world) protected override bool WorldCalculation(IGenericWindow window, out Matrix4 world)