Holidays 12.10. -> 25.10.2020

~ Moved code around in files.

SM.Base:
+ PostProcessing-system
+ OnInitialization() for Scenes.
+ Shader-Extensions
+ Added option to not react while unfocused to the window.
+ Added Screenshots to the window.
+ Connected the log system to the SM.OGL-action system.

~ Replaced IShader with abstract MaterialShader.
~ When a log compression folder doesn't exist, it will create one.

SM.OGL:
+ Added support for UniformArrays
+ Added ShaderPreProcessing
+ Added Shader Extensions.
+ Added Debug actions.
+ SM.OGL settings

~ Framebuffer Size is automaticly changed, when the window and scale is set.

SM2D:
+ Added easy shader drawing.
This commit is contained in:
Michel Fedde 2020-10-24 15:10:36 +02:00
parent 2c00dbd31a
commit 03b3942732
102 changed files with 2683 additions and 1398 deletions

View file

@ -1,32 +1,26 @@
using System; #region usings
using OpenTK; using OpenTK;
using OpenTK.Input; using OpenTK.Input;
#endregion
namespace SM.Base.Controls namespace SM.Base.Controls
{ {
/// <summary> /// <summary>
/// Mouse controller /// Mouse controller
/// </summary> /// </summary>
/// <typeparam name="TWindow">The type of window this controller is connected to.</typeparam> /// <typeparam name="TWindow">The type of window this controller is connected to.</typeparam>
public class Mouse<TWindow> public class Mouse<TWindow>
where TWindow : GenericWindow where TWindow : GenericWindow
{ {
/// <summary> /// <summary>
/// The window it is connected to. /// The window it is connected to.
/// </summary> /// </summary>
protected TWindow _window; protected TWindow _window;
/// <summary> /// <summary>
/// The current position of the mouse in the screen. /// The constructor
/// </summary>
public Vector2 InScreen { get; private set; }
/// <summary>
/// The current position of the mouse in the screen from 0..1.
/// </summary>
public Vector2 InScreenNormalized { get; private set; }
/// <summary>
/// The constructor
/// </summary> /// </summary>
/// <param name="window">The window, its listen to.</param> /// <param name="window">The window, its listen to.</param>
protected internal Mouse(TWindow window) protected internal Mouse(TWindow window)
@ -35,13 +29,23 @@ namespace SM.Base.Controls
} }
/// <summary> /// <summary>
/// The event to update the values. /// The current position of the mouse in the screen.
/// </summary>
public Vector2 InScreen { get; private set; }
/// <summary>
/// The current position of the mouse in the screen from 0..1.
/// </summary>
public Vector2 InScreenNormalized { get; private set; }
/// <summary>
/// The event to update the values.
/// </summary> /// </summary>
/// <param name="mmea">The event args.</param> /// <param name="mmea">The event args.</param>
protected void MouseMoveEvent(MouseMoveEventArgs mmea) protected void MouseMoveEvent(MouseMoveEventArgs mmea)
{ {
InScreen = new Vector2(mmea.X, mmea.Y); InScreen = new Vector2(mmea.X, mmea.Y);
InScreenNormalized = new Vector2(mmea.X / (float)_window.Width, mmea.Y / (float)_window.Height); InScreenNormalized = new Vector2(mmea.X / (float) _window.Width, mmea.Y / (float) _window.Height);
} }
} }
} }

View file

@ -1,21 +1,25 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Objects.Static;
using SM.OGL.Mesh; using SM.OGL.Mesh;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Contains general basis systems for drawing objects. /// Contains general basis systems for drawing objects.
/// </summary> /// </summary>
public abstract class DrawingBasis : IShowItem public abstract class DrawingBasis : IShowItem
{ {
/// <summary> /// <summary>
/// The material it should use. /// The material it should use.
/// </summary> /// </summary>
protected Material _material = new Material(); protected Material _material = new Material();
/// <summary> /// <summary>
/// The mesh it should use. /// The mesh it should use.
/// </summary> /// </summary>
protected GenericMesh _mesh = SMRenderer.DefaultMesh; protected GenericMesh _mesh = SMRenderer.DefaultMesh;
@ -31,7 +35,6 @@ namespace SM.Base.Scene
/// <inheritdoc /> /// <inheritdoc />
public virtual void Update(UpdateContext context) public virtual void Update(UpdateContext context)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
@ -46,33 +49,31 @@ namespace SM.Base.Scene
/// <inheritdoc /> /// <inheritdoc />
public virtual void OnAdded(object sender) public virtual void OnAdded(object sender)
{ {
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual void OnRemoved(object sender) public virtual void OnRemoved(object sender)
{ {
} }
/// <summary> /// <summary>
/// Draws the context, that was given to them. /// Draws the context, that was given to them.
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected virtual void DrawContext(ref DrawContext context) protected virtual void DrawContext(ref DrawContext context)
{ {
} }
} }
/// <summary> /// <summary>
/// Contains general basis systems for drawing objects. /// Contains general basis systems for drawing objects.
/// </summary> /// </summary>
/// <typeparam name="TTransformation">The transformation type</typeparam> /// <typeparam name="TTransformation">The transformation type</typeparam>
public abstract class DrawingBasis<TTransformation> : DrawingBasis public abstract class DrawingBasis<TTransformation> : DrawingBasis
where TTransformation : GenericTransformation, new() where TTransformation : GenericTransformation, new()
{ {
/// <summary> /// <summary>
/// The current transformation. /// The current transformation.
/// </summary> /// </summary>
public TTransformation Transform = new TTransformation(); public TTransformation Transform = new TTransformation();
} }

View file

@ -1,23 +1,28 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Contains methods for using transformations right. /// Contains methods for using transformations right.
/// </summary> /// </summary>
public abstract class GenericTransformation public abstract class GenericTransformation
{ {
/// <summary> /// <summary>
/// Contains the current model matrix. /// Contains the current model matrix.
/// </summary> /// </summary>
protected Matrix4 _modelMatrix { get; private set; } protected Matrix4 _modelMatrix { get; private set; }
/// <summary> /// <summary>
/// Contains the last frame the matrix was calculated. /// Contains the last frame the matrix was calculated.
/// </summary> /// </summary>
protected ulong _lastFrame { get; private set; } protected ulong _lastFrame { get; private set; }
/// <summary> /// <summary>
/// Returns the current model matrix. /// Returns the current model matrix.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public Matrix4 GetMatrix() public Matrix4 GetMatrix()
@ -32,7 +37,7 @@ namespace SM.Base.Scene
} }
/// <summary> /// <summary>
/// Calculates the current matrix. /// Calculates the current matrix.
/// </summary> /// </summary>
/// <returns>The current matrix.</returns> /// <returns>The current matrix.</returns>
protected abstract Matrix4 RequestMatrix(); protected abstract Matrix4 RequestMatrix();

View file

@ -1,18 +0,0 @@
using System.Collections.Generic;
using OpenTK;
using SM.Base.Contexts;
namespace SM.Base.Scene
{
/// <summary>
/// A general interface to work with material shaders properly.
/// </summary>
public interface IShader
{
/// <summary>
/// Draws the context.
/// </summary>
/// <param name="context">The context</param>
void Draw(DrawContext context);
}
}

View file

@ -1,22 +1,28 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// This represens a drawing instance. /// This represens a drawing instance.
/// </summary> /// </summary>
public struct Instance public struct Instance
{ {
/// <summary> /// <summary>
/// The model matrix. /// The model matrix.
/// </summary> /// </summary>
public Matrix4 ModelMatrix; public Matrix4 ModelMatrix;
/// <summary> /// <summary>
/// The texture offset. /// The texture offset.
/// </summary> /// </summary>
public Vector2 TexturePosition; public Vector2 TexturePosition;
/// <summary> /// <summary>
/// The texture scale. /// The texture scale.
/// </summary> /// </summary>
public Vector2 TextureScale; public Vector2 TextureScale;
} }

View file

@ -1,25 +1,30 @@
using OpenTK.Graphics; #region usings
using OpenTK.Graphics;
using SM.OGL.Texture; using SM.OGL.Texture;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Represents a material. /// Represents a material.
/// </summary> /// </summary>
public class Material public class Material
{ {
/// <summary> /// <summary>
/// The base texture. (aka. Diffuse Texture) /// A custom shader, that is used to draw this material.
/// </summary> /// </summary>
public TextureBase Texture; public MaterialShader CustomShader;
/// <summary>
/// The tint or color.
/// </summary>
public Color4 Tint = Color4.White;
/// <summary> /// <summary>
/// A custom shader, that is used to draw this material. /// The base texture. (aka. Diffuse Texture)
/// </summary> /// </summary>
public IShader CustomShader; public TextureBase Texture;
/// <summary>
/// The tint or color.
/// </summary>
public Color4 Tint = Color4.White;
} }
} }

View file

@ -0,0 +1,47 @@
#region usings
using OpenTK.Graphics.OpenGL4;
using SM.Base.Contexts;
using SM.OGL.Shaders;
#endregion
namespace SM.Base.Scene
{
/// <summary>
/// A general class to work with material shaders properly.
/// </summary>
public abstract class MaterialShader : GenericShader
{
protected MaterialShader(string vertex, string fragment) : base(vertex, fragment)
{
}
protected MaterialShader(ShaderFileCollection shaderFileFiles) : base(shaderFileFiles)
{
}
/// <summary>
/// Draws the context.
/// </summary>
/// <param name="context">The context</param>
public virtual void Draw(DrawContext context)
{
GL.UseProgram(this);
GL.BindVertexArray(context.Mesh);
DrawProcess(context);
CleanUp();
GL.UseProgram(0);
}
protected virtual void DrawProcess(DrawContext context)
{
}
}
}

View file

