28.10.2020

SM.Core:
+ Particle System
+ scriptable system for scripts

~ Moved Texts- and Particles-namespace to SM.Base.Drawing
~ Changed how you tell the stopwatch to pause. (From method to property)
~ Fixed Randomize.GetFloat(min, max)
~ Now automaticly adds the DrawingBase.Transformation to DrawContext.ModelMatrix. No need to change DrawContext.Instances[0], anymore.

SM.OGL:
+ "one-file-shader"-support

SM2D:
+ DrawParticles (Control for Texture and Color not there yet)

~ Changed coordnate system to upper-right as (1,1)
~ Changed default shader to "one-file-shader"
This commit is contained in:
Michel Fedde 2020-10-28 18:19:15 +01:00
parent 03b3942732
commit beb9c19081
45 changed files with 580 additions and 190 deletions

View file

@ -2,11 +2,12 @@
using System.Collections.Generic;
using SM.Base.Contexts;
using SM.Base.Scene;
using SM.OGL.Mesh;
#endregion
namespace SM.Base.Scene
namespace SM.Base.Drawing
{
/// <summary>
/// Contains general basis systems for drawing objects.
@ -31,12 +32,7 @@ namespace SM.Base.Scene
/// <inheritdoc />
public ICollection<string> Flags { get; set; }
/// <inheritdoc />
public virtual void Update(UpdateContext context)
{
}
/// <inheritdoc />
public void Draw(DrawContext context)
{
@ -76,5 +72,11 @@ namespace SM.Base.Scene
/// The current transformation.
/// </summary>
public TTransformation Transform = new TTransformation();
/// <inheritdoc />
protected override void DrawContext(ref DrawContext context)
{
context.ModelMaster = Transform.GetMatrix();
}
}
}

View file

