From 7acdba92f80158dbaeea112c6f30ba133b6d1781 Mon Sep 17 00:00:00 2001 From: Michel Fedde Date: Wed, 30 Sep 2020 21:26:42 +0200 Subject: [PATCH] 30.09.2020 + Mouse support + Started to add summaries to SM.Base --- SMCode/SM.Base/Controls/Mouse.cs | 39 +++++++ SMCode/SM.Base/Defaults.cs | 3 +- SMCode/SM.Base/Drawing/DrawingBasis.cs | 22 +++- .../SM.Base/Drawing/GenericTransformation.cs | 7 ++ SMCode/SM.Base/Drawing/IShader.cs | 7 ++ SMCode/SM.Base/Drawing/Instance.cs | 12 ++ SMCode/SM.Base/Drawing/Material.cs | 13 +++ SMCode/SM.Base/Objects/Static/Plate.cs | 9 +- SMCode/SM.Base/SM.Base.csproj | 1 + SMCode/SM.Base/Scene/GenericScene.cs | 9 +- SMCode/SM.Base/Types/Vector.cs | 58 ++++++++++ SMCode/SM.Base/Types/Vector2.cs | 4 + SMCode/SM.Base/Window/GenericWindow.cs | 103 ++++++++++++------ SMCode/SM.OGL/Mesh/GenericMesh.cs | 2 +- SMCode/SM2D/Controls/Mouse2D.cs | 22 ++++ SMCode/SM2D/Drawing/DrawColor.cs | 1 + SMCode/SM2D/GLWindow2D.cs | 28 +++++ SMCode/SM2D/Object/Polygon.cs | 14 +++ SMCode/SM2D/SM2D.csproj | 1 + SMCode/SM2D/Types/Transformation.cs | 3 +- SM_TEST/Program.cs | 25 ++--- 21 files changed, 325 insertions(+), 58 deletions(-) create mode 100644 SMCode/SM.Base/Controls/Mouse.cs create mode 100644 SMCode/SM2D/Controls/Mouse2D.cs diff --git a/SMCode/SM.Base/Controls/Mouse.cs b/SMCode/SM.Base/Controls/Mouse.cs new file mode 100644 index 0000000..f631755 --- /dev/null +++ b/SMCode/SM.Base/Controls/Mouse.cs @@ -0,0 +1,39 @@ +using System; +using OpenTK; +using OpenTK.Input; + +namespace SM.Base.Controls +{ + /// + /// Mouse controller + /// + /// The type of window this controller is connected to. + public class Mouse + where TWindow : GenericWindow + { + /// + /// The window it is connected to. + /// + protected TWindow _window; + + /// + /// The current position of the mouse in the screen. + /// + public Vector2 InScreen { get; private set; } + /// + /// The current position of the mouse in the screen from 0..1. + /// + public Vector2 InScreenNormalized { get; private set; } + + protected internal Mouse(TWindow window) + { + _window = window; + } + + protected void MouseMoveEvent(MouseMoveEventArgs mmea) + { + InScreen = new Vector2(mmea.X, mmea.Y); + InScreenNormalized = new Vector2(mmea.X / (float)_window.Width, mmea.Y / (float)_window.Height); + } + } +} \ No newline at end of file diff --git a/SMCode/SM.Base/Defaults.cs b/SMCode/SM.Base/Defaults.cs index 5e76af0..83b3a6b 100644 --- a/SMCode/SM.Base/Defaults.cs +++ b/SMCode/SM.Base/Defaults.cs @@ -1,12 +1,13 @@ using SM.Base.Objects; using SM.Base.Objects.Static; using SM.Base.Scene; +using SM.OGL.Mesh; namespace SM.Base { public class Defaults { public static IShader DefaultShader; - public static Mesh DefaultMesh = Plate.Object; + public static GenericMesh DefaultMesh = Plate.Object; } } \ No newline at end of file diff --git a/SMCode/SM.Base/Drawing/DrawingBasis.cs b/SMCode/SM.Base/Drawing/DrawingBasis.cs index d823ee7..e51c212 100644 --- a/SMCode/SM.Base/Drawing/DrawingBasis.cs +++ b/SMCode/SM.Base/Drawing/DrawingBasis.cs @@ -4,9 +4,18 @@ using SM.OGL.Mesh; namespace SM.Base.Scene { + /// + /// Contains general basis systems for drawing objects. + /// public abstract class DrawingBasis : IShowItem { + /// + /// The material it should use. + /// protected Material _material = new Material(); + /// + /// The mesh it should use. + /// protected GenericMesh _mesh = Defaults.DefaultMesh; public virtual void Update(UpdateContext context) { @@ -14,14 +23,25 @@ namespace SM.Base.Scene } public virtual void Draw(DrawContext context) - { } + { + } + /// + /// Applies the current settings to the context. + /// + /// protected void ApplyContext(ref DrawContext context) { + _material.Shader ??= Defaults.DefaultShader; + context.Material = _material; context.Mesh = _mesh; } } + /// + /// Contains general basis systems for drawing objects. + /// + /// The transformation type public abstract class DrawingBasis : DrawingBasis where TTransformation : GenericTransformation, new() { diff --git a/SMCode/SM.Base/Drawing/GenericTransformation.cs b/SMCode/SM.Base/Drawing/GenericTransformation.cs index 05223f6..f6c0e83 100644 --- a/SMCode/SM.Base/Drawing/GenericTransformation.cs +++ b/SMCode/SM.Base/Drawing/GenericTransformation.cs @@ -2,8 +2,15 @@ namespace SM.Base.Scene { + /// + /// Contains methods for using transformations right. + /// public abstract class GenericTransformation { + /// + /// Calculates the current matrix. + /// + /// The current matrix. public abstract Matrix4 GetMatrix(); } } \ No newline at end of file diff --git a/SMCode/SM.Base/Drawing/IShader.cs b/SMCode/SM.Base/Drawing/IShader.cs index e6df907..3083576 100644 --- a/SMCode/SM.Base/Drawing/IShader.cs +++ b/SMCode/SM.Base/Drawing/IShader.cs @@ -4,8 +4,15 @@ using SM.Base.Contexts; namespace SM.Base.Scene { + /// + /// A general interface to work with material shaders properly. + /// public interface IShader { + /// + /// Draws the context. + /// + /// The context void Draw(DrawContext context); } } \ No newline at end of file diff --git a/SMCode/SM.Base/Drawing/Instance.cs b/SMCode/SM.Base/Drawing/Instance.cs index 6d15f60..2d17607 100644 --- a/SMCode/SM.Base/Drawing/Instance.cs +++ b/SMCode/SM.Base/Drawing/Instance.cs @@ -2,10 +2,22 @@ namespace SM.Base.Scene { + /// + /// This represens a drawing instance. + /// public struct Instance { + /// + /// The model matrix. + /// public Matrix4 ModelMatrix; + /// + /// The texture offset. + /// public Vector2 TexturePosition; + /// + /// The texture scale. + /// public Vector2 TextureScale; } } \ No newline at end of file diff --git a/SMCode/SM.Base/Drawing/Material.cs b/SMCode/SM.Base/Drawing/Material.cs index c313e25..7d29edf 100644 --- a/SMCode/SM.Base/Drawing/Material.cs +++ b/SMCode/SM.Base/Drawing/Material.cs @@ -3,11 +3,24 @@ using SM.OGL.Texture; namespace SM.Base.Scene { + /// + /// Represents a material. + /// public class Material { + /// + /// The base texture. (aka. Diffuse Texture) + /// public TextureBase Texture; + /// + /// The tint or color. + /// public Color4 Tint = Color4.White; + /// + /// A shader, that is used to draw this material. + /// Default: Defaults.DefaultShaders + /// public IShader Shader = Defaults.DefaultShader; } } \ No newline at end of file diff --git a/SMCode/SM.Base/Objects/Static/Plate.cs b/SMCode/SM.Base/Objects/Static/Plate.cs index 01061dd..05ce4ee 100644 --- a/SMCode/SM.Base/Objects/Static/Plate.cs +++ b/SMCode/SM.Base/Objects/Static/Plate.cs @@ -1,11 +1,18 @@ using OpenTK; +using OpenTK.Graphics; using OpenTK.Graphics.OpenGL4; using SM.OGL.Mesh; namespace SM.Base.Objects.Static { - public class Plate : Mesh + /// + /// A basic plate + /// + public class Plate : GenericMesh { + /// + /// The object. + /// public static Plate Object = new Plate(); public override VBO Vertex { get; } = new VBO() diff --git a/SMCode/SM.Base/SM.Base.csproj b/SMCode/SM.Base/SM.Base.csproj index d40e145..2a8d9f5 100644 --- a/SMCode/SM.Base/SM.Base.csproj +++ b/SMCode/SM.Base/SM.Base.csproj @@ -47,6 +47,7 @@ + diff --git a/SMCode/SM.Base/Scene/GenericScene.cs b/SMCode/SM.Base/Scene/GenericScene.cs index 161fa2c..afbda70 100644 --- a/SMCode/SM.Base/Scene/GenericScene.cs +++ b/SMCode/SM.Base/Scene/GenericScene.cs @@ -19,7 +19,7 @@ namespace SM.Base.Scene public virtual void Draw(DrawContext context) { - if (!context.ForceViewport && Camera != null) context.View = Camera.ViewMatrix; + if (!context.ForceViewport && Camera != null) context.View = Camera.CalculateViewMatrix(); DrawContext backgroundDrawContext = context; backgroundDrawContext.View = BackgroundCamera.CalculateViewMatrix(); @@ -33,5 +33,12 @@ namespace SM.Base.Scene HUD[i].Draw(context); } + internal void Activate() + { + OnActivating(); + } + + protected virtual void OnActivating() + { } } } \ No newline at end of file diff --git a/SMCode/SM.Base/Types/Vector.cs b/SMCode/SM.Base/Types/Vector.cs index 6edfcb7..f3ef9f3 100644 --- a/SMCode/SM.Base/Types/Vector.cs +++ b/SMCode/SM.Base/Types/Vector.cs @@ -1,4 +1,5 @@ using System; +using System.Configuration.Assemblies; using OpenTK; namespace SM.Base.Types @@ -41,7 +42,64 @@ namespace SM.Base.Types _z = z; _w = w; } + + #region Set + protected void Set(float x, float y) + { + _X = x; + _Y = y; + } + protected void Set(OpenTK.Vector2 vector) + { + Set(vector.X, vector.Y); + } + + protected void Set(float x, float y, float z) + { + Set(x,y); + _Z = z; + } + + protected void Set(OpenTK.Vector3 vector) + { + Set(vector.X, vector.Y, vector.Z); + } + + protected void Set(float x, float y, float z, float w) + { + Set(x,y,z); + _W = w; + } + + protected void Set(OpenTK.Vector4 vector) + { + Set(vector.X, vector.Y, vector.Z, vector.W); + } + #endregion + + #region Add + + protected void Add(OpenTK.Vector2 vector) + { + _X += vector.X; + _Y += vector.Y; + } + protected void Add(OpenTK.Vector3 vector) + { + _X += vector.X; + _Y += vector.Y; + _Z += vector.Z; + } + protected void Add(OpenTK.Vector4 vector) + { + _X += vector.X; + _Y += vector.Y; + _Z += vector.Z; + _W += vector.W; + } + + #endregion public static implicit operator OpenTK.Vector2(Vector v) => new OpenTK.Vector2(v._x, v._y); public static implicit operator OpenTK.Vector3(Vector v) => new OpenTK.Vector3(v._x, v._y, v._z); public static implicit operator OpenTK.Vector4(Vector v) => new OpenTK.Vector4(v._x, v._y, v._z, v._w); diff --git a/SMCode/SM.Base/Types/Vector2.cs b/SMCode/SM.Base/Types/Vector2.cs index c686177..2dabb58 100644 --- a/SMCode/SM.Base/Types/Vector2.cs +++ b/SMCode/SM.Base/Types/Vector2.cs @@ -23,6 +23,10 @@ public Vector2(float x, float y) : base(x,y, default, default) {} protected Vector2(float x, float y, float z, float w) : base(x, y, z, w) {} + public new void Set(float x, float y) => base.Set(x, y); + public new void Set(OpenTK.Vector2 vector) => base.Set(vector); + + public new void Add(OpenTK.Vector2 vector) => base.Add(vector); public static implicit operator Vector2(OpenTK.Vector2 v) => new Vector2(v.X, v.Y); } diff --git a/SMCode/SM.Base/Window/GenericWindow.cs b/SMCode/SM.Base/Window/GenericWindow.cs index b859aaf..87e930c 100644 --- a/SMCode/SM.Base/Window/GenericWindow.cs +++ b/SMCode/SM.Base/Window/GenericWindow.cs @@ -3,32 +3,28 @@ using System.IO; using OpenTK; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL4; +using OpenTK.Input; using SM.Base.Contexts; using SM.Base.Objects.Static; using SM.Base.Scene; using SM.OGL; using SM.OGL.Shaders; +using SM.Utility; namespace SM.Base { - public class GenericWindow : GameWindow - where TScene : GenericScene, new() - where TItem : IShowItem - where TCamera : GenericCamera, new() + public abstract class GenericWindow : GameWindow { - private TCamera _viewportCamera; + private bool _loading = false; - public TScene CurrentScene { get; private set; } public bool ForceViewportCamera { get; set; } = false; - public Vector2? Scaling { get; set; } - public Vector2 WorldScale { get; private set; }= Vector2.Zero; + protected Vector2 _worldScale = Vector2.Zero; public float Aspect { get; private set; } = 0f; - public GenericWindow() : base(1280, 720, GraphicsMode.Default, "Testing", GameWindowFlags.Default, DisplayDevice.Default, 0, 0, GraphicsContextFlags.Default, null, true) - { - _viewportCamera = new TCamera(); - } + protected GenericWindow() : base(1280, 720, GraphicsMode.Default, "Generic OGL Title", GameWindowFlags.Default, + DisplayDevice.Default, 0, 0, GraphicsContextFlags.Default, null, true) + { } protected override void OnLoad(EventArgs e) { @@ -44,18 +40,74 @@ namespace SM.Base $"----------------------------------\n"); base.OnLoad(e); + _loading = true; + } + protected override void OnResize(EventArgs e) + { + base.OnResize(e); + + Aspect = (float)Width / Height; + _worldScale = new Vector2(Width, Height); + SetWorldScale(); + GL.Viewport(ClientRectangle); + + if (_loading) + { + _loading = false; + OnLoaded(); + } + } + + protected virtual void OnLoaded() + { + + } + + protected virtual void SetWorldScale() { } + + protected override void OnUpdateFrame(FrameEventArgs e) + { + base.OnUpdateFrame(e); + Deltatime.UpdateDelta = (float)e.Time; + } + + public void GrabCursor(bool makeItInvisible = true) + { + CursorGrabbed = true; + CursorVisible = !makeItInvisible; + } + + public void UngrabCursor() + { + CursorGrabbed = false; + if (!CursorVisible) CursorVisible = true; + } + } + + public abstract class GenericWindow : GenericWindow + where TScene : GenericScene, new() + where TItem : IShowItem + where TCamera : GenericCamera, new() + { + public TCamera ViewportCamera { get; } + + public TScene CurrentScene { get; private set; } + + protected GenericWindow() + { + ViewportCamera = new TCamera(); } protected override void OnRenderFrame(FrameEventArgs e) { DrawContext drawContext = new DrawContext() { - World = _viewportCamera.World, - View = _viewportCamera.CalculateViewMatrix(), + World = ViewportCamera.World, + View = ViewportCamera.CalculateViewMatrix(), Instances = new[] { new Instance {ModelMatrix = Matrix4.Identity, TexturePosition = Vector2.Zero, TextureScale = Vector2.One } }, Mesh = Plate.Object, ForceViewport = ForceViewportCamera, - WorldScale = WorldScale + WorldScale = _worldScale }; base.OnRenderFrame(e); @@ -71,30 +123,13 @@ namespace SM.Base { base.OnResize(e); - Aspect = (float)Width / Height; - WorldScale = new Vector2(Width, Height); - if (Scaling.HasValue) - { - if (Scaling.Value.X > 0 && Scaling.Value.Y > 0) WorldScale = Scaling.Value; - else if(Scaling.Value.X > 0) WorldScale = new Vector2(Scaling.Value.X, Scaling.Value.X / Aspect); - else if(Scaling.Value.Y > 0) WorldScale = new Vector2(Aspect * Scaling.Value.Y, Scaling.Value.Y); - } - - GL.Viewport(ClientRectangle); - _viewportCamera.RecalculateWorld(WorldScale, Aspect); + ViewportCamera.RecalculateWorld(_worldScale, Aspect); } public virtual void SetScene(TScene scene) { CurrentScene = scene; + scene.Activate(); } } - - public enum WindowScaling - { - None, - Width, - Height, - FixedSize - } } \ No newline at end of file diff --git a/SMCode/SM.OGL/Mesh/GenericMesh.cs b/SMCode/SM.OGL/Mesh/GenericMesh.cs index 13c004b..702e1f8 100644 --- a/SMCode/SM.OGL/Mesh/GenericMesh.cs +++ b/SMCode/SM.OGL/Mesh/GenericMesh.cs @@ -43,7 +43,7 @@ namespace SM.OGL.Mesh /// /// Connects the different buffer objects with ids. /// - protected Dictionary AttribDataIndex { get; } + public Dictionary AttribDataIndex { get; } /// /// Stores indices for a more performance friendly method to draw objects. diff --git a/SMCode/SM2D/Controls/Mouse2D.cs b/SMCode/SM2D/Controls/Mouse2D.cs new file mode 100644 index 0000000..5661462 --- /dev/null +++ b/SMCode/SM2D/Controls/Mouse2D.cs @@ -0,0 +1,22 @@ +using OpenTK; +using OpenTK.Input; +using SM.Base; +using SM.Base.Controls; +using SM2D.Scene; + +namespace SM2D.Controls +{ + public class Mouse2D : Mouse + { + protected internal Mouse2D(GLWindow2D window) : base(window) + { } + + internal new void MouseMoveEvent(MouseMoveEventArgs mmea) => base.MouseMoveEvent(mmea); + + public Vector2 InWorld(Camera cam) + { + Vector2 res = _window.WorldScale; + return InScreenNormalized * res - res / 2; + } + } +} \ No newline at end of file diff --git a/SMCode/SM2D/Drawing/DrawColor.cs b/SMCode/SM2D/Drawing/DrawColor.cs index 2269fd9..695f5ef 100644 --- a/SMCode/SM2D/Drawing/DrawColor.cs +++ b/SMCode/SM2D/Drawing/DrawColor.cs @@ -1,4 +1,5 @@ using OpenTK.Graphics; +using SM.Base; using SM.Base.Contexts; using SM.Base.Scene; using SM2D.Scene; diff --git a/SMCode/SM2D/GLWindow2D.cs b/SMCode/SM2D/GLWindow2D.cs index 3f5e73d..b1342b5 100644 --- a/SMCode/SM2D/GLWindow2D.cs +++ b/SMCode/SM2D/GLWindow2D.cs @@ -1,15 +1,27 @@ using System; using OpenTK; using OpenTK.Graphics.OpenGL4; +using OpenTK.Input; using SM.Base; +using SM.Base.Controls; +using SM2D.Controls; using SM2D.Scene; using SM2D.Shader; +using Vector2 = OpenTK.Vector2; namespace SM2D { public class GLWindow2D : GenericWindow { + public Vector2? Scaling { get; set; } + public Vector2 WorldScale => _worldScale; + public Mouse2D Mouse { get; } + + public GLWindow2D() + { + Mouse = new Mouse2D(this); + } protected override void OnLoad(EventArgs e) { @@ -25,5 +37,21 @@ namespace SM2D GL.Disable(EnableCap.DepthTest); base.OnRenderFrame(e); } + + protected override void SetWorldScale() + { + if (Scaling.HasValue) + { + if (Scaling.Value.X > 0 && Scaling.Value.Y > 0) _worldScale = Scaling.Value; + else if (Scaling.Value.X > 0) _worldScale = new Vector2(Scaling.Value.X, Scaling.Value.X / Aspect); + else if (Scaling.Value.Y > 0) _worldScale = new Vector2(Aspect * Scaling.Value.Y, Scaling.Value.Y); + } + } + + protected override void OnMouseMove(MouseMoveEventArgs e) + { + base.OnMouseMove(e); + Mouse.MouseMoveEvent(e); + } } } \ No newline at end of file diff --git a/SMCode/SM2D/Object/Polygon.cs b/SMCode/SM2D/Object/Polygon.cs index 999aa18..0077eb2 100644 --- a/SMCode/SM2D/Object/Polygon.cs +++ b/SMCode/SM2D/Object/Polygon.cs @@ -58,5 +58,19 @@ namespace SM2D.Object Vector2 uv = Vector2.Divide(vertex, BoundingBox.Max.Xy) + BoundingBox.Min.Xy; UVs.Add(uv); } + + public static Polygon GenerateCircle(int secments = 32) + { + List vertices = new List() {Vector2.Zero}; + + float step = 360f / secments; + for (int i = 0; i < secments + 1; i++) + { + Vector2 vertex = new Vector2( 0.5f * (float)Math.Cos(step * i * Math.PI / 180f), 0.5f * (float)Math.Sin(step * i * Math.PI / 180f)); + vertices.Add(vertex); + } + + return new Polygon(vertices); + } } } \ No newline at end of file diff --git a/SMCode/SM2D/SM2D.csproj b/SMCode/SM2D/SM2D.csproj index 4284ee1..9484dd6 100644 --- a/SMCode/SM2D/SM2D.csproj +++ b/SMCode/SM2D/SM2D.csproj @@ -45,6 +45,7 @@ + diff --git a/SMCode/SM2D/Types/Transformation.cs b/SMCode/SM2D/Types/Transformation.cs index 1f8b74d..980c53a 100644 --- a/SMCode/SM2D/Types/Transformation.cs +++ b/SMCode/SM2D/Types/Transformation.cs @@ -9,13 +9,12 @@ namespace SM2D.Types public Vector2 Position = new Vector2(0); public Vector2 Size = new Vector2(50); public float Rotation; - public int ZIndex = 0; public override Matrix4 GetMatrix() { return Matrix4.CreateScale(Size.X, Size.Y, 1) * Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(Rotation)) * - Matrix4.CreateTranslation(Position.X, Position.Y, ZIndex); + Matrix4.CreateTranslation(Position.X, Position.Y, 0); } } } \ No newline at end of file diff --git a/SM_TEST/Program.cs b/SM_TEST/Program.cs index a24f552..a898f54 100644 --- a/SM_TEST/Program.cs +++ b/SM_TEST/Program.cs @@ -17,6 +17,8 @@ namespace SM_TEST static Scene scene; private static Font font; private static ItemCollection col; + private static DrawPolygon polyogn; + private static GLWindow2D window; static void Main(string[] args) { font = new Font(@"C:\Windows\Fonts\Arial.ttf") @@ -24,18 +26,17 @@ namespace SM_TEST FontSize = 32 }; - GLWindow2D window = new GLWindow2D {Scaling = new Vector2(0, 1000)}; + window = new GLWindow2D {Scaling = new Vector2(0, 1000)}; + window.GrabCursor(); window.SetScene(scene = new Scene()); window.Load += WindowOnLoad; - window.UpdateFrame += WindowOnUpdateFrame; + window.RenderFrame += WindowOnUpdateFrame; window.Run(); } private static void WindowOnUpdateFrame(object sender, FrameEventArgs e) { - float speed = 40; - - //col.Transform.Position.Y += (float)e.Time * speed; + polyogn.Transform.Position.Set(window.Mouse.InWorld(window.ViewportCamera)); } private static void WindowOnLoad(object sender, EventArgs e) @@ -53,6 +54,7 @@ namespace SM_TEST col.Objects.Add(new DrawColor(Color4.Black) { Transform = { Rotation = 45, Position = new SM.Base.Types.Vector2(0, 25) }, + ZIndex = 2 }); scene.Objects.Add(col); @@ -62,18 +64,7 @@ namespace SM_TEST Color = Color4.Black }); - scene.Objects.Add(new DrawPolygon(new Polygon(new[] - { - new Vector2(.25f, 0), - new Vector2(.75f, 0), - new Vector2(1, .25f), - new Vector2(1, .75f), - new Vector2(.75f, 1), - new Vector2(.25f, 1), - new Vector2(0, .75f), - new Vector2(0, .25f) - }),Color4.Blue) - ); + scene.Objects.Add(polyogn = new DrawPolygon(Polygon.GenerateCircle(),Color4.Blue)); scene.Objects.Add(new DrawPolygon(new Polygon(new[] { new PolygonVertex(new Vector2(.25f, 0), Color4.White),