@ -1,98 +1,108 @@
using System; #region usings
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Net.Http;
using System.Windows.Forms; using System.Windows.Forms;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.OGL; using SM.OGL;
#endregion
namespace SM.Base namespace SM.Base
{ {
/// <summary> /// <summary>
/// Specifies the target. /// Specifies the target.
/// </summary> /// </summary>
[Flags] [Flags]
public enum LogTarget public enum LogTarget
{ {
/// <summary> /// <summary>
/// No target, will not draw. /// No target, will not draw.
/// </summary> /// </summary>
None = 0, None = 0,
/// <summary> /// <summary>
/// Takes the <see cref="Log.DefaultTarget"/>. /// Takes the <see cref="Log.DefaultTarget" />.
/// </summary> /// </summary>
Default = 1, Default = 1,
/// <summary> /// <summary>
/// Writes the log to the console. /// Writes the log to the console.
/// </summary> /// </summary>
Console = 2, Console = 2,
/// <summary> /// <summary>
/// Writes the log to the debugger at <see cref="Debug"/>. /// Writes the log to the debugger at <see cref="Debug" />.
/// </summary> /// </summary>
Debugger = 4, Debugger = 4,
/// <summary> /// <summary>
/// Writes the log to the specific file. /// Writes the log to the specific file.
/// </summary> /// </summary>
File = 8, File = 8,
/// <summary> /// <summary>
/// Writes the log to every target. /// Writes the log to every target.
/// </summary> /// </summary>
All = Console | Debugger | File All = Console | Debugger | File
} }
/// <summary> /// <summary>
/// Preset log types. /// Preset log types.
/// </summary> /// </summary>
public enum LogType public enum LogType
{ {
/// <summary> /// <summary>
/// Informations. Console Color: Green /// Informations. Console Color: Green
/// </summary> /// </summary>
Info, Info,
/// <summary> /// <summary>
/// Warnings. Console Color: Yellow /// Warnings. Console Color: Yellow
/// </summary> /// </summary>
Warning, Warning,
/// <summary> /// <summary>
/// Error. Console Color: Red /// Error. Console Color: Red
/// </summary> /// </summary>
Error Error
} }
/// <summary> /// <summary>
/// Contains the system for logging. /// Contains the system for logging.
/// </summary> /// </summary>
public class Log public class Log
{ {
private static StreamWriter _logStream; private static StreamWriter _logStream;
private static bool _init = false; private static bool _init;
/// <summary> /// <summary>
/// Presets for the log targets. /// Presets for the log targets.
/// </summary> /// </summary>
public static Dictionary<LogTarget, string> Preset = new Dictionary<LogTarget, string>() public static Dictionary<LogTarget, string> Preset = new Dictionary<LogTarget, string>
{ {
{LogTarget.Console, "[%type%] %msg%"}, {LogTarget.Console, "[%type%] %msg%"},
{LogTarget.Debugger, "[%type%] %msg%"}, {LogTarget.Debugger, "[%type%] %msg%"},
{LogTarget.File, "<%date%, %time%> [%type%] %msg%"} {LogTarget.File, "<%date%, %time%> [%type%] %msg%"}
}; };
private static readonly Dictionary<LogType, ConsoleColor> Colors = new Dictionary<LogType, ConsoleColor>() private static readonly Dictionary<LogType, ConsoleColor> Colors = new Dictionary<LogType, ConsoleColor>
{ {
{LogType.Info, ConsoleColor.Green}, {LogType.Info, ConsoleColor.Green},
{LogType.Warning, ConsoleColor.Yellow}, {LogType.Warning, ConsoleColor.Yellow},
{LogType.Error, ConsoleColor.Red}, {LogType.Error, ConsoleColor.Red}
}; };
/// <summary> /// <summary>
/// Specified the default target. /// Specified the default target.
/// </summary> /// </summary>
public static LogTarget DefaultTarget = LogTarget.All; public static LogTarget DefaultTarget = LogTarget.All;
/// <summary> /// <summary>
/// Sets the log file. At wish compresses the old file to a zip file. /// Sets the log file. At wish compresses the old file to a zip file.
/// </summary> /// </summary>
/// <param name="path">The path to the log file.</param> /// <param name="path">The path to the log file.</param>
/// <param name="compressionFolder">Path for the compression, if desired.</param> /// <param name="compressionFolder">Path for the compression, if desired.</param>
@ -106,10 +116,12 @@ namespace SM.Base
{ {
if (compressionFolder != "") if (compressionFolder != "")
{ {
DateTime creation = File.GetLastWriteTime(path); if (!Directory.Exists(compressionFolder)) Directory.CreateDirectory(compressionFolder);
var creation = File.GetLastWriteTime(path);
try try
{ {
using ZipArchive archive = using var archive =
ZipFile.Open( 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", $"{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); ZipArchiveMode.Create);
@ -127,11 +139,12 @@ namespace SM.Base
_logStream = new StreamWriter(path) {AutoFlush = true}; _logStream = new StreamWriter(path) {AutoFlush = true};
Write(LogType.Info, $"Activated new log file. ['{path}']"); Write(LogType.Info, $"Activated new log file. ['{path}']");
} }
static void Init() internal static void Init()
{ {
if (_init) return;
AppDomain.CurrentDomain.UnhandledException += ExceptionHandler; AppDomain.CurrentDomain.UnhandledException += ExceptionHandler;
AppDomain.CurrentDomain.DomainUnload += (sender, args) => AppDomain.CurrentDomain.DomainUnload += (sender, args) =>
{ {
@ -139,27 +152,25 @@ namespace SM.Base
_logStream.Close(); _logStream.Close();
}; };
GLDebugging.DebugAction = GLDebugAction; GLCustomActions.AtKHRDebug = GLDebugAction;
GLDebugging.GlErrorAction = code => GLCustomActions.AtError = err => Write(LogType.Error, err);
{ GLCustomActions.AtWarning = warning => Write(LogType.Warning, warning);
Write(LogType.Warning, $"A '{code}' GL error occured."); GLCustomActions.AtInfo = info => Write(LogType.Info, info);
};
_init = true; _init = true;
} }
private static void GLDebugAction(DebugSource source, DebugType type, DebugSeverity severity, string msg) private static void GLDebugAction(DebugSource source, DebugType type, DebugSeverity severity, string msg)
{ {
if (type.HasFlag(DebugType.DebugTypeError)) if (type.HasFlag(DebugType.DebugTypeError)) throw new Exception("[GLError] " + msg);
{
throw new Exception("[GLError] "+msg);
}
Write(type != DebugType.DontCare ? type.ToString().Substring(9) : "DontCare", ConsoleColor.Gray, msg); Write(type != DebugType.DontCare ? type.ToString().Substring(9) : "DontCare", ConsoleColor.Gray, msg);
} }
[DebuggerStepThrough] [DebuggerStepThrough]
private static void ExceptionHandler(object sender, UnhandledExceptionEventArgs e) private static void ExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{ {
Write(e.IsTerminating ? "Terminating Error" : LogType.Error.ToString(), e.IsTerminating ? ConsoleColor.DarkRed : ConsoleColor.Red, e.ExceptionObject); Write(e.IsTerminating ? "Terminating Error" : LogType.Error.ToString(),
e.IsTerminating ? ConsoleColor.DarkRed : ConsoleColor.Red, e.ExceptionObject);
if (e.IsTerminating) if (e.IsTerminating)
{ {
@ -170,30 +181,31 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// Writes multiple lines of the same type to the log. /// Writes multiple lines of the same type to the log.
/// </summary> /// </summary>
public static void Write<T>(LogType type, params T[] values) => Write<T>(type.ToString(), Colors[type], values); public static void Write<T>(LogType type, params T[] values)
/// <summary>
/// Writes multiple lines of the same type to the log.
/// </summary>
public static void Write<T>(string type, ConsoleColor color, params T[] values)
{ {
for (var i = 0; i < values.Length; i++) Write(type.ToString(), Colors[type], values);
{
Write(type, color, values[i], DefaultTarget);
}
} }
/// <summary> /// <summary>
/// Writes one line to the log. /// Writes multiple lines of the same type to the log.
/// </summary> /// </summary>
public static void Write<T>(LogType type, T value, LogTarget target = LogTarget.Default) => public static void Write<T>(string type, ConsoleColor color, params T[] values)
Write<T>(type.ToString(), Colors[type], value, target); {
for (var i = 0; i < values.Length; i++) Write(type, color, values[i], DefaultTarget);
}
/// <summary> /// <summary>
/// Writes one line to the log. /// Writes one line to the log.
/// /// </summary>
public static void Write<T>(LogType type, T value, LogTarget target = LogTarget.Default)
{
Write(type.ToString(), Colors[type], value, target);
}
/// <summary>
/// Writes one line to the log.
/// </summary> /// </summary>
public static void Write<T>(string type, ConsoleColor color, T value, LogTarget target = LogTarget.Default) public static void Write<T>(string type, ConsoleColor color, T value, LogTarget target = LogTarget.Default)
{ {
@ -209,23 +221,23 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// Writes a text with a different color. /// Writes a text with a different color.
/// </summary> /// </summary>
/// <param name="color"></param> /// <param name="color"></param>
/// <param name="value"></param> /// <param name="value"></param>
public static void ColorfulWriteLine(ConsoleColor color, string value) public static void ColorfulWriteLine(ConsoleColor color, string value)
{ {
ConsoleColor before = Console.ForegroundColor; var before = Console.ForegroundColor;
Console.ForegroundColor = color; Console.ForegroundColor = color;
Console.WriteLine(value); Console.WriteLine(value);
Console.ForegroundColor = before; Console.ForegroundColor = before;
} }
static string ProcessPreset(LogTarget target, string type, string msg) private static string ProcessPreset(LogTarget target, string type, string msg)
{ {
string preset = Preset[target]; var preset = Preset[target];
DateTime now = DateTime.Now; var now = DateTime.Now;
return preset.Replace("%date%", now.ToShortDateString()) return preset.Replace("%date%", now.ToShortDateString())
.Replace("%time%", now.ToShortTimeString()) .Replace("%time%", now.ToShortTimeString())

View file

@ -1,4 +1,8 @@
using SM.OGL.Mesh; #region usings
using SM.OGL.Mesh;
#endregion
namespace SM.Base.Objects namespace SM.Base.Objects
{ {
@ -6,16 +10,16 @@ namespace SM.Base.Objects
public class Mesh : GenericMesh public class Mesh : GenericMesh
{ {
/// <summary> /// <summary>
/// Contains vertex colors /// While initializing, it will add the <see cref="Color" /> to the data index.
/// </summary>
public virtual VBO Color { get; }
/// <summary>
/// While initializing, it will add the <see cref="Color"/> to the data index.
/// </summary> /// </summary>
protected Mesh() protected Mesh()
{ {
AttribDataIndex.Add(3, Color); AttribDataIndex.Add(3, Color);
} }
/// <summary>
/// Contains vertex colors
/// </summary>
public virtual VBO Color { get; }
} }
} }

View file

@ -1,27 +1,36 @@
using OpenTK; #region usings
using OpenTK.Graphics;
using OpenTK;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.OGL.Mesh; using SM.OGL.Mesh;
#endregion
namespace SM.Base.Objects.Static namespace SM.Base.Objects.Static
{ {
/// <summary> /// <summary>
/// A basic plate /// A basic plate
/// </summary> /// </summary>
public class Plate : GenericMesh public class Plate : GenericMesh
{ {
/// <summary> /// <summary>
/// The object. /// The object.
/// </summary> /// </summary>
public static Plate Object = new Plate(); public static Plate Object = new Plate();
//public override int[] Indices { get; set; } = new[] {0, 1, 2, 3};
private Plate()
{
}
/// <inheritdoc /> /// <inheritdoc />
public override VBO Vertex { get; } = new VBO() public override VBO Vertex { get; } = new VBO
{ {
{-.5f, -.5f, 0}, {-.5f, -.5f, 0},
{-.5f, .5f, 0}, {-.5f, .5f, 0},
{.5f, .5f, 0}, {.5f, .5f, 0},
{.5f, -.5f, 0}, {.5f, -.5f, 0}
}; };
/// <inheritdoc /> /// <inheritdoc />
@ -30,17 +39,14 @@ namespace SM.Base.Objects.Static
{0, 0}, {0, 0},
{0, 1}, {0, 1},
{1, 1}, {1, 1},
{1, 0}, {1, 0}
}; };
/// <inheritdoc /> /// <inheritdoc />
public override PrimitiveType PrimitiveType { get; } = PrimitiveType.Quads; public override PrimitiveType PrimitiveType { get; } = PrimitiveType.Quads;
/// <inheritdoc /> /// <inheritdoc />
public override BoundingBox BoundingBox { get; } = new BoundingBox(new Vector3(-.5f, -.5f, 0), new Vector3(.5f, .5f, 0)); public override BoundingBox BoundingBox { get; } =
new BoundingBox(new Vector3(-.5f, -.5f, 0), new Vector3(.5f, .5f, 0));
//public override int[] Indices { get; set; } = new[] {0, 1, 2, 3};
private Plate() {}
} }
} }

View file

@ -0,0 +1,9 @@
#version 330
in vec2 vTexture;
uniform sampler2D renderedTexture;
vec4 GetRenderColor() {
return texture(renderedTexture, vTexture);
}

View file

@ -0,0 +1,14 @@
#version 330
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTex;
uniform mat4 MVP;
out vec2 vTexture;
void main() {
vTexture = aTex;
gl_Position = MVP * vec4(aPos, 1);
}

View file

@ -0,0 +1,18 @@
#version 330
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTex;
uniform mat4 MVP;
out vec2 vTexture;
void vertex();
void main() {
vTexture = aTex;
gl_Position = MVP * vec4(aPos, 1);
vertex();
}

View file

@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using OpenTK;
using OpenTK.Graphics.OpenGL4;
using SM.Base.Objects.Static;
using SM.OGL.Framebuffer;
using SM.OGL.Shaders;
namespace SM.Base.PostProcess
{
public abstract class PostProcessEffect
{
internal static Matrix4 Mvp;
public virtual ICollection<Framebuffer> RequiredFramebuffers { get; }
public virtual void Init() {}
public virtual void Init(Framebuffer main)
{
Init();
}
public virtual void Draw(Framebuffer main)
{
}
}
}

View file

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using OpenTK.Graphics.OpenGL4;
using SM.Base.Objects.Static;
using SM.OGL.Framebuffer;
using SM.OGL.Shaders;
using SM.Utility;
namespace SM.Base.PostProcess
{
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 =
AssemblyUtility.ReadAssemblyFile("SM.Base.PostProcess.DefaultFiles.vertexWithExt.vert");
public PostProcessShader(string fragment) : this(_normalVertex,
new ShaderFile(fragment)) { }
public PostProcessShader(string vertexExt, string fragment) : this(new ShaderFile(_normalVertexWithExt)
{
GLSLExtensions = new List<ShaderFile>() { new ShaderFile(vertexExt) }
}, new ShaderFile(fragment)) { }
private PostProcessShader(ShaderFile vertex, ShaderFile fragment) : base(
new ShaderFileCollection(vertex, fragment))
{
fragment.GLSLExtensions.Add(_fragExtensions);
}
public void Draw(ColorAttachment color)
{
GL.UseProgram(this);
GL.BindVertexArray(Plate.Object);
Uniforms["MVP"].SetMatrix4(PostProcessEffect.Mvp);
Uniforms["renderedTexture"].SetTexture(color, 0);
GL.DrawArrays(PrimitiveType.Quads, 0, 4);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindVertexArray(0);
GL.UseProgram(0);
}
public void Draw(ColorAttachment color, Action<UniformCollection> setUniformAction)
{
GL.UseProgram(this);
GL.BindVertexArray(Plate.Object);
Uniforms["MVP"].SetMatrix4(PostProcessEffect.Mvp);
Uniforms["renderedTexture"].SetTexture(color, 0);
setUniformAction(Uniforms);
GL.DrawArrays(PrimitiveType.Quads, 0, 4);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindVertexArray(0);
GL.UseProgram(0);
}
}
}

View file

@ -1,16 +0,0 @@
using System.Collections.Generic;
using SM.OGL.Framebuffer;
namespace SM.Base.PostProcessing
{
public abstract class PostProcessingEffect
{
public virtual Dictionary<string, int> AdditionalFramebufferOutputs { get; }
public virtual ICollection<Framebuffer> AdditionalFramebuffers { get; }
public void ApplyOutputs(Framebuffer mainbuffer)
{
mainbuffer.Append();
}
}
}

View file

@ -1,16 +1,19 @@
using System.Reflection; #region usings
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endregion
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("SM.Base")] [assembly: AssemblyTitle("Basis for every SMRenderer")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("SMRenderer-Basis functions")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyCompany("iedSoftworks")]
[assembly: AssemblyProduct("SM.Base")] [assembly: AssemblyProduct("SM.Base")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2020")] [assembly: AssemblyCopyright("Copyright © iedSoftworks 2020")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View file

@ -34,8 +34,8 @@
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="OpenTK, Version=3.2.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> <Reference Include="OpenTK, Version=3.2.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.3.2\lib\net20\OpenTK.dll</HintPath> <HintPath>..\..\packages\OpenTK.3.2.1\lib\net20\OpenTK.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@ -43,27 +43,23 @@
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" /> <Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Controls\Mouse.cs" /> <Compile Include="Controls\Mouse.cs" />
<Compile Include="Drawing\DrawingBasis.cs" /> <Compile Include="Drawing\DrawingBasis.cs" />
<Compile Include="Drawing\GenericTransformation.cs" /> <Compile Include="Drawing\GenericTransformation.cs" />
<Compile Include="Drawing\Instance.cs" /> <Compile Include="Drawing\Instance.cs" />
<Compile Include="Drawing\IShader.cs" /> <Compile Include="Drawing\MaterialShader.cs" />
<Compile Include="Log.cs" /> <Compile Include="Log.cs" />
<Compile Include="Objects\Mesh.cs" /> <Compile Include="Objects\Mesh.cs" />
<Compile Include="PostProcessing\PostProcessingEffect.cs" /> <Compile Include="PostProcess\PostProcessEffect.cs" />
<Compile Include="PostProcess\PostProcessShader.cs" />
<Compile Include="Scene\IShowCollection.cs" /> <Compile Include="Scene\IShowCollection.cs" />
<Compile Include="Scene\IShowItem.cs" /> <Compile Include="Scene\IShowItem.cs" />
<Compile Include="Drawing\Material.cs" /> <Compile Include="Drawing\Material.cs" />
<Compile Include="Scene\IBackgroundItem.cs" /> <Compile Include="Scene\IBackgroundItem.cs" />
<Compile Include="Scene\GenericItemCollection.cs" /> <Compile Include="Scene\GenericItemCollection.cs" />
<Compile Include="ShaderExtension\ExtensionManager.cs" />
<Compile Include="SMRenderer.cs" /> <Compile Include="SMRenderer.cs" />
<Compile Include="Textures\Texture.cs" /> <Compile Include="Textures\Texture.cs" />
<Compile Include="Text\CharParameter.cs" /> <Compile Include="Text\CharParameter.cs" />
@ -81,6 +77,7 @@
<Compile Include="Utility\Deltatime.cs" /> <Compile Include="Utility\Deltatime.cs" />
<Compile Include="Utility\Randomize.cs" /> <Compile Include="Utility\Randomize.cs" />
<Compile Include="Utility\RotationUtility.cs" /> <Compile Include="Utility\RotationUtility.cs" />
<Compile Include="Utility\ShaderUtility.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" />
<Compile Include="Window\GenericWindow.cs" /> <Compile Include="Window\GenericWindow.cs" />
@ -91,8 +88,9 @@
<Compile Include="Window\RenderPipeline.cs" /> <Compile Include="Window\RenderPipeline.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="OpenTK.dll.config" /> <EmbeddedResource Include="ShaderExtension\vertex\basic.vert" />
<None Include="packages.config" /> <EmbeddedResource Include="PostProcess\DefaultFiles\vertexFile.vert" />
<EmbeddedResource Include="PostProcess\DefaultFiles\extensions.frag" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\SM.OGL\SM.OGL.csproj"> <ProjectReference Include="..\SM.OGL\SM.OGL.csproj">
@ -100,6 +98,15 @@
<Name>SM.OGL</Name> <Name>SM.OGL</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<Folder Include="ShaderExtension\fragment\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="PostProcess\DefaultFiles\vertexWithExt.vert" />
</ItemGroup>
<ItemGroup>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -1,33 +1,54 @@
using SM.Base.Objects.Static; #region usings
using SM.Base.Objects.Static;
using SM.Base.Scene;
using SM.Base.Text; using SM.Base.Text;
using SM.OGL.Mesh; using SM.OGL.Mesh;
using SM.OGL.Shaders;
using SM.Utility; using SM.Utility;
#endregion
namespace SM.Base namespace SM.Base
{ {
/// <summary> /// <summary>
/// Contains different information about this renderer. /// Contains different information about this renderer.
/// </summary> /// </summary>
public class SMRenderer public class SMRenderer
{ {
/// <summary> /// <summary>
/// The default mesh. /// Defines, how many instances the 'SM_base_vertex_basic'-extension can handle.
/// </summary>
public const int MaxInstances = 32;
/// <summary>
/// The default mesh.
/// </summary> /// </summary>
public static GenericMesh DefaultMesh = Plate.Object; public static GenericMesh DefaultMesh = Plate.Object;
/// <summary> /// <summary>
/// The default font. /// The default font.
/// </summary> /// </summary>
public static Font DefaultFont; public static Font DefaultFont;
/// <summary> /// <summary>
/// The default deltatime helper. /// The default deltatime helper.
/// </summary> /// </summary>
public static Deltatime DefaultDeltatime = new Deltatime(); public static Deltatime DefaultDeltatime = new Deltatime();
public static MaterialShader DefaultMaterialShader;
/// <summary> /// <summary>
/// Current Frame /// Shows more information onto the log system.
/// </summary>
public static bool AdvancedDebugging = false;
/// <summary>
/// Current Frame
/// </summary> /// </summary>
public static ulong CurrentFrame { get; internal set; } = 0; public static ulong CurrentFrame { get; internal set; } = 0;
public static GenericWindow CurrentWindow;
public static GenericScene CurrentScene;
} }
} }

View file

@ -1,41 +1,52 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Controller for a camera /// Controller for a camera
/// </summary> /// </summary>
public abstract class GenericCamera public abstract class GenericCamera
{ {
/// <summary> /// <summary>
/// The matrix for the orthographic world. /// The matrix for the orthographic world.
/// </summary> /// </summary>
public static Matrix4 OrthographicWorld { get; protected set; } public static Matrix4 OrthographicWorld { get; protected set; }
/// <summary> /// <summary>
/// The matrix for the perspective world. /// The matrix for the perspective world.
/// </summary> /// </summary>
public static Matrix4 PerspectiveWorld { get; protected set; } public static Matrix4 PerspectiveWorld { get; protected set; }
/// <summary> /// <summary>
/// This defines what is up. (Normalized) /// This defines what is up. (Normalized)
/// <para>Default: <see cref="Vector3.UnitY"/></para> /// <para>Default: <see cref="Vector3.UnitY" /></para>
/// </summary> /// </summary>
public static Vector3 UpVector { get; set; } = Vector3.UnitY; public static Vector3 UpVector { get; set; } = Vector3.UnitY;
/// <summary> /// <summary>
/// Contains the view matrix of this camera. /// Contains the view matrix of this camera.
/// <para>Default: <see cref="Matrix4.Identity"/></para> /// <para>Default: <see cref="Matrix4.Identity" /></para>
/// </summary> /// </summary>
public Matrix4 ViewMatrix { get; protected set; } = Matrix4.Identity; public Matrix4 ViewMatrix { get; protected set; } = Matrix4.Identity;
/// <summary> /// <summary>
/// Returns the world matrix that is connected to this camera. /// Returns the world matrix that is connected to this camera.
/// </summary> /// </summary>
public Matrix4 World => Orthographic ? OrthographicWorld : PerspectiveWorld; public Matrix4 World => Orthographic ? OrthographicWorld : PerspectiveWorld;
/// <summary> /// <summary>
/// Calculates the view matrix. /// Represents if the camera is orthographic.
/// </summary> /// </summary>
/// <returns>The calculated view matrix. Same as <see cref="ViewMatrix"/></returns> public abstract bool Orthographic { get; }
/// <summary>
/// Calculates the view matrix.
/// </summary>
/// <returns>The calculated view matrix. Same as <see cref="ViewMatrix" /></returns>
internal Matrix4 CalculateViewMatrix() internal Matrix4 CalculateViewMatrix()
{ {
ViewMatrix = ViewCalculation(); ViewMatrix = ViewCalculation();
@ -43,18 +54,17 @@ namespace SM.Base.Scene
} }
/// <summary> /// <summary>
/// This calculates the view matrix. /// This calculates the view matrix.
/// </summary> /// </summary>
/// <returns>The new view matrix. This is the returns for <see cref="CalculateViewMatrix"/> and the next value for <see cref="ViewMatrix"/>. </returns> /// <returns>
/// The new view matrix. This is the returns for <see cref="CalculateViewMatrix" /> and the next value for
/// <see cref="ViewMatrix" />.
/// </returns>
protected abstract Matrix4 ViewCalculation(); protected abstract Matrix4 ViewCalculation();
/// <summary> /// <summary>
/// Represents if the camera is orthographic. /// This will calculate the world.
/// </summary> /// <para>This is called on <see cref="GenericWindow{TScene,TCamera}.ViewportCamera" /> to calculate the world.</para>
public abstract bool Orthographic { get; }
/// <summary>
/// This will calculate the world.
/// <para>This is called on <see cref="GenericWindow{TScene,TCamera}.ViewportCamera"/> to calculate the world.</para>
/// </summary> /// </summary>
/// <param name="world">The world scale</param> /// <param name="world">The world scale</param>
/// <param name="aspect">The aspect ratio from the window.</param> /// <param name="aspect">The aspect ratio from the window.</param>

View file

@ -1,10 +1,14 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Contains a list of show items. /// Contains a list of show items.
/// </summary> /// </summary>
/// <typeparam name="TItem">The type of show items.</typeparam> /// <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>
@ -22,8 +26,32 @@ namespace SM.Base.Scene
/// <inheritdoc /> /// <inheritdoc />
public ICollection<string> Flags { get; set; } = new[] {"collection"}; public ICollection<string> Flags { get; set; } = new[] {"collection"};
/// <inheritdoc />
public virtual void Update(UpdateContext context)
{
for (var i = 0; i < Objects.Count; i++)
this[i].Update(context);
}
/// <inheritdoc cref="IShowCollection{TItem}.Draw" />
public virtual void Draw(DrawContext context)
{
for (var i = 0; i < Objects.Count; i++)
this[i].Draw(context);
}
/// <inheritdoc />
public virtual void OnAdded(object sender)
{
}
/// <inheritdoc />
public virtual void OnRemoved(object sender)
{
}
/// <summary> /// <summary>
/// Adds a item. /// Adds a item.
/// </summary> /// </summary>
public new void Add(TItem item) public new void Add(TItem item)
{ {
@ -33,7 +61,7 @@ namespace SM.Base.Scene
} }
/// <summary> /// <summary>
/// Removes a item. /// Removes a item.
/// </summary> /// </summary>
/// <param name="item"></param> /// <param name="item"></param>
public new void Remove(TItem item) public new void Remove(TItem item)
@ -43,72 +71,46 @@ namespace SM.Base.Scene
item.OnRemoved(this); item.OnRemoved(this);
} }
/// <inheritdoc />
public virtual void Update(UpdateContext context)
{
for(int i = 0; i < Objects.Count; i++)
this[i].Update(context);
}
/// <inheritdoc cref="IShowCollection{TItem}.Draw" />
public virtual void Draw(DrawContext context)
{
for (int i = 0; i < Objects.Count; i++)
this[i].Draw(context);
}
/// <inheritdoc />
public virtual void OnAdded(object sender)
{
}
/// <inheritdoc />
public virtual void OnRemoved(object sender)
{ }
/// <summary> /// <summary>
/// Returns a object with this name or the default, if not available. /// Returns a object with this name or the default, if not available.
/// <para>Not reclusive.</para> /// <para>Not reclusive.</para>
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
/// <returns></returns> /// <returns></returns>
public TItem GetItemByName(string name) public TItem GetItemByName(string name)
{ {
TItem obj = default; TItem obj = default;
for (var i = 0; i < this.Count; i++) for (var i = 0; i < Count; i++)
{
if (this[i].Name == name) if (this[i].Name == name)
{ {
obj = this[i]; obj = this[i];
break; break;
} }
}
return obj; return obj;
} }
/// <summary> /// <summary>
/// Returns a object with this name or the default if not available. /// Returns a object with this name or the default if not available.
/// <para>Not reclusive.</para> /// <para>Not reclusive.</para>
/// </summary> /// </summary>
/// <typeparam name="TGetItem">Type of return</typeparam> /// <typeparam name="TGetItem">Type of return</typeparam>
public TGetItem GetItemByName<TGetItem>(string name) public TGetItem GetItemByName<TGetItem>(string name)
where TGetItem : TItem where TGetItem : TItem
{ {
return (TGetItem)GetItemByName(name); return (TGetItem) GetItemByName(name);
} }
/// <summary> /// <summary>
/// Returns all object that have this flag. /// Returns all object that have this flag.
/// <para>Only in this list.</para> /// <para>Only in this list.</para>
/// </summary> /// </summary>
public ICollection<TItem> GetItemsWithFlag(string flag) public ICollection<TItem> GetItemsWithFlag(string flag)
{ {
List<TItem> list = new List<TItem>(); var list = new List<TItem>();
for (var i = 0; i < this.Count; i++) for (var i = 0; i < Count; i++)
{ {
TItem obj = this[i]; var obj = this[i];
if (obj.Flags.Contains(flag)) list.Add(obj); if (obj.Flags.Contains(flag)) list.Add(obj);
} }
@ -117,7 +119,7 @@ namespace SM.Base.Scene
} }
/// <summary> /// <summary>
/// Contains a list of show items with transformation. /// Contains a list of show items with transformation.
/// </summary> /// </summary>
/// <typeparam name="TItem">The type of show items.</typeparam> /// <typeparam name="TItem">The type of show items.</typeparam>
/// <typeparam name="TTransformation">The type of transformation.</typeparam> /// <typeparam name="TTransformation">The type of transformation.</typeparam>
@ -126,7 +128,7 @@ namespace SM.Base.Scene
where TTransformation : GenericTransformation, new() where TTransformation : GenericTransformation, new()
{ {
/// <summary> /// <summary>
/// Transformation of the collection /// Transformation of the collection
/// </summary> /// </summary>
public TTransformation Transform = new TTransformation(); public TTransformation Transform = new TTransformation();

View file

@ -1,19 +1,22 @@
using System; #region usings
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK; using System.Dynamic;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// A generic scene, that imports functions for scene control. /// A generic scene, that imports functions for scene control.
/// </summary> /// </summary>
public abstract class GenericScene public abstract class GenericScene
{ {
private IBackgroundItem _background; private IBackgroundItem _background;
/// <summary> /// <summary>
/// This contains the background. /// This contains the background.
/// </summary> /// </summary>
protected IBackgroundItem _Background protected IBackgroundItem _Background
{ {
@ -24,41 +27,53 @@ namespace SM.Base.Scene
_background = value; _background = value;
} }
} }
public bool IsInitialized { get; private set; }
/// <summary> /// <summary>
/// Updates this scene. /// Updates this scene.
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
public virtual void Update(UpdateContext context) public virtual void Update(UpdateContext context)
{ {
} }
/// <summary> /// <summary>
/// Draws this scene. /// Draws this scene.
/// </summary> /// </summary>
public virtual void Draw(DrawContext context) public virtual void Draw(DrawContext context)
{ {
} }
/// <summary> /// <summary>
/// Called, when the user activates the scene. /// Called, when the user activates the scene.
/// </summary> /// </summary>
internal void Activate() internal void Activate()
{ {
if (!IsInitialized)
{
OnInitialization();
IsInitialized = true;
}
OnActivating(); OnActivating();
} }
/// <summary> /// <summary>
/// Called, when the user activates the scene. /// Called, when the user activates the scene for the first time.
/// </summary>
protected virtual void OnInitialization()
{ }
/// <summary>
/// Called, when the user activates the scene.
/// </summary> /// </summary>
protected virtual void OnActivating() protected virtual void OnActivating()
{ } {
}
} }
/// <summary> /// <summary>
/// A generic scene that imports different functions. /// A generic scene that imports different functions.
/// </summary> /// </summary>
/// <typeparam name="TCamera">The type of cameras.</typeparam> /// <typeparam name="TCamera">The type of cameras.</typeparam>
/// <typeparam name="TItem">The type of show items.</typeparam> /// <typeparam name="TItem">The type of show items.</typeparam>
@ -68,25 +83,32 @@ namespace SM.Base.Scene
where TCollection : GenericItemCollection<TItem>, new() where TCollection : GenericItemCollection<TItem>, new()
where TItem : IShowItem where TItem : IShowItem
{ {
private TCollection _objectCollection = new TCollection();
private TCollection _hud = new TCollection(); private TCollection _hud = new TCollection();
private TCollection _objectCollection = new TCollection();
/// <summary> /// <summary>
/// The active camera, that is used if the context doesn't force the viewport camera. /// A collection for cameras to switch easier to different cameras.
/// <para>If none set, it automaticly uses the viewport camera.</para> /// </summary>
public Dictionary<string, TCamera> Cameras = new Dictionary<string, TCamera>();
/// <summary>
/// The active camera, that is used if the context doesn't force the viewport camera.
/// <para>If none set, it automaticly uses the viewport camera.</para>
/// </summary> /// </summary>
public TCamera Camera { get; set; } public TCamera Camera { get; set; }
/// <summary> /// <summary>
/// A camera to control the background. /// A camera to control the background.
/// </summary> /// </summary>
public TCamera BackgroundCamera { get; set; } = new TCamera(); public TCamera BackgroundCamera { get; set; } = new TCamera();
/// <summary> /// <summary>
/// A camera to control the HUD. /// A camera to control the HUD.
/// </summary> /// </summary>
public TCamera HUDCamera { get; set; } = new TCamera(); public TCamera HUDCamera { get; set; } = new TCamera();
/// <summary> /// <summary>
/// Objects inside the scene. /// Objects inside the scene.
/// </summary> /// </summary>
public TCollection Objects public TCollection Objects
{ {
@ -99,7 +121,7 @@ namespace SM.Base.Scene
} }
/// <summary> /// <summary>
/// This defines the HUD objects. /// This defines the HUD objects.
/// </summary> /// </summary>
public TCollection HUD public TCollection HUD
{ {
@ -110,10 +132,6 @@ namespace SM.Base.Scene
_hud = value; _hud = value;
} }
} }
/// <summary>
/// A collection for cameras to switch easier to different cameras.
/// </summary>
public Dictionary<string, TCamera> Cameras = new Dictionary<string, TCamera>();
/// <inheritdoc /> /// <inheritdoc />
@ -127,14 +145,28 @@ namespace SM.Base.Scene
/// <inheritdoc /> /// <inheritdoc />
public override void Draw(DrawContext context) public override void Draw(DrawContext context)
{ {
if (!context.ForceViewport && Camera != null) context.View = Camera.CalculateViewMatrix(); DrawBackground(context);
DrawContext backgroundDrawContext = context; DrawMainObjects(context);
DrawHUD(context);
}
public void DrawBackground(DrawContext context)
{
var backgroundDrawContext = context;
backgroundDrawContext.View = BackgroundCamera.CalculateViewMatrix(); backgroundDrawContext.View = BackgroundCamera.CalculateViewMatrix();
_Background?.Draw(backgroundDrawContext); _Background?.Draw(backgroundDrawContext);
}
public void DrawMainObjects(DrawContext context)
{
if (!context.ForceViewport && Camera != null) context.View = Camera.CalculateViewMatrix();
_objectCollection.Draw(context); _objectCollection.Draw(context);
}
public void DrawHUD(DrawContext context)
{
context.View = HUDCamera.CalculateViewMatrix(); context.View = HUDCamera.CalculateViewMatrix();
_hud.Draw(context); _hud.Draw(context);
} }

View file

@ -1,10 +1,9 @@
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// A iteration of <see cref="IShowItem"/> to reduce clutter. /// A iteration of <see cref="IShowItem" /> to reduce clutter.
/// </summary> /// </summary>
public interface IBackgroundItem : IShowItem public interface IBackgroundItem : IShowItem
{ {
} }
} }

View file

@ -1,21 +1,25 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Adds functions, that is required for a collection. /// Adds functions, that is required for a collection.
/// </summary> /// </summary>
/// <typeparam name="TItem">The type of show item.</typeparam> /// <typeparam name="TItem">The type of show item.</typeparam>
public interface IShowCollection<TItem> where TItem : IShowItem public interface IShowCollection<TItem> where TItem : IShowItem
{ {
/// <summary> /// <summary>
/// The object collection. /// The object collection.
/// </summary> /// </summary>
List<TItem> Objects { get; } List<TItem> Objects { get; }
/// <summary> /// <summary>
/// This draws the objects in the <see cref="Objects"/> list. /// This draws the objects in the <see cref="Objects" /> list.
/// </summary> /// </summary>
/// <param name="context">The context how the objects need to be drawn.</param> /// <param name="context">The context how the objects need to be drawn.</param>
void Draw(DrawContext context); void Draw(DrawContext context);

View file

@ -1,45 +1,51 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
/// <summary> /// <summary>
/// Adds requirements to object, to be properly used as a update and/or draw item. /// Adds requirements to object, to be properly used as a update and/or draw item.
/// </summary> /// </summary>
public interface IShowItem public interface IShowItem
{ {
/// <summary> /// <summary>
/// Parent of the object. /// Parent of the object.
/// </summary> /// </summary>
object Parent { get; set; } object Parent { get; set; }
/// <summary> /// <summary>
/// Contains the name for the object. /// Contains the name for the object.
/// </summary> /// </summary>
string Name { get; set; } string Name { get; set; }
/// <summary> /// <summary>
/// Contains specific flags for the object. /// Contains specific flags for the object.
/// </summary> /// </summary>
ICollection<string> Flags { get; set; } ICollection<string> Flags { get; set; }
/// <summary> /// <summary>
/// Tells the object to update own systems. /// Tells the object to update own systems.
/// </summary> /// </summary>
/// <param name="context">The update context</param> /// <param name="context">The update context</param>
void Update(UpdateContext context); void Update(UpdateContext context);
/// <summary> /// <summary>
/// Tells the object to draw its object. /// Tells the object to draw its object.
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
void Draw(DrawContext context); void Draw(DrawContext context);
/// <summary> /// <summary>
/// Action, that is called, when the object was added to a GenericItemCollection. /// Action, that is called, when the object was added to a GenericItemCollection.
/// </summary> /// </summary>
void OnAdded(object sender); void OnAdded(object sender);
/// <summary> /// <summary>
/// Action, that is called, when the object was removed from a GenericItemCollection. /// Action, that is called, when the object was removed from a GenericItemCollection.
/// </summary> /// </summary>
void OnRemoved(object sender); void OnRemoved(object sender);
} }

View file

@ -0,0 +1,19 @@
#region usings
using SM.OGL.Shaders;
#endregion
namespace SM.Base.ShaderExtension
{
internal class ExtensionManager
{
internal static void InitExtensions()
{
ShaderExtensions.AddAssemblyExtensions("SM_base", "SM.Base.ShaderExtension");
ShaderExtensions.Extensions["SM_base_vertex_basic"].StringOverrides["instanceMax"] =
SMRenderer.MaxInstances.ToString();
}
}
}

View file

@ -0,0 +1,35 @@
#version 330
#define maxInstances //!instanceMax
struct Instance {
mat4 ModelMatrix;
vec2 TextureOffset;
vec2 TextureScale;
};
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTex;
layout(location = 3) in vec4 aColor;
uniform mat4 MVP;
uniform bool HasVColor;
uniform Instance[maxInstances] Instances;
out vec2 vTexture;
out vec4 vColor;
out vec3 FragPos;
void ApplyTexModifier() {
vTexture = aTex * Instances[gl_InstanceID].TextureScale + Instances[gl_InstanceID].TextureOffset;
}
void CheckVertexColor() {
if (HasVColor) vColor = aColor;
else vColor = vec4(1);
}
void ApplyModelTransformation() {
gl_Position = MVP * Instances[gl_InstanceID].ModelMatrix * vec4(aPos, 1);
FragPos = vec3(Instances[gl_InstanceID].ModelMatrix * vec4(aPos, 1));
}

View file

@ -1,28 +1,34 @@
using System; #region usings
using System;
#endregion
namespace SM.Base.Text namespace SM.Base.Text
{ {
/// <summary> /// <summary>
/// Contains information for a font character. /// Contains information for a font character.
/// </summary> /// </summary>
[Serializable] [Serializable]
public struct CharParameter public struct CharParameter
{ {
/// <summary> /// <summary>
/// The position on the X-axis. /// The position on the X-axis.
/// </summary> /// </summary>
public int X; public int X;
/// <summary> /// <summary>
/// The width of the character. /// The width of the character.
/// </summary> /// </summary>
public float Width; public float Width;
/// <summary> /// <summary>
/// The normalized position inside the texture. /// The normalized position inside the texture.
/// </summary> /// </summary>
public float NormalizedX; public float NormalizedX;
/// <summary> /// <summary>
/// The normalized width inside the texture. /// The normalized width inside the texture.
/// </summary> /// </summary>
public float NormalizedWidth; public float NormalizedWidth;
} }

View file

@ -1,71 +1,74 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Drawing.Text; using System.Drawing.Text;
using System.Security.Policy;
using OpenTK;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using OpenTK.Input;
using SM.Base.Textures; using SM.Base.Textures;
using SM.Data.Fonts; using SM.Data.Fonts;
using SM.OGL.Texture;
#endregion
namespace SM.Base.Text namespace SM.Base.Text
{ {
/// <summary> /// <summary>
/// Represents a font. /// Represents a font.
/// </summary> /// </summary>
public class Font : Texture public class Font : Texture
{ {
/// <inheritdoc />
public override TextureWrapMode WrapMode { get; set; } = TextureWrapMode.ClampToEdge;
/// <summary> /// <summary>
/// The font family, that is used to find the right font. /// The char set for the font.
/// </summary> /// <para>Default: <see cref="FontCharStorage.SimpleUTF8" /></para>
public FontFamily FontFamily;
/// <summary>
/// The font style.
/// <para>Default: <see cref="System.Drawing.FontStyle.Regular"/></para>
/// </summary>
public FontStyle FontStyle = FontStyle.Regular;
/// <summary>
/// The font size.
/// <para>Default: 12</para>
/// </summary>
public float FontSize = 12;
/// <summary>
/// The char set for the font.
/// <para>Default: <see cref="FontCharStorage.SimpleUTF8"/></para>
/// </summary> /// </summary>
public ICollection<char> CharSet = FontCharStorage.SimpleUTF8; public ICollection<char> CharSet = FontCharStorage.SimpleUTF8;
/// <summary> /// <summary>
/// This contains all information for the different font character. /// The font family, that is used to find the right font.
/// </summary>
public FontFamily FontFamily;
/// <summary>
/// The font size.
/// <para>Default: 12</para>
/// </summary>
public float FontSize = 12;
/// <summary>
/// The font style.
/// <para>Default: <see cref="System.Drawing.FontStyle.Regular" /></para>
/// </summary>
public FontStyle FontStyle = FontStyle.Regular;
/// <summary>
/// This contains all information for the different font character.
/// </summary> /// </summary>
public Dictionary<char, CharParameter> Positions = new Dictionary<char, CharParameter>(); public Dictionary<char, CharParameter> Positions = new Dictionary<char, CharParameter>();
/// <summary> /// <summary>
/// Generates a font from a font family from the specified path. /// Generates a font from a font family from the specified path.
/// </summary> /// </summary>
/// <param name="path">The specified path</param> /// <param name="path">The specified path</param>
public Font(string path) public Font(string path)
{ {
PrivateFontCollection pfc = new PrivateFontCollection(); var pfc = new PrivateFontCollection();
pfc.AddFontFile(path); pfc.AddFontFile(path);
FontFamily = pfc.Families[0]; FontFamily = pfc.Families[0];
} }
/// <summary> /// <summary>
/// Generates a font from a specified font family. /// Generates a font from a specified font family.
/// </summary> /// </summary>
/// <param name="font">Font-Family</param> /// <param name="font">Font-Family</param>
public Font(FontFamily font) public Font(FontFamily font)
{ {
FontFamily = font; FontFamily = font;
} }
/// <inheritdoc />
public override TextureWrapMode WrapMode { get; set; } = TextureWrapMode.ClampToEdge;
/// <summary> /// <summary>
/// Regenerates the texture. /// Regenerates the texture.
/// </summary> /// </summary>
public void RegenerateTexture() public void RegenerateTexture()
{ {
@ -74,47 +77,47 @@ namespace SM.Base.Text
Positions = new Dictionary<char, CharParameter>(); Positions = new Dictionary<char, CharParameter>();
Bitmap map = new Bitmap(1000, 20); var map = new Bitmap(1000, 20);
Dictionary<char, float[]> charParams = new Dictionary<char, float[]>(); var charParams = new Dictionary<char, float[]>();
using (System.Drawing.Font f = new System.Drawing.Font(FontFamily, FontSize, FontStyle)) using (var f = new System.Drawing.Font(FontFamily, FontSize, FontStyle))
{ {
using (Graphics g = Graphics.FromImage(map)) using (var g = Graphics.FromImage(map))
{ {
g.Clear(Color.Transparent); g.Clear(Color.Transparent);
foreach (char c in CharSet) foreach (var c in CharSet)
{ {
string s = c.ToString(); var s = c.ToString();
SizeF size = g.MeasureString(s, f); var size = g.MeasureString(s, f);
try try
{ {
charParams.Add(c, new[] {size.Width, Width }); charParams.Add(c, new[] {size.Width, Width});
} }
catch catch
{ {
// ignored // ignored
} }
if (Height < size.Height) Height = (int)size.Height; if (Height < size.Height) Height = (int) size.Height;
Width += (int)size.Width; Width += (int) size.Width;
} }
} }
map = new Bitmap(Width, Height); map = new Bitmap(Width, Height);
using (Graphics g = Graphics.FromImage(map)) using (var g = Graphics.FromImage(map))
{ {
foreach (KeyValuePair<char, float[]> keyValuePair in charParams) foreach (var keyValuePair in charParams)
{ {
float normalizedX = (keyValuePair.Value[1] + 0.00001f) / Width; var normalizedX = (keyValuePair.Value[1] + 0.00001f) / Width;
float normalizedWidth = (keyValuePair.Value[0]) / Width; var normalizedWidth = keyValuePair.Value[0] / Width;
CharParameter parameter; CharParameter parameter;
Positions.Add(keyValuePair.Key, parameter = new CharParameter() Positions.Add(keyValuePair.Key, parameter = new CharParameter
{ {
NormalizedWidth = normalizedWidth, NormalizedWidth = normalizedWidth,
NormalizedX = normalizedX, NormalizedX = normalizedX,
Width = keyValuePair.Value[0], Width = keyValuePair.Value[0],
X = (int)keyValuePair.Value[1] X = (int) keyValuePair.Value[1]
}); });
g.DrawString(keyValuePair.Key.ToString(), f, Brushes.White, parameter.X, 0); g.DrawString(keyValuePair.Key.ToString(), f, Brushes.White, parameter.X, 0);

View file

@ -1,28 +1,29 @@
namespace SM.Data.Fonts namespace SM.Data.Fonts
{ {
/// <summary> /// <summary>
/// Contains default char sets. /// Contains default char sets.
/// </summary> /// </summary>
public class FontCharStorage public class FontCharStorage
{ {
/// <summary> /// <summary>
/// Contains the english alphabet and the common special character. /// Contains the english alphabet and the common special character.
/// </summary> /// </summary>
public static readonly char[] SimpleUTF8 = new char[] public static readonly char[] SimpleUTF8 =
{ {
'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', '2', '3', '4', '5',
'6',
'7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_', '`',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~' 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'
}; };
/// <summary> /// <summary>
/// Contains only numbers. /// Contains only numbers.
/// </summary> /// </summary>
public static readonly char[] Numbers = new[] public static readonly char[] Numbers =
{ {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9' '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
}; };
} }
} }

View file

@ -1,30 +1,49 @@
using System; #region usings
using System;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Data.Fonts;
#endregion
namespace SM.Base.Text namespace SM.Base.Text
{ {
/// <summary> /// <summary>
/// Defines a basis for text drawing. /// Defines a basis for text drawing.
/// </summary> /// </summary>
/// <typeparam name="TTransform">Transformation type</typeparam> /// <typeparam name="TTransform">Transformation type</typeparam>
public abstract class TextDrawingBasis<TTransform> : DrawingBasis<TTransform> public abstract class TextDrawingBasis<TTransform> : DrawingBasis<TTransform>
where TTransform : GenericTransformation, new() where TTransform : GenericTransformation, new()
{ {
/// <summary> /// <summary>
/// The different instances for drawing. /// The different instances for drawing.
/// </summary> /// </summary>
protected Instance[] _instances; protected Instance[] _instances;
/// <summary> /// <summary>
/// The text, that is drawn. /// The text, that is drawn.
/// </summary> /// </summary>
protected string _text; protected string _text;
/// <summary> /// <summary>
/// The font. /// The spacing between numbers.
/// <para>Default: 1</para>
/// </summary>
public float Spacing = 1;
/// <summary>
/// Creates a text object with a font.
/// </summary>
/// <param name="font">The font.</param>
protected TextDrawingBasis(Font font)
{
_material.Texture = font;
}
/// <summary>
/// The font.
/// </summary> /// </summary>
public Font Font public Font Font
{ {
@ -37,7 +56,7 @@ namespace SM.Base.Text
} }
/// <summary> /// <summary>
/// The text, that is drawn. /// The text, that is drawn.
/// </summary> /// </summary>
public string Text public string Text
{ {
@ -50,7 +69,7 @@ namespace SM.Base.Text
} }
/// <summary> /// <summary>
/// The font color. /// The font color.
/// </summary> /// </summary>
public Color4 Color public Color4 Color
{ {
@ -58,21 +77,6 @@ namespace SM.Base.Text
set => _material.Tint = value; set => _material.Tint = value;
} }
/// <summary>
/// The spacing between numbers.
/// <para>Default: 1</para>
/// </summary>
public float Spacing = 1;
/// <summary>
/// Creates a text object with a font.
/// </summary>
/// <param name="font">The font.</param>
protected TextDrawingBasis(Font font)
{
_material.Texture = font;
}
/// <inheritdoc /> /// <inheritdoc />
protected override void DrawContext(ref DrawContext context) protected override void DrawContext(ref DrawContext context)
@ -81,7 +85,7 @@ namespace SM.Base.Text
} }
/// <summary> /// <summary>
/// This generates the instances. /// This generates the instances.
/// </summary> /// </summary>
/// <exception cref="Exception">The font doesn't contain a character that is needed for the text.</exception> /// <exception cref="Exception">The font doesn't contain a character that is needed for the text.</exception>
public void GenerateMatrixes() public void GenerateMatrixes()
@ -91,7 +95,7 @@ namespace SM.Base.Text
_instances = new Instance[_text.Length]; _instances = new Instance[_text.Length];
float x = 0; float x = 0;
CharParameter _last = new CharParameter(); var _last = new CharParameter();
for (var i = 0; i < _text.Length; i++) for (var i = 0; i < _text.Length; i++)
{ {
if (_text[i] == 32) if (_text[i] == 32)
@ -110,8 +114,8 @@ namespace SM.Base.Text
throw new Exception("Font doesn't contain '" + _text[i] + "'"); throw new Exception("Font doesn't contain '" + _text[i] + "'");
} }
Matrix4 matrix = Matrix4.CreateScale(parameter.Width, Font.Height, 1) * var matrix = Matrix4.CreateScale(parameter.Width, Font.Height, 1) *
Matrix4.CreateTranslation(x, 0, 0); Matrix4.CreateTranslation(x, 0, 0);
_instances[i] = new Instance _instances[i] = new Instance
{ {
ModelMatrix = matrix, ModelMatrix = matrix,

View file

@ -1,38 +1,48 @@
using System.Drawing; #region usings
using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.OGL.Texture; using SM.OGL.Texture;
using PixelFormat = System.Drawing.Imaging.PixelFormat; using PixelFormat = System.Drawing.Imaging.PixelFormat;
#endregion
namespace SM.Base.Textures namespace SM.Base.Textures
{ {
/// <summary> /// <summary>
/// Texture that can be drawn to an object. /// Texture that can be drawn to an object.
/// </summary> /// </summary>
public class Texture : TextureBase public class Texture : TextureBase
{ {
/// <summary> /// <summary>
/// The texture as bitmap. /// Decides if the bitmap will automatically dispose itself.
/// </summary>
public Bitmap Map;
/// <summary>
/// Decides if the bitmap will automatically dispose itself.
/// </summary> /// </summary>
public bool AutoDispose = false; public bool AutoDispose = false;
/// <summary> /// <summary>
/// Empty constructor /// The texture as bitmap.
/// </summary> /// </summary>
protected Texture() {} public Bitmap Map;
/// <summary> /// <summary>
/// Creates a texture with only the map. /// Empty constructor
/// <para>Sets the filter to Linear and WrapMode to Repeat.</para> /// </summary>
protected Texture()
{
}
/// <summary>
/// Creates a texture with only the map.
/// <para>Sets the filter to Linear and WrapMode to Repeat.</para>
/// </summary> /// </summary>
/// <param name="map">The map</param> /// <param name="map">The map</param>
public Texture(Bitmap map) : this(map, TextureMinFilter.Linear, TextureWrapMode.Repeat) {} public Texture(Bitmap map) : this(map, TextureMinFilter.Linear, TextureWrapMode.Repeat)
{
}
/// <summary> /// <summary>
/// Creates the texture. /// Creates the texture.
/// </summary> /// </summary>
/// <param name="map">The texture map</param> /// <param name="map">The texture map</param>
/// <param name="filter">The filter</param> /// <param name="filter">The filter</param>
@ -62,22 +72,23 @@ namespace SM.Base.Textures
} }
/// <summary> /// <summary>
/// Generates a OpenGL-texture. /// Generates a OpenGL-texture.
/// </summary> /// </summary>
/// <param name="map">The texture as bitmap</param> /// <param name="map">The texture as bitmap</param>
/// <param name="filter">The filter</param> /// <param name="filter">The filter</param>
/// <param name="wrapMode">The wrap mode</param> /// <param name="wrapMode">The wrap mode</param>
/// <param name="dispose">Auto dispose of the bitmap? Default: false</param> /// <param name="dispose">Auto dispose of the bitmap? Default: false</param>
/// <returns></returns> /// <returns></returns>
public static int GenerateTexture(Bitmap map, TextureMinFilter filter, TextureWrapMode wrapMode, bool dispose = false) public static int GenerateTexture(Bitmap map, TextureMinFilter filter, TextureWrapMode wrapMode,
bool dispose = false)
{ {
int id = GL.GenTexture(); var id = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, id); GL.BindTexture(TextureTarget.Texture2D, id);
BitmapData data = map.LockBits(new Rectangle(0, 0, map.Width, map.Height), ImageLockMode.ReadOnly, var data = map.LockBits(new Rectangle(0, 0, map.Width, map.Height), ImageLockMode.ReadOnly,
map.PixelFormat); map.PixelFormat);
bool transparenz = map.PixelFormat == PixelFormat.Format32bppArgb; var transparenz = map.PixelFormat == PixelFormat.Format32bppArgb;
GL.TexImage2D(TextureTarget.Texture2D, 0, GL.TexImage2D(TextureTarget.Texture2D, 0,
transparenz ? PixelInternalFormat.Rgba : PixelInternalFormat.Rgb, transparenz ? PixelInternalFormat.Rgba : PixelInternalFormat.Rgb,
@ -85,10 +96,10 @@ namespace SM.Base.Textures
transparenz ? OpenTK.Graphics.OpenGL4.PixelFormat.Bgra : OpenTK.Graphics.OpenGL4.PixelFormat.Bgr, transparenz ? OpenTK.Graphics.OpenGL4.PixelFormat.Bgra : OpenTK.Graphics.OpenGL4.PixelFormat.Bgr,
PixelType.UnsignedByte, data.Scan0); PixelType.UnsignedByte, data.Scan0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)filter); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) filter);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)filter); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) filter);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)wrapMode); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) wrapMode);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)wrapMode); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) wrapMode);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
@ -101,8 +112,11 @@ namespace SM.Base.Textures
} }
/// <summary> /// <summary>
/// Converts a bitmap to a texture. /// Converts a bitmap to a texture.
/// </summary> /// </summary>
public static implicit operator Texture(Bitmap map) => new Texture(map); public static implicit operator Texture(Bitmap map)
{
return new Texture(map);
}
} }
} }

View file

@ -1,10 +1,14 @@
using System; #region usings
using System;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Time namespace SM.Base.Time
{ {
/// <summary> /// <summary>
/// Performs intervals. /// Performs intervals.
/// </summary> /// </summary>
public class Interval : Timer public class Interval : Timer
{ {
@ -24,13 +28,14 @@ namespace SM.Base.Time
protected override void Stopping(UpdateContext context) protected override void Stopping(UpdateContext context)
{ {
TriggerEndAction(context); TriggerEndAction(context);
if (_stop){base.Stop();} if (_stop)
base.Stop();
else Reset(); else Reset();
} }
/// <summary> /// <summary>
/// This will tell the interval to stop after the next iteration. /// This will tell the interval to stop after the next iteration.
/// <para>To stop immediately use <see cref="Cancel"/></para> /// <para>To stop immediately use <see cref="Cancel" /></para>
/// </summary> /// </summary>
public override void Stop() public override void Stop()
{ {
@ -38,7 +43,7 @@ namespace SM.Base.Time
} }
/// <summary> /// <summary>
/// This will stop the interval immediately. /// This will stop the interval immediately.
/// </summary> /// </summary>
public void Cancel() public void Cancel()
{ {

View file

@ -1,22 +1,26 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Time namespace SM.Base.Time
{ {
/// <summary> /// <summary>
/// Represents a stopwatch. /// Represents a stopwatch.
/// </summary> /// </summary>
public class Stopwatch public class Stopwatch
{ {
private static List<Stopwatch> _activeStopwatches = new List<Stopwatch>(); private static List<Stopwatch> _activeStopwatches = new List<Stopwatch>();
/// <summary> /// <summary>
/// Contains how much time already has passed. (in seconds) /// Contains how much time already has passed. (in seconds)
/// </summary> /// </summary>
public float Elapsed { get; private set; } public float Elapsed { get; private set; }
/// <summary> /// <summary>
/// Starts the stopwatch. /// Starts the stopwatch.
/// </summary> /// </summary>
public virtual void Start() public virtual void Start()
{ {
@ -24,7 +28,7 @@ namespace SM.Base.Time
} }
/// <summary> /// <summary>
/// Performs a tick. /// Performs a tick.
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
private protected virtual void Tick(UpdateContext context) private protected virtual void Tick(UpdateContext context)
@ -33,7 +37,7 @@ namespace SM.Base.Time
} }
/// <summary> /// <summary>
/// Stops the stopwatch. /// Stops the stopwatch.
/// </summary> /// </summary>
public virtual void Stop() public virtual void Stop()
{ {
@ -41,7 +45,7 @@ namespace SM.Base.Time
} }
/// <summary> /// <summary>
/// Resets the stopwatch. /// Resets the stopwatch.
/// </summary> /// </summary>
public void Reset() public void Reset()
{ {
@ -50,10 +54,7 @@ namespace SM.Base.Time
internal static void PerformTicks(UpdateContext context) internal static void PerformTicks(UpdateContext context)
{ {
for (var i = 0; i < _activeStopwatches.Count; i++) for (var i = 0; i < _activeStopwatches.Count; i++) _activeStopwatches[i].Tick(context);
{
_activeStopwatches[i].Tick(context);
}
} }
} }
} }

View file

@ -1,31 +1,19 @@
using System; #region usings
using System.Collections.Generic;
using System;
using SM.Base.Contexts; using SM.Base.Contexts;
#endregion
namespace SM.Base.Time namespace SM.Base.Time
{ {
/// <summary> /// <summary>
/// Timer-System /// Timer-System
/// </summary> /// </summary>
public class Timer : Stopwatch public class Timer : Stopwatch
{ {
/// <summary> /// <summary>
/// The target time in seconds. /// Creates a timer with specified seconds.
/// </summary>
public float Target { get; private set; }
/// <summary>
/// The already elapsed time but normalized to the target.
/// </summary>
public float ElapsedNormalized { get; private set; }
/// <summary>
/// The event, that is triggered when the timer stops.
/// </summary>
public event Action<Timer, UpdateContext> EndAction;
/// <summary>
/// Creates a timer with specified seconds.
/// </summary> /// </summary>
/// <param name="seconds"></param> /// <param name="seconds"></param>
public Timer(float seconds) public Timer(float seconds)
@ -34,14 +22,29 @@ namespace SM.Base.Time
} }
/// <summary> /// <summary>
/// Creates a timer with a time span. /// Creates a timer with a time span.
/// </summary> /// </summary>
/// <param name="timeSpan"></param> /// <param name="timeSpan"></param>
public Timer(TimeSpan timeSpan) public Timer(TimeSpan timeSpan)
{ {
Target = (float)timeSpan.TotalSeconds; Target = (float) timeSpan.TotalSeconds;
} }
/// <summary>
/// The target time in seconds.
/// </summary>
public float Target { get; private set; }
/// <summary>
/// The already elapsed time but normalized to the target.
/// </summary>
public float ElapsedNormalized { get; private set; }
/// <summary>
/// The event, that is triggered when the timer stops.
/// </summary>
public event Action<Timer, UpdateContext> EndAction;
/// <inheritdoc /> /// <inheritdoc />
public override void Start() public override void Start()
{ {
@ -58,15 +61,16 @@ namespace SM.Base.Time
} }
/// <summary> /// <summary>
/// Occurs, when the timer tries to stop. /// Occurs, when the timer tries to stop.
/// </summary> /// </summary>
protected virtual void Stopping(UpdateContext context) protected virtual void Stopping(UpdateContext context)
{ {
EndAction?.Invoke(this, context); EndAction?.Invoke(this, context);
Stop(); Stop();
} }
/// <summary> /// <summary>
/// This will trigger <see cref="EndAction"/> /// This will trigger <see cref="EndAction" />
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="context"></param>
protected void TriggerEndAction(UpdateContext context) protected void TriggerEndAction(UpdateContext context)

View file

@ -1,146 +1,145 @@
using System; #region usings
using System.Configuration.Assemblies;
using System.Diagnostics; using System.Diagnostics;
using OpenTK; using OpenTK;
#endregion
namespace SM.Base.Types namespace SM.Base.Types
{ {
/// <summary> /// <summary>
/// Represents a base vector-class /// Represents a base vector-class
/// </summary> /// </summary>
public abstract class CVector public abstract class CVector
{ {
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private float _x = default;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private float _y = default;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private float _z = default;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private float _w = default;
/// <summary> /// <summary>
/// The X-component. /// Creates a vector by setting every component to the same value.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _X
{
get => _x;
set => _x = value;
}
/// <summary>
/// The Y-component
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _Y
{
get => _y;
set => _y = value;
}
/// <summary>
/// The Z-component.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _Z
{
get => _z;
set => _z = value;
}
/// <summary>
/// The W-component.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _W
{
get => _w;
set => _w = value;
}
/// <summary>
/// Creates a vector by setting every component to the same value.
/// </summary> /// </summary>
protected CVector(float uniform) : this(uniform, uniform, uniform, uniform) protected CVector(float uniform) : this(uniform, uniform, uniform, uniform)
{ } {
}
/// <summary> /// <summary>
/// Creates a vector by setting values for each component. /// Creates a vector by setting values for each component.
/// </summary> /// </summary>
protected CVector(float x, float y, float z, float w) protected CVector(float x, float y, float z, float w)
{ {
_x = x; _X = x;
_y = y; _Y = y;
_z = z; _Z = z;
_w = w; _W = w;
} }
#region Set
/// <summary> /// <summary>
/// Sets the X and Y-component. /// The X-component.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _X { get; set; }
/// <summary>
/// The Y-component
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _Y { get; set; }
/// <summary>
/// The Z-component.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _Z { get; set; }
/// <summary>
/// The W-component.
/// </summary>
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected float _W { get; set; }
/// <summary>
/// Transforms a <see cref="CVector" /> to a <see cref="OpenTK.Vector2" />
/// </summary>
public static implicit operator Vector2(CVector v) => new Vector2(v._X, v._Y);
/// <summary>
/// Transforms a <see cref="CVector" /> to a <see cref="OpenTK.Vector3" />
/// </summary>
public static implicit operator Vector3(CVector v) => new Vector3(v._X, v._Y, v._Z);
/// <summary>
/// Transforms a <see cref="CVector" /> to a <see cref="OpenTK.Vector4" />
/// </summary>
public static implicit operator Vector4(CVector v) => new Vector4(v._X, v._Y, v._Z, v._W);
#region Set
/// <summary>
/// Sets the X and Y-component.
/// </summary> /// </summary>
protected void Set(float x, float y) protected void Set(float x, float y)
{ {
_X = x; _X = x;
_Y = y; _Y = y;
} }
/// <summary> /// <summary>
/// Sets the X and Y-component from a <see cref="OpenTK.Vector2"/> /// Sets the X and Y-component from a <see cref="OpenTK.Vector2" />
/// </summary> /// </summary>
protected void Set(OpenTK.Vector2 vector) protected void Set(Vector2 vector)
{ {
Set(vector.X, vector.Y); Set(vector.X, vector.Y);
} }
/// <summary> /// <summary>
/// Sets the X, Y and Z-component. /// Sets the X, Y and Z-component.
/// </summary> /// </summary>
protected void Set(float x, float y, float z) protected void Set(float x, float y, float z)
{ {
Set(x,y); Set(x, y);
_Z = z; _Z = z;
} }
/// <summary> /// <summary>
/// Sets the X, Y and Z-component from a <see cref="OpenTK.Vector3"/>. /// Sets the X, Y and Z-component from a <see cref="OpenTK.Vector3" />.
/// </summary> /// </summary>
/// <param name="vector"></param> /// <param name="vector"></param>
protected void Set(OpenTK.Vector3 vector) protected void Set(Vector3 vector)
{ {
Set(vector.X, vector.Y, vector.Z); Set(vector.X, vector.Y, vector.Z);
} }
/// <summary> /// <summary>
/// Sets the X, Y, Z and W-component. /// Sets the X, Y, Z and W-component.
/// </summary> /// </summary>
protected void Set(float x, float y, float z, float w) protected void Set(float x, float y, float z, float w)
{ {
Set(x,y,z); Set(x, y, z);
_W = w; _W = w;
} }
/// <summary> /// <summary>
/// Sets the X, Y, Z and W-component from a <see cref="OpenTK.Vector4"/>. /// Sets the X, Y, Z and W-component from a <see cref="OpenTK.Vector4" />.
/// </summary> /// </summary>
protected void Set(OpenTK.Vector4 vector) protected void Set(Vector4 vector)
{ {
Set(vector.X, vector.Y, vector.Z, vector.W); Set(vector.X, vector.Y, vector.Z, vector.W);
} }
#endregion #endregion
#region Add #region Add
/// <summary> /// <summary>
/// Adds a <see cref="OpenTK.Vector2"/> to the X and Y-component. /// Adds a <see cref="OpenTK.Vector2" /> to the X and Y-component.
/// </summary> /// </summary>
protected void Add(OpenTK.Vector2 vector) protected void Add(Vector2 vector)
{ {
_X += vector.X; _X += vector.X;
_Y += vector.Y; _Y += vector.Y;
} }
/// <summary> /// <summary>
/// Adds a <see cref="OpenTK.Vector3"/> to the X, Y and Z-component. /// Adds a <see cref="OpenTK.Vector3" /> to the X, Y and Z-component.
/// </summary> /// </summary>
protected void Add(OpenTK.Vector3 vector) protected void Add(Vector3 vector)
{ {
_X += vector.X; _X += vector.X;
_Y += vector.Y; _Y += vector.Y;
@ -148,9 +147,9 @@ namespace SM.Base.Types
} }
/// <summary> /// <summary>
/// Adds a <see cref="OpenTK.Vector4"/> to the X, Y, Z and W-component. /// Adds a <see cref="OpenTK.Vector4" /> to the X, Y, Z and W-component.
/// </summary> /// </summary>
protected void Add(OpenTK.Vector4 vector) protected void Add(Vector4 vector)
{ {
_X += vector.X; _X += vector.X;
_Y += vector.Y; _Y += vector.Y;
@ -159,18 +158,5 @@ namespace SM.Base.Types
} }
#endregion #endregion
/// <summary>
/// Transforms a <see cref="CVector"/> to a <see cref="OpenTK.Vector2"/>
/// </summary>
public static implicit operator OpenTK.Vector2(CVector v) => new OpenTK.Vector2(v._x, v._y);
/// <summary>
/// Transforms a <see cref="CVector"/> to a <see cref="OpenTK.Vector3"/>
/// </summary>
public static implicit operator OpenTK.Vector3(CVector v) => new OpenTK.Vector3(v._x, v._y, v._z);
/// <summary>
/// Transforms a <see cref="CVector"/> to a <see cref="OpenTK.Vector4"/>
/// </summary>
public static implicit operator OpenTK.Vector4(CVector v) => new OpenTK.Vector4(v._x, v._y, v._z, v._w);
} }
} }

View file

@ -1,20 +1,47 @@
namespace SM.Base.Types #region usings
using OpenTK;
#endregion
namespace SM.Base.Types
{ {
/// <summary> /// <summary>
/// Represents a vector of two floats. /// Represents a vector of two floats.
/// </summary> /// </summary>
public class CVector2 : CVector public class CVector2 : CVector
{ {
/// <inheritdoc />
public CVector2() : this(0)
{
}
/// <inheritdoc />
public CVector2(float uniform) : base(uniform)
{
}
/// <inheritdoc />
public CVector2(float x, float y) : base(x, y, default, default)
{
}
/// <inheritdoc />
protected CVector2(float x, float y, float z, float w) : base(x, y, z, w)
{
}
/// <summary> /// <summary>
/// X-component /// X-component
/// </summary> /// </summary>
public float X public float X
{ {
get => _X; get => _X;
set => _X = value; set => _X = value;
} }
/// <summary> /// <summary>
/// Y-component /// Y-component
/// </summary> /// </summary>
public float Y public float Y
{ {
@ -22,35 +49,30 @@
set => _Y = value; set => _Y = value;
} }
/// <inheritdoc /> /// <summary>
public CVector2() : this(0) /// Sets the X and Y-component.
{} /// </summary>
public new void Set(float x, float y)
/// <inheritdoc />
public CVector2(float uniform) : base(uniform)
{ {
base.Set(x, y);
} }
/// <inheritdoc /> /// <summary>
public CVector2(float x, float y) : base(x,y, default, default) {} /// Sets the X and Y-component from a <see cref="OpenTK.Vector2" />
/// </summary>
/// <inheritdoc /> public new void Set(Vector2 vector)
protected CVector2(float x, float y, float z, float w) : base(x, y, z, w) {} {
base.Set(vector);
}
/// <summary> /// <summary>
/// Sets the X and Y-component. /// Adds a <see cref="OpenTK.Vector2" /> to the X and Y-component.
/// </summary> /// </summary>
public new void Set(float x, float y) => base.Set(x, y); public new void Add(Vector2 vector)
{
base.Add(vector);
}
/// <summary> public static implicit operator CVector2(Vector2 v) => new CVector2(v.X,v.Y);
/// Sets the X and Y-component from a <see cref="OpenTK.Vector2"/>
/// </summary>
public new void Set(OpenTK.Vector2 vector) => base.Set(vector);
/// <summary>
/// Adds a <see cref="OpenTK.Vector2"/> to the X and Y-component.
/// </summary>
public new void Add(OpenTK.Vector2 vector) => base.Add(vector);
} }
} }

View file

@ -1,16 +1,33 @@
using System.Drawing.Design; #region usings
using System.Runtime.InteropServices;
using OpenTK; using OpenTK;
#endregion
namespace SM.Base.Types namespace SM.Base.Types
{ {
/// <summary> /// <summary>
/// Represents a Vector of three floats. /// Represents a Vector of three floats.
/// </summary> /// </summary>
public class CVector3 : CVector2 public class CVector3 : CVector2
{ {
/// <inheritdoc />
public CVector3(float uniform) : base(uniform)
{
}
/// <inheritdoc />
public CVector3(float x, float y, float z) : base(x, y, z, default)
{
}
/// <inheritdoc />
protected CVector3(float x, float y, float z, float w) : base(x, y, z, w)
{
}
/// <summary> /// <summary>
/// Z-component /// Z-component
/// </summary> /// </summary>
public float Z public float Z
{ {
@ -18,29 +35,28 @@ namespace SM.Base.Types
set => _Z = value; set => _Z = value;
} }
/// <inheritdoc /> /// <summary>
public CVector3(float uniform) : base(uniform) /// Sets the X, Y and Z-component.
{ } /// </summary>
public new void Set(float x, float y, float z)
/// <inheritdoc /> {
public CVector3(float x, float y, float z) : base(x, y, z, default) base.Set(x, y, z);
{ } }
/// <inheritdoc />
protected CVector3(float x, float y, float z, float w) : base(x, y, z, w) { }
/// <summary> /// <summary>
/// Sets the X, Y and Z-component. /// Sets the X, Y and Z-component from a <see cref="OpenTK.Vector3" />.
/// </summary> /// </summary>
public new void Set(float x, float y, float z) => base.Set(x, y, z); public new void Set(Vector3 vector)
/// <summary> {
/// Sets the X, Y and Z-component from a <see cref="OpenTK.Vector3"/>. base.Set(vector);
/// </summary> }
public new void Set(Vector3 vector) => base.Set(vector);
/// <summary> /// <summary>
/// Adds a <see cref="OpenTK.Vector3"/> to the X, Y and Z-component. /// Adds a <see cref="OpenTK.Vector3" /> to the X, Y and Z-component.
/// </summary> /// </summary>
public new void Add(Vector3 vector) => base.Add(vector); public new void Add(Vector3 vector)
{
base.Add(vector);
}
} }
} }

View file

@ -1,21 +1,16 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Types namespace SM.Base.Types
{ {
/// <summary> /// <summary>
/// Represents a vector of four floats. /// Represents a vector of four floats.
/// </summary> /// </summary>
public class CVector4 : CVector3 public class CVector4 : CVector3
{ {
/// <summary>
/// W-component
/// </summary>
public float W
{
get => _W;
set => _W = value;
}
/// <inheritdoc /> /// <inheritdoc />
public CVector4(float uniform) : base(uniform) public CVector4(float uniform) : base(uniform)
{ {
@ -27,16 +22,36 @@ namespace SM.Base.Types
} }
/// <summary> /// <summary>
/// Sets the X, Y, Z and W-component. /// W-component
/// </summary> /// </summary>
public new void Set(float x, float y, float z, float w) => base.Set(x, y, z, w); public float W
{
get => _W;
set => _W = value;
}
/// <summary> /// <summary>
/// Sets the X, Y, Z and W-component from a <see cref="OpenTK.Vector4"/>. /// Sets the X, Y, Z and W-component.
/// </summary> /// </summary>
public new void Set(Vector4 vector) => base.Set(vector); public new void Set(float x, float y, float z, float w)
{
base.Set(x, y, z, w);
}
/// <summary> /// <summary>
/// Adds a <see cref="OpenTK.Vector4"/> to the X, Y, Z and W-component. /// Sets the X, Y, Z and W-component from a <see cref="OpenTK.Vector4" />.
/// </summary> /// </summary>
public new void Add(Vector4 vector) => base.Add(vector); public new void Set(Vector4 vector)
{
base.Set(vector);
}
/// <summary>
/// Adds a <see cref="OpenTK.Vector4" /> to the X, Y, Z and W-component.
/// </summary>
public new void Add(Vector4 vector)
{
base.Add(vector);
}
} }
} }

View file

@ -1,43 +1,60 @@
using System; #region usings
using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
#endregion
namespace SM.Utility namespace SM.Utility
{ {
/// <summary> /// <summary>
/// Contains utility functions for handling with assemblies. /// Contains utility functions for handling with assemblies.
/// </summary> /// </summary>
public class AssemblyUtility public class AssemblyUtility
{ {
/// <summary> /// <summary>
/// Read a file that is saved in a assembly /// Read a file that is saved in a assembly
/// </summary> /// </summary>
/// <param name="ass">The assembly that contains the file</param> /// <param name="ass">The assembly that contains the file</param>
/// <param name="path">The path to the file inside the assembly</param> /// <param name="path">The path to the file inside the assembly</param>
/// <returns></returns> /// <returns></returns>
public static string ReadAssemblyFile(Assembly ass, string path) { return new StreamReader(GetAssemblyStream(ass, path)).ReadToEnd(); } public static string ReadAssemblyFile(Assembly ass, string path)
{
return new StreamReader(GetAssemblyStream(ass, path)).ReadToEnd();
}
/// <summary> /// <summary>
/// Read a file that is saved in the calling assembly /// Read a file that is saved in the calling assembly
/// </summary> /// </summary>
/// <param name="path">The path to the file inside the assembly</param> /// <param name="path">The path to the file inside the assembly</param>
/// <returns></returns> /// <returns></returns>
public static string ReadAssemblyFile(string path) { return ReadAssemblyFile(Assembly.GetCallingAssembly(), path); } public static string ReadAssemblyFile(string path)
{
return ReadAssemblyFile(Assembly.GetCallingAssembly(), path);
}
/// <summary> /// <summary>
/// Returns a stream of a requested resource. /// Returns a stream of a requested resource.
/// </summary> /// </summary>
/// <param name="ass">The assembly the resource is in.</param> /// <param name="ass">The assembly the resource is in.</param>
/// <param name="path">The path to the resource.</param> /// <param name="path">The path to the resource.</param>
/// <returns>The stream</returns> /// <returns>The stream</returns>
public static Stream GetAssemblyStream(Assembly ass, string path) { return ass.GetManifestResourceStream(path) ?? throw new InvalidOperationException("Assembly couldn't find resource at path '" + path + "'."); } public static Stream GetAssemblyStream(Assembly ass, string path)
{
return ass.GetManifestResourceStream(path) ??
throw new InvalidOperationException("Assembly couldn't find resource at path '" + path + "'.");
}
/// <summary> /// <summary>
/// Returns a stream of a requested resource in the calling assembly. /// Returns a stream of a requested resource in the calling assembly.
/// </summary> /// </summary>
/// <param name="path">The path to the resource</param> /// <param name="path">The path to the resource</param>
/// <returns>The stream</returns> /// <returns>The stream</returns>
public static Stream GetAssemblyStream(string path) { return GetAssemblyStream(Assembly.GetCallingAssembly(), path); } public static Stream GetAssemblyStream(string path)
{
return GetAssemblyStream(Assembly.GetCallingAssembly(), path);
}
} }
} }

View file

@ -1,46 +1,49 @@
namespace SM.Utility namespace SM.Utility
{ {
/// <summary> /// <summary>
/// A assistant to control the delta time. /// A assistant to control the delta time.
/// </summary> /// </summary>
public class Deltatime public class Deltatime
{ {
/// <summary> /// <summary>
/// The current update delta time. /// Scaling of the delta time.
/// </summary> /// <para>Default: 1</para>
public static float UpdateDelta { get; internal set; }
/// <summary>
/// The current render delta time.
/// </summary>
public static float RenderDelta { get; internal set; }
/// <summary>
/// If true, it uses <see cref="RenderDelta"/>, otherwise <see cref="UpdateDelta"/>.
/// <para>Default: false</para>
/// </summary>
public bool UseRender;
/// <summary>
/// Scaling of the delta time.
/// <para>Default: 1</para>
/// </summary> /// </summary>
public float Scale; public float Scale;
/// <summary> /// <summary>
/// The calculated delta time. /// If true, it uses <see cref="RenderDelta" />, otherwise <see cref="UpdateDelta" />.
/// <para>Default: false</para>
/// </summary> /// </summary>
public float DeltaTime => (UseRender ? RenderDelta : UpdateDelta) * Scale; public bool UseRender;
/// <summary> /// <summary>
/// Creates a delta time assistant. /// Creates a delta time assistant.
/// </summary> /// </summary>
/// <param name="scale">The start scale for the delta time. Default: 1</param> /// <param name="scale">The start scale for the delta time. Default: 1</param>
/// <param name="useRender">If true, it uses <see cref="RenderDelta"/>, otherwise <see cref="UpdateDelta"/>. Default: false</param> /// <param name="useRender">
public Deltatime(float scale = 1, bool useRender = false) /// If true, it uses <see cref="RenderDelta" />, otherwise <see cref="UpdateDelta" />. Default:
/// false
/// </param>
public Deltatime(float scale = 1, bool useRender = false)
{ {
UseRender = useRender; UseRender = useRender;
Scale = scale; Scale = scale;
} }
/// <summary>
/// The current update delta time.
/// </summary>
public static float UpdateDelta { get; internal set; }
/// <summary>
/// The current render delta time.
/// </summary>
public static float RenderDelta { get; internal set; }
/// <summary>
/// The calculated delta time.
/// </summary>
public float DeltaTime => (UseRender ? RenderDelta : UpdateDelta) * Scale;
} }
} }

View file

@ -1,53 +1,84 @@
using System; #region usings
using System;
#endregion
namespace SM.Utility namespace SM.Utility
{ {
/// <summary> /// <summary>
/// A global helper class for randomization. /// A global helper class for randomization.
/// </summary> /// </summary>
public class Randomize public class Randomize
{ {
/// <summary> /// <summary>
/// The randomizer. /// The randomizer.
/// </summary> /// </summary>
public static Random Randomizer = new Random(); public static Random Randomizer = new Random();
/// <summary> /// <summary>
/// Sets the seed for the randomizer. /// Sets the seed for the randomizer.
/// </summary> /// </summary>
/// <param name="seed">The specified seed.</param> /// <param name="seed">The specified seed.</param>
public static void SetSeed(int seed) { Randomizer = new Random(seed); } public static void SetSeed(int seed)
{
Randomizer = new Random(seed);
}
/// <summary> /// <summary>
/// Generates a double and checks if its under the tolerance. /// Generates a double and checks if its under the tolerance.
/// </summary> /// </summary>
public static bool GetBool(float tolerance) { return Randomizer.NextDouble() < tolerance; } public static bool GetBool(float tolerance)
{
return Randomizer.NextDouble() < tolerance;
}
/// <summary> /// <summary>
/// Generates a integer. /// Generates a integer.
/// </summary> /// </summary>
public static int GetInt() { return Randomizer.Next(); } public static int GetInt()
/// <summary> {
/// Generates a integer with a maximum. return Randomizer.Next();
/// </summary> }
public static int GetInt(int max) { return Randomizer.Next(max); }
/// <summary>
/// Generates a integer with a minimum and maximum
/// </summary>
public static int GetInt(int min, int max) { return Randomizer.Next(min, max); }
/// <summary> /// <summary>
/// Generates a float between 0 and 1. /// Generates a integer with a maximum.
/// </summary> /// </summary>
public static float GetFloat() { return (float)Randomizer.NextDouble(); } public static int GetInt(int max)
/// <summary> {
/// Generates a float between 0 and the specified maximum. return Randomizer.Next(max);
/// </summary> }
public static float GetFloat(float max) { return (float)Randomizer.NextDouble() * max; }
/// <summary>
/// Generates a float between the specified minimum and the specified maximum.
/// </summary>
public static float GetFloat(float min, float max) { return (float)Randomizer.NextDouble() * max + min; }
/// <summary>
/// Generates a integer with a minimum and maximum
/// </summary>
public static int GetInt(int min, int max)
{
return Randomizer.Next(min, max);
}
/// <summary>
/// Generates a float between 0 and 1.
/// </summary>
public static float GetFloat()
{
return (float) Randomizer.NextDouble();
}
/// <summary>
/// Generates a float between 0 and the specified maximum.
/// </summary>
public static float GetFloat(float max)
{
return (float) Randomizer.NextDouble() * max;
}
/// <summary>
/// Generates a float between the specified minimum and the specified maximum.
/// </summary>
public static float GetFloat(float min, float max)
{
return (float) Randomizer.NextDouble() * max + min;
}
} }
} }

View file

@ -1,20 +1,24 @@
using System; #region usings
using System;
using OpenTK; using OpenTK;
#endregion
namespace SM.Utility namespace SM.Utility
{ {
/// <summary> /// <summary>
/// Utilitys for rotations /// Utilitys for rotations
/// </summary> /// </summary>
public class RotationUtility public class RotationUtility
{ {
/// <summary> /// <summary>
/// Angle towards an coordinate. /// Angle towards an coordinate.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public static float TurnTowards(Vector2 origin, Vector2 target) public static float TurnTowards(Vector2 origin, Vector2 target)
{ {
return MathHelper.RadiansToDegrees((float)Math.Atan2(target.Y - origin.Y, target.X - origin.X)); return MathHelper.RadiansToDegrees((float) Math.Atan2(target.Y - origin.Y, target.X - origin.X));
} }
} }
} }

View file

@ -0,0 +1,7 @@
namespace SM.Utility
{
public class ShaderUtility
{
}
}

View file

@ -1,61 +1,71 @@
using System.Collections.Generic; #region usings
using OpenTK; using OpenTK;
using SM.Base.Scene; using SM.Base.Scene;
using SM.OGL.Mesh; using SM.OGL.Mesh;
#endregion
namespace SM.Base.Contexts namespace SM.Base.Contexts
{ {
/// <summary> /// <summary>
/// Contains important information for drawing. /// Contains important information for drawing.
/// </summary> /// </summary>
public struct DrawContext public struct DrawContext
{ {
/// <summary> /// <summary>
/// This says if it was forced to use the viewport camera. /// This says if it was forced to use the viewport camera.
/// </summary> /// </summary>
public bool ForceViewport; public bool ForceViewport;
/// <summary> /// <summary>
/// The current world matrix. /// The current world matrix.
/// </summary> /// </summary>
public Matrix4 World; public Matrix4 World;
/// <summary> /// <summary>
/// The current view matrix. /// The current view matrix.
/// </summary> /// </summary>
public Matrix4 View; public Matrix4 View;
/// <summary> /// <summary>
/// The master model matrix. /// The master model matrix.
/// </summary> /// </summary>
public Matrix4 ModelMaster; public Matrix4 ModelMaster;
/// <summary> /// <summary>
/// The drawing instances. /// The drawing instances.
/// <para>If there is only one, it's index 0</para> /// <para>If there is only one, it's index 0</para>
/// </summary> /// </summary>
public Instance[] Instances; public Instance[] Instances;
/// <summary> /// <summary>
/// The mesh. /// The mesh.
/// </summary> /// </summary>
public GenericMesh Mesh; public GenericMesh Mesh;
/// <summary> /// <summary>
/// The material. /// The material.
/// </summary> /// </summary>
public Material Material; public Material Material;
/// <summary> /// <summary>
/// Contains the currently used render pipeline. /// Contains the currently used render pipeline.
/// </summary> /// </summary>
public RenderPipeline ActivePipeline; public RenderPipeline ActivePipeline;
/// <summary> /// <summary>
/// The current world scale. /// The current world scale.
/// </summary> /// </summary>
public Vector2 WorldScale; public Vector2 WorldScale;
/// <summary> /// <summary>
/// Returns the appropriate shader. /// Returns the appropriate shader.
/// <para>Returns the material shader, if available, otherwise it will take the default shader from the render pipeline.</para> /// <para>
/// Returns the material shader, if available, otherwise it will take the default shader from the render
/// pipeline.
/// </para>
/// </summary> /// </summary>
public IShader Shader => Material.CustomShader ?? ActivePipeline._defaultShader; public MaterialShader Shader => Material.CustomShader ?? ActivePipeline._defaultShader;
} }
} }

View file

@ -1,25 +1,28 @@
using OpenTK.Input; #region usings
using SM.Utility;
using OpenTK.Input;
#endregion
namespace SM.Base.Contexts namespace SM.Base.Contexts
{ {
/// <summary> /// <summary>
/// The update context. /// The update context.
/// </summary> /// </summary>
public struct UpdateContext public struct UpdateContext
{ {
/// <summary> /// <summary>
/// The delta time. /// The delta time.
/// </summary> /// </summary>
public float Deltatime => SMRenderer.DefaultDeltatime.DeltaTime; public float Deltatime => SMRenderer.DefaultDeltatime.DeltaTime;
/// <summary> /// <summary>
/// The current keyboard state. /// The current keyboard state.
/// </summary> /// </summary>
public KeyboardState KeyboardState; public KeyboardState KeyboardState;
/// <summary> /// <summary>
/// The current mouse state. /// The current mouse state.
/// </summary> /// </summary>
public MouseState MouseState; public MouseState MouseState;
} }

View file

@ -1,53 +1,86 @@
using System; #region usings
using System.IO;
using System;
using System.Drawing;
using System.Linq;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using OpenTK.Input; using OpenTK.Input;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Objects.Static; using SM.Base.Objects.Static;
using SM.Base.PostProcess;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Base.ShaderExtension;
using SM.Base.Time; using SM.Base.Time;
using SM.OGL; using SM.OGL;
using SM.OGL.Shaders; using SM.OGL.Framebuffer;
using SM.Utility; using SM.Utility;
#endregion
namespace SM.Base namespace SM.Base
{ {
/// <summary> /// <summary>
/// The base window. /// The base window.
/// </summary> /// </summary>
public abstract class GenericWindow : GameWindow public abstract class GenericWindow : GameWindow
{ {
private bool _loading = false; private bool _loading;
/// <summary> /// <summary>
/// This tells you the current world scale. /// This tells you the current world scale.
/// </summary> /// </summary>
protected Vector2 _worldScale = Vector2.Zero; protected Vector2 _worldScale = Vector2.Zero;
/// <summary> /// <summary>
/// This tells you the current aspect ratio of this window. /// This tells you the current aspect ratio of this window.
/// </summary> /// </summary>
public float Aspect { get; private set; } = 0f; public float Aspect { get; private set; }
public bool ReactWhileUnfocused = false;
/// <inheritdoc /> /// <inheritdoc />
protected GenericWindow() : base(1280, 720, GraphicsMode.Default, "Generic OGL Title", GameWindowFlags.Default, protected GenericWindow() : this(1280, 720, "Generic OGL Title", GameWindowFlags.Default)
DisplayDevice.Default, 0, 0, GraphicsContextFlags.Default, null, true) {
{ } }
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)
{
VSync = vSync ? VSyncMode.On : VSyncMode.Off;
}
/// <inheritdoc /> /// <inheritdoc />
protected override void OnLoad(EventArgs e) protected override void OnLoad(EventArgs e)
{ {
GLSystem.INIT_SYSTEM(); GLSystem.INIT_SYSTEM();
GLSettings.ShaderPreProcessing = true;
var args = Environment.GetCommandLineArgs();
if (args.Contains("--advDebugging"))
{
SMRenderer.AdvancedDebugging = true;
GLSettings.InfoEveryUniform = true;
}
Log.Init();
Log.Write("#", ConsoleColor.Cyan, "----------------------", Log.Write("#", ConsoleColor.Cyan, "----------------------",
"--- OpenGL Loading ---", "--- OpenGL Loading ---",
"----------------------------------", "----------------------------------",
$"--- {"DeviceVersion",14}: {GLSystem.DeviceVersion,-10} ---", $"--- {"DeviceVersion",14}: {GLSystem.DeviceVersion,-10} ---",
$"--- {"ForcedVersion",14}: {GLSystem.ForcedVersion,-10} ---", $"--- {"ForcedVersion",14}: {GLSettings.ForcedVersion,-10} ---",
$"--- {"ShadingVersion",14}: {GLSystem.ShadingVersion,-10} ---", $"--- {"ShadingVersion",14}: {GLSystem.ShadingVersion,-10} ---",
$"--- {"Debugging",14}: {GLSystem.Debugging,-10} ---", $"--- {"Debugging",14}: {GLSystem.Debugging,-10} ---",
$"----------------------------------"); $"--- {"AdvDebugging",14}: {SMRenderer.AdvancedDebugging,-10} ---",
"----------------------------------");
if (SMRenderer.AdvancedDebugging) Log.Write("Extension", ConsoleColor.DarkCyan, GLSystem.Extensions);
ExtensionManager.InitExtensions();
base.OnLoad(e); base.OnLoad(e);
_loading = true; _loading = true;
@ -58,7 +91,7 @@ namespace SM.Base
{ {
base.OnResize(e); base.OnResize(e);
Aspect = (float)Width / Height; Aspect = (float) Width / Height;
_worldScale = new Vector2(Width, Height); _worldScale = new Vector2(Width, Height);
SetWorldScale(); SetWorldScale();
GL.Viewport(ClientRectangle); GL.Viewport(ClientRectangle);
@ -71,25 +104,28 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// This is triggered after all the window-loading has been done. /// This is triggered after all the window-loading has been done.
/// </summary> /// </summary>
protected virtual void OnLoaded() protected virtual void OnLoaded()
{ {
} }
/// <summary> /// <summary>
/// Sets the world scale. /// Sets the world scale.
/// </summary> /// </summary>
protected virtual void SetWorldScale() { } protected virtual void SetWorldScale()
{
}
/// <inheritdoc /> /// <inheritdoc />
protected override void OnUpdateFrame(FrameEventArgs e) protected override void OnUpdateFrame(FrameEventArgs e)
{ {
if (!ReactWhileUnfocused && !Focused) return;
base.OnUpdateFrame(e); base.OnUpdateFrame(e);
Deltatime.UpdateDelta = (float)e.Time; Deltatime.UpdateDelta = (float) e.Time;
UpdateContext context = new UpdateContext() var context = new UpdateContext
{ {
KeyboardState = Keyboard.GetState(), KeyboardState = Keyboard.GetState(),
MouseState = Mouse.GetState() MouseState = Mouse.GetState()
@ -99,7 +135,7 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// Updates the system. /// Updates the system.
/// </summary> /// </summary>
/// <param name="e"></param> /// <param name="e"></param>
/// <param name="context"></param> /// <param name="context"></param>
@ -109,7 +145,7 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// Grabs the cursor and make sure it doesn't leave the window. /// Grabs the cursor and make sure it doesn't leave the window.
/// </summary> /// </summary>
/// <param name="makeItInvisible">If true, it makes the cursor invisible.</param> /// <param name="makeItInvisible">If true, it makes the cursor invisible.</param>
public void GrabCursor(bool makeItInvisible = true) public void GrabCursor(bool makeItInvisible = true)
@ -119,17 +155,42 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// Ungrabs the cursor. /// Ungrabs the cursor.
/// </summary> /// </summary>
public void UngrabCursor() public void UngrabCursor()
{ {
CursorGrabbed = false; CursorGrabbed = false;
if (!CursorVisible) CursorVisible = true; if (!CursorVisible) CursorVisible = true;
} }
public Bitmap TakeScreenshot(Framebuffer framebuffer, ReadBufferMode readBuffer, int x, int y, int width, int height)
{
GL.GetInteger(GetPName.FramebufferBinding, out int prevFBId);
GL.GetInteger(GetPName.DrawFramebufferBinding, out int prevFBDrawId);
GL.GetInteger(GetPName.ReadFramebufferBinding, out int prevFBReadId);
Bitmap b = new Bitmap(width, height);
System.Drawing.Imaging.BitmapData bits = b.LockBits(new Rectangle(0, 0, width, height),
System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, framebuffer);
GL.ReadBuffer(readBuffer);
GL.ReadPixels(x, y, width, height, OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte,
bits.Scan0);
b.UnlockBits(bits);
b.RotateFlip(RotateFlipType.RotateNoneFlipY);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, prevFBId);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, prevFBDrawId);
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, prevFBReadId);
return b;
}
} }
/// <summary> /// <summary>
/// The base window. /// The base window.
/// </summary> /// </summary>
/// <typeparam name="TScene">The scene type</typeparam> /// <typeparam name="TScene">The scene type</typeparam>
/// <typeparam name="TCamera">The camera type</typeparam> /// <typeparam name="TCamera">The camera type</typeparam>
@ -137,31 +198,32 @@ namespace SM.Base
where TScene : GenericScene, new() where TScene : GenericScene, new()
where TCamera : GenericCamera, new() where TCamera : GenericCamera, new()
{ {
/// <summary>
/// The viewport camera.
/// </summary>
public TCamera ViewportCamera { get; }
/// <summary>
/// This forces the render to use the viewport camera.
/// </summary>
public bool ForceViewportCamera { get; set; } = false;
/// <summary>
/// The current scene.
/// </summary>
public TScene CurrentScene { get; private set; }
/// <summary>
/// Controls how a scene is rendered.
/// </summary>
public RenderPipeline<TScene> RenderPipeline { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
protected GenericWindow() protected GenericWindow()
{ {
ViewportCamera = new TCamera(); ViewportCamera = new TCamera();
} }
/// <summary>
/// The viewport camera.
/// </summary>
public TCamera ViewportCamera { get; }
/// <summary>
/// This forces the render to use the viewport camera.
/// </summary>
public bool ForceViewportCamera { get; set; } = false;
/// <summary>
/// The current scene.
/// </summary>
public TScene CurrentScene { get; private set; }
/// <summary>
/// Controls how a scene is rendered.
/// </summary>
public RenderPipeline<TScene> RenderPipeline { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
protected override void Update(FrameEventArgs e, ref UpdateContext context) protected override void Update(FrameEventArgs e, ref UpdateContext context)
{ {
@ -172,15 +234,21 @@ namespace SM.Base
/// <inheritdoc /> /// <inheritdoc />
protected override void OnRenderFrame(FrameEventArgs e) protected override void OnRenderFrame(FrameEventArgs e)
{ {
if (!ReactWhileUnfocused && !Focused) return;
SMRenderer.CurrentFrame++; SMRenderer.CurrentFrame++;
Deltatime.RenderDelta = (float)e.Time; Deltatime.RenderDelta = (float) e.Time;
DrawContext drawContext = new DrawContext() var drawContext = new DrawContext
{ {
World = ViewportCamera.World, World = ViewportCamera.World,
View = ViewportCamera.CalculateViewMatrix(), View = ViewportCamera.CalculateViewMatrix(),
ModelMaster = Matrix4.Identity, ModelMaster = Matrix4.Identity,
Instances = new[] { new Instance {ModelMatrix = Matrix4.Identity, TexturePosition = Vector2.Zero, TextureScale = Vector2.One } }, Instances = new[]
{
new Instance
{ModelMatrix = Matrix4.Identity, TexturePosition = Vector2.Zero, TextureScale = Vector2.One}
},
Mesh = Plate.Object, Mesh = Plate.Object,
ForceViewport = ForceViewportCamera, ForceViewport = ForceViewportCamera,
WorldScale = _worldScale WorldScale = _worldScale
@ -202,10 +270,14 @@ namespace SM.Base
ViewportCamera.RecalculateWorld(_worldScale, Aspect); ViewportCamera.RecalculateWorld(_worldScale, Aspect);
RenderPipeline.Resize(); RenderPipeline.Resize();
PostProcessEffect.Mvp = Matrix4.CreateScale(_worldScale.X, -_worldScale.Y, 1) *
Matrix4.LookAt(0, 0, 1, 0, 0, 0, 0, 1, 0) *
GenericCamera.OrthographicWorld;
} }
/// <summary> /// <summary>
/// Sets the scene. /// Sets the scene.
/// </summary> /// </summary>
/// <param name="scene"></param> /// <param name="scene"></param>
public virtual void SetScene(TScene scene) public virtual void SetScene(TScene scene)
@ -215,7 +287,7 @@ namespace SM.Base
} }
/// <summary> /// <summary>
/// Defines the render pipeline. /// Defines the render pipeline.
/// </summary> /// </summary>
/// <param name="pipeline"></param> /// <param name="pipeline"></param>
public void SetRenderPipeline(RenderPipeline<TScene> pipeline) public void SetRenderPipeline(RenderPipeline<TScene> pipeline)

View file

@ -1,70 +1,79 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using System.Threading;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM.OGL.Framebuffer; using SM.OGL.Framebuffer;
#endregion
namespace SM.Base namespace SM.Base
{ {
/// <summary> /// <summary>
/// Definition of specific render options. /// Definition of specific render options.
/// </summary> /// </summary>
public abstract class RenderPipeline public abstract class RenderPipeline
{ {
/// <summary> /// <summary>
/// The framebuffers, that are used in this Pipeline. /// The framebuffers, that are used in this Pipeline.
/// </summary> /// </summary>
protected virtual List<Framebuffer> _framebuffers { get; } protected virtual List<Framebuffer> _framebuffers { get; }
/// <summary> /// <summary>
/// The default shader for the pipeline. /// The default shader for the pipeline.
/// </summary> /// </summary>
protected internal virtual IShader _defaultShader { get; } protected internal virtual MaterialShader _defaultShader { get; } = SMRenderer.DefaultMaterialShader;
/// <summary> /// <summary>
/// Occurs, when the window is loading. /// Occurs, when the window is loading.
/// </summary> /// </summary>
protected internal virtual void Load() protected internal virtual void Load()
{ {
foreach (Framebuffer framebuffer in _framebuffers)
framebuffer.Compile();
} }
/// <summary> /// <summary>
/// Occurs, when the window is resizing. /// Occurs, when the window is resizing.
/// </summary> /// </summary>
protected internal virtual void Resize() protected internal virtual void Resize()
{ } {
if (_framebuffers == null) return;
foreach (var framebuffer in _framebuffers)
framebuffer.Dispose();
Thread.Sleep(50);
foreach (Framebuffer framebuffer in _framebuffers)
{
framebuffer.Compile();
}
}
/// <summary> /// <summary>
/// Occurs, when the pipeline was connected to a window. /// Occurs, when the pipeline was connected to a window.
/// </summary> /// </summary>
protected internal virtual void Activate(GenericWindow window) protected internal virtual void Activate(GenericWindow window)
{ {
} }
/// <summary> /// <summary>
/// Occurs, when the window is unloading. /// Occurs, when the window is unloading.
/// </summary> /// </summary>
protected internal virtual void Unload() protected internal virtual void Unload()
{ {
foreach (Framebuffer framebuffer in _framebuffers)
{
framebuffer.Dispose();
}
} }
} }
/// <summary> /// <summary>
/// Represents a render pipeline. /// Represents a render pipeline.
/// </summary> /// </summary>
/// <typeparam name="TScene">The scene type</typeparam> /// <typeparam name="TScene">The scene type</typeparam>
public abstract class RenderPipeline<TScene> : RenderPipeline public abstract class RenderPipeline<TScene> : RenderPipeline
where TScene : GenericScene where TScene : GenericScene
{ {
/// <summary> /// <summary>
/// The system to render stuff. /// The system to render stuff.
/// </summary> /// </summary>
protected internal virtual void Render(ref DrawContext context, TScene scene) protected internal virtual void Render(ref DrawContext context, TScene scene)
{ {

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="OpenTK" version="3.2" targetFramework="net452" /> <package id="OpenTK" version="3.2.1" targetFramework="net452" />
</packages> </packages>

View file

@ -1,11 +1,20 @@
using System; #region usings
using System;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.OGL.Texture; using SM.OGL.Texture;
#endregion
namespace SM.OGL.Framebuffer namespace SM.OGL.Framebuffer
{ {
public class ColorAttachment : TextureBase public class ColorAttachment : TextureBase
{ {
public ColorAttachment(int attachmentId)
{
AttachmentID = attachmentId;
}
public int AttachmentID { get; } public int AttachmentID { get; }
public FramebufferAttachment FramebufferAttachment => FramebufferAttachment.ColorAttachment0 + AttachmentID; public FramebufferAttachment FramebufferAttachment => FramebufferAttachment.ColorAttachment0 + AttachmentID;
@ -13,11 +22,6 @@ namespace SM.OGL.Framebuffer
public ReadBufferMode ReadBufferMode => ReadBufferMode.ColorAttachment0 + AttachmentID; public ReadBufferMode ReadBufferMode => ReadBufferMode.ColorAttachment0 + AttachmentID;
public DrawBuffersEnum DrawBuffersEnum => DrawBuffersEnum.ColorAttachment0 + AttachmentID; public DrawBuffersEnum DrawBuffersEnum => DrawBuffersEnum.ColorAttachment0 + AttachmentID;
public ColorAttachment(int attachmentId)
{
AttachmentID = attachmentId;
}
public void Generate(Framebuffer f) public void Generate(Framebuffer f)
{ {
_id = GL.GenTexture(); _id = GL.GenTexture();
@ -26,10 +30,14 @@ namespace SM.OGL.Framebuffer
(int) f.Size.X, (int) f.Size.Y, (int) f.Size.X, (int) f.Size.Y,
0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero); 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMinFilter.Linear); (int) TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge); (int) TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
(int) TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT,
(int) TextureParameterName.ClampToEdge);
} }
} }
} }

View file

@ -1,15 +1,18 @@
using System; #region usings
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK; using OpenTK;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using OpenTK.Platform;
#endregion
namespace SM.OGL.Framebuffer namespace SM.OGL.Framebuffer
{ {
// TODO: Write summeries for framebuffer-system. // TODO: Write summeries for framebuffer-system.
public class Framebuffer : GLObject public class Framebuffer : GLObject
{ {
public static readonly Framebuffer Screen = new Framebuffer() public static readonly Framebuffer Screen = new Framebuffer
{ {
_id = 0, _id = 0,
_canBeCompiled = false _canBeCompiled = false
@ -17,34 +20,45 @@ namespace SM.OGL.Framebuffer
private bool _canBeCompiled = true; private bool _canBeCompiled = true;
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Framebuffer; private INativeWindow _window;
private float _windowScale;
public Vector2 Size { get; private set; }
public Dictionary<string, ColorAttachment> ColorAttachments { get; private set; } = new Dictionary<string, ColorAttachment>();
public Framebuffer() public Framebuffer()
{ } {
}
public Framebuffer(INativeWindow window, float scale = 1) : this(new Vector2(window.Width * scale, window.Height * scale)) public Framebuffer(INativeWindow window, float scale = 1) : this(new Vector2(window.Width * scale,
{ } window.Height * scale))
{
_window = window;
_windowScale = scale;
}
public Framebuffer(Vector2 size) public Framebuffer(Vector2 size)
{ {
Size = size; Size = size;
} }
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Framebuffer;
public Vector2 Size { get; private set; }
public Dictionary<string, ColorAttachment> ColorAttachments { get; private set; } =
new Dictionary<string, ColorAttachment>();
public override void Compile() public override void Compile()
{ {
if (!_canBeCompiled) return; if (!_canBeCompiled) return;
if (_window != null) Size = new Vector2(_window.Width * _windowScale, _window.Height * _windowScale);
base.Compile(); base.Compile();
_id = GL.GenFramebuffer(); _id = GL.GenFramebuffer();
GL.BindFramebuffer(FramebufferTarget.Framebuffer, _id); GL.BindFramebuffer(FramebufferTarget.Framebuffer, _id);
DrawBuffersEnum[] enums = new DrawBuffersEnum[ColorAttachments.Count]; var enums = new DrawBuffersEnum[ColorAttachments.Count];
int c = 0; var c = 0;
foreach (KeyValuePair<string, ColorAttachment> pair in ColorAttachments) foreach (var pair in ColorAttachments)
{ {
pair.Value.Generate(this); pair.Value.Generate(this);
@ -53,11 +67,12 @@ namespace SM.OGL.Framebuffer
GL.DrawBuffers(enums.Length, enums); GL.DrawBuffers(enums.Length, enums);
foreach (var pair in ColorAttachments) foreach (var pair in ColorAttachments)
GL.FramebufferTexture(FramebufferTarget.Framebuffer, pair.Value.FramebufferAttachment, pair.Value.ID, 0); GL.FramebufferTexture(FramebufferTarget.Framebuffer, pair.Value.FramebufferAttachment, pair.Value.ID,
0);
FramebufferErrorCode err = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); var err = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer);
if (err != FramebufferErrorCode.FramebufferComplete) if (err != FramebufferErrorCode.FramebufferComplete)
throw new Exception("Failed loading framebuffer.\nProblem: "+err); throw new Exception("Failed loading framebuffer.\nProblem: " + err);
GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0); GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
GL.BindTexture(TextureTarget.Texture2D, 0); GL.BindTexture(TextureTarget.Texture2D, 0);
@ -66,23 +81,36 @@ namespace SM.OGL.Framebuffer
public override void Dispose() public override void Dispose()
{ {
base.Dispose(); base.Dispose();
foreach (ColorAttachment attachment in ColorAttachments.Values) attachment.Dispose(); foreach (var attachment in ColorAttachments.Values) attachment.Dispose();
GL.DeleteFramebuffer(this); GL.DeleteFramebuffer(this);
} }
public void Append(string key, int pos) => Append(key, new ColorAttachment(pos));
public void Append(string key, ColorAttachment value) public void Append(string key, ColorAttachment value)
{ {
ColorAttachments.Add(key, value); ColorAttachments.Add(key, value);
} }
public void Activate() => Activate(FramebufferTarget.Framebuffer, ClearBufferMask.None); public void Activate()
public void Activate(FramebufferTarget target) => Activate(target, ClearBufferMask.None); {
public void Activate(ClearBufferMask clearMask) => Activate(FramebufferTarget.Framebuffer, clearMask); 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) public void Activate(FramebufferTarget target, ClearBufferMask clear)
{ {
GL.Clear(clear);
GL.BindFramebuffer(target, this); GL.BindFramebuffer(target, this);
GL.Clear(clear);
} }
} }
} }

View file

@ -0,0 +1,47 @@
#region usings
using System;
using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL
{
public class GLCustomActions
{
/// <summary>
/// A action that is performed, when a OpenGL-error occurs.
/// </summary>
public static Action<DebugSource, DebugType, DebugSeverity, string> AtKHRDebug = DefaultDebugAction;
/// <summary>
/// A action, that is performed, when a GLError occurred.
/// <para>Doesn't account for "KHR_debugging"</para>
/// </summary>
public static Action<string> AtError;
/// <summary>
/// A action, that is performed, when a warning want to be shown.
/// </summary>
public static Action<string> AtWarning;
/// <summary>
/// A action, that is performed, when a information needs to be shown.
/// </summary>
public static Action<string> AtInfo;
/// <summary>
/// Default action for 'AtKHRDebug'.
/// </summary>
/// <param name="source"></param>
/// <param name="type"></param>
/// <param name="severity"></param>
/// <param name="msg"></param>
private static void DefaultDebugAction(DebugSource source, DebugType type, DebugSeverity severity, string msg)
{
Console.WriteLine($"{severity}, {type}, {source} -> {msg}");
if (type == DebugType.DebugTypeError) throw new Exception(msg);
}
}
}

View file

@ -1,36 +1,33 @@
using System; #region usings
using System;
using System.Diagnostics; using System.Diagnostics;
using System.Net.Http;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using OpenTK.Platform.Egl;
using ErrorCode = OpenTK.Graphics.OpenGL4.ErrorCode; #endregion
namespace SM.OGL namespace SM.OGL
{ {
/// <summary> /// <summary>
/// Contains everything that is needed to debug OpenGL /// Contains everything that is needed to debug OpenGL
/// </summary> /// </summary>
public static class GLDebugging public static class GLDebugging
{ {
private static DebugProc _debugProc = DebugCallback; private static DebugProc _debugProc = DebugCallback;
private static GCHandle _debugGcHandle; private static GCHandle _debugGcHandle;
/// <summary>
/// A action that is performed, when a OpenGL-error occurs.
/// </summary>
public static Action<DebugSource, DebugType, DebugSeverity, string> DebugAction = DefaultDebugAction;
[DebuggerStepThrough] [DebuggerStepThrough]
private static void DebugCallback(DebugSource source, DebugType type, int id, DebugSeverity severity, private static void DebugCallback(DebugSource source, DebugType type, int id, DebugSeverity severity,
int length, IntPtr message, IntPtr userparam) int length, IntPtr message, IntPtr userparam)
{ {
string msg = Marshal.PtrToStringAnsi(message, length); var msg = Marshal.PtrToStringAnsi(message, length);
DebugAction?.Invoke(source, type, severity, msg); GLCustomActions.AtKHRDebug?.Invoke(source, type, severity, msg);
} }
/// <summary> /// <summary>
/// Enables the debugging. /// Enables the debugging.
/// </summary> /// </summary>
public static void EnableDebugging() public static void EnableDebugging()
{ {
@ -47,40 +44,33 @@ namespace SM.OGL
Console.WriteLine("Enableing proper GLDebugging failed. \n" + Console.WriteLine("Enableing proper GLDebugging failed. \n" +
"Often it fails, because your hardware doesn't provide proper OpenGL 4 \n" + "Often it fails, because your hardware doesn't provide proper OpenGL 4 \n" +
" or KHR_debug extension support."); " or KHR_debug extension support.");
} }
} }
/// <summary> /// <summary>
/// Default action for 'DebugAction'. /// Checks for OpenGL errors.
/// </summary>
/// <param name="source"></param>
/// <param name="type"></param>
/// <param name="severity"></param>
/// <param name="msg"></param>
public static void DefaultDebugAction(DebugSource source, DebugType type, DebugSeverity severity, string msg)
{
Console.WriteLine($"{severity}, {type}, {source} -> {msg}");
if (type == DebugType.DebugTypeError) throw new Exception(msg);
}
/// <summary>
/// A action, that is performed, when <see cref="GLDebugging.CheckGLErrors"/> find an error.
/// </summary>
public static Action<ErrorCode> GlErrorAction;
/// <summary>
/// Checks for OpenGL errors.
/// </summary> /// </summary>
public static bool CheckGLErrors() public static bool CheckGLErrors()
{ {
bool hasError = false; var hasError = false;
ErrorCode c; ErrorCode c;
while ((c = GL.GetError()) != ErrorCode.NoError) while ((c = GL.GetError()) != ErrorCode.NoError)
{ {
hasError = true; hasError = true;
GlErrorAction?.Invoke(c); GLCustomActions.AtError?.Invoke("A GLError occurred: " + c);
}
return hasError;
}
public static bool CheckGLErrors(string formating)
{
var hasError = false;
ErrorCode c;
while ((c = GL.GetError()) != ErrorCode.NoError)
{
hasError = true;
GLCustomActions.AtError?.Invoke(formating.Replace("%code%", c.ToString()));
} }
return hasError; return hasError;

View file

@ -1,30 +1,35 @@
using System.Diagnostics; #region usings
using System.Diagnostics;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL namespace SM.OGL
{ {
/// <summary> /// <summary>
/// Specifies default object behaviour. /// Specifies default object behaviour.
/// </summary> /// </summary>
public abstract class GLObject public abstract class GLObject
{ {
/// <summary> /// <summary>
/// Contains the OpenGL ID /// Contains the OpenGL ID
/// </summary> /// </summary>
protected int _id = -1; protected int _id = -1;
/// <summary> /// <summary>
/// If true, the system will call "Compile()", when "ID" is tried to get, but the id is still -1. /// If true, the system will call "Compile()", when "ID" is tried to get, but the id is still -1.
/// </summary> /// </summary>
protected virtual bool AutoCompile { get; } = false; protected virtual bool AutoCompile { get; } = false;
/// <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;
/// <summary> /// <summary>
/// Returns the id for this object. /// Returns the id for this object.
/// <para>It will auto compile, if needed and allowed.</para> /// <para>It will auto compile, if needed and allowed.</para>
/// </summary> /// </summary>
public virtual int ID public virtual int ID
{ {
@ -36,7 +41,7 @@ namespace SM.OGL
} }
/// <summary> /// <summary>
/// Identifies the object. /// Identifies the object.
/// </summary> /// </summary>
public abstract ObjectLabelIdentifier TypeIdentifier { get; } public abstract ObjectLabelIdentifier TypeIdentifier { get; }
@ -47,21 +52,21 @@ namespace SM.OGL
} }
/// <summary> /// <summary>
/// The action, that is called, when "ID" tries to compile something. /// The action, that is called, when "ID" tries to compile something.
/// </summary> /// </summary>
public virtual void Compile() public virtual void Compile()
{ {
} }
/// <summary> /// <summary>
/// Is triggered, when something want to dispose this object. /// Is triggered, when something want to dispose this object.
/// </summary> /// </summary>
public virtual void Dispose() {} public virtual void Dispose()
{
}
/// <summary> /// <summary>
/// Re-compiles the object. /// Re-compiles the object.
/// </summary> /// </summary>
public void Recompile() public void Recompile()
{ {
@ -72,7 +77,7 @@ namespace SM.OGL
} }
/// <summary> /// <summary>
/// Names the object for debugging. /// Names the object for debugging.
/// </summary> /// </summary>
/// <param name="name"></param> /// <param name="name"></param>
public void Name(string name) public void Name(string name)
@ -81,9 +86,12 @@ namespace SM.OGL
} }
/// <summary> /// <summary>
/// Returns the ID for the object. /// Returns the ID for the object.
/// </summary> /// </summary>
/// <param name="glo"></param> /// <param name="glo"></param>
public static implicit operator int(GLObject glo) => glo.ID; public static implicit operator int(GLObject glo)
{
return glo.ID;
}
} }
} }

View file

@ -0,0 +1,15 @@
namespace SM.OGL
{
public class GLSettings
{
public static bool InfoEveryUniform = false;
/// <summary>
/// Get/Sets the forced version for OpenGL.
/// <para>Needs to be set before init a window.</para>
/// </summary>
public static Version ForcedVersion { get; set; } = new Version();
public static bool ShaderPreProcessing { get; set; } = false;
}
}

View file

@ -1,43 +1,44 @@
using System.Linq; #region usings
using System.Linq;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL namespace SM.OGL
{ {
/// <summary> /// <summary>
/// Contains data about the current OpenGL system. /// Contains data and settings about the current OpenGL system.
/// </summary> /// </summary>
public class GLSystem public class GLSystem
{ {
private static bool _init = false; private static bool _init;
/// <summary> /// <summary>
/// Contains the device version of OpenGL. /// Contains the device version of OpenGL.
/// </summary> /// </summary>
public static Version DeviceVersion { get; private set; } public static Version DeviceVersion { get; private set; }
/// <summary>
/// Get/Sets the forced version for OpenGL.
/// <para>Needs to be set before init a window.</para>
/// </summary>
public static Version ForcedVersion { get; set; } = new Version();
/// <summary> /// <summary>
/// Contains the shader version for GLSL. /// Contains the shader version for GLSL.
/// </summary> /// </summary>
public static Version ShadingVersion { get; private set; } public static Version ShadingVersion { get; private set; }
/// <summary> /// <summary>
/// Contains the extensions for OpenGL. /// Contains the extensions for OpenGL.
/// </summary> /// </summary>
public static string[] Extensions { get; private set; } public static string[] Extensions { get; private set; }
/// <summary> /// <summary>
/// Checks if proper Debugging is for this system available. /// Checks if proper Debugging is for this system available.
/// <para>Determent, if the system has the "KHR_debug"-extension. </para> /// <para>Determent, if the system has the "KHR_debug"-extension. </para>
/// </summary> /// </summary>
public static bool Debugging { get; private set; } public static bool Debugging { get; private set; }
/// <summary> /// <summary>
/// Initialize the system data. /// Initialize the system data.
/// <para>Does nothing after the data was already collected.</para> /// <para>Does nothing after the data was already collected.</para>
/// </summary> /// </summary>
public static void INIT_SYSTEM() public static void INIT_SYSTEM()
{ {

View file

@ -1,39 +1,36 @@
using System; #region usings
using System.Runtime.CompilerServices;
using System;
using OpenTK; using OpenTK;
#endregion
namespace SM.OGL.Mesh namespace SM.OGL.Mesh
{ {
/// <summary> /// <summary>
/// Contains information about bounding boxes of meshes /// Contains information about bounding boxes of meshes
/// </summary> /// </summary>
public class BoundingBox public class BoundingBox
{ {
/// <summary> /// <summary>
/// The minimum corner. /// The maximum corner.
/// </summary>
public Vector3 Min = Vector3.Zero;
/// <summary>
/// The maximum corner.
/// </summary> /// </summary>
public Vector3 Max = Vector3.Zero; public Vector3 Max = Vector3.Zero;
/// <summary> /// <summary>
/// Returns specific configurations of corners /// The minimum corner.
/// </summary> /// </summary>
/// <param name="x">If true, it takes the X-value of maximum, otherwise the minimum.</param> public Vector3 Min = Vector3.Zero;
/// <param name="y">If true, it takes the Y-value of maximum, otherwise the minimum.</param>
/// <param name="z">If true, it takes the Z-value of maximum, otherwise the minimum.</param>
/// <returns></returns>
public Vector3 this[bool x, bool y, bool z] => new Vector3(x ? Max.X : Min.X, y ? Max.Y : Min.Y, z ? Max.Z : Min.Z);
/// <summary> /// <summary>
/// Empty constructor /// Empty constructor
/// </summary> /// </summary>
public BoundingBox() {} public BoundingBox()
{
}
/// <summary> /// <summary>
/// Creates the bounding box with predefined min and max values /// Creates the bounding box with predefined min and max values
/// </summary> /// </summary>
/// <param name="min"></param> /// <param name="min"></param>
/// <param name="max"></param> /// <param name="max"></param>
@ -44,12 +41,22 @@ namespace SM.OGL.Mesh
} }
/// <summary> /// <summary>
/// Updates the bounding box. /// Returns specific configurations of corners
/// </summary>
/// <param name="x">If true, it takes the X-value of maximum, otherwise the minimum.</param>
/// <param name="y">If true, it takes the Y-value of maximum, otherwise the minimum.</param>
/// <param name="z">If true, it takes the Z-value of maximum, otherwise the minimum.</param>
/// <returns></returns>
public Vector3 this[bool x, bool y, bool z] =>
new Vector3(x ? Max.X : Min.X, y ? Max.Y : Min.Y, z ? Max.Z : Min.Z);
/// <summary>
/// Updates the bounding box.
/// </summary> /// </summary>
/// <param name="vector"></param> /// <param name="vector"></param>
public void Update(Vector2 vector) public void Update(Vector2 vector)
{ {
for (int i = 0; i < 2; i++) for (var i = 0; i < 2; i++)
{ {
Min[i] = Math.Min(Min[i], vector[i]); Min[i] = Math.Min(Min[i], vector[i]);
Max[i] = Math.Max(Max[i], vector[i]); Max[i] = Math.Max(Max[i], vector[i]);
@ -57,12 +64,12 @@ namespace SM.OGL.Mesh
} }
/// <summary> /// <summary>
/// Updates the bounding box. /// Updates the bounding box.
/// </summary> /// </summary>
/// <param name="vector"></param> /// <param name="vector"></param>
public void Update(Vector3 vector) public void Update(Vector3 vector)
{ {
for (int i = 0; i < 3; i++) for (var i = 0; i < 3; i++)
{ {
Min[i] = Math.Min(Min[i], vector[i]); Min[i] = Math.Min(Min[i], vector[i]);
Max[i] = Math.Max(Min[i], vector[i]); Max[i] = Math.Max(Min[i], vector[i]);

View file

@ -1,15 +1,31 @@
using System; #region usings
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using Buffer = OpenTK.Graphics.OpenGL4.Buffer;
#endregion
namespace SM.OGL.Mesh namespace SM.OGL.Mesh
{ {
/// <summary> /// <summary>
/// Contains information for meshes /// Contains information for meshes
/// </summary> /// </summary>
public abstract class GenericMesh : GLObject public abstract class GenericMesh : GLObject
{ {
/// <summary>
/// Generates the AttribDataIndex
/// </summary>
protected GenericMesh()
{
AttribDataIndex = new Dictionary<int, VBO>
{
{0, Vertex},
{1, UVs},
{2, Normals}
};
}
/// <inheritdoc /> /// <inheritdoc />
protected override bool AutoCompile { get; } = true; protected override bool AutoCompile { get; } = true;
@ -17,52 +33,41 @@ namespace SM.OGL.Mesh
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.VertexArray; public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.VertexArray;
/// <summary> /// <summary>
/// The primitive type, that determinants how the mesh is drawn. /// The primitive type, that determinants how the mesh is drawn.
/// <para>Default: Triangles</para> /// <para>Default: Triangles</para>
/// </summary> /// </summary>
public virtual PrimitiveType PrimitiveType { get; } = PrimitiveType.Triangles; public virtual PrimitiveType PrimitiveType { get; } = PrimitiveType.Triangles;
/// <summary> /// <summary>
/// Contains the vertices for the mesh. /// Contains the vertices for the mesh.
/// </summary> /// </summary>
public virtual VBO Vertex { get; } public virtual VBO Vertex { get; }
/// <summary> /// <summary>
/// Contains the texture coords for the mesh. /// Contains the texture coords for the mesh.
/// </summary> /// </summary>
public virtual VBO UVs { get; } public virtual VBO UVs { get; }
/// <summary> /// <summary>
/// Contains the normals for the mesh. /// Contains the normals for the mesh.
/// </summary> /// </summary>
public virtual VBO Normals { get; } public virtual VBO Normals { get; }
/// <summary> /// <summary>
/// Represents the bounding box. /// Represents the bounding box.
/// </summary> /// </summary>
public virtual BoundingBox BoundingBox { get; } = new BoundingBox(); public virtual BoundingBox BoundingBox { get; } = new BoundingBox();
/// <summary> /// <summary>
/// Connects the different buffer objects with ids. /// Connects the different buffer objects with ids.
/// </summary> /// </summary>
public Dictionary<int, VBO> AttribDataIndex { get; } public Dictionary<int, VBO> AttribDataIndex { get; }
/// <summary> /// <summary>
/// Stores indices for a more performance friendly method to draw objects. /// Stores indices for a more performance friendly method to draw objects.
/// </summary> /// </summary>
public virtual int[] Indices { get; set; } public virtual int[] Indices { get; set; }
/// <summary>
/// Generates the AttribDataIndex
/// </summary>
protected GenericMesh()
{
AttribDataIndex = new Dictionary<int, VBO>()
{
{0, Vertex},
{1, UVs},
{2, Normals},
};
}
/// <inheritdoc /> /// <inheritdoc />
public override void Compile() public override void Compile()
{ {
@ -71,7 +76,7 @@ namespace SM.OGL.Mesh
if (AttribDataIndex == null) throw new Exception("[Critical] The model requires a attribute data index."); if (AttribDataIndex == null) throw new Exception("[Critical] The model requires a attribute data index.");
foreach (KeyValuePair<int, VBO> kvp in AttribDataIndex) kvp.Value?.BindBuffer(kvp.Key); foreach (var kvp in AttribDataIndex) kvp.Value?.BindBuffer(kvp.Key);
GL.BindVertexArray(0); GL.BindVertexArray(0);
} }

View file

@ -1,51 +1,78 @@
using System; #region usings
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Mesh namespace SM.OGL.Mesh
{ {
/// <summary> /// <summary>
/// Represents a Vertex Buffer Object used for meshes. /// Represents a Vertex Buffer Object used for meshes.
/// </summary> /// </summary>
public class VBO : List<float> public class VBO : List<float>
{ {
/// <summary> /// <summary>
/// Specifies the expected usage pattern of the data store. /// Specifies the expected usage pattern of the data store.
/// </summary> /// </summary>
public BufferUsageHint BufferUsageHint; public BufferUsageHint BufferUsageHint;
/// <summary> /// <summary>
/// Specifies the data type of each component in the array. /// Normalise floats?
/// </summary>
public VertexAttribPointerType PointerType;
/// <summary>
/// Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4.
/// </summary>
public int PointerSize;
/// <summary>
/// Normalise floats?
/// </summary> /// </summary>
public bool Normalised; public bool Normalised;
/// <summary> /// <summary>
/// Specifies the byte offset between consecutive generic vertex attributes. /// Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of
/// </summary> /// the buffer currently bound to the GL_ARRAY_BUFFER target.
public int PointerStride;
/// <summary>
/// Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target.
/// </summary> /// </summary>
public int PointerOffset; public int PointerOffset;
/// <summary> /// <summary>
/// Generates a VBO for inserting mesh data. /// Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4.
/// </summary> /// </summary>
/// <param name="bufferUsageHint">Specifies the expected usage pattern of the data store. <para>Default: StaticDraw</para></param> public int PointerSize;
/// <param name="pointerType">Specifies the data type of each component in the array. <para>Default: Float</para></param>
/// <param name="pointerSize">Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. <para>Default: 3</para></param> /// <summary>
/// <param name="pointerStride">Specifies the byte offset between consecutive generic vertex attributes. <para>Default: 0</para></param> /// Specifies the byte offset between consecutive generic vertex attributes.
/// <param name="pointerOffset">Specifies a offset of the first component of the first generic vertex attribute in the array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target. <para>Default: 0</para></param> /// </summary>
/// <param name="normalised">Normalise floats? <para>Default: false</para></param> public int PointerStride;
/// <summary>
/// Specifies the data type of each component in the array.
/// </summary>
public VertexAttribPointerType PointerType;
/// <summary>
/// Generates a VBO for inserting mesh data.
/// </summary>
/// <param name="bufferUsageHint">
/// Specifies the expected usage pattern of the data store.
/// <para>Default: StaticDraw</para>
/// </param>
/// <param name="pointerType">
/// Specifies the data type of each component in the array.
/// <para>Default: Float</para>
/// </param>
/// <param name="pointerSize">
/// Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4.
/// <para>Default: 3</para>
/// </param>
/// <param name="pointerStride">
/// Specifies the byte offset between consecutive generic vertex attributes.
/// <para>Default: 0</para>
/// </param>
/// <param name="pointerOffset">
/// Specifies a offset of the first component of the first generic vertex attribute in the
/// array in the data store of the buffer currently bound to the GL_ARRAY_BUFFER target.
/// <para>Default: 0</para>
/// </param>
/// <param name="normalised">
/// Normalise floats?
/// <para>Default: false</para>
/// </param>
public VBO(BufferUsageHint bufferUsageHint = BufferUsageHint.StaticDraw, public VBO(BufferUsageHint bufferUsageHint = BufferUsageHint.StaticDraw,
VertexAttribPointerType pointerType = VertexAttribPointerType.Float, int pointerSize = 3, VertexAttribPointerType pointerType = VertexAttribPointerType.Float, int pointerSize = 3,
int pointerStride = 0, int pointerOffset = 0, bool normalised = false) int pointerStride = 0, int pointerOffset = 0, bool normalised = false)
@ -59,56 +86,95 @@ namespace SM.OGL.Mesh
} }
/// <summary> /// <summary>
/// Adds two values to the VBO. /// Adds two values to the VBO.
/// </summary> /// </summary>
public void Add(float x, float y) => AddRange(new[] {x,y}); public void Add(float x, float y)
/// <summary> {
/// Adds three values to the VBO. AddRange(new[] {x, y});
/// </summary> }
public void Add(float x, float y, float z) => AddRange(new[] {x,y,z});
/// <summary>
/// Adds four values to the VBO.
/// </summary>
public void Add(float x, float y, float z, float w) => AddRange(new[] {x,y,z,w});
/// <summary>
/// Adds a Vector2.
/// </summary>
public void Add(Vector2 vector) => Add(vector.X, vector.Y);
/// <summary>
/// Adds a Vector2 and a value.
/// </summary>
public void Add(Vector2 vector, float z) => Add(vector.X, vector.Y, z);
/// <summary>
/// Adds a Vector2 and two values.
/// </summary>
public void Add(Vector2 vector, float z, float w) => Add(vector.X, vector.Y, z, w);
/// <summary>
/// Adds a Vector3.
/// </summary>
public void Add(Vector3 vector) => Add(vector.X, vector.Y, vector.Z);
/// <summary>
/// Adds a Vector3 and a value.
/// </summary>
public void Add(Vector3 vector, float w) => Add(vector.X, vector.Y, vector.Z, w);
/// <summary>
/// Adds a vector4.
/// </summary>
/// <param name="vector"></param>
public void Add(Vector4 vector) => Add(vector.X, vector.Y, vector.Z, vector.W);
/// <summary>
/// Adds a color.
/// </summary>
public void Add(Color4 color) => Add(color.R, color.G, color.B, color.A);
/// <summary> /// <summary>
/// Binds the buffer to the active VAO. /// Adds three values to the VBO.
/// </summary>
public void Add(float x, float y, float z)
{
AddRange(new[] {x, y, z});
}
/// <summary>
/// Adds four values to the VBO.
/// </summary>
public void Add(float x, float y, float z, float w)
{
AddRange(new[] {x, y, z, w});
}
/// <summary>
/// Adds a Vector2.
/// </summary>
public void Add(Vector2 vector)
{
Add(vector.X, vector.Y);
}
/// <summary>
/// Adds a Vector2 and a value.
/// </summary>
public void Add(Vector2 vector, float z)
{
Add(vector.X, vector.Y, z);
}
/// <summary>
/// Adds a Vector2 and two values.
/// </summary>
public void Add(Vector2 vector, float z, float w)
{
Add(vector.X, vector.Y, z, w);
}
/// <summary>
/// Adds a Vector3.
/// </summary>
public void Add(Vector3 vector)
{
Add(vector.X, vector.Y, vector.Z);
}
/// <summary>
/// Adds a Vector3 and a value.
/// </summary>
public void Add(Vector3 vector, float w)
{
Add(vector.X, vector.Y, vector.Z, w);
}
/// <summary>
/// Adds a vector4.
/// </summary>
/// <param name="vector"></param>
public void Add(Vector4 vector)
{
Add(vector.X, vector.Y, vector.Z, vector.W);
}
/// <summary>
/// Adds a color.
/// </summary>
public void Add(Color4 color)
{
Add(color.R, color.G, color.B, color.A);
}
/// <summary>
/// Binds the buffer to the active VAO.
/// </summary> /// </summary>
/// <param name="attribID">The id for the attribute.</param> /// <param name="attribID">The id for the attribute.</param>
internal void BindBuffer(int attribID) internal void BindBuffer(int attribID)
{ {
float[] data = ToArray(); var data = ToArray();
int buffer = GL.GenBuffer(); var buffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, buffer); GL.BindBuffer(BufferTarget.ArrayBuffer, buffer);
GL.BufferData(BufferTarget.ArrayBuffer, data.Length * sizeof(float), data, BufferUsageHint); GL.BufferData(BufferTarget.ArrayBuffer, data.Length * sizeof(float), data, BufferUsageHint);

View file

@ -1,16 +1,19 @@
using System.Reflection; #region usings
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endregion
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("SM.Core")] [assembly: AssemblyTitle("OpenGL Bindings for SMRederer")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("Defines classes to work with OpenTK/OpenGL")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyCompany("iedSoftworks")]
[assembly: AssemblyProduct("SM.Core")] [assembly: AssemblyProduct("SM.Core")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2020")] [assembly: AssemblyCopyright("Copyright © iedSoftworks 2020")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View file

@ -23,6 +23,7 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<DocumentationFile> <DocumentationFile>
</DocumentationFile> </DocumentationFile>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@ -31,39 +32,39 @@
<DefineConstants>TRACE</DefineConstants> <DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="OpenTK, Version=3.2.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> <Reference Include="OpenTK, Version=3.2.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\packages\OpenTK.3.2\lib\net20\OpenTK.dll</HintPath> <HintPath>..\..\packages\OpenTK.3.2.1\lib\net20\OpenTK.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Framebuffer\ColorAttachment.cs" /> <Compile Include="Framebuffer\ColorAttachment.cs" />
<Compile Include="Framebuffer\Framebuffer.cs" /> <Compile Include="Framebuffer\Framebuffer.cs" />
<Compile Include="GLCustomActions.cs" />
<Compile Include="GLDebugging.cs" /> <Compile Include="GLDebugging.cs" />
<Compile Include="GLObject.cs" /> <Compile Include="GLObject.cs" />
<Compile Include="GLSettings.cs" />
<Compile Include="GLSystem.cs" /> <Compile Include="GLSystem.cs" />
<Compile Include="Mesh\BoundingBox.cs" /> <Compile Include="Mesh\BoundingBox.cs" />
<Compile Include="Mesh\GenericMesh.cs" /> <Compile Include="Mesh\GenericMesh.cs" />
<Compile Include="Mesh\VBO.cs" /> <Compile Include="Mesh\VBO.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Shaders\GenericShader.cs" /> <Compile Include="Shaders\GenericShader.cs" />
<Compile Include="Shaders\IUniform.cs" />
<Compile Include="Shaders\ShaderExtensions.cs" />
<Compile Include="Shaders\ShaderFileCollection.cs" /> <Compile Include="Shaders\ShaderFileCollection.cs" />
<Compile Include="Shaders\ShaderFile.cs" /> <Compile Include="Shaders\ShaderFile.cs" />
<Compile Include="Shaders\ShaderPreProcess.cs" />
<Compile Include="Shaders\Uniform.cs" /> <Compile Include="Shaders\Uniform.cs" />
<Compile Include="Shaders\UniformArray.cs" />
<Compile Include="Shaders\UniformCollection.cs" /> <Compile Include="Shaders\UniformCollection.cs" />
<Compile Include="Texture\TextureBase.cs" /> <Compile Include="Texture\TextureBase.cs" />
<Compile Include="Version.cs" /> <Compile Include="Version.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup />
<ItemGroup> <ItemGroup>
<None Include="OpenTK.dll.config" /> <None Include="OpenTK.dll.config" />
<None Include="packages.config" /> <None Include="packages.config" />

View file

@ -1,25 +1,30 @@
using System; #region usings
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.OGL.Mesh;
#endregion
namespace SM.OGL.Shaders namespace SM.OGL.Shaders
{ {
/// <summary> /// <summary>
/// Abstract class, that is used to create graphic shader. /// Abstract class, that is used to create graphic shader.
/// </summary> /// </summary>
public abstract class GenericShader : GLObject public abstract class GenericShader : GLObject
{ {
protected override bool AutoCompile { get; } = true;
/// <summary> /// <summary>
/// Contains the different files for the shader. /// Contains the different files for the shader.
/// </summary> /// </summary>
protected ShaderFileCollection ShaderFileFiles; protected ShaderFileCollection ShaderFileFiles;
/// <summary> /// <summary>
/// Contains and manage the uniforms from the shader. /// Contains and manage the uniforms from the shader.
/// </summary> /// </summary>
protected UniformCollection Uniforms; protected UniformCollection Uniforms;
/// <inheritdoc /> protected GenericShader(string vertex, string fragment) : this(new ShaderFileCollection(vertex, fragment)){}
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Program;
/// <inheritdoc /> /// <inheritdoc />
protected GenericShader(ShaderFileCollection shaderFileFiles) protected GenericShader(ShaderFileCollection shaderFileFiles)
@ -27,35 +32,26 @@ namespace SM.OGL.Shaders
ShaderFileFiles = shaderFileFiles; ShaderFileFiles = shaderFileFiles;
} }
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Program;
/// <summary> /// <summary>
/// Loads the shader to the GPU. /// Loads the shader to the GPU.
/// </summary> /// </summary>
public void Load() public void Load()
{ {
_id = GL.CreateProgram(); _id = GL.CreateProgram();
ShaderFileFiles.Append(this); ShaderFileFiles.Append(this);
GL.LinkProgram(_id); GL.LinkProgram(_id);
this.Name(GetType().Name); Name(GetType().Name);
ShaderFileFiles.Detach(this); ShaderFileFiles.Detach(this);
GL.GetProgram(_id, GetProgramParameterName.ActiveUniforms, out int uniformCount);
if (uniformCount < 1)
throw new Exception("[Critical] No uniforms has been found.");
Uniforms = new UniformCollection(); Uniforms = new UniformCollection();
Uniforms._parentShader = this; Uniforms.ParentShader = this;
for (int i = 0; i < uniformCount; i++) Uniforms.Import(this);
{
string key = GL.GetActiveUniform(_id, i, out _, out _);
int loc = GL.GetUniformLocation(_id, key);
if (key.EndsWith("]"))
key = key.Split('[', ']')[0];
Uniforms.Add(key, loc);
}
GLDebugging.CheckGLErrors($"A error occured at shader creation for '{GetType()}': %code%");
} }
/// <inheritdoc /> /// <inheritdoc />
@ -65,22 +61,21 @@ namespace SM.OGL.Shaders
} }
/// <summary> /// <summary>
/// Draws the mesh. /// Draws the mesh.
/// </summary> /// </summary>
/// <param name="mesh">The mesh.</param> /// <param name="mesh">The mesh.</param>
/// <param name="amount">The amounts for instancing.</param> /// <param name="amount">The amounts for instancing.</param>
/// <param name="bindVAO">Binds the vertex array for the mesh.</param> /// <param name="bindVAO">Binds the vertex array for the mesh.</param>
protected void DrawObject(Mesh.GenericMesh mesh, int amount = 1, bool bindVAO = false) protected void DrawObject(GenericMesh mesh, int amount = 1)
{ {
if (bindVAO) GL.BindVertexArray(mesh);
if (mesh.Indices != null) if (mesh.Indices != null)
GL.DrawElementsInstanced(mesh.PrimitiveType, 0, DrawElementsType.UnsignedInt, mesh.Indices, amount); GL.DrawElementsInstanced(mesh.PrimitiveType, 0, DrawElementsType.UnsignedInt, mesh.Indices, amount);
else else
GL.DrawArraysInstanced(mesh.PrimitiveType, 0, mesh.Vertex.Count, amount); GL.DrawArraysInstanced(mesh.PrimitiveType, 0, mesh.Vertex.Count, amount);
} }
/// <summary> /// <summary>
/// Resets the shader specific settings to ensure proper workings. /// Resets the shader specific settings to ensure proper workings.
/// </summary> /// </summary>
protected void CleanUp() protected void CleanUp()
{ {

View file

@ -0,0 +1,7 @@
namespace SM.OGL.Shaders
{
public interface IUniform
{
int Location { get; }
}
}

View file

@ -0,0 +1,38 @@
#region usings
using System.Collections.Generic;
using System.IO;
using System.Reflection;
#endregion
namespace SM.OGL.Shaders
{
public class ShaderExtensions
{
public static Dictionary<string, ShaderFile> Extensions { get; private set; } =
new Dictionary<string, ShaderFile>();
public static void AddAssemblyExtensions(string prefix, string path)
{
AddAssemblyExtensions(prefix, Assembly.GetCallingAssembly(), path);
}
public static void AddAssemblyExtensions(string prefix, Assembly assembly, string path)
{
var paths = assembly.GetManifestResourceNames();
for (var i = 0; i < paths.Length; i++)
{
var filePath = paths[i];
if (!filePath.StartsWith(path)) continue;
using (var reader = new StreamReader(assembly.GetManifestResourceStream(filePath)))
{
var name =
$"{prefix}{Path.GetFileNameWithoutExtension(filePath.Substring(path.Length)).Replace('.', '_')}";
Extensions.Add(name, new ShaderFile(reader.ReadToEnd()));
}
}
}
}
}

View file

@ -1,30 +1,37 @@
using System; #region usings
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Shaders namespace SM.OGL.Shaders
{ {
/// <summary> /// <summary>
/// Contains/Represents a file used in shaders. /// Contains/Represents a file used in shaders.
/// </summary> /// </summary>
public class ShaderFile : GLObject public class ShaderFile : GLObject
{ {
private string _data; private string _data;
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Shader;
/// <summary> /// <summary>
/// Contains overrides, that can be used to import values from the CPU to the shader before it is been send to the GPU. /// Contains other shader files to allow access to their functions.
/// </summary>
public Dictionary<string, string> StringOverrides = new Dictionary<string, string>();
/// <summary>
/// Contains other shader files to allow access to their functions.
/// </summary> /// </summary>
public List<ShaderFile> GLSLExtensions = new List<ShaderFile>(); public List<ShaderFile> GLSLExtensions = new List<ShaderFile>();
/// <summary> /// <summary>
/// Creates a file. /// Gets/Sets the name for this shader file.
/// </summary>
public new string Name;
/// <summary>
/// Contains overrides, that can be used to import values from the CPU to the shader before it is been send to the GPU.
/// </summary>
public Dictionary<string, string> StringOverrides = new Dictionary<string, string>();
/// <summary>
/// Creates a file.
/// </summary> /// </summary>
/// <param name="data">The source file.</param> /// <param name="data">The source file.</param>
public ShaderFile(string data) public ShaderFile(string data)
@ -32,11 +39,28 @@ namespace SM.OGL.Shaders
_data = data; _data = data;
} }
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Shader;
private void GenerateSource() private void GenerateSource()
{ {
foreach (KeyValuePair<string, string> kvp in StringOverrides) if (!GLSettings.ShaderPreProcessing) return;
_data = _data.Replace("//! " + kvp.Key, kvp.Value);
if (_data.Contains("//#"))
{
var commandSplits = _data.Split(new[] {"//#"}, StringSplitOptions.RemoveEmptyEntries);
for (var i = 1; i < commandSplits.Length; i++)
{
var split = commandSplits[i].Split('\r', '\n')[0].Trim();
var cmdArgs = split.Split(new[] {' '}, 2);
ShaderPreProcess.Actions[cmdArgs[0]]?.Invoke(this, cmdArgs[1]);
}
}
foreach (var kvp in StringOverrides)
_data = _data.Replace("//!" + kvp.Key, kvp.Value);
} }
internal void Compile(GenericShader shader, ShaderType type) internal void Compile(GenericShader shader, ShaderType type)
@ -49,7 +73,11 @@ namespace SM.OGL.Shaders
GL.ShaderSource(_id, _data); GL.ShaderSource(_id, _data);
GL.CompileShader(_id); GL.CompileShader(_id);
} }
GL.AttachShader(shader, _id); GL.AttachShader(shader, _id);
GLDebugging.CheckGLErrors($"Error at loading shader file: '{shader.GetType()}', '{type}', %code%");
for (var i = 0; i < GLSLExtensions.Count; i++) GLSLExtensions[i].Compile(shader, type);
} }
} }
} }

View file

@ -1,36 +1,43 @@
using System; #region usings
using System.Collections.Generic;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Shaders namespace SM.OGL.Shaders
{ {
/// <summary> /// <summary>
/// Collects all files that are needed for a shader. /// Collects all files that are needed for a shader.
/// </summary> /// </summary>
public struct ShaderFileCollection public struct ShaderFileCollection
{ {
/// <summary> /// <summary>
/// Contains the vertex file. /// Contains the vertex file.
/// </summary> /// </summary>
public ShaderFile Vertex; public ShaderFile Vertex;
/// <summary> /// <summary>
/// Contains the geometry file. /// Contains the geometry file.
/// </summary> /// </summary>
public ShaderFile Geometry; public ShaderFile Geometry;
/// <summary> /// <summary>
/// Contains the fragment file. /// Contains the fragment file.
/// </summary> /// </summary>
public ShaderFile Fragment; public ShaderFile Fragment;
/// <summary> /// <summary>
/// Creating the collection with vertex and fragment files. /// Creating the collection with vertex and fragment files.
/// </summary> /// </summary>
/// <param name="vertex">The vertex source file.</param> /// <param name="vertex">The vertex source file.</param>
/// <param name="fragment">The fragment 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) : this(new ShaderFile(vertex),
new ShaderFile(fragment))
{
}
/// <summary> /// <summary>
/// Creating the collection with shader files. /// Creating the collection with shader files.
/// </summary> /// </summary>
/// <param name="vertex"></param> /// <param name="vertex"></param>
/// <param name="fragment"></param> /// <param name="fragment"></param>
@ -43,7 +50,7 @@ namespace SM.OGL.Shaders
} }
/// <summary> /// <summary>
/// Appends the files to the shader. /// Appends the files to the shader.
/// </summary> /// </summary>
/// <param name="shader"></param> /// <param name="shader"></param>
internal void Append(GenericShader shader) internal void Append(GenericShader shader)
@ -54,14 +61,16 @@ namespace SM.OGL.Shaders
} }
/// <summary> /// <summary>
/// Removes the files form the shader. /// Removes the files form the shader.
/// </summary> /// </summary>
/// <param name="shader"></param> /// <param name="shader"></param>
internal void Detach(GenericShader shader) internal void Detach(GenericShader shader)
{ {
GL.DetachShader(Vertex, shader); GL.DetachShader(shader, Vertex);
if (Geometry != null) GL.DetachShader(Geometry, shader); if (Geometry != null) GL.DetachShader(shader, Geometry);
GL.DetachShader(Fragment, shader); GL.DetachShader(shader, Fragment);
GLDebugging.CheckGLErrors($"Error at detaching '{shader.GetType()}'");
} }
} }
} }

View file

@ -0,0 +1,24 @@
#region usings
using System;
using System.Collections.Generic;
#endregion
namespace SM.OGL.Shaders
{
public class ShaderPreProcess
{
public static Dictionary<string, Action<ShaderFile, string>> Actions =
new Dictionary<string, Action<ShaderFile, string>>
{
{"import", Import}
};
private static void Import(ShaderFile file, string param)
{
foreach (var extension in param.Split(' '))
file.GLSLExtensions.Add(ShaderExtensions.Extensions[extension]);
}
}
}

View file

@ -1,27 +1,35 @@
using OpenTK; #region usings
using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using SM.OGL.Texture; using SM.OGL.Texture;
#endregion
namespace SM.OGL.Shaders namespace SM.OGL.Shaders
{ {
/// <summary> /// <summary>
/// Manages the uniforms. /// Manages the uniforms.
/// </summary> /// </summary>
public struct Uniform public struct Uniform : IUniform
{ {
/// <summary> /// <summary>
/// This contains the location for the uniform. /// This contains the location for the uniform.
/// </summary> /// </summary>
private int Location; public int Location { get; internal set; }
/// <summary>
/// This contains the Parent collection of this uniform.
/// </summary>
internal UniformCollection Parent;
/// <summary> /// <summary>
/// This create a new uniform manager /// This contains the Parent collection of this uniform.
/// </summary>
public UniformCollection Parent { get; }
public Uniform(int location) : this(location, null)
{
}
/// <summary>
/// This create a new uniform manager
/// </summary> /// </summary>
/// <param name="location">Location id</param> /// <param name="location">Location id</param>
/// <param name="parent">Parent collection</param> /// <param name="parent">Parent collection</param>
@ -38,114 +46,343 @@ namespace SM.OGL.Shaders
GL.Uniform1(Location, value ? 1 : 0); GL.Uniform1(Location, value ? 1 : 0);
} }
public void SetUniform1(int value) { GL.Uniform1(Location, value); } public void SetUniform1(int value)
public void SetUniform1(int count, params int[] values) { GL.Uniform1(Location, count, values); } {
public void SetUniform1(int count, ref int values) { GL.Uniform1(Location, count, ref values); } GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params int[] values)
{
GL.Uniform1(Location, count, values);
}
public void SetUniform1(int count, ref int values)
{
GL.Uniform1(Location, count, ref values);
}
public void SetUniform1(uint value) { GL.Uniform1(Location, value); } public void SetUniform1(uint value)
public void SetUniform1(int count, params uint[] values) { GL.Uniform1(Location, count, values); } {
public void SetUniform1(int count, ref uint values) { GL.Uniform1(Location, count, ref values); } GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params uint[] values)
{
GL.Uniform1(Location, count, values);
}
public void SetUniform1(int count, ref uint values)
{
GL.Uniform1(Location, count, ref values);
}
public void SetUniform1(float value) { GL.Uniform1(Location, value); } public void SetUniform1(float value)
public void SetUniform1(int count, params float[] values) { GL.Uniform1(Location, count, values); } {
public void SetUniform1(int count, ref float value) { GL.Uniform1(Location, count, ref value); } GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params float[] values)
{
GL.Uniform1(Location, count, values);
}
public void SetUniform1(int count, ref float value)
{
GL.Uniform1(Location, count, ref value);
}
public void SetUniform1(double value) { GL.Uniform1(Location, value); } public void SetUniform1(double value)
public void SetUniform1(int count, params double[] values) { GL.Uniform1(Location, count, values); } {
public void SetUniform1(int count, ref double value) { GL.Uniform1(Location, count, ref value); } GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params double[] values)
{
GL.Uniform1(Location, count, values);
}
public void SetUniform1(int count, ref double value)
{
GL.Uniform1(Location, count, ref value);
}
#endregion #endregion
#region Uniform2 #region Uniform2
public void SetUniform2(float x, float y) { GL.Uniform2(Location, x, y); } public void SetUniform2(float x, float y)
public void SetUniform2(double x, double y) { GL.Uniform2(Location, x, y); } {
public void SetUniform2(uint x, uint y) { GL.Uniform2(Location, x, y); } GL.Uniform2(Location, x, y);
public void SetUniform2(int x, int y) { GL.Uniform2(Location, x, y); } }
public void SetUniform2(int count, params float[] values) { GL.Uniform2(Location, count, values); } public void SetUniform2(double x, double y)
public void SetUniform2(int count, params double[] values) { GL.Uniform2(Location, count, values); } {
public void SetUniform2(int count, params int[] values) { GL.Uniform2(Location, count, values); } GL.Uniform2(Location, x, y);
public void SetUniform2(int count, params uint[] values) { GL.Uniform2(Location, count, values); } }
public void SetUniform2(int count, ref float values) { GL.Uniform2(Location, count, ref values); } public void SetUniform2(uint x, uint y)
public void SetUniform2(int count, ref double values) { GL.Uniform2(Location, count, ref values); } {
public void SetUniform2(int count, ref uint values) { GL.Uniform2(Location, count, ref values); } GL.Uniform2(Location, x, y);
}
public void SetUniform2(Vector2 vector2) { GL.Uniform2(Location, vector2); } public void SetUniform2(int x, int y)
public void SetUniform2(ref Vector2 vector2) { GL.Uniform2(Location, ref vector2); } {
GL.Uniform2(Location, x, y);
}
public void SetUniform2(int count, params float[] values)
{
GL.Uniform2(Location, count, values);
}
public void SetUniform2(int count, params double[] values)
{
GL.Uniform2(Location, count, values);
}
public void SetUniform2(int count, params int[] values)
{
GL.Uniform2(Location, count, values);
}
public void SetUniform2(int count, params uint[] values)
{
GL.Uniform2(Location, count, values);
}
public void SetUniform2(int count, ref float values)
{
GL.Uniform2(Location, count, ref values);
}
public void SetUniform2(int count, ref double values)
{
GL.Uniform2(Location, count, ref values);
}
public void SetUniform2(int count, ref uint values)
{
GL.Uniform2(Location, count, ref values);
}
public void SetUniform2(Vector2 vector2)
{
GL.Uniform2(Location, vector2);
}
public void SetUniform2(ref Vector2 vector2)
{
GL.Uniform2(Location, ref vector2);
}
#endregion #endregion
#region Uniform3 #region Uniform3
public void SetUniform3(float x, float y, float z) { GL.Uniform3(Location, x, y, z); } public void SetUniform3(float x, float y, float z)
public void SetUniform3(double x, double y, double z) { GL.Uniform3(Location, x, y, z); } {
public void SetUniform3(uint x, uint y, uint z) { GL.Uniform3(Location, x, y, z); } GL.Uniform3(Location, x, y, z);
public void SetUniform3(int x, int y, int z) { GL.Uniform3(Location, x, y, z); } }
public void SetUniform3(int count, params float[] values) { GL.Uniform3(Location, count, values); } public void SetUniform3(double x, double y, double z)
public void SetUniform3(int count, params double[] values) { GL.Uniform3(Location, count, values); } {
public void SetUniform3(int count, params int[] values) { GL.Uniform3(Location, count, values); } GL.Uniform3(Location, x, y, z);
public void SetUniform3(int count, params uint[] values) { GL.Uniform3(Location, count, values); } }
public void SetUniform3(int count, ref float values) { GL.Uniform3(Location, count, ref values); } public void SetUniform3(uint x, uint y, uint z)
public void SetUniform3(int count, ref double values) { GL.Uniform3(Location, count, ref values); } {
public void SetUniform3(int count, ref uint values) { GL.Uniform3(Location, count, ref values); } GL.Uniform3(Location, x, y, z);
}
public void SetUniform3(Vector3 vector) { GL.Uniform3(Location, vector); } public void SetUniform3(int x, int y, int z)
public void SetUniform3(ref Vector3 vector) { GL.Uniform3(Location, ref vector); } {
GL.Uniform3(Location, x, y, z);
}
public void SetUniform3(int count, params float[] values)
{
GL.Uniform3(Location, count, values);
}
public void SetUniform3(int count, params double[] values)
{
GL.Uniform3(Location, count, values);
}
public void SetUniform3(int count, params int[] values)
{
GL.Uniform3(Location, count, values);
}
public void SetUniform3(int count, params uint[] values)
{
GL.Uniform3(Location, count, values);
}
public void SetUniform3(int count, ref float values)
{
GL.Uniform3(Location, count, ref values);
}
public void SetUniform3(int count, ref double values)
{
GL.Uniform3(Location, count, ref values);
}
public void SetUniform3(int count, ref uint values)
{
GL.Uniform3(Location, count, ref values);
}
public void SetUniform3(Vector3 vector)
{
GL.Uniform3(Location, vector);
}
public void SetUniform3(ref Vector3 vector)
{
GL.Uniform3(Location, ref vector);
}
#endregion #endregion
#region Uniform4 #region Uniform4
public void SetUniform4(float x, float y, float z, float w) { GL.Uniform4(Location, x, y, z, w); } public void SetUniform4(float x, float y, float z, float w)
public void SetUniform4(double x, double y, double z, double w) { GL.Uniform4(Location, x, y, z, w); } {
public void SetUniform4(uint x, uint y, uint z, uint w) { GL.Uniform4(Location, x, y, z, w); } GL.Uniform4(Location, x, y, z, w);
public void SetUniform4(int x, int y, int z, int w) { GL.Uniform4(Location, x, y, z, w); } }
public void SetUniform4(int count, params float[] values) { GL.Uniform4(Location, count, values); } public void SetUniform4(double x, double y, double z, double w)
public void SetUniform4(int count, params double[] values) { GL.Uniform4(Location, count, values); } {
public void SetUniform4(int count, params int[] values) { GL.Uniform4(Location, count, values); } GL.Uniform4(Location, x, y, z, w);
public void SetUniform4(int count, params uint[] values) { GL.Uniform4(Location, count, values); } }
public void SetUniform4(int count, ref float values) { GL.Uniform4(Location, count, ref values); } public void SetUniform4(uint x, uint y, uint z, uint w)
public void SetUniform4(int count, ref double values) { GL.Uniform4(Location, count, ref values); } {
public void SetUniform4(int count, ref uint values) { GL.Uniform4(Location, count, ref values); } GL.Uniform4(Location, x, y, z, w);
}
public void SetUniform4(Vector4 vector) { GL.Uniform4(Location, vector); } public void SetUniform4(int x, int y, int z, int w)
public void SetUniform4(ref Vector4 vector) { GL.Uniform4(Location, ref vector); } {
GL.Uniform4(Location, x, y, z, w);
}
public void SetUniform4(Color4 color) { GL.Uniform4(Location, color); } public void SetUniform4(int count, params float[] values)
public void SetUniform4(Quaternion quaternion) { GL.Uniform4(Location, quaternion); } {
GL.Uniform4(Location, count, values);
}
public void SetUniform4(int count, params double[] values)
{
GL.Uniform4(Location, count, values);
}
public void SetUniform4(int count, params int[] values)
{
GL.Uniform4(Location, count, values);
}
public void SetUniform4(int count, params uint[] values)
{
GL.Uniform4(Location, count, values);
}
public void SetUniform4(int count, ref float values)
{
GL.Uniform4(Location, count, ref values);
}
public void SetUniform4(int count, ref double values)
{
GL.Uniform4(Location, count, ref values);
}
public void SetUniform4(int count, ref uint values)
{
GL.Uniform4(Location, count, ref values);
}
public void SetUniform4(Vector4 vector)
{
GL.Uniform4(Location, vector);
}
public void SetUniform4(ref Vector4 vector)
{
GL.Uniform4(Location, ref vector);
}
public void SetUniform4(Color4 color)
{
GL.Uniform4(Location, color);
}
public void SetUniform4(Quaternion quaternion)
{
GL.Uniform4(Location, quaternion);
}
#endregion #endregion
#region Matrix2 #region Matrix2
public void SetMatrix2(ref Matrix2 matrix, bool transpose = false) { GL.UniformMatrix2(Location, transpose, ref matrix); } public void SetMatrix2(ref Matrix2 matrix, bool transpose = false)
{
GL.UniformMatrix2(Location, transpose, ref matrix);
}
public void SetMatrix2(int count, ref double value, bool transpose = false) { GL.UniformMatrix2(Location, count, transpose, ref value); } public void SetMatrix2(int count, ref double value, bool transpose = false)
public void SetMatrix2(int count, ref float value, bool transpose = false) { GL.UniformMatrix2(Location, count, transpose, ref value); } {
GL.UniformMatrix2(Location, count, transpose, ref value);
}
public void SetMatrix2(int count, double[] value, bool transpose = false) { GL.UniformMatrix2(Location, count, transpose, value); } public void SetMatrix2(int count, ref float value, bool transpose = false)
public void SetMatrix2(int count, float[] value, bool transpose = false) { GL.UniformMatrix2(Location, count, transpose, value); } {
GL.UniformMatrix2(Location, count, transpose, ref value);
}
public void SetMatrix2(int count, double[] value, bool transpose = false)
{
GL.UniformMatrix2(Location, count, transpose, value);
}
public void SetMatrix2(int count, float[] value, bool transpose = false)
{
GL.UniformMatrix2(Location, count, transpose, value);
}
#endregion #endregion
#region Matrix3 #region Matrix3
public void SetMatrix3(ref Matrix3 matrix, bool transpose = false) { GL.UniformMatrix3(Location, transpose, ref matrix); } public void SetMatrix3(ref Matrix3 matrix, bool transpose = false)
{
GL.UniformMatrix3(Location, transpose, ref matrix);
}
public void SetMatrix3(int count, ref double value, bool transpose = false) { GL.UniformMatrix3(Location, count, transpose, ref value); } public void SetMatrix3(int count, ref double value, bool transpose = false)
public void SetMatrix3(int count, ref float value, bool transpose = false) { GL.UniformMatrix3(Location, count, transpose, ref value); } {
GL.UniformMatrix3(Location, count, transpose, ref value);
}
public void SetMatrix3(int count, double[] value, bool transpose = false) { GL.UniformMatrix3(Location, count, transpose, value); } public void SetMatrix3(int count, ref float value, bool transpose = false)
public void SetMatrix3(int count, float[] value, bool transpose = false) { GL.UniformMatrix3(Location, count, transpose, value); } {
GL.UniformMatrix3(Location, count, transpose, ref value);
}
public void SetMatrix3(int count, double[] value, bool transpose = false)
{
GL.UniformMatrix3(Location, count, transpose, value);
}
public void SetMatrix3(int count, float[] value, bool transpose = false)
{
GL.UniformMatrix3(Location, count, transpose, value);
}
#endregion #endregion
@ -155,18 +392,36 @@ namespace SM.OGL.Shaders
{ {
GL.UniformMatrix4(Location, transpose, ref matrix); GL.UniformMatrix4(Location, transpose, ref matrix);
} }
public void SetMatrix4(ref Matrix4 matrix, bool transpose = false) { GL.UniformMatrix4(Location, transpose, ref matrix); }
public void SetMatrix4(int count, ref double value, bool transpose = false) { GL.UniformMatrix4(Location, count, transpose, ref value); } public void SetMatrix4(ref Matrix4 matrix, bool transpose = false)
public void SetMatrix4(int count, ref float value, bool transpose = false) { GL.UniformMatrix4(Location, count, transpose, ref value); } {
GL.UniformMatrix4(Location, transpose, ref matrix);
}
public void SetMatrix4(int count, double[] value, bool transpose = false) { GL.UniformMatrix4(Location, count, transpose, value); } public void SetMatrix4(int count, ref double value, bool transpose = false)
public void SetMatrix4(int count, float[] value, bool transpose = false) { GL.UniformMatrix4(Location, count, transpose, value); } {
GL.UniformMatrix4(Location, count, transpose, ref value);
}
public void SetMatrix4(int count, ref float value, bool transpose = false)
{
GL.UniformMatrix4(Location, count, transpose, ref value);
}
public void SetMatrix4(int count, double[] value, bool transpose = false)
{
GL.UniformMatrix4(Location, count, transpose, value);
}
public void SetMatrix4(int count, float[] value, bool transpose = false)
{
GL.UniformMatrix4(Location, count, transpose, value);
}
#endregion #endregion
/// <summary> /// <summary>
/// Try to sets the texture at the next possible position and tells the checkUniform, if worked or not. /// Try to sets the texture at the next possible position and tells the checkUniform, if worked or not.
/// </summary> /// </summary>
/// <param name="texture">The texture you want to add</param> /// <param name="texture">The texture you want to add</param>
/// <param name="checkUniform">The check uniform.</param> /// <param name="checkUniform">The check uniform.</param>
@ -177,7 +432,7 @@ namespace SM.OGL.Shaders
} }
/// <summary> /// <summary>
/// Try to sets the texture at the specified position and tells the checkUniform, if worked or not. /// Try to sets the texture at the specified position and tells the checkUniform, if worked or not.
/// </summary> /// </summary>
/// <param name="texture">The texture you want to add</param> /// <param name="texture">The texture you want to add</param>
/// <param name="pos">The position</param> /// <param name="pos">The position</param>
@ -187,14 +442,18 @@ namespace SM.OGL.Shaders
checkUniform.SetUniform1(texture != null); checkUniform.SetUniform1(texture != null);
if (texture != null) SetTexture(texture); if (texture != null) SetTexture(texture);
} }
/// <summary>
/// Sets the texture to the next possible position.
/// </summary>
/// <param name="texture"></param>
public void SetTexture(TextureBase texture) => SetTexture(texture, Parent.NextTexture++);
/// <summary> /// <summary>
/// Sets the texture to the specified position. /// Sets the texture to the next possible position.
/// </summary>
/// <param name="texture"></param>
public void SetTexture(TextureBase texture)
{
if (Parent != null) SetTexture(texture, Parent.NextTexture++);
}
/// <summary>
/// Sets the texture to the specified position.
/// </summary> /// </summary>
/// <param name="texture"></param> /// <param name="texture"></param>
/// <param name="texturePos"></param> /// <param name="texturePos"></param>
@ -206,9 +465,12 @@ namespace SM.OGL.Shaders
} }
/// <summary> /// <summary>
/// Returns the location from the uniform /// Returns the location from the uniform
/// </summary> /// </summary>
/// <param name="u"></param> /// <param name="u"></param>
public static implicit operator int(Uniform u) => u.Location; public static implicit operator int(Uniform u)
{
return u.Location;
}
} }
} }

View file

@ -0,0 +1,50 @@
#region usings
using System;
using System.Collections.Generic;
#endregion
namespace SM.OGL.Shaders
{
public class UniformArray : IUniform
{
internal UniformCollection collection;
internal Dictionary<string, int> Offsets = new Dictionary<string, int>();
internal int Size;
internal bool Struct = false;
public int Location { get; internal set; }
public GenericShader Parent { get; internal set; }
public string Name { get; internal set; }
public UniformArray()
{
collection = new UniformCollection()
{
ParentShader = Parent
};
}
public void Set(Action<int, Uniform> setAction)
{
for (var i = 0; i < Size; i++) setAction(i, new Uniform(Location + i));
}
public void Set(Func<int, UniformCollection, bool> setAction)
{
collection.ParentShader ??= Parent;
for (var i = 0; i < Size; i++)
{
collection.KeyString = $"{Name}[{i}]";
foreach (var pair in Offsets)
collection.Set(pair.Key, new Uniform(Location + pair.Value + i));
if (!setAction(i, collection)) break;
}
}
}
}

View file

@ -1,56 +1,109 @@
using System; #region usings
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Shaders namespace SM.OGL.Shaders
{ {
/// <summary> public class UniformCollection : Dictionary<string, IUniform>
/// Contains and manages the uniform of the parent shader.
/// </summary>
public class UniformCollection : Dictionary<string, Uniform>
{ {
/// <summary>
/// The next texture id for the uniform.
/// </summary>
internal int NextTexture = 0; internal int NextTexture = 0;
internal string KeyString = "";
public GenericShader ParentShader { get; internal set; }
/// <summary> public new Uniform this[string key] => Get(key);
/// The parent shader.
/// </summary>
internal GenericShader _parentShader;
/// <summary> public Uniform Get(string key)
/// Get you the uniform under the variable name.
/// <para>If it don't find the uniform, it tries to recreate it.</para>
/// <para>If the variable doesn't exist in the first place, it will after the recreation send everything to -1, what is the void.</para>
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public new Uniform this[string key]
{ {
get try
{ {
try return (Uniform) base[key];
{ }
return base[key]; catch (KeyNotFoundException)
} {
catch (KeyNotFoundException) GLCustomActions.AtWarning?.Invoke("Uniform '" + KeyString + key + "' was not found. Tried to recreate it.");
{ var u = new Uniform(GL.GetUniformLocation(ParentShader, KeyString + key), this);
Console.WriteLine("[Error] Uniform '"+key+"' was not found. Tried to recreate it."); Add(key, u);
Uniform u = new Uniform(GL.GetUniformLocation(_parentShader, key), this); return u;
Add(key, u);
return u;
}
} }
} }
/// <summary>
/// Adds a uniform with a location. public UniformArray GetArray(string key)
/// </summary> {
/// <param name="key"></param> try
/// <param name="location"></param> {
return (UniformArray) base[key];
}
catch (KeyNotFoundException)
{
throw new Exception("UniformArray '"+key+"' wasn't found");
}
}
public void Add(string key, int location) public void Add(string key, int location)
{ {
base.Add(key, new Uniform(location, this)); base.Add(key, new Uniform(location, this));
} }
internal void Set(string key, IUniform value)
{
base[key] = value;
}
internal void Import(GenericShader shader)
{
GL.GetProgram(shader, GetProgramParameterName.ActiveUniforms, out var uniformCount);
if (uniformCount < 1)
GLCustomActions.AtError("No uniforms has been found.");
var lastArrayKey = "";
var array = new UniformArray();
var arrayFilled = false;
if (GLSettings.InfoEveryUniform) GLCustomActions.AtInfo?.Invoke("Uniforms for: " + shader.GetType());
for (var i = 0; i < uniformCount; i++)
{
var key = GL.GetActiveUniform(shader, i, out _, out _);
var loc = GL.GetUniformLocation(shader, key);
if (GLSettings.InfoEveryUniform) GLCustomActions.AtInfo?.Invoke($"{key} - {loc}");
if (key.Contains("["))
{
var keySplits = key.Split('[', ']');
if (keySplits[0] != lastArrayKey)
{
if (arrayFilled) Add(lastArrayKey, array);
array = new UniformArray
{
Location = loc,
Name = keySplits[0],
Parent = ParentShader,
Struct = keySplits.Length > 2
};
arrayFilled = true;
lastArrayKey = keySplits[0];
}
var curIndex = int.Parse(keySplits[1]);
if (array.Size < curIndex) array.Size = curIndex;
if (array.Struct)
if (!array.Offsets.ContainsKey(keySplits[2].Trim('.')))
array.Offsets.Add(keySplits[2].Trim('.'), loc - array.Location);
}
else
{
Add(key, loc);
}
}
if (arrayFilled) Add(lastArrayKey, array);
}
} }
} }

View file

@ -1,9 +1,13 @@
using OpenTK.Graphics.OpenGL4; #region usings
using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Texture namespace SM.OGL.Texture
{ {
/// <summary> /// <summary>
/// Works as a basis for textures. /// Works as a basis for textures.
/// </summary> /// </summary>
public abstract class TextureBase : GLObject public abstract class TextureBase : GLObject
{ {
@ -14,23 +18,24 @@ namespace SM.OGL.Texture
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Texture; public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Texture;
/// <summary> /// <summary>
/// The texture filter. /// The texture filter.
/// <para>Default: <see cref="TextureMinFilter.Linear"/></para> /// <para>Default: <see cref="TextureMinFilter.Linear" /></para>
/// </summary> /// </summary>
public virtual TextureMinFilter Filter { get; set; } = TextureMinFilter.Linear; public virtual TextureMinFilter Filter { get; set; } = TextureMinFilter.Linear;
/// <summary> /// <summary>
/// The wrap mode. /// The wrap mode.
/// <para>Default: <see cref="TextureWrapMode.Repeat"/></para> /// <para>Default: <see cref="TextureWrapMode.Repeat" /></para>
/// </summary> /// </summary>
public virtual TextureWrapMode WrapMode { get; set; } = TextureWrapMode.Repeat; public virtual TextureWrapMode WrapMode { get; set; } = TextureWrapMode.Repeat;
/// <summary> /// <summary>
/// The Width of the texture /// The Width of the texture
/// </summary> /// </summary>
public int Width { get; protected set; } public int Width { get; protected set; }
/// <summary> /// <summary>
/// The height of the texture /// The height of the texture
/// </summary> /// </summary>
public int Height { get; protected set; } public int Height { get; protected set; }

View file

@ -1,21 +1,22 @@
namespace SM.OGL namespace SM.OGL
{ {
/// <summary> /// <summary>
/// Helper struct to manage versions. /// Helper struct to manage versions.
/// </summary> /// </summary>
public struct Version public struct Version
{ {
/// <summary> /// <summary>
/// The major version. /// The major version.
/// </summary> /// </summary>
public int MajorVersion; public int MajorVersion;
/// <summary> /// <summary>
/// The minor version. /// The minor version.
/// </summary> /// </summary>
public int MinorVersion; public int MinorVersion;
/// <summary> /// <summary>
/// Creates the struct with specific major and minor versions. /// Creates the struct with specific major and minor versions.
/// </summary> /// </summary>
/// <param name="majorVersion"></param> /// <param name="majorVersion"></param>
/// <param name="minorVersion"></param> /// <param name="minorVersion"></param>
@ -26,12 +27,12 @@
} }
/// <summary> /// <summary>
/// Creates the struct by reading it out of a string. /// Creates the struct by reading it out of a string.
/// </summary> /// </summary>
/// <param name="version"></param> /// <param name="version"></param>
public Version(string version) public Version(string version)
{ {
string[] splits = version.Trim().Split(new []{'.'}, 2); var splits = version.Trim().Split(new[] {'.'}, 2);
MajorVersion = int.Parse(splits[0]); MajorVersion = int.Parse(splits[0]);
MinorVersion = int.Parse(splits[1]); MinorVersion = int.Parse(splits[1]);
} }
@ -43,7 +44,7 @@
} }
/// <summary> /// <summary>
/// Create a version struct, with a OpenGL Version string. /// Create a version struct, with a OpenGL Version string.
/// </summary> /// </summary>
/// <param name="version"></param> /// <param name="version"></param>
/// <returns></returns> /// <returns></returns>

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="OpenTK" version="3.2" targetFramework="net452" /> <package id="OpenTK" version="3.2.1" targetFramework="net452" />
</packages> </packages>

View file

@ -1,21 +1,28 @@
using OpenTK; #region usings
using OpenTK;
using OpenTK.Input; using OpenTK.Input;
using SM.Base;
using SM.Base.Controls; using SM.Base.Controls;
using SM2D.Scene; using SM2D.Scene;
#endregion
namespace SM2D.Controls namespace SM2D.Controls
{ {
public class Mouse2D : Mouse<GLWindow2D> public class Mouse2D : Mouse<GLWindow2D>
{ {
protected internal Mouse2D(GLWindow2D window) : base(window) protected internal Mouse2D(GLWindow2D window) : base(window)
{ } {
}
internal new void MouseMoveEvent(MouseMoveEventArgs mmea) => base.MouseMoveEvent(mmea); internal new void MouseMoveEvent(MouseMoveEventArgs mmea)
{
base.MouseMoveEvent(mmea);
}
public Vector2 InWorld() public Vector2 InWorld()
{ {
Vector2 res = _window.WorldScale; var res = _window.WorldScale;
return InScreenNormalized * res - res / 2; return InScreenNormalized * res - res / 2;
} }

View file

@ -1,15 +1,16 @@
using System.Collections.Generic; #region usings
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
using SM.Base;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Objects.Static; using SM.Base.Objects.Static;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Base.Textures; using SM.Base.Textures;
using SM.OGL.Texture; using SM.OGL.Texture;
using SM2D.Shader;
using SM2D.Types; #endregion
namespace SM2D.Drawing namespace SM2D.Drawing
{ {
@ -17,6 +18,22 @@ namespace SM2D.Drawing
{ {
private Material _material = new Material(); private Material _material = new Material();
public DrawBackground(Color4 color)
{
Color = color;
}
public DrawBackground(Bitmap texture)
{
Texture = (Texture) texture;
}
public DrawBackground(Bitmap texture, Color4 tint)
{
Color = tint;
Texture = (Texture) texture;
}
public Color4 Color public Color4 Color
{ {
get => _material.Tint; get => _material.Tint;
@ -28,28 +45,14 @@ namespace SM2D.Drawing
get => _material.Texture; get => _material.Texture;
set => _material.Texture = value; set => _material.Texture = value;
} }
public DrawBackground(Color4 color)
{
Color = color;
}
public DrawBackground(Bitmap texture)
{
Texture = (Texture)texture;
}
public DrawBackground(Bitmap texture, Color4 tint)
{
Color = tint;
Texture = (Texture) texture;
}
public object Parent { get; set; } public object Parent { get; set; }
public string Name { get; set; } = "Background"; public string Name { get; set; } = "Background";
public ICollection<string> Flags { get; set; } = new string[0]; public ICollection<string> Flags { get; set; } = new string[0];
public void Update(UpdateContext context) public void Update(UpdateContext context)
{ } {
}
public void Draw(DrawContext context) public void Draw(DrawContext context)
{ {

View file

@ -0,0 +1,19 @@
using SM.Base.Contexts;
using SM.Base.Scene;
using SM2D.Scene;
namespace SM2D.Drawing
{
public class DrawBackgroundShader : DrawShader, IBackgroundItem
{
public DrawBackgroundShader(MaterialShader shader) : base(shader)
{ }
protected override void DrawContext(ref DrawContext context)
{
Transform.Size.Set(context.WorldScale);
base.DrawContext(ref context);
}
}
}

View file

@ -1,14 +1,26 @@
using OpenTK.Graphics; #region usings
using SM.Base;
using OpenTK.Graphics;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM2D.Scene; using SM2D.Scene;
using SM2D.Types; using SM2D.Types;
#endregion
namespace SM2D.Drawing namespace SM2D.Drawing
{ {
public class DrawColor : DrawingBasis<Transformation>, I2DShowItem public class DrawColor : DrawingBasis<Transformation>, I2DShowItem
{ {
public DrawColor()
{
}
public DrawColor(Color4 color)
{
_material.Tint = color;
}
public Color4 Color public Color4 Color
{ {
get => _material.Tint; get => _material.Tint;
@ -17,13 +29,6 @@ namespace SM2D.Drawing
public int ZIndex { get; set; } public int ZIndex { get; set; }
public DrawColor() {}
public DrawColor(Color4 color)
{
_material.Tint = color;
}
protected override void DrawContext(ref DrawContext context) protected override void DrawContext(ref DrawContext context)
{ {
context.Instances[0].ModelMatrix = Transform.GetMatrix(); context.Instances[0].ModelMatrix = Transform.GetMatrix();

View file

@ -1,15 +1,17 @@
using SM.Base.Contexts; #region usings
using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM.OGL.Mesh; using SM.OGL.Mesh;
using SM2D.Scene; using SM2D.Scene;
using SM2D.Types; using SM2D.Types;
#endregion
namespace SM2D.Drawing namespace SM2D.Drawing
{ {
public class DrawComplex: DrawingBasis<Transformation>, I2DShowItem public class DrawComplex : DrawingBasis<Transformation>, I2DShowItem
{ {
public int ZIndex { get; set; }
public Material Material public Material Material
{ {
get => _material; get => _material;
@ -22,6 +24,8 @@ namespace SM2D.Drawing
set => _mesh = value; set => _mesh = value;
} }
public int ZIndex { get; set; }
protected override void DrawContext(ref DrawContext context) protected override void DrawContext(ref DrawContext context)
{ {
context.Instances[0].ModelMatrix = Transform.GetMatrix(); context.Instances[0].ModelMatrix = Transform.GetMatrix();

View file

@ -1,38 +1,46 @@
using System.Drawing; #region usings
using System.Drawing;
using OpenTK.Graphics; using OpenTK.Graphics;
using SM.Base.Textures; using SM.Base.Textures;
using SM.OGL.Texture;
using SM2D.Object; using SM2D.Object;
#endregion
namespace SM2D.Drawing namespace SM2D.Drawing
{ {
public class DrawPolygon : DrawColor public class DrawPolygon : DrawColor
{ {
public Polygon Polygon public DrawPolygon(Polygon polygon) : this(polygon, Color4.White)
{ {
get => (Polygon)_mesh;
set => _mesh = value;
} }
public Texture Texture public DrawPolygon(Polygon polygon, Bitmap map) : this(polygon, map, Color4.White)
{ {
get => (Texture)_material.Texture;
set => _material.Texture = value;
} }
public DrawPolygon(Polygon polygon) {}
public DrawPolygon(Polygon polygon, Bitmap map) : this(polygon, map, Color4.White) {}
public DrawPolygon(Polygon polygon, Color4 color) : base(color) public DrawPolygon(Polygon polygon, Color4 color) : base(color)
{ {
_mesh = polygon; _mesh = polygon;
} }
public DrawPolygon(Polygon polygon, Bitmap map, Color4 tint) : base(tint) public DrawPolygon(Polygon polygon, Bitmap map, Color4 tint) : base(tint)
{ {
_mesh = polygon; _mesh = polygon;
_material.Texture = new Texture(map); _material.Texture = new Texture(map);
} }
public Polygon Polygon
{
get => (Polygon) _mesh;
set => _mesh = value;
}
public Texture Texture
{
get => (Texture) _material.Texture;
set => _material.Texture = value;
}
} }
} }

View file

@ -0,0 +1,24 @@
using SM.Base.Contexts;
using SM.Base.Scene;
using SM2D.Scene;
using SM2D.Types;
namespace SM2D.Drawing
{
public class DrawShader : DrawingBasis<Transformation>, I2DShowItem
{
public int ZIndex { get; set; }
public DrawShader(MaterialShader shader)
{
_material.CustomShader = shader;
}
protected override void DrawContext(ref DrawContext context)
{
context.Instances[0].ModelMatrix = Transform.GetMatrix();
_material.CustomShader.Draw(context);
}
}
}

View file

@ -1,10 +1,13 @@
using SM.Base; #region usings
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Text; using SM.Base.Text;
using SM.Base.Types; using SM.Base.Types;
using SM2D.Scene; using SM2D.Scene;
using SM2D.Types; using SM2D.Types;
#endregion
namespace SM2D.Drawing namespace SM2D.Drawing
{ {
public class DrawText : TextDrawingBasis<Transformation>, I2DShowItem public class DrawText : TextDrawingBasis<Transformation>, I2DShowItem
@ -15,6 +18,8 @@ namespace SM2D.Drawing
Transform.Size = new CVector2(1); Transform.Size = new CVector2(1);
} }
public int ZIndex { get; set; }
protected override void DrawContext(ref DrawContext context) protected override void DrawContext(ref DrawContext context)
{ {
base.DrawContext(ref context); base.DrawContext(ref context);
@ -24,7 +29,5 @@ namespace SM2D.Drawing
context.Shader.Draw(context); context.Shader.Draw(context);
} }
public int ZIndex { get; set; }
} }
} }

View file

@ -1,36 +1,37 @@
using System.Drawing; #region usings
using OpenTK;
using System.Drawing;
using OpenTK.Graphics; using OpenTK.Graphics;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene;
using SM.Base.Textures; using SM.Base.Textures;
using SM.Base.Types; using SM.Base.Types;
using SM2D.Scene;
using SM2D.Types; #endregion
namespace SM2D.Drawing namespace SM2D.Drawing
{ {
public class DrawTexture : DrawColor public class DrawTexture : DrawColor
{ {
public static float MasterScale = .25f; public static float MasterScale = .25f;
public bool ManualSize = false;
public float Scale = 1; public float Scale = 1;
public bool ManualSize = false;
public Texture Texture public DrawTexture()
{ {
get => (Texture) _material.Texture;
set => _material.Texture = value;
} }
public DrawTexture() {} protected DrawTexture(Color4 color) : base(color)
{
protected DrawTexture(Color4 color) : base(color) { } }
public DrawTexture(Bitmap map) : this(map, Color4.White) public DrawTexture(Bitmap map) : this(map, Color4.White)
{ } {
}
public DrawTexture(Bitmap map, Color4 color) : this((Texture)map, color) public DrawTexture(Bitmap map, Color4 color) : this((Texture) map, color)
{ } {
}
public DrawTexture(Texture texture, Color4 color) public DrawTexture(Texture texture, Color4 color)
{ {
@ -38,9 +39,17 @@ namespace SM2D.Drawing
_material.Tint = color; _material.Tint = color;
} }
public Texture Texture
{
get => (Texture) _material.Texture;
set => _material.Texture = value;
}
protected override void DrawContext(ref DrawContext context) protected override void DrawContext(ref DrawContext context)
{ {
if (!ManualSize) Transform.Size = new CVector2(Texture.Map.Width * MasterScale * Scale, Texture.Map.Height * MasterScale * Scale); if (!ManualSize)
Transform.Size = new CVector2(Texture.Map.Width * MasterScale * Scale,
Texture.Map.Height * MasterScale * Scale);
base.DrawContext(ref context); base.DrawContext(ref context);
} }
} }

View file

@ -1,29 +1,31 @@
using System; #region usings
using System;
using OpenTK; using OpenTK;
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using OpenTK.Input; using OpenTK.Input;
using SM.Base; using SM.Base;
using SM.Base.Controls;
using SM2D.Controls; using SM2D.Controls;
using SM2D.Pipelines; using SM2D.Pipelines;
using SM2D.Scene; using SM2D.Scene;
using SM2D.Shader; using SM2D.Shader;
using Vector2 = OpenTK.Vector2;
#endregion
namespace SM2D namespace SM2D
{ {
public class GLWindow2D : GenericWindow<Scene.Scene, Camera> public class GLWindow2D : GenericWindow<Scene.Scene, Camera>
{ {
public Vector2? Scaling { get; set; }
public Vector2 WorldScale => _worldScale;
public Mouse2D Mouse { get; }
public GLWindow2D() public GLWindow2D()
{ {
Mouse = new Mouse2D(this); Mouse = new Mouse2D(this);
} }
public Vector2? Scaling { get; set; }
public Vector2 WorldScale => _worldScale;
public Mouse2D Mouse { get; }
protected override void OnLoad(EventArgs e) protected override void OnLoad(EventArgs e)
{ {
base.OnLoad(e); base.OnLoad(e);
@ -34,6 +36,8 @@ namespace SM2D
protected override void OnLoaded() protected override void OnLoaded()
{ {
base.OnLoaded(); base.OnLoaded();
SMRenderer.DefaultMaterialShader = Default2DShader.MaterialShader;
SetRenderPipeline(new Basic2DPipeline()); SetRenderPipeline(new Basic2DPipeline());
} }

View file

@ -1,5 +1,6 @@
using System; #region usings
using System.Collections;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using OpenTK; using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
@ -7,46 +8,40 @@ using OpenTK.Graphics.OpenGL4;
using SM.Base.Objects; using SM.Base.Objects;
using SM.OGL.Mesh; using SM.OGL.Mesh;
#endregion
namespace SM2D.Object namespace SM2D.Object
{ {
public class Polygon : Mesh public class Polygon : Mesh
{ {
public override VBO Vertex { get; } = new VBO();
public override VBO UVs { get; } = new VBO(pointerSize:2);
public override VBO Color { get; } = new VBO(pointerSize: 4);
public override PrimitiveType PrimitiveType { get; } = PrimitiveType.TriangleFan;
public Polygon(ICollection<Vector2> vertices) public Polygon(ICollection<Vector2> vertices)
{ {
foreach (Vector2 vertex in vertices) foreach (var vertex in vertices)
{ {
Color.Add(Color4.White); Color.Add(Color4.White);
AddVertex(vertex); AddVertex(vertex);
} }
foreach (Vector2 vertex in vertices) foreach (var vertex in vertices) AddUV(vertex);
{
AddUV(vertex);
}
} }
public Polygon(ICollection<PolygonVertex> vertices) public Polygon(ICollection<PolygonVertex> vertices)
{ {
foreach (PolygonVertex polygonVertex in vertices) foreach (var polygonVertex in vertices)
{ {
Color.Add(polygonVertex.Color); Color.Add(polygonVertex.Color);
AddVertex(polygonVertex.Vertex); AddVertex(polygonVertex.Vertex);
} }
foreach (PolygonVertex vertex in vertices) foreach (var vertex in vertices) AddUV(vertex.Vertex);
{
AddUV(vertex.Vertex);
}
} }
public override VBO Vertex { get; } = new VBO();
public override VBO UVs { get; } = new VBO(pointerSize: 2);
public override VBO Color { get; } = new VBO(pointerSize: 4);
public override PrimitiveType PrimitiveType { get; } = PrimitiveType.TriangleFan;
private void AddVertex(Vector2 vertex) private void AddVertex(Vector2 vertex)
{ {
BoundingBox.Update(vertex); BoundingBox.Update(vertex);
@ -55,18 +50,19 @@ namespace SM2D.Object
private void AddUV(Vector2 vertex) private void AddUV(Vector2 vertex)
{ {
Vector2 uv = Vector2.Divide(vertex, BoundingBox.Max.Xy) + BoundingBox.Min.Xy; var uv = Vector2.Divide(vertex, BoundingBox.Max.Xy) + BoundingBox.Min.Xy;
UVs.Add(uv); UVs.Add(uv);
} }
public static Polygon GenerateCircle(int secments = 32) public static Polygon GenerateCircle(int secments = 32)
{ {
List<Vector2> vertices = new List<Vector2>() {Vector2.Zero}; var vertices = new List<Vector2> {Vector2.Zero};
float step = 360f / secments; var step = 360f / secments;
for (int i = 0; i < secments + 1; i++) for (var 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)); var 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); vertices.Add(vertex);
} }

View file

@ -1,6 +1,10 @@
using OpenTK; #region usings
using OpenTK;
using OpenTK.Graphics; using OpenTK.Graphics;
#endregion
namespace SM2D.Object namespace SM2D.Object
{ {
public struct PolygonVertex public struct PolygonVertex

View file

@ -2,6 +2,5 @@
{ {
public class Adv2DPipeline public class Adv2DPipeline
{ {
} }
} }

View file

@ -1,15 +1,18 @@
using OpenTK.Graphics.OpenGL4; #region usings
using OpenTK.Graphics.OpenGL4;
using SM.Base; using SM.Base;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM.OGL.Framebuffer; using SM.OGL.Framebuffer;
using SM2D.Shader; using SM2D.Shader;
#endregion
namespace SM2D.Pipelines namespace SM2D.Pipelines
{ {
public class Basic2DPipeline : RenderPipeline<Scene.Scene> public class Basic2DPipeline : RenderPipeline<Scene.Scene>
{ {
protected override IShader _defaultShader { get; } = Default2DShader.Shader;
protected override void Render(ref DrawContext context, Scene.Scene scene) protected override void Render(ref DrawContext context, Scene.Scene scene)
{ {

View file

@ -1,16 +1,19 @@
using System.Reflection; #region usings
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endregion
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("SM2D")] [assembly: AssemblyTitle("SMRenderer for 2D-projects")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("Scene and Render system for 2D-projects")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")] [assembly: AssemblyCompany("iedSoftworks")]
[assembly: AssemblyProduct("SM2D")] [assembly: AssemblyProduct("SM2D")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2020")] [assembly: AssemblyCopyright("Copyright © iedSoftworks 2020")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]

View file

@ -31,25 +31,21 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="OpenTK, Version=3.2.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL"> <Reference Include="OpenTK, Version=3.2.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\..\packages\OpenTK.3.2\lib\net20\OpenTK.dll</HintPath> <HintPath>..\..\packages\OpenTK.3.2.1\lib\net20\OpenTK.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Controls\Mouse2D.cs" /> <Compile Include="Controls\Mouse2D.cs" />
<Compile Include="Drawing\DrawBackground.cs" /> <Compile Include="Drawing\DrawBackground.cs" />
<Compile Include="Drawing\DrawBackgroundShader.cs" />
<Compile Include="Drawing\DrawColor.cs" /> <Compile Include="Drawing\DrawColor.cs" />
<Compile Include="Drawing\DrawComplex.cs" /> <Compile Include="Drawing\DrawComplex.cs" />
<Compile Include="Drawing\DrawPolygon.cs" /> <Compile Include="Drawing\DrawPolygon.cs" />
<Compile Include="Drawing\DrawShader.cs" />
<Compile Include="Drawing\DrawText.cs" /> <Compile Include="Drawing\DrawText.cs" />
<Compile Include="Drawing\DrawTexture.cs" /> <Compile Include="Drawing\DrawTexture.cs" />
<Compile Include="GLWindow2D.cs" /> <Compile Include="GLWindow2D.cs" />
@ -76,11 +72,12 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
<EmbeddedResource Include="Shader\ShaderFiles\default.frag" /> <EmbeddedResource Include="Shader\ShaderFiles\default.frag" />
<EmbeddedResource Include="Shader\ShaderFiles\default.vert" /> <EmbeddedResource Include="Shader\ShaderFiles\default.vert" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup>
<None Include="OpenTK.dll.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View file

@ -1,23 +1,27 @@
using OpenTK; #region usings
using OpenTK;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Base.Types; using SM.Base.Types;
#endregion
namespace SM2D.Scene namespace SM2D.Scene
{ {
public class Camera : GenericCamera public class Camera : GenericCamera
{ {
public override bool Orthographic { get; } = true;
public CVector2 Position = new CVector2(0); public CVector2 Position = new CVector2(0);
public override bool Orthographic { get; } = true;
protected override Matrix4 ViewCalculation() protected override Matrix4 ViewCalculation()
{ {
return Matrix4.LookAt(Position.X, Position.Y, 2, Position.X, Position.Y, 0, 0, 1, 0); return Matrix4.LookAt(Position.X, Position.Y, 2, Position.X, Position.Y, 0, 0, 1, 0);
} }
public override void RecalculateWorld(OpenTK.Vector2 world, float aspect) 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); OrthographicWorld =
Matrix4.CreateOrthographicOffCenter(-world.X / 2, world.X / 2, world.Y / 2, -world.Y / 2, 0.1f, 4f);
} }
} }
} }

View file

@ -1,10 +1,13 @@
using SM.Base.Scene; #region usings
using SM.Base.Scene;
#endregion
namespace SM2D.Scene namespace SM2D.Scene
{ {
public interface I2DShowItem : IShowItem public interface I2DShowItem : IShowItem
{ {
int ZIndex { get; set; } int ZIndex { get; set; }
} }
} }

View file

@ -1,8 +1,12 @@
using SM.Base.Contexts; #region usings
using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Base.Types; using SM.Base.Types;
using SM2D.Types; using SM2D.Types;
#endregion
namespace SM2D.Scene namespace SM2D.Scene
{ {
public class ItemCollection : GenericItemCollection<I2DShowItem, Transformation>, I2DShowItem public class ItemCollection : GenericItemCollection<I2DShowItem, Transformation>, I2DShowItem

View file

@ -1,17 +1,20 @@
using OpenTK.Graphics; #region usings
using SM.Base.Contexts;
using OpenTK.Graphics;
using SM.Base.Scene; using SM.Base.Scene;
using SM2D.Drawing; using SM2D.Drawing;
#endregion
namespace SM2D.Scene namespace SM2D.Scene
{ {
public class Scene : GenericScene<Camera, ItemCollection, I2DShowItem> public class Scene : GenericScene<Camera, ItemCollection, I2DShowItem>
{ {
public DrawBackground Background => (DrawBackground)_Background;
public Scene() public Scene()
{ {
_Background = new DrawBackground(Color4.Black); _Background = new DrawBackground(Color4.Black);
} }
public DrawBackground Background => (DrawBackground) _Background;
} }
} }

View file

@ -1,14 +1,18 @@
using OpenTK.Graphics.OpenGL4; #region usings
using OpenTK.Graphics.OpenGL4;
using SM.Base.Contexts; using SM.Base.Contexts;
using SM.Base.Scene; using SM.Base.Scene;
using SM.OGL.Shaders; using SM.OGL.Shaders;
using SM.Utility; using SM.Utility;
#endregion
namespace SM2D.Shader namespace SM2D.Shader
{ {
public class Default2DShader : GenericShader, IShader public class Default2DShader : MaterialShader
{ {
public static Default2DShader Shader = new Default2DShader(); public static Default2DShader MaterialShader = new Default2DShader();
//protected override bool AutoCompile { get; } = true; //protected override bool AutoCompile { get; } = true;
@ -18,32 +22,31 @@ namespace SM2D.Shader
{ {
Load(); Load();
} }
public void Draw(DrawContext context)
protected override void DrawProcess(DrawContext context)
{ {
GL.UseProgram(this);
GL.BindVertexArray(context.Mesh);
// Vertex Uniforms // Vertex Uniforms
Uniforms["MVP"].SetMatrix4(context.ModelMaster * context.View * context.World); Uniforms["MVP"].SetMatrix4(context.ModelMaster * context.View * context.World);
Uniforms["HasVColor"].SetUniform1(context.Mesh.AttribDataIndex.ContainsKey(3) && context.Mesh.AttribDataIndex[3] != null); Uniforms["HasVColor"]
.SetUniform1(context.Mesh.AttribDataIndex.ContainsKey(3) && context.Mesh.AttribDataIndex[3] != null);
for (int i = 0; i < context.Instances.Length; i++) Uniforms.GetArray("Instances").Set((i, uniforms) =>
{ {
GL.UniformMatrix4(Uniforms["ModelMatrix"] + i, false, ref context.Instances[i].ModelMatrix); if (i >= context.Instances.Length) return false;
GL.Uniform2(Uniforms["TextureOffset"] + i, context.Instances[i].TexturePosition);
GL.Uniform2(Uniforms["TextureScale"] + i, context.Instances[i].TextureScale); var instance = context.Instances[i];
} uniforms["ModelMatrix"].SetMatrix4(instance.ModelMatrix);
uniforms["TextureOffset"].SetUniform2(instance.TexturePosition);
uniforms["TextureScale"].SetUniform2(instance.TextureScale);
return true;
});
// Fragment Uniforms // Fragment Uniforms
Uniforms["Tint"].SetUniform4(context.Material.Tint); Uniforms["Tint"].SetUniform4(context.Material.Tint);
Uniforms["Texture"].SetTexture(context.Material.Texture, Uniforms["UseTexture"]); Uniforms["Texture"].SetTexture(context.Material.Texture, Uniforms["UseTexture"]);
DrawObject(context.Mesh, context.Instances.Length); DrawObject(context.Mesh, context.Instances.Length);
CleanUp();
GL.UseProgram(0);
} }
} }
} }

View file

@ -1,23 +1,12 @@
#version 330 #version 330
#define maxInstances 32
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTex;
layout(location = 3) in vec4 aColor;
uniform mat4 MVP; //# import SM_base_vertex_basic
uniform bool HasVColor; void ApplyTexModifier();
uniform mat4 ModelMatrix[maxInstances]; void CheckVertexColor();
uniform vec2 TextureOffset[maxInstances]; void ApplyModelTransformation();
uniform vec2 TextureScale[maxInstances];
out vec2 vTexture;
out vec4 vColor;
void main() { void main() {
vTexture = aTex * TextureScale[gl_InstanceID] + TextureOffset[gl_InstanceID]; ApplyTexModifier();
CheckVertexColor();
if (HasVColor) vColor = aColor; ApplyModelTransformation();
else vColor = vec4(1);
gl_Position = MVP * ModelMatrix[gl_InstanceID] * vec4(aPos, 1);
} }

View file

@ -1,52 +1,39 @@
using System; #region usings
using System.Configuration.Assemblies;
using OpenTK; using OpenTK;
using SM.Base.Scene; using SM.Base.Scene;
using SM.Base.Types; using SM.Base.Types;
using SM.Utility; using SM.Utility;
#endregion
namespace SM2D.Types namespace SM2D.Types
{ {
public class Transformation : GenericTransformation public class Transformation : GenericTransformation
{ {
private float _eulerRotation = 0; public CVector2 Position { get; set; } = new CVector2(0);
private CVector2 _position = new CVector2(0);
private CVector2 _scale = new CVector2(50);
public CVector2 Position public CVector2 Size { get; set; } = new CVector2(50);
{
get => _position;
set => _position = value;
}
public CVector2 Size public float Rotation { get; set; }
{
get => _scale;
set => _scale = value;
}
public float Rotation
{
get => _eulerRotation;
set => _eulerRotation = value;
}
protected override Matrix4 RequestMatrix() protected override Matrix4 RequestMatrix()
{ {
return Matrix4.CreateScale(_scale.X, _scale.Y, 1) * return Matrix4.CreateScale(Size.X, Size.Y, 1) *
Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(_eulerRotation)) * Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(Rotation)) *
Matrix4.CreateTranslation(_position.X, _position.Y, 0); Matrix4.CreateTranslation(Position.X, Position.Y, 0);
} }
public void TurnTo(Vector2 v) public void TurnTo(Vector2 v)
{ {
_eulerRotation = RotationUtility.TurnTowards(Position, v); Rotation = RotationUtility.TurnTowards(Position, v);
} }
public Vector2 LookAtVector() public Vector2 LookAtVector()
{ {
if (_modelMatrix.Determinant < 0.0001) return new Vector2(0); if (_modelMatrix.Determinant < 0.0001) return new Vector2(0);
Vector3 vec = Vector3.TransformNormal(Vector3.UnitX, _modelMatrix); var vec = Vector3.TransformNormal(Vector3.UnitX, _modelMatrix);
vec.Normalize(); vec.Normalize();
return vec.Xy; return vec.Xy;
} }

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="OpenTK" version="3.2" targetFramework="net452" /> <package id="OpenTK" version="3.2.1" targetFramework="net452" />
</packages> </packages>

View file

@ -1,7 +1,10 @@
using System.Reflection; #region usings
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
#endregion
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.

View file

@ -33,12 +33,6 @@
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />

View file

@ -45,16 +45,10 @@ namespace SM_TEST
Vector2 mousepos = window.Mouse.InWorld(); Vector2 mousepos = window.Mouse.InWorld();
//polyogn.Transform.Position.Set(mousepos); //polyogn.Transform.Position.Set(mousepos);
polyogn.Transform.TurnTo(mousepos); polyogn.Transform.TurnTo(mousepos);
Log.Write(LogType.Info, polyogn.Transform.LookAtVector());
} }
private static void WindowOnLoad(object sender, EventArgs e) private static void WindowOnLoad(object sender, EventArgs e)
{ {
Interval timer = new Interval(5);
timer.EndAction += (timer1, context) => Console.WriteLine("Interval...");
timer.Start();
col = new ItemCollection() col = new ItemCollection()
{ {
Transform = { Position = new SM.Base.Types.CVector2(0, 400) }, Transform = { Position = new SM.Base.Types.CVector2(0, 400) },

Some files were not shown because too many files have changed in this diff Show more