@ -4,7 +4,7 @@ using OpenTK;
#endregion
namespace SM.Base.Scene
namespace SM.Base.Drawing
{
/// <summary>
/// Contains methods for using transformations right.

View file

@ -4,26 +4,26 @@ using OpenTK;
#endregion
namespace SM.Base.Scene
namespace SM.Base.Drawing
{
/// <summary>
/// This represens a drawing instance.
/// </summary>
public struct Instance
public class Instance
{
/// <summary>
/// The model matrix.
/// </summary>
public Matrix4 ModelMatrix;
public Matrix4 ModelMatrix = Matrix4.Identity;
/// <summary>
/// The texture offset.
/// </summary>
public Vector2 TexturePosition;
public Vector2 TexturePosition = Vector2.Zero;
/// <summary>
/// The texture scale.
/// </summary>
public Vector2 TextureScale;
public Vector2 TextureScale = Vector2.One;
}
}

View file

@ -5,7 +5,7 @@ using SM.OGL.Texture;
#endregion
namespace SM.Base.Scene
namespace SM.Base.Drawing
{
/// <summary>
/// Represents a material.

View file

@ -6,24 +6,29 @@ using SM.OGL.Shaders;
#endregion
namespace SM.Base.Scene
namespace SM.Base.Drawing
{
/// <summary>
/// A general class to work with material shaders properly.
/// </summary>
public abstract class MaterialShader : GenericShader
{
/// <inheritdoc />
protected MaterialShader(string combinedData) : base(combinedData)
{}
/// <inheritdoc />
protected MaterialShader(string vertex, string fragment) : base(vertex, fragment)
{
}
/// <inheritdoc />
protected MaterialShader(ShaderFileCollection shaderFileFiles) : base(shaderFileFiles)
{
}
/// <summary>
/// Draws the context.
/// Prepares the context for the drawing.
/// </summary>
/// <param name="context">The context</param>
public virtual void Draw(DrawContext context)
@ -39,6 +44,10 @@ namespace SM.Base.Scene
GL.UseProgram(0);
}
/// <summary>
/// Draws the context.
/// </summary>
/// <param name="context"></param>
protected virtual void DrawProcess(DrawContext context)
{

View file

@ -0,0 +1,19 @@
using SM.Base.Time;
namespace SM.Base.Drawing.Particles
{
/// <summary>
/// A context, with that the particle system sends the information for the movement function.
/// </summary>
public struct ParticleContext
{
/// <summary>
/// The Timer of the particles
/// </summary>
public Timer Timer;
/// <summary>
/// The current speed of the particles.
/// </summary>
public float Speed;
}
}

View file

@ -0,0 +1,126 @@
using System;
using System.Collections.Generic;
using OpenTK;
using SM.Base.Contexts;
using SM.Base.Scene;
using SM.Base.Time;
using SM.Base.Types;
using SM.OGL.Shaders;
namespace SM.Base.Drawing.Particles
{
/// <summary>
/// The (drawing) basis for particles
/// </summary>
public abstract class ParticleDrawingBasis<TTransform, TDirection> : DrawingBasis<TTransform>, IScriptable
where TTransform : GenericTransformation, new()
where TDirection : struct
{
/// <summary>
/// This contains all important information for each particle.
/// </summary>
protected ParticleStruct<TDirection>[] particleStructs;
/// <summary>
/// This contains the different instances for the particles.
/// </summary>
protected List<Instance> instances;
/// <summary>
/// The stopwatch of the particles.
/// </summary>
protected Timer timer;
/// <summary>
/// The amount of particles
/// </summary>
public int Amount = 32;
/// <summary>
/// The maximum speed of the particles
/// </summary>
public float MaxSpeed = 1;
/// <summary>
/// Get/Sets the state of pausing.
/// </summary>
public bool Paused
{
get => timer.Paused;
set => timer.Paused = value;
}
/// <summary>
/// Controls the movement of each particles.
/// </summary>
public abstract Func<TDirection, ParticleContext, TDirection> MovementCalculation { get; set; }
protected ParticleDrawingBasis(TimeSpan duration)
{
timer = new Timer(duration);
}
/// <summary>
/// Triggers the particles.
/// </summary>
public void Trigger()
{
timer.Start();
CreateParticles();
}
/// <inheritdoc />
public void Update(UpdateContext context)
{
if (!timer.Running) return;
ParticleContext particleContext = new ParticleContext()
{
Timer = timer,
};
for (int i = 0; i < Amount; i++)
{
particleContext.Speed = particleStructs[i].Speed;
instances[i].ModelMatrix = CreateMatrix(particleStructs[i], MovementCalculation(particleStructs[i].Direction, particleContext));
}
}
/// <inheritdoc />
protected override void DrawContext(ref DrawContext context)
{
if (!timer.Active) return;
base.DrawContext(ref context);
context.Instances = instances;
context.Shader.Draw(context);
}
/// <summary>
/// Creates the particles.
/// </summary>
protected virtual void CreateParticles()
{
particleStructs = new ParticleStruct<TDirection>[Amount];
instances = new List<Instance>();
for (int i = 0; i < Amount; i++)
{
particleStructs[i] = CreateObject(i);
instances.Add(new Instance());
}
}
/// <summary>
/// Creates a particle.
/// </summary>
protected abstract ParticleStruct<TDirection> CreateObject(int index);
/// <summary>
/// Generates the desired matrix for drawing.
/// </summary>
protected abstract Matrix4 CreateMatrix(ParticleStruct<TDirection> Struct, TDirection relativePosition);
}
}

View file

@ -0,0 +1,19 @@
using OpenTK;
namespace SM.Base.Drawing.Particles
{
/// <summary>
/// Contains methods for particle movements.
/// </summary>
public class ParticleMovement
{
/// <summary>
/// Default movement for 2D.
/// </summary>
public static Vector2 Default2D(Vector2 direction, ParticleContext context) => direction * (context.Timer.Elapsed * context.Speed);
/// <summary>
/// Default movement for 3D.
/// </summary>
public static Vector3 Default3D(Vector3 direction, ParticleContext context) => direction * (context.Timer.Elapsed * context.Speed);
}
}

View file

@ -0,0 +1,25 @@
using OpenTK;
using SM.Base.Types;
namespace SM.Base.Drawing.Particles
{
/// <summary>
/// A particle...
/// </summary>
public struct ParticleStruct<TDirection>
where TDirection : struct
{
/// <summary>
/// A direction, that the particle should travel.
/// </summary>
public TDirection Direction;
/// <summary>
/// A matrix to store rotation and scale.
/// </summary>
public Matrix4 Matrix;
/// <summary>
/// Speeeeeeeeeed
/// </summary>
public float Speed;
}
}

View file

@ -4,7 +4,7 @@ using System;
#endregion
namespace SM.Base.Text
namespace SM.Base.Drawing.Text
{
/// <summary>
/// Contains information for a font character.

View file

@ -5,11 +5,10 @@ using System.Drawing;
using System.Drawing.Text;
using OpenTK.Graphics.OpenGL4;
using SM.Base.Textures;
using SM.Data.Fonts;
#endregion
namespace SM.Base.Text
namespace SM.Base.Drawing.Text
{
/// <summary>
/// Represents a font.

View file

@ -1,4 +1,4 @@
namespace SM.Data.Fonts
namespace SM.Base.Drawing.Text
{
/// <summary>
/// Contains default char sets.

View file

@ -4,11 +4,10 @@ using System;
using OpenTK;
using OpenTK.Graphics;
using SM.Base.Contexts;
using SM.Base.Scene;
#endregion
namespace SM.Base.Text
namespace SM.Base.Drawing.Text
{
/// <summary>
/// Defines a basis for text drawing.

View file

@ -8,20 +8,33 @@ using SM.Utility;
namespace SM.Base.PostProcess
{
/// <summary>
/// Specific shader for post processing.
/// </summary>
public class PostProcessShader : GenericShader
{
private static ShaderFile _fragExtensions = new ShaderFile(AssemblyUtility.ReadAssemblyFile("SM.Base.PostProcess.DefaultFiles.extensions.frag"));
private static ShaderFile _normalVertex = new ShaderFile(AssemblyUtility.ReadAssemblyFile("SM.Base.PostProcess.DefaultFiles.vertexFile.vert"));
private static string _normalVertexWithExt =
private static readonly ShaderFile _fragExtensions = new ShaderFile(AssemblyUtility.ReadAssemblyFile("SM.Base.PostProcess.DefaultFiles.extensions.frag"));
private static readonly ShaderFile _normalVertex = new ShaderFile(AssemblyUtility.ReadAssemblyFile("SM.Base.PostProcess.DefaultFiles.vertexFile.vert"));
private static readonly string _normalVertexWithExt =
AssemblyUtility.ReadAssemblyFile("SM.Base.PostProcess.DefaultFiles.vertexWithExt.vert");
/// <summary>
/// Creates the shader with the default vertex shader and custom fragment.
/// </summary>
public PostProcessShader(string fragment) : this(_normalVertex,
new ShaderFile(fragment)) { }
new ShaderFile(fragment))
{ }
/// <summary>
/// Creates the shader with an vertex extension and custom fragment.
/// </summary>
/// <param name="vertexExt"></param>
/// <param name="fragment"></param>
public PostProcessShader(string vertexExt, string fragment) : this(new ShaderFile(_normalVertexWithExt)
{
GLSLExtensions = new List<ShaderFile>() { new ShaderFile(vertexExt) }
}, new ShaderFile(fragment)) { }
}, new ShaderFile(fragment))
{ }
private PostProcessShader(ShaderFile vertex, ShaderFile fragment) : base(
new ShaderFileCollection(vertex, fragment))
@ -29,6 +42,10 @@ namespace SM.Base.PostProcess
fragment.GLSLExtensions.Add(_fragExtensions);
}
/// <summary>
/// Draws the shader without special uniforms.
/// </summary>
/// <param name="color"></param>
public void Draw(ColorAttachment color)
{
GL.UseProgram(this);
@ -44,6 +61,11 @@ namespace SM.Base.PostProcess
GL.UseProgram(0);
}
/// <summary>
/// Draws the shader with special uniforms.
/// </summary>
/// <param name="color"></param>
/// <param name="setUniformAction"></param>
public void Draw(ColorAttachment color, Action<UniformCollection> setUniformAction)
{
GL.UseProgram(this);

View file

@ -50,10 +50,15 @@
<Compile Include="Drawing\GenericTransformation.cs" />
<Compile Include="Drawing\Instance.cs" />
<Compile Include="Drawing\MaterialShader.cs" />
<Compile Include="Drawing\Particles\ParticleContext.cs" />
<Compile Include="Drawing\Particles\ParticleMovement.cs" />
<Compile Include="Drawing\Particles\ParticleStruct.cs" />
<Compile Include="Drawing\Particles\ParticleDrawingBasis.cs" />
<Compile Include="Log.cs" />
<Compile Include="Objects\Mesh.cs" />
<Compile Include="PostProcess\PostProcessEffect.cs" />
<Compile Include="PostProcess\PostProcessShader.cs" />
<Compile Include="Scene\IScriptable.cs" />
<Compile Include="Scene\IShowCollection.cs" />
<Compile Include="Scene\IShowItem.cs" />
<Compile Include="Drawing\Material.cs" />
@ -62,10 +67,10 @@
<Compile Include="ShaderExtension\ExtensionManager.cs" />
<Compile Include="SMRenderer.cs" />
<Compile Include="Textures\Texture.cs" />
<Compile Include="Text\CharParameter.cs" />
<Compile Include="Text\Font.cs" />
<Compile Include="Text\FontCharStorage.cs" />
<Compile Include="Text\TextDrawingBasis.cs" />
<Compile Include="Drawing\Text\CharParameter.cs" />
<Compile Include="Drawing\Text\Font.cs" />
<Compile Include="Drawing\Text\FontCharStorage.cs" />
<Compile Include="Drawing\Text\TextDrawingBasis.cs" />
<Compile Include="Time\Interval.cs" />
<Compile Include="Time\Stopwatch.cs" />
<Compile Include="Time\Timer.cs" />

View file

@ -1,8 +1,9 @@
#region usings
using SM.Base.Drawing;
using SM.Base.Drawing.Text;
using SM.Base.Objects.Static;
using SM.Base.Scene;
using SM.Base.Text;
using SM.OGL.Mesh;
using SM.OGL.Shaders;
using SM.Utility;
@ -36,6 +37,9 @@ namespace SM.Base
/// </summary>
public static Deltatime DefaultDeltatime = new Deltatime();
/// <summary>
/// The default material shader.
/// </summary>
public static MaterialShader DefaultMaterialShader;
/// <summary>
@ -48,7 +52,9 @@ namespace SM.Base
/// </summary>
public static ulong CurrentFrame { get; internal set; } = 0;
public static GenericWindow CurrentWindow;
public static GenericScene CurrentScene;
/// <summary>
/// Represents the current active window.
/// </summary>
public static GenericWindow CurrentWindow { get; internal set; }
}
}

View file

@ -1,7 +1,9 @@
#region usings
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SM.Base.Contexts;
using SM.Base.Drawing;
#endregion
@ -11,9 +13,15 @@ namespace SM.Base.Scene
/// Contains a list of show items.
/// </summary>
/// <typeparam name="TItem">The type of show items.</typeparam>
public abstract class GenericItemCollection<TItem> : List<TItem>, IShowItem, IShowCollection<TItem>
public abstract class GenericItemCollection<TItem> : List<TItem>, IShowItem, IShowCollection<TItem>, IScriptable
where TItem : IShowItem
{
private List<IScriptable> _scriptableObjects = new List<IScriptable>();
/// <summary>
/// Currently active script objects.
/// </summary>
public ReadOnlyCollection<IScriptable> ScriptableObjects => new ReadOnlyCollection<IScriptable>(_scriptableObjects);
/// <inheritdoc />
public List<TItem> Objects => this;
@ -24,18 +32,20 @@ namespace SM.Base.Scene
public string Name { get; set; } = "Unnamed Item Collection";
/// <inheritdoc />
public ICollection<string> Flags { get; set; } = new[] {"collection"};
public ICollection<string> Flags { get; set; } = new List<string>() {"collection"};
/// <inheritdoc />
public virtual void Update(UpdateContext context)
{
for (var i = 0; i < Objects.Count; i++)
this[i].Update(context);
for (var i = 0; i < _scriptableObjects.Count; i++)
_scriptableObjects[i].Update(context);
}
/// <inheritdoc cref="IShowCollection{TItem}.Draw" />
public virtual void Draw(DrawContext context)
{
context.LastPassthough = this;
for (var i = 0; i < Objects.Count; i++)
this[i].Draw(context);
}
@ -51,26 +61,68 @@ namespace SM.Base.Scene
}
/// <summary>
/// Adds a item.
/// Adds a item to the draw and the script collection, when applicable.
/// </summary>
public new void Add(TItem item)
{
AddObject(item);
if (item is IScriptable scriptable)
AddScript(scriptable);
}
/// <summary>
/// Adds the object to the collection.
/// </summary>
/// <param name="item"></param>
public void AddObject(TItem item)
{
base.Add(item);
item.Parent = this;
item.OnAdded(this);
}
/// <summary>
/// Adds the script to the collection.
/// </summary>
/// <param name="item"></param>
public void AddScript(IScriptable item)
{
_scriptableObjects.Add(item);
}
/// <summary>
/// Removes a item.
/// Removes a item from the draw and script collection, when applicable.
/// </summary>
/// <param name="item"></param>
public new void Remove(TItem item)
{
RemoveObject(item);
if (item.GetType().IsAssignableFrom(typeof(IScriptable)))
RemoveScript((IScriptable)item);
}
/// <summary>
/// Remove the object from the draw collection.
/// </summary>
/// <param name="item"></param>
public void RemoveObject(TItem item)
{
base.Remove(item);
item.Parent = null;
item.OnRemoved(this);
}
/// <summary>
/// Remove the object from the script collection.
/// </summary>
/// <param name="item"></param>
public void RemoveScript(IScriptable item)
{
_scriptableObjects.Remove(item);
}
/// <summary>
/// Returns a object with this name or the default, if not available.
/// <para>Not reclusive.</para>
@ -111,6 +163,7 @@ namespace SM.Base.Scene
for (var i = 0; i < Count; i++)
{
var obj = this[i];
if (obj.Flags == null) continue;
if (obj.Flags.Contains(flag)) list.Add(obj);
}

View file

@ -13,6 +13,8 @@ namespace SM.Base.Scene
/// </summary>
public abstract class GenericScene
{
private IBackgroundItem _background;
/// <summary>
@ -27,6 +29,9 @@ namespace SM.Base.Scene
_background = value;
}
}
/// <summary>
/// If true, the scene was already initialized.
/// </summary>
public bool IsInitialized { get; private set; }
/// <summary>
@ -137,7 +142,6 @@ namespace SM.Base.Scene
/// <inheritdoc />
public override void Update(UpdateContext context)
{
_Background?.Update(context);
_objectCollection.Update(context);
_hud.Update(context);
}

View file

@ -0,0 +1,15 @@
using SM.Base.Contexts;
namespace SM.Base.Scene
{
/// <summary>
/// Defines a object as script.
/// </summary>
public interface IScriptable
{
/// <summary>
/// Updates the object.
/// </summary>
void Update(UpdateContext context);
}
}

View file

@ -26,13 +26,7 @@ namespace SM.Base.Scene
/// Contains specific flags for the object.
/// </summary>
ICollection<string> Flags { get; set; }
/// <summary>
/// Tells the object to update own systems.
/// </summary>
/// <param name="context">The update context</param>
void Update(UpdateContext context);
/// <summary>
/// Tells the object to draw its object.
/// </summary>

View file

@ -28,26 +28,7 @@ namespace SM.Base.Time
protected override void Stopping(UpdateContext context)
{
TriggerEndAction(context);
if (_stop)
base.Stop();
else Reset();
}
/// <summary>
/// This will tell the interval to stop after the next iteration.
/// <para>To stop immediately use <see cref="Cancel" /></para>
/// </summary>
public override void Stop()
{
_stop = true;
}
/// <summary>
/// This will stop the interval immediately.
/// </summary>
public void Cancel()
{
base.Stop();
Reset();
}
}
}

View file

@ -1,5 +1,6 @@
#region usings
using System;
using System.Collections.Generic;
using SM.Base.Contexts;
@ -13,20 +14,47 @@ namespace SM.Base.Time
public class Stopwatch
{
private static List<Stopwatch> _activeStopwatches = new List<Stopwatch>();
private bool _paused = false;
public bool Active { get; private set; } = false;
public bool Paused
{
get => _paused;
set
{
if (value)
Pause();
else
Resume();
}
}
public bool Running => Active && !Paused;
/// <summary>
/// Contains how much time already has passed. (in seconds)
/// </summary>
public float Elapsed { get; private set; }
public float Elapsed { get; protected set; }
/// <summary>
/// Contains the TimeSpan of how much time already passed.
/// </summary>
public TimeSpan ElapsedSpan { get; protected set; }
/// <summary>
/// Starts the stopwatch.
/// </summary>
public virtual void Start()
{
if (Active) return;
_activeStopwatches.Add(this);
Active = true;
}
/// <summary>
/// Performs a tick.
/// </summary>
@ -34,6 +62,23 @@ namespace SM.Base.Time
private protected virtual void Tick(UpdateContext context)
{
Elapsed += context.Deltatime;
ElapsedSpan = TimeSpan.FromSeconds(Elapsed);
}
/// <summary>
/// Resumes the timer.
/// </summary>
protected virtual void Resume()
{
_paused = false;
}
/// <summary>
/// Pauses the timer.
/// </summary>
protected virtual void Pause()
{
_paused = true;
}
/// <summary>
@ -41,6 +86,9 @@ namespace SM.Base.Time
/// </summary>
public virtual void Stop()
{
if (!Active) return;
Active = false;
_activeStopwatches.Remove(this);
}
@ -54,7 +102,11 @@ namespace SM.Base.Time
internal static void PerformTicks(UpdateContext context)
{
for (var i = 0; i < _activeStopwatches.Count; i++) _activeStopwatches[i].Tick(context);
for (var i = 0; i < _activeStopwatches.Count; i++)
{
if (_activeStopwatches[i].Paused) continue;
_activeStopwatches[i].Tick(context);
}
}
}
}

View file

@ -65,7 +65,7 @@ namespace SM.Base.Time
/// </summary>
protected virtual void Stopping(UpdateContext context)
{
EndAction?.Invoke(this, context);
TriggerEndAction(context);
Stop();
}

View file

@ -73,6 +73,9 @@ namespace SM.Base.Types
base.Add(vector);
}
/// <summary>
/// Converts a <see cref="OpenTK.Vector2"/> to <see cref="CVector2"/>
/// </summary>
public static implicit operator CVector2(Vector2 v) => new CVector2(v.X,v.Y);
}
}

