diff --git a/SMCode/SM.Base/Defaults.cs b/SMCode/SM.Base/Defaults.cs
index cab5f23..5c6e62f 100644
--- a/SMCode/SM.Base/Defaults.cs
+++ b/SMCode/SM.Base/Defaults.cs
@@ -1,6 +1,7 @@
using SM.Base.Objects;
using SM.Base.Objects.Static;
using SM.Base.Scene;
+using SM.Base.Text;
using SM.OGL.Mesh;
using SM.Utility;
@@ -11,15 +12,16 @@ namespace SM.Base
///
public class Defaults
{
- ///
- /// The default shader.
- ///
- public static IShader DefaultShader;
///
/// The default mesh.
///
public static GenericMesh DefaultMesh = Plate.Object;
+ ///
+ /// The default font.
+ ///
+ public static Font DefaultFont;
+
///
/// The default deltatime helper.
///
diff --git a/SMCode/SM.Base/Drawing/DrawingBasis.cs b/SMCode/SM.Base/Drawing/DrawingBasis.cs
index 7594647..a0325f5 100644
--- a/SMCode/SM.Base/Drawing/DrawingBasis.cs
+++ b/SMCode/SM.Base/Drawing/DrawingBasis.cs
@@ -25,20 +25,21 @@ namespace SM.Base.Scene
}
///
- public virtual void Draw(DrawContext context)
+ public void Draw(DrawContext context)
{
+ context.Material = _material;
+ context.Mesh = _mesh;
+
+ DrawContext(ref context);
}
///
- /// Applies the current settings to the context.
+ /// Draws the context, that was given to them.
///
///
- protected void ApplyContext(ref DrawContext context)
+ protected virtual void DrawContext(ref DrawContext context)
{
- _material.Shader ??= Defaults.DefaultShader;
- context.Material = _material;
- context.Mesh = _mesh;
}
}
///
diff --git a/SMCode/SM.Base/Drawing/Material.cs b/SMCode/SM.Base/Drawing/Material.cs
index 7d29edf..839ab4f 100644
--- a/SMCode/SM.Base/Drawing/Material.cs
+++ b/SMCode/SM.Base/Drawing/Material.cs
@@ -18,9 +18,8 @@ namespace SM.Base.Scene
public Color4 Tint = Color4.White;
///
- /// A shader, that is used to draw this material.
- /// Default: Defaults.DefaultShaders
+ /// A custom shader, that is used to draw this material.
///
- public IShader Shader = Defaults.DefaultShader;
+ public IShader CustomShader;
}
}
\ No newline at end of file
diff --git a/SMCode/SM.Base/Log.cs b/SMCode/SM.Base/Log.cs
new file mode 100644
index 0000000..95124d5
--- /dev/null
+++ b/SMCode/SM.Base/Log.cs
@@ -0,0 +1,236 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.IO.Compression;
+using System.Net.Http;
+using System.Windows.Forms;
+using OpenTK.Graphics.OpenGL4;
+using SM.OGL;
+
+namespace SM.Base
+{
+ ///
+ /// Specifies the target.
+ ///
+ [Flags]
+ public enum LogTarget
+ {
+ ///
+ /// No target, will not draw.
+ ///
+ None = 0,
+ ///
+ /// Takes the .
+ ///
+ Default = 1,
+ ///
+ /// Writes the log to the console.
+ ///
+ Console = 2,
+ ///
+ /// Writes the log to the debugger at .
+ ///
+ Debugger = 4,
+ ///
+ /// Writes the log to the specific file.
+ ///
+ File = 8,
+ ///
+ /// Writes the log to every target.
+ ///
+ All = Console | Debugger | File
+ }
+
+ ///
+ /// Preset log types.
+ ///
+ public enum LogType
+ {
+ ///
+ /// Informations. Console Color: Green
+ ///
+ Info,
+ ///
+ /// Warnings. Console Color: Yellow
+ ///
+ Warning,
+ ///
+ /// Error. Console Color: Red
+ ///
+ Error
+ }
+
+ ///
+ /// Contains the system for logging.
+ ///
+ public class Log
+ {
+ private static StreamWriter _logStream;
+ private static bool _init = false;
+
+ ///
+ /// Presets for the log targets.
+ ///
+ public static Dictionary Preset = new Dictionary()
+ {
+ {LogTarget.Console, "[%type%] %msg%"},
+ {LogTarget.Debugger, "[%type%] %msg%"},
+ {LogTarget.File, "<%date%, %time%> [%type%] %msg%"}
+ };
+
+ private static readonly Dictionary Colors = new Dictionary()
+ {
+ {LogType.Info, ConsoleColor.Green},
+ {LogType.Warning, ConsoleColor.Yellow},
+ {LogType.Error, ConsoleColor.Red},
+ };
+
+ ///
+ /// Specified the default target.
+ ///
+ public static LogTarget DefaultTarget = LogTarget.All;
+
+ ///
+ /// Sets the log file. At wish compresses the old file to a zip file.
+ ///
+ /// The path to the log file.
+ /// Path for the compression, if desired.
+ public static void SetLogFile(string path = "sm.log", string compressionFolder = "")
+ {
+ _logStream?.Close();
+
+ if (!_init) Init();
+
+ if (File.Exists(path))
+ {
+ if (compressionFolder != "")
+ {
+ DateTime creation = File.GetLastWriteTime(path);
+ try
+ {
+ using ZipArchive archive =
+ ZipFile.Open(
+ $"{compressionFolder}{Path.DirectorySeparatorChar}{Path.GetFileName(path)}_{creation.Year.ToString() + creation.Month + creation.Day}_{creation.Hour.ToString() + creation.Minute + creation.Second + creation.Millisecond}.zip",
+ ZipArchiveMode.Create);
+ archive.CreateEntryFromFile(path, Path.GetFileName(path));
+ }
+ catch
+ {
+ // ignore
+ }
+ }
+
+ File.Delete(path);
+ }
+
+ _logStream = new StreamWriter(path) {AutoFlush = true};
+
+ Write(LogType.Info, $"Activated new log file. ['{path}']");
+
+ }
+
+ static void Init()
+ {
+ AppDomain.CurrentDomain.UnhandledException += ExceptionHandler;
+ AppDomain.CurrentDomain.DomainUnload += (sender, args) =>
+ {
+ _logStream.WriteLine("Unload application");
+ _logStream.Close();
+ };
+
+ GLDebugging.DebugAction = GLDebugAction;
+ GLDebugging.GlErrorAction = code =>
+ {
+ Write(LogType.Warning, $"A '{code}' GL error occured.");
+ };
+ _init = true;
+ }
+
+ private static void GLDebugAction(DebugSource source, DebugType type, DebugSeverity severity, string msg)
+ {
+ if (type.HasFlag(DebugType.DebugTypeError))
+ {
+ throw new Exception("[GLError] "+msg);
+ }
+ Write(type != DebugType.DontCare ? type.ToString().Substring(9) : "DontCare", ConsoleColor.Gray, msg);
+ }
+
+ [DebuggerStepThrough]
+ private static void ExceptionHandler(object sender, UnhandledExceptionEventArgs e)
+ {
+ Write(e.IsTerminating ? "Terminating Error" : LogType.Error.ToString(), e.IsTerminating ? ConsoleColor.DarkRed : ConsoleColor.Red, e.ExceptionObject);
+
+ if (e.IsTerminating)
+ {
+ MessageBox.Show($"Critical error occured.\n\n{e.ExceptionObject}",
+ $"Terminating Error: {e.ExceptionObject.GetType().Name}");
+ _logStream?.Close();
+ }
+ }
+
+ ///
+ /// Writes multiple lines of the same type to the log.
+ ///
+ public static void Write(LogType type, params T[] values) => Write(type.ToString(), Colors[type], values);
+
+ ///
+ /// Writes multiple lines of the same type to the log.
+ ///
+ public static void Write(string type, ConsoleColor color, params T[] values)
+ {
+ for (var i = 0; i < values.Length; i++)
+ {
+ Write(type, color, values[i], DefaultTarget);
+ }
+ }
+
+ ///
+ /// Writes one line to the log.
+ ///
+ public static void Write(LogType type, T value, LogTarget target = LogTarget.Default) =>
+ Write(type.ToString(), Colors[type], value, target);
+
+ ///
+ /// Writes one line to the log.
+ ///
+ ///
+ public static void Write(string type, ConsoleColor color, T value, LogTarget target = LogTarget.Default)
+ {
+ if (target == LogTarget.Default)
+ target = DefaultTarget;
+
+ if (target.HasFlag(LogTarget.Console))
+ ColorfulWriteLine(color, ProcessPreset(LogTarget.Console, type, value.ToString()));
+ if (target.HasFlag(LogTarget.Debugger))
+ Debug.WriteLine(ProcessPreset(LogTarget.Debugger, type, value.ToString()));
+ if (target.HasFlag(LogTarget.File))
+ _logStream?.WriteLine(ProcessPreset(LogTarget.File, type, value.ToString()));
+ }
+
+ ///
+ /// Writes a text with a different color.
+ ///
+ ///
+ ///
+ public static void ColorfulWriteLine(ConsoleColor color, string value)
+ {
+ ConsoleColor before = Console.ForegroundColor;
+
+ Console.ForegroundColor = color;
+ Console.WriteLine(value);
+ Console.ForegroundColor = before;
+ }
+
+ static string ProcessPreset(LogTarget target, string type, string msg)
+ {
+ string preset = Preset[target];
+ DateTime now = DateTime.Now;
+
+ return preset.Replace("%date%", now.ToShortDateString())
+ .Replace("%time%", now.ToShortTimeString())
+ .Replace("%type%", type)
+ .Replace("%msg%", msg);
+ }
+ }
+}
\ No newline at end of file
diff --git a/SMCode/SM.Base/SM.Base.csproj b/SMCode/SM.Base/SM.Base.csproj
index 4c63000..1810f80 100644
--- a/SMCode/SM.Base/SM.Base.csproj
+++ b/SMCode/SM.Base/SM.Base.csproj
@@ -40,6 +40,9 @@
+
+
+
@@ -54,6 +57,7 @@
+
@@ -82,6 +86,7 @@
+
diff --git a/SMCode/SM.Base/Scene/GenericCamera.cs b/SMCode/SM.Base/Scene/GenericCamera.cs
index e6d3887..441b0a9 100644
--- a/SMCode/SM.Base/Scene/GenericCamera.cs
+++ b/SMCode/SM.Base/Scene/GenericCamera.cs
@@ -54,7 +54,7 @@ namespace SM.Base.Scene
public abstract bool Orthographic { get; }
///
/// This will calculate the world.
- /// This is called on to calculate the world.
+ /// This is called on to calculate the world.
///
/// The world scale
/// The aspect ratio from the window.
diff --git a/SMCode/SM.Base/Scene/GenericItemCollection.cs b/SMCode/SM.Base/Scene/GenericItemCollection.cs
index 84d081f..30f7882 100644
--- a/SMCode/SM.Base/Scene/GenericItemCollection.cs
+++ b/SMCode/SM.Base/Scene/GenericItemCollection.cs
@@ -7,23 +7,24 @@ namespace SM.Base.Scene
/// Contains a list of show items.
///
/// The type of show items.
- public abstract class GenericItemCollection : IShowItem, IShowCollection
+ public abstract class GenericItemCollection : List, IShowItem, IShowCollection
where TItem : IShowItem
{
///
- public List Objects { get; } = new List();
+ public List Objects => this;
///
public void Update(UpdateContext context)
{
- throw new System.NotImplementedException();
+ for(int i = 0; i < Objects.Count; i++)
+ this[i].Update(context);
}
///
public virtual void Draw(DrawContext context)
{
for (int i = 0; i < Objects.Count; i++)
- Objects[i].Draw(context);
+ this[i].Draw(context);
}
}
diff --git a/SMCode/SM.Base/Scene/GenericScene.cs b/SMCode/SM.Base/Scene/GenericScene.cs
index 6b6cdf9..53ed232 100644
--- a/SMCode/SM.Base/Scene/GenericScene.cs
+++ b/SMCode/SM.Base/Scene/GenericScene.cs
@@ -4,13 +4,48 @@ using SM.Base.Contexts;
namespace SM.Base.Scene
{
+ ///
+ /// A generic scene, that imports functions for scene control.
+ ///
+ public abstract class GenericScene
+ {
+ ///
+ /// This contains the background.
+ ///
+ protected IBackgroundItem _background;
+
+ ///
+ /// Draws this scene.
+ ///
+ public virtual void Draw(DrawContext context)
+ {
+
+ }
+
+ ///
+ /// Called, when the user activates the scene.
+ ///
+ internal void Activate()
+ {
+ OnActivating();
+ }
+
+ ///
+ /// Called, when the user activates the scene.
+ ///
+ protected virtual void OnActivating()
+ { }
+ }
+
///
/// A generic scene that imports different functions.
///
/// The type of cameras.
/// The type of show items.
- public abstract class GenericScene : GenericItemCollection
+ /// The type for collections
+ public abstract class GenericScene : GenericScene
where TCamera : GenericCamera, new()
+ where TCollection : GenericItemCollection, new()
where TItem : IShowItem
{
///
@@ -28,13 +63,13 @@ namespace SM.Base.Scene
public TCamera HUDCamera { get; set; } = new TCamera();
///
- /// This contains the background.
+ /// Objects inside the scene.
///
- protected IBackgroundItem _background;
+ public TCollection Objects { get; set; } = new TCollection();
///
/// This defines the HUD objects.
///
- public List HUD { get; } = new List();
+ public TCollection HUD { get; } = new TCollection();
///
/// A collection for cameras to switch easier to different cameras.
///
@@ -49,25 +84,10 @@ namespace SM.Base.Scene
backgroundDrawContext.View = BackgroundCamera.CalculateViewMatrix();
_background?.Draw(backgroundDrawContext);
- base.Draw(context);
+ Objects.Draw(context);
context.View = HUDCamera.CalculateViewMatrix();
- for (int i = 0; i < HUD.Count; i++)
- HUD[i].Draw(context);
+ HUD.Draw(context);
}
-
- ///
- /// Called, when the user activates the scene.
- ///
- internal void Activate()
- {
- OnActivating();
- }
-
- ///
- /// Called, when the user activates the scene.
- ///
- protected virtual void OnActivating()
- { }
}
}
\ No newline at end of file
diff --git a/SMCode/SM.Base/Text/Font.cs b/SMCode/SM.Base/Text/Font.cs
index 4225543..b8cbfd0 100644
--- a/SMCode/SM.Base/Text/Font.cs
+++ b/SMCode/SM.Base/Text/Font.cs
@@ -127,7 +127,7 @@ namespace SM.Base.Text
}
///
- protected override void Compile()
+ public override void Compile()
{
RegenerateTexture();
base.Compile();
diff --git a/SMCode/SM.Base/Text/TextDrawingBasis.cs b/SMCode/SM.Base/Text/TextDrawingBasis.cs
index 66cbfdf..07bd17d 100644
--- a/SMCode/SM.Base/Text/TextDrawingBasis.cs
+++ b/SMCode/SM.Base/Text/TextDrawingBasis.cs
@@ -75,9 +75,8 @@ namespace SM.Base.Text
///
- public override void Draw(DrawContext context)
+ protected override void DrawContext(ref DrawContext context)
{
- base.Draw(context);
if (_instances == null) GenerateMatrixes();
}
diff --git a/SMCode/SM.Base/Textures/Texture.cs b/SMCode/SM.Base/Textures/Texture.cs
index 020d2e7..2fc5a96 100644
--- a/SMCode/SM.Base/Textures/Texture.cs
+++ b/SMCode/SM.Base/Textures/Texture.cs
@@ -46,7 +46,7 @@ namespace SM.Base.Textures
///
- protected override void Compile()
+ public override void Compile()
{
base.Compile();
@@ -54,7 +54,7 @@ namespace SM.Base.Textures
}
///
- protected override void Dispose()
+ public override void Dispose()
{
base.Dispose();
diff --git a/SMCode/SM.Base/Window/Contexts/DrawContext.cs b/SMCode/SM.Base/Window/Contexts/DrawContext.cs
index a25c60e..406eede 100644
--- a/SMCode/SM.Base/Window/Contexts/DrawContext.cs
+++ b/SMCode/SM.Base/Window/Contexts/DrawContext.cs
@@ -38,9 +38,20 @@ namespace SM.Base.Contexts
///
public Material Material;
+ ///
+ /// Contains the currently used render pipeline.
+ ///
+ public RenderPipeline ActivePipeline;
+
///
/// The current world scale.
///
public Vector2 WorldScale;
+
+ ///
+ /// Returns the appropriate shader.
+ /// Returns the material shader, if available, otherwise it will take the default shader from the render pipeline.
+ ///
+ public IShader Shader => Material.CustomShader ?? ActivePipeline._defaultShader;
}
}
\ No newline at end of file
diff --git a/SMCode/SM.Base/Window/GenericWindow.cs b/SMCode/SM.Base/Window/GenericWindow.cs
index 1b92b4f..7aa2751 100644
--- a/SMCode/SM.Base/Window/GenericWindow.cs
+++ b/SMCode/SM.Base/Window/GenericWindow.cs
@@ -41,14 +41,14 @@ namespace SM.Base
{
GLSystem.INIT_SYSTEM();
- Console.Write("----------------------\n" +
- "--- OpenGL Loading ---\n" +
- "----------------------------------\n" +
- $"--- {"DeviceVersion",14}: {GLSystem.DeviceVersion,-10} ---\n" +
- $"--- {"ForcedVersion",14}: {GLSystem.ForcedVersion,-10} ---\n" +
- $"--- {"ShadingVersion",14}: {GLSystem.ShadingVersion,-10} ---\n" +
- $"--- {"Debugging",14}: {GLSystem.Debugging,-10} ---\n" +
- $"----------------------------------\n");
+ Log.Write("#", ConsoleColor.Cyan, "----------------------",
+ "--- OpenGL Loading ---",
+ "----------------------------------",
+ $"--- {"DeviceVersion",14}: {GLSystem.DeviceVersion,-10} ---",
+ $"--- {"ForcedVersion",14}: {GLSystem.ForcedVersion,-10} ---",
+ $"--- {"ShadingVersion",14}: {GLSystem.ShadingVersion,-10} ---",
+ $"--- {"Debugging",14}: {GLSystem.Debugging,-10} ---",
+ $"----------------------------------");
base.OnLoad(e);
_loading = true;
@@ -123,11 +123,9 @@ namespace SM.Base
/// The base window.
///
/// The scene type
- /// The base item type
/// The camera type
- public abstract class GenericWindow : GenericWindow
- where TScene : GenericScene, new()
- where TItem : IShowItem
+ public abstract class GenericWindow : GenericWindow
+ where TScene : GenericScene, new()
where TCamera : GenericCamera, new()
{
///
@@ -144,6 +142,11 @@ namespace SM.Base
///
public TScene CurrentScene { get; private set; }
+ ///
+ /// Controls how a scene is rendered.
+ ///
+ public RenderPipeline RenderPipeline { get; private set; }
+
///
protected GenericWindow()
{
@@ -153,6 +156,7 @@ namespace SM.Base
///
protected override void OnRenderFrame(FrameEventArgs e)
{
+ Deltatime.RenderDelta = (float)e.Time;
DrawContext drawContext = new DrawContext()
{
World = ViewportCamera.World,
@@ -165,11 +169,11 @@ namespace SM.Base
base.OnRenderFrame(e);
- GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
-
- CurrentScene.Draw(drawContext);
+ RenderPipeline.Render(ref drawContext, CurrentScene);
SwapBuffers();
+
+ GLDebugging.CheckGLErrors();
}
///
@@ -178,6 +182,7 @@ namespace SM.Base
base.OnResize(e);
ViewportCamera.RecalculateWorld(_worldScale, Aspect);
+ RenderPipeline.Resize();
}
///
@@ -189,5 +194,15 @@ namespace SM.Base
CurrentScene = scene;
scene.Activate();
}
+
+ ///
+ /// Defines the render pipeline.
+ ///
+ ///
+ public void SetRenderPipeline(RenderPipeline pipeline)
+ {
+ RenderPipeline = pipeline;
+ pipeline.Activate(this);
+ }
}
}
\ No newline at end of file
diff --git a/SMCode/SM.Base/Window/RenderPipeline.cs b/SMCode/SM.Base/Window/RenderPipeline.cs
new file mode 100644
index 0000000..60c5e22
--- /dev/null
+++ b/SMCode/SM.Base/Window/RenderPipeline.cs
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using SM.Base.Contexts;
+using SM.Base.Scene;
+using SM.OGL.Framebuffer;
+
+namespace SM.Base
+{
+ ///
+ /// Definition of specific render options.
+ ///
+ public abstract class RenderPipeline
+ {
+
+ ///
+ /// The framebuffers, that are used in this Pipeline.
+ ///
+ protected virtual List _framebuffers { get; }
+
+ ///
+ /// The default shader for the pipeline.
+ ///
+ protected internal virtual IShader _defaultShader { get; }
+
+ ///
+ /// Occurs, when the window is loading.
+ ///
+ protected internal virtual void Load()
+ {
+ foreach (Framebuffer framebuffer in _framebuffers)
+ framebuffer.Compile();
+ }
+
+ ///
+ /// Occurs, when the window is resizing.
+ ///
+ protected internal virtual void Resize()
+ { }
+
+ ///
+ /// Occurs, when the pipeline was connected to a window.
+ ///
+ protected internal virtual void Activate(GenericWindow window)
+ {
+ }
+
+ ///
+ /// Occurs, when the window is unloading.
+ ///
+ protected internal virtual void Unload()
+ {
+ foreach (Framebuffer framebuffer in _framebuffers)
+ {
+ framebuffer.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Represents a render pipeline.
+ ///
+ /// The scene type
+ public abstract class RenderPipeline : RenderPipeline
+ where TScene : GenericScene
+ {
+
+ ///
+ /// The system to render stuff.
+ ///
+ protected internal virtual void Render(ref DrawContext context, TScene scene)
+ {
+ context.ActivePipeline = this;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs b/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs
new file mode 100644
index 0000000..60865b1
--- /dev/null
+++ b/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs
@@ -0,0 +1,35 @@
+using System;
+using OpenTK.Graphics.OpenGL4;
+using SM.OGL.Texture;
+
+namespace SM.OGL.Framebuffer
+{
+ public class ColorAttachment : TextureBase
+ {
+ public int AttachmentID { get; }
+
+ public FramebufferAttachment FramebufferAttachment => FramebufferAttachment.ColorAttachment0 + AttachmentID;
+ public DrawBufferMode DrawBufferMode => DrawBufferMode.ColorAttachment0 + AttachmentID;
+ public ReadBufferMode ReadBufferMode => ReadBufferMode.ColorAttachment0 + AttachmentID;
+ public DrawBuffersEnum DrawBuffersEnum => DrawBuffersEnum.ColorAttachment0 + AttachmentID;
+
+ public ColorAttachment(int attachmentId)
+ {
+ AttachmentID = attachmentId;
+ }
+
+ public void Generate(Framebuffer f)
+ {
+ _id = GL.GenTexture();
+ GL.BindTexture(TextureTarget.Texture2D, _id);
+ GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8,
+ (int) f.Size.X, (int) f.Size.Y,
+ 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
+
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMinFilter.Linear);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
+ GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
+ }
+ }
+}
\ No newline at end of file
diff --git a/SMCode/SM.OGL/Framebuffer/Framebuffer.cs b/SMCode/SM.OGL/Framebuffer/Framebuffer.cs
new file mode 100644
index 0000000..82b81b6
--- /dev/null
+++ b/SMCode/SM.OGL/Framebuffer/Framebuffer.cs
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using OpenTK;
+using OpenTK.Graphics.OpenGL4;
+using OpenTK.Platform;
+
+namespace SM.OGL.Framebuffer
+{
+ // TODO: Write summeries for framebuffer-system.
+ public class Framebuffer : GLObject
+ {
+ public static readonly Framebuffer Screen = new Framebuffer()
+ {
+ _id = 0,
+ _canBeCompiled = false
+ };
+
+ private bool _canBeCompiled = true;
+
+ public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Framebuffer;
+
+ public Vector2 Size { get; private set; }
+
+ public Dictionary ColorAttachments { get; private set; } = new Dictionary();
+
+ public Framebuffer()
+ { }
+
+ public Framebuffer(INativeWindow window, float scale = 1) : this(new Vector2(window.Width * scale, window.Height * scale))
+ { }
+
+ public Framebuffer(Vector2 size)
+ {
+ Size = size;
+ }
+
+ public override void Compile()
+ {
+ if (!_canBeCompiled) return;
+
+ base.Compile();
+ _id = GL.GenFramebuffer();
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, _id);
+
+ DrawBuffersEnum[] enums = new DrawBuffersEnum[ColorAttachments.Count];
+ int c = 0;
+ foreach (KeyValuePair pair in ColorAttachments)
+ {
+ pair.Value.Generate(this);
+
+ enums[c++] = pair.Value.DrawBuffersEnum;
+ }
+
+ GL.DrawBuffers(enums.Length, enums);
+ foreach (var pair in ColorAttachments)
+ GL.FramebufferTexture(FramebufferTarget.Framebuffer, pair.Value.FramebufferAttachment, pair.Value.ID, 0);
+
+ FramebufferErrorCode err = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
+ if (err != FramebufferErrorCode.FramebufferComplete)
+ throw new Exception("Failed loading framebuffer.\nProblem: "+err);
+
+ GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
+ GL.BindTexture(TextureTarget.Texture2D, 0);
+ }
+
+ public override void Dispose()
+ {
+ base.Dispose();
+ foreach (ColorAttachment attachment in ColorAttachments.Values) attachment.Dispose();
+ GL.DeleteFramebuffer(this);
+ }
+
+ public void Append(string key, ColorAttachment value)
+ {
+ ColorAttachments.Add(key, value);
+ }
+
+
+ public void Activate() => Activate(FramebufferTarget.Framebuffer, ClearBufferMask.None);
+ public void Activate(FramebufferTarget target) => Activate(target, ClearBufferMask.None);
+ public void Activate(ClearBufferMask clearMask) => Activate(FramebufferTarget.Framebuffer, clearMask);
+ public void Activate(FramebufferTarget target, ClearBufferMask clear)
+ {
+ GL.Clear(clear);
+ GL.BindFramebuffer(target, this);
+ }
+ }
+}
\ No newline at end of file
diff --git a/SMCode/SM.OGL/GLDebugging.cs b/SMCode/SM.OGL/GLDebugging.cs
index 94b4fbd..daa3ae1 100644
--- a/SMCode/SM.OGL/GLDebugging.cs
+++ b/SMCode/SM.OGL/GLDebugging.cs
@@ -4,11 +4,12 @@ using System.Net.Http;
using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Platform.Egl;
+using ErrorCode = OpenTK.Graphics.OpenGL4.ErrorCode;
namespace SM.OGL
{
///
- /// Contains everything that is needed to properly debug OpenGL
+ /// Contains everything that is needed to debug OpenGL
///
public static class GLDebugging
{
@@ -63,5 +64,26 @@ namespace SM.OGL
if (type == DebugType.DebugTypeError) throw new Exception(msg);
}
+
+ ///
+ /// A action, that is performed, when find an error.
+ ///
+ public static Action GlErrorAction;
+
+ ///
+ /// Checks for OpenGL errors.
+ ///
+ public static bool CheckGLErrors()
+ {
+ bool hasError = false;
+ ErrorCode c;
+ while ((c = GL.GetError()) != ErrorCode.NoError)
+ {
+ hasError = true;
+ GlErrorAction?.Invoke(c);
+ }
+
+ return hasError;
+ }
}
}
\ No newline at end of file
diff --git a/SMCode/SM.OGL/GLObject.cs b/SMCode/SM.OGL/GLObject.cs
index 3de92f7..6f52109 100644
--- a/SMCode/SM.OGL/GLObject.cs
+++ b/SMCode/SM.OGL/GLObject.cs
@@ -1,4 +1,5 @@
-using OpenTK.Graphics.OpenGL4;
+using System.Diagnostics;
+using OpenTK.Graphics.OpenGL4;
namespace SM.OGL
{
@@ -29,7 +30,7 @@ namespace SM.OGL
{
get
{
- if (AutoCompile && !WasCompiled) Compile();
+ if (AutoCompile && !WasCompiled) PerformCompile();
return _id;
}
}
@@ -39,10 +40,17 @@ namespace SM.OGL
///
public abstract ObjectLabelIdentifier TypeIdentifier { get; }
+ [DebuggerStepThrough]
+ private void PerformCompile()
+ {
+ Compile();
+ }
+
///
/// The action, that is called, when "ID" tries to compile something.
///
- protected virtual void Compile()
+
+ public virtual void Compile()
{
}
@@ -50,7 +58,7 @@ namespace SM.OGL
///
/// Is triggered, when something want to dispose this object.
///
- protected virtual void Dispose() {}
+ public virtual void Dispose() {}
///
/// Re-compiles the object.
@@ -72,10 +80,15 @@ namespace SM.OGL
if (GLSystem.Debugging) GL.ObjectLabel(TypeIdentifier, _id, name.Length, name);
}
+ protected virtual int GetID()
+ {
+ return _id;
+ }
+
///
/// Returns the ID for the object.
///
///
- public static implicit operator int(GLObject glo) => glo.ID;
+ public static implicit operator int(GLObject glo) => glo.GetID();
}
}
\ No newline at end of file
diff --git a/SMCode/SM.OGL/Mesh/GenericMesh.cs b/SMCode/SM.OGL/Mesh/GenericMesh.cs
index 702e1f8..3af41fd 100644
--- a/SMCode/SM.OGL/Mesh/GenericMesh.cs
+++ b/SMCode/SM.OGL/Mesh/GenericMesh.cs
@@ -64,7 +64,7 @@ namespace SM.OGL.Mesh
}
///
- protected override void Compile()
+ public override void Compile()
{
_id = GL.GenVertexArray();
GL.BindVertexArray(_id);
diff --git a/SMCode/SM.OGL/SM.OGL.csproj b/SMCode/SM.OGL/SM.OGL.csproj
index 0039260..5fc7a58 100644
--- a/SMCode/SM.OGL/SM.OGL.csproj
+++ b/SMCode/SM.OGL/SM.OGL.csproj
@@ -46,6 +46,8 @@
+
+
diff --git a/SMCode/SM.OGL/Shaders/GenericShader.cs b/SMCode/SM.OGL/Shaders/GenericShader.cs
index a09f2c3..a39e659 100644
--- a/SMCode/SM.OGL/Shaders/GenericShader.cs
+++ b/SMCode/SM.OGL/Shaders/GenericShader.cs
@@ -59,7 +59,7 @@ namespace SM.OGL.Shaders
}
///
- protected override void Compile()
+ public override void Compile()
{
Load();
}
@@ -70,7 +70,7 @@ namespace SM.OGL.Shaders
/// The mesh.
/// The amounts for instancing.
/// Binds the vertex array for the mesh.
- protected void DrawObject(Mesh.GenericMesh mesh, int amount, bool bindVAO = false)
+ protected void DrawObject(Mesh.GenericMesh mesh, int amount = 1, bool bindVAO = false)
{
if (bindVAO) GL.BindVertexArray(mesh);
diff --git a/SMCode/SM.OGL/Texture/TextureBase.cs b/SMCode/SM.OGL/Texture/TextureBase.cs
index d2ffb23..8779140 100644
--- a/SMCode/SM.OGL/Texture/TextureBase.cs
+++ b/SMCode/SM.OGL/Texture/TextureBase.cs
@@ -33,5 +33,11 @@ namespace SM.OGL.Texture
/// The height of the texture
///
public int Height { get; protected set; }
+
+ public override void Dispose()
+ {
+ base.Dispose();
+ GL.DeleteTexture(_id);
+ }
}
}
\ No newline at end of file
diff --git a/SMCode/SM2D/Drawing/DrawBackground.cs b/SMCode/SM2D/Drawing/DrawBackground.cs
index 2f1eab5..bdc17c8 100644
--- a/SMCode/SM2D/Drawing/DrawBackground.cs
+++ b/SMCode/SM2D/Drawing/DrawBackground.cs
@@ -50,13 +50,11 @@ namespace SM2D.Drawing
public void Draw(DrawContext context)
{
- if (_material.Shader == null) _material.Shader = Defaults.DefaultShader;
-
context.Material = _material;
context.Mesh = Plate.Object;
context.Instances[0].ModelMatrix = Matrix4.CreateScale(context.WorldScale.X, context.WorldScale.Y, 1);
- _material.Shader.Draw(context);
+ context.Shader.Draw(context);
}
}
}
\ No newline at end of file
diff --git a/SMCode/SM2D/Drawing/DrawColor.cs b/SMCode/SM2D/Drawing/DrawColor.cs
index 695f5ef..2cc6b84 100644
--- a/SMCode/SM2D/Drawing/DrawColor.cs
+++ b/SMCode/SM2D/Drawing/DrawColor.cs
@@ -24,13 +24,11 @@ namespace SM2D.Drawing
_material.Tint = color;
}
- public override void Draw(DrawContext context)
+ protected override void DrawContext(ref DrawContext context)
{
- base.Draw(context);
- ApplyContext(ref context);
context.Instances[0].ModelMatrix = Transform.GetMatrix();
- _material.Shader.Draw(context);
+ context.Shader.Draw(context);
}
}
}
\ No newline at end of file
diff --git a/SMCode/SM2D/Drawing/DrawComplex.cs b/SMCode/SM2D/Drawing/DrawComplex.cs
index a6f9370..6d52794 100644
--- a/SMCode/SM2D/Drawing/DrawComplex.cs
+++ b/SMCode/SM2D/Drawing/DrawComplex.cs
@@ -22,14 +22,11 @@ namespace SM2D.Drawing
set => _mesh = value;
}
- public override void Draw(DrawContext context)
+ protected override void DrawContext(ref DrawContext context)
{
- base.Draw(context);
- ApplyContext(ref context);
-
context.Instances[0].ModelMatrix = Transform.GetMatrix();
- _material.Shader.Draw(context);
+ context.Shader.Draw(context);
}
}
}
\ No newline at end of file
diff --git a/SMCode/SM2D/Drawing/DrawText.cs b/SMCode/SM2D/Drawing/DrawText.cs
index e18ff07..66e2985 100644
--- a/SMCode/SM2D/Drawing/DrawText.cs
+++ b/SMCode/SM2D/Drawing/DrawText.cs
@@ -1,4 +1,5 @@
-using SM.Base.Contexts;
+using SM.Base;
+using SM.Base.Contexts;
using SM.Base.Text;
using SM.Base.Types;
using SM2D.Scene;
@@ -14,15 +15,14 @@ namespace SM2D.Drawing
Transform.Size = new CVector2(1);
}
- public override void Draw(DrawContext context)
+ protected override void DrawContext(ref DrawContext context)
{
- base.Draw(context);
+ base.DrawContext(ref context);
context.Instances = _instances;
- ApplyContext(ref context);
context.View = Transform.GetMatrix() * context.View;
- _material.Shader.Draw(context);
+ context.Shader.Draw(context);
}
public int ZIndex { get; set; }
diff --git a/SMCode/SM2D/Drawing/DrawTexture.cs b/SMCode/SM2D/Drawing/DrawTexture.cs
index ad7b550..bc2765c 100644
--- a/SMCode/SM2D/Drawing/DrawTexture.cs
+++ b/SMCode/SM2D/Drawing/DrawTexture.cs
@@ -15,6 +15,7 @@ namespace SM2D.Drawing
public static float MasterScale = .25f;
public float Scale = 1;
+ public bool ManualSize = false;
public Texture Texture
{
get => (Texture) _material.Texture;
@@ -28,16 +29,19 @@ namespace SM2D.Drawing
public DrawTexture(Bitmap map) : this(map, Color4.White)
{ }
- public DrawTexture(Bitmap map, Color4 color)
+ public DrawTexture(Bitmap map, Color4 color) : this((Texture)map, color)
+ { }
+
+ public DrawTexture(Texture texture, Color4 color)
{
- _material.Texture = new Texture(map);
+ _material.Texture = texture;
_material.Tint = color;
}
- public override void Draw(DrawContext context)
+ protected override void DrawContext(ref DrawContext context)
{
- Transform.Size = new CVector2(Texture.Map.Width * MasterScale * Scale, Texture.Map.Height * MasterScale * Scale);
- base.Draw(context);
+ if (!ManualSize) Transform.Size = new CVector2(Texture.Map.Width * MasterScale * Scale, Texture.Map.Height * MasterScale * Scale);
+ base.DrawContext(ref context);
}
}
}
\ No newline at end of file
diff --git a/SMCode/SM2D/GLWindow2D.cs b/SMCode/SM2D/GLWindow2D.cs
index b1342b5..da64f07 100644
--- a/SMCode/SM2D/GLWindow2D.cs
+++ b/SMCode/SM2D/GLWindow2D.cs
@@ -5,13 +5,14 @@ using OpenTK.Input;
using SM.Base;
using SM.Base.Controls;
using SM2D.Controls;
+using SM2D.Pipelines;
using SM2D.Scene;
using SM2D.Shader;
using Vector2 = OpenTK.Vector2;
namespace SM2D
{
- public class GLWindow2D : GenericWindow
+ public class GLWindow2D : GenericWindow
{
public Vector2? Scaling { get; set; }
public Vector2 WorldScale => _worldScale;
@@ -25,13 +26,17 @@ namespace SM2D
protected override void OnLoad(EventArgs e)
{
- Defaults.DefaultShader = new Default2DShader();
-
base.OnLoad(e);
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
}
+ protected override void OnLoaded()
+ {
+ base.OnLoaded();
+ SetRenderPipeline(new Basic2DPipeline());
+ }
+
protected override void OnRenderFrame(FrameEventArgs e)
{
GL.Disable(EnableCap.DepthTest);
diff --git a/SMCode/SM2D/Pipelines/Basic2DPipeline.cs b/SMCode/SM2D/Pipelines/Basic2DPipeline.cs
new file mode 100644
index 0000000..d70a156
--- /dev/null
+++ b/SMCode/SM2D/Pipelines/Basic2DPipeline.cs
@@ -0,0 +1,23 @@
+using OpenTK.Graphics.OpenGL4;
+using SM.Base;
+using SM.Base.Contexts;
+using SM.Base.Scene;
+using SM.OGL.Framebuffer;
+using SM2D.Shader;
+
+namespace SM2D.Pipelines
+{
+ public class Basic2DPipeline : RenderPipeline
+ {
+ protected override IShader _defaultShader { get; } = Default2DShader.Shader;
+
+ protected override void Render(ref DrawContext context, Scene.Scene scene)
+ {
+ base.Render(ref context, scene);
+
+ Framebuffer.Screen.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
+
+ scene.Draw(context);
+ }
+ }
+}
\ No newline at end of file
diff --git a/SMCode/SM2D/SM2D.csproj b/SMCode/SM2D/SM2D.csproj
index 9484dd6..dd1d2da 100644
--- a/SMCode/SM2D/SM2D.csproj
+++ b/SMCode/SM2D/SM2D.csproj
@@ -55,6 +55,7 @@
+
diff --git a/SMCode/SM2D/Scene/ItemCollection.cs b/SMCode/SM2D/Scene/ItemCollection.cs
index 986f5d4..6dbb38e 100644
--- a/SMCode/SM2D/Scene/ItemCollection.cs
+++ b/SMCode/SM2D/Scene/ItemCollection.cs
@@ -14,7 +14,7 @@ namespace SM2D.Scene
public override void Draw(DrawContext context)
{
- Objects.Sort((x, y) => x.ZIndex - y.ZIndex);
+ Sort((x, y) => x.ZIndex - y.ZIndex);
base.Draw(context);
}
diff --git a/SMCode/SM2D/Scene/Scene.cs b/SMCode/SM2D/Scene/Scene.cs
index 17f784f..9a94156 100644
--- a/SMCode/SM2D/Scene/Scene.cs
+++ b/SMCode/SM2D/Scene/Scene.cs
@@ -5,7 +5,7 @@ using SM2D.Drawing;
namespace SM2D.Scene
{
- public class Scene : GenericScene
+ public class Scene : GenericScene
{
public DrawBackground Background => (DrawBackground)_background;
@@ -13,11 +13,5 @@ namespace SM2D.Scene
{
_background = new DrawBackground(Color4.Black);
}
-
- public override void Draw(DrawContext context)
- {
- Objects.Sort((x,y) => x.ZIndex - y.ZIndex);
- base.Draw(context);
- }
}
}
\ No newline at end of file
diff --git a/SMCode/SM2D/Shader/Default2DShader.cs b/SMCode/SM2D/Shader/Default2DShader.cs
index 1932adf..854f00f 100644
--- a/SMCode/SM2D/Shader/Default2DShader.cs
+++ b/SMCode/SM2D/Shader/Default2DShader.cs
@@ -8,13 +8,15 @@ namespace SM2D.Shader
{
public class Default2DShader : GenericShader, IShader
{
- protected override bool AutoCompile { get; } = true;
+ public static Default2DShader Shader = new Default2DShader();
- public Default2DShader() : base(new ShaderFileCollection(
+ //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")))
{
-
+ Load();
}
public void Draw(DrawContext context)
{
diff --git a/SM_TEST/Program.cs b/SM_TEST/Program.cs
index ae04fc0..ad6816d 100644
--- a/SM_TEST/Program.cs
+++ b/SM_TEST/Program.cs
@@ -4,6 +4,7 @@ using System.Drawing;
using System.Runtime.InteropServices;
using OpenTK;
using OpenTK.Graphics;
+using SM.Base;
using SM.Base.Time;
using SM2D;
using SM2D.Drawing;
@@ -28,6 +29,8 @@ namespace SM_TEST
FontSize = 32
};
+ Log.SetLogFile(compressionFolder:"logs");
+
window = new GLWindow2D {Scaling = new Vector2(0, 1000)};
//window.GrabCursor();
window.SetScene(scene = new Scene());
@@ -53,11 +56,11 @@ namespace SM_TEST
ZIndex = 1
};
- col.Objects.Add(new DrawTexture(new Bitmap("soldier_logo.png"))
+ col.Add(new DrawTexture(new Bitmap("soldier_logo.png"))
{
ZIndex = 1
});
- col.Objects.Add(new DrawColor(Color4.Black)
+ col.Add(new DrawColor(Color4.Black)
{
Transform = { Rotation = 45, Position = new SM.Base.Types.CVector2(0, 25) },
ZIndex = 2