View file

@ -1,6 +1,9 @@
#region usings
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
#endregion
@ -9,7 +12,7 @@ namespace SM.Utility
/// <summary>
/// A global helper class for randomization.
/// </summary>
public class Randomize
public static class Randomize
{
/// <summary>
/// The randomizer.
@ -78,7 +81,12 @@ namespace SM.Utility
/// </summary>
public static float GetFloat(float min, float max)
{
return (float) Randomizer.NextDouble() * max + min;
return (float) Randomizer.NextDouble() * (max - min) + min;
}
public static TSource GetRandomItem<TSource>(this IList<TSource> list)
{
return list[GetInt(0, list.Count - 1)];
}
}
}

View file

@ -1,6 +1,8 @@
#region usings
using System.Collections.Generic;
using OpenTK;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM.OGL.Mesh;
@ -28,6 +30,11 @@ namespace SM.Base.Contexts
/// </summary>
public Matrix4 View;
/// <summary>
/// The current WorldView matrix.
/// </summary>
public Matrix4 WorldView;
/// <summary>
/// The master model matrix.
/// </summary>
@ -37,7 +44,7 @@ namespace SM.Base.Contexts
/// The drawing instances.
/// <para>If there is only one, it's index 0</para>
/// </summary>
public Instance[] Instances;
public IList<Instance> Instances;
/// <summary>
/// The mesh.
@ -59,6 +66,11 @@ namespace SM.Base.Contexts
/// </summary>
public Vector2 WorldScale;
/// <summary>
/// The last collection the context was passed though.
/// </summary>
public object LastPassthough;
/// <summary>
/// Returns the appropriate shader.
/// <para>

View file

@ -8,6 +8,7 @@ using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Input;
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Objects.Static;
using SM.Base.PostProcess;
using SM.Base.Scene;
@ -38,6 +39,12 @@ namespace SM.Base
/// </summary>
public float Aspect { get; private set; }
/// <summary>
/// If false, the window will not react on updates and will not render something.
/// <para>
/// Default: false
/// </para>
/// </summary>
public bool ReactWhileUnfocused = false;
/// <inheritdoc />
@ -45,6 +52,9 @@ namespace SM.Base
{
}
/// <summary>
/// Creates a window...
/// </summary>
protected GenericWindow(int width, int height, string title, GameWindowFlags flags, bool vSync = true) : base(width, height,
GraphicsMode.Default, title, flags, DisplayDevice.Default, GLSettings.ForcedVersion.MajorVersion,
GLSettings.ForcedVersion.MinorVersion, GraphicsContextFlags.Default)
@ -56,6 +66,8 @@ namespace SM.Base
/// <inheritdoc />
protected override void OnLoad(EventArgs e)
{
SMRenderer.CurrentWindow = this;
GLSystem.INIT_SYSTEM();
GLSettings.ShaderPreProcessing = true;
@ -251,7 +263,8 @@ namespace SM.Base
},
Mesh = Plate.Object,
ForceViewport = ForceViewportCamera,
WorldScale = _worldScale
WorldScale = _worldScale,
LastPassthough = this
};
base.OnRenderFrame(e);

View file

@ -3,6 +3,7 @@
using System.Collections.Generic;
using System.Threading;
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM.OGL.Framebuffer;

View file

@ -1,5 +1,7 @@
#region usings
using System;
using System.Linq;
using OpenTK.Graphics.OpenGL4;
using SM.OGL.Mesh;
@ -24,6 +26,46 @@ namespace SM.OGL.Shaders
/// </summary>
protected UniformCollection Uniforms;
protected GenericShader(string combinedData)
{
int firstPos = combinedData.IndexOf("//# region ", StringComparison.Ordinal);
string header = combinedData.Substring(0, firstPos);
int regionAmount = combinedData.Split(new string[] {"//# region "}, StringSplitOptions.None).Length - 1;
int pos = firstPos + 10;
string vertex = "";
string geometry = "";
string fragment = "";
for (int i = 0; i < regionAmount; i++)
{
int posOfBreak = combinedData.IndexOf("\n", pos, StringComparison.Ordinal);
string name = combinedData.Substring(pos, posOfBreak - pos).Trim();
int nextPos = i == regionAmount - 1 ? combinedData.Length : combinedData.IndexOf("//# region ", posOfBreak, StringComparison.Ordinal);
string data = header + combinedData.Substring(posOfBreak, nextPos - posOfBreak);
pos = nextPos + 10;
switch (name)
{
case "vertex":
vertex = data.Replace("vmain()", "main()");
break;
case "geometry":
geometry = data.Replace("gmain()", "main()");
break;
case "fragment":
fragment = data.Replace("fmain()", "main()");
break;
}
}
Console.WriteLine();
ShaderFileFiles = new ShaderFileCollection(vertex,fragment, geometry);
}
protected GenericShader(string vertex, string fragment) : this(new ShaderFileCollection(vertex, fragment)){}
/// <inheritdoc />
@ -47,8 +89,7 @@ namespace SM.OGL.Shaders
Name(GetType().Name);
ShaderFileFiles.Detach(this);
Uniforms = new UniformCollection();
Uniforms.ParentShader = this;
Uniforms = new UniformCollection {ParentShader = this};
Uniforms.Import(this);
GLDebugging.CheckGLErrors($"A error occured at shader creation for '{GetType()}': %code%");

View file

@ -31,8 +31,8 @@ namespace SM.OGL.Shaders
/// </summary>
/// <param name="vertex">The vertex source file.</param>
/// <param name="fragment">The fragment source file.</param>
public ShaderFileCollection(string vertex, string fragment) : this(new ShaderFile(vertex),
new ShaderFile(fragment))
public ShaderFileCollection(string vertex, string fragment, string geometry = "") : this(new ShaderFile(vertex),
new ShaderFile(fragment), geometry != "" ? new ShaderFile(geometry) : null)
{
}

View file

@ -5,6 +5,7 @@ using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Objects.Static;
using SM.Base.Scene;
using SM.Base.Textures;

View file

@ -1,4 +1,5 @@
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM2D.Scene;

View file

@ -2,6 +2,7 @@
using OpenTK.Graphics;
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM2D.Scene;
using SM2D.Types;
@ -31,8 +32,6 @@ namespace SM2D.Drawing
protected override void DrawContext(ref DrawContext context)
{
context.Instances[0].ModelMatrix = Transform.GetMatrix();
context.Shader.Draw(context);
}
}

View file

@ -1,6 +1,7 @@
#region usings
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM.OGL.Mesh;
using SM2D.Scene;
@ -28,7 +29,7 @@ namespace SM2D.Drawing
protected override void DrawContext(ref DrawContext context)
{
context.Instances[0].ModelMatrix = Transform.GetMatrix();
base.DrawContext(ref context);
context.Shader.Draw(context);
}

View file

@ -0,0 +1,34 @@
using System;
using OpenTK;
using SM.Base.Drawing.Particles;
using SM.Utility;
using SM2D.Scene;
using SM2D.Types;
namespace SM2D.Drawing
{
public class DrawParticles : ParticleDrawingBasis<Transformation, Vector2>, I2DShowItem
{
public int ZIndex { get; set; }
public override Func<Vector2, ParticleContext, Vector2> MovementCalculation { get; set; } = ParticleMovement.Default2D;
public DrawParticles(TimeSpan duration) : base(duration)
{
}
protected override ParticleStruct<Vector2> CreateObject(int index)
{
return new ParticleStruct<Vector2>()
{
Matrix = Matrix4.CreateScale(1),
Direction = new Vector2(Randomize.GetFloat(-1, 1), Randomize.GetFloat(-1, 1)),
Speed = Randomize.GetFloat(MaxSpeed)
};
}
protected override Matrix4 CreateMatrix(ParticleStruct<Vector2> Struct, Vector2 direction)
{
return Struct.Matrix * Matrix4.CreateTranslation(direction.X, direction.Y, 0);
}
}
}

View file

@ -1,4 +1,5 @@
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM2D.Scene;
using SM2D.Types;
@ -16,8 +17,7 @@ namespace SM2D.Drawing
protected override void DrawContext(ref DrawContext context)
{
context.Instances[0].ModelMatrix = Transform.GetMatrix();
base.DrawContext(ref context);
_material.CustomShader.Draw(context);
}
}

View file

@ -1,7 +1,7 @@
#region usings
using SM.Base.Contexts;
using SM.Base.Text;
using SM.Base.Drawing.Text;
using SM.Base.Types;
using SM2D.Scene;
using SM2D.Types;
@ -24,9 +24,7 @@ namespace SM2D.Drawing
{
base.DrawContext(ref context);
context.Instances = _instances;
context.View = Transform.GetMatrix() * context.View;
context.Shader.Draw(context);
}
}

View file

@ -44,6 +44,7 @@
<Compile Include="Drawing\DrawBackgroundShader.cs" />
<Compile Include="Drawing\DrawColor.cs" />
<Compile Include="Drawing\DrawComplex.cs" />
<Compile Include="Drawing\DrawParticles.cs" />
<Compile Include="Drawing\DrawPolygon.cs" />
<Compile Include="Drawing\DrawShader.cs" />
<Compile Include="Drawing\DrawText.cs" />
@ -71,13 +72,10 @@
<Name>SM.OGL</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Shader\ShaderFiles\default.frag" />
<EmbeddedResource Include="Shader\ShaderFiles\default.vert" />
</ItemGroup>
<ItemGroup>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<EmbeddedResource Include="Shader\ShaderFiles\default.glsl" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View file

@ -21,7 +21,7 @@ namespace SM2D.Scene
public override void RecalculateWorld(Vector2 world, float aspect)
{
OrthographicWorld =
Matrix4.CreateOrthographicOffCenter(-world.X / 2, world.X / 2, world.Y / 2, -world.Y / 2, 0.1f, 4f);
Matrix4.CreateOrthographic(world.X, world.Y, 0.1f, 100f);
}
}
}

View file

@ -2,6 +2,7 @@
using OpenTK.Graphics.OpenGL4;
using SM.Base.Contexts;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM.OGL.Shaders;
using SM.Utility;
@ -13,12 +14,9 @@ namespace SM2D.Shader
public class Default2DShader : MaterialShader
{
public static Default2DShader MaterialShader = new Default2DShader();
//protected override bool AutoCompile { get; } = true;
private Default2DShader() : base(new ShaderFileCollection(
AssemblyUtility.ReadAssemblyFile("SM2D.Shader.ShaderFiles.default.vert"),
AssemblyUtility.ReadAssemblyFile("SM2D.Shader.ShaderFiles.default.frag")))
private Default2DShader() : base(AssemblyUtility.ReadAssemblyFile("SM2D.Shader.ShaderFiles.default.glsl"))
{
Load();
}
@ -32,7 +30,7 @@ namespace SM2D.Shader
Uniforms.GetArray("Instances").Set((i, uniforms) =>
{
if (i >= context.Instances.Length) return false;
if (i >= context.Instances.Count) return false;
var instance = context.Instances[i];
uniforms["ModelMatrix"].SetMatrix4(instance.ModelMatrix);
@ -46,7 +44,7 @@ namespace SM2D.Shader
Uniforms["Tint"].SetUniform4(context.Material.Tint);
Uniforms["Texture"].SetTexture(context.Material.Texture, Uniforms["UseTexture"]);
DrawObject(context.Mesh, context.Instances.Length);
DrawObject(context.Mesh, context.Instances.Count);
}
}
}

View file

@ -1,15 +0,0 @@
#version 330
in vec2 vTexture;
in vec4 vColor;
uniform vec4 Tint;
uniform bool UseTexture;
uniform sampler2D Texture;
layout(location = 0) out vec4 color;
void main() {
color = vColor * Tint;
if (UseTexture) color *= texture(Texture, vTexture);
}

View file

@ -0,0 +1,29 @@
#version 330
//# region vertex
//# import SM_base_vertex_basic
void ApplyTexModifier();
void CheckVertexColor();
void ApplyModelTransformation();
void vmain() {
ApplyTexModifier();
CheckVertexColor();
ApplyModelTransformation();
}
//# region fragment
in vec2 vTexture;
in vec4 vColor;
uniform vec4 Tint;
uniform bool UseTexture;
uniform sampler2D Texture;
layout(location = 0) out vec4 color;
void fmain() {
color = vColor * Tint;
if (UseTexture) color *= texture(Texture, vTexture);
}

View file

@ -1,12 +0,0 @@
#version 330
//# import SM_base_vertex_basic
void ApplyTexModifier();
void CheckVertexColor();
void ApplyModelTransformation();
void main() {
ApplyTexModifier();
CheckVertexColor();
ApplyModelTransformation();
}

View file

@ -1,6 +1,7 @@
#region usings
using OpenTK;
using SM.Base.Drawing;
using SM.Base.Scene;
using SM.Base.Types;
using SM.Utility;