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,7 +1,10 @@
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>
@ -16,15 +19,6 @@ namespace SM.Base.Controls
/// </summary> /// </summary>
protected TWindow _window; protected TWindow _window;
/// <summary>
/// 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> /// <summary>
/// The constructor /// The constructor
/// </summary> /// </summary>
@ -34,6 +28,16 @@ namespace SM.Base.Controls
_window = window; _window = window;
} }
/// <summary>
/// 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> /// <summary>
/// The event to update the values. /// The event to update the values.
/// </summary> /// </summary>

View file

@ -1,8 +1,11 @@
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>
@ -14,6 +17,7 @@ namespace SM.Base.Scene
/// 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>
@ -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,13 +49,11 @@ 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>
@ -61,9 +62,9 @@ namespace SM.Base.Scene
/// <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>

View file

@ -1,4 +1,8 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
@ -11,6 +15,7 @@ namespace SM.Base.Scene
/// 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>

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,4 +1,8 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
@ -11,10 +15,12 @@ namespace SM.Base.Scene
/// 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>

View file

@ -1,6 +1,10 @@
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>
@ -8,18 +12,19 @@ namespace SM.Base.Scene
/// </summary> /// </summary>
public class Material public class Material
{ {
/// <summary>
/// A custom shader, that is used to draw this material.
/// </summary>
public MaterialShader CustomShader;
/// <summary> /// <summary>
/// The base texture. (aka. Diffuse Texture) /// The base texture. (aka. Diffuse Texture)
/// </summary> /// </summary>
public TextureBase Texture; public TextureBase Texture;
/// <summary> /// <summary>
/// The tint or color. /// The tint or color.
/// </summary> /// </summary>
public Color4 Tint = Color4.White; public Color4 Tint = Color4.White;
/// <summary>
/// A custom shader, that is used to draw this material.
/// </summary>
public IShader CustomShader;
} }
} }

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,13 +1,16 @@
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>
@ -20,22 +23,27 @@ namespace SM.Base
/// 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>
@ -51,10 +59,12 @@ namespace SM.Base
/// 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>
@ -67,23 +77,23 @@ namespace SM.Base
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>
@ -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)
{ {
@ -172,28 +183,29 @@ 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)
{
Write(type.ToString(), Colors[type], values);
}
/// <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>(string type, ConsoleColor color, params T[] values) public static void Write<T>(string type, ConsoleColor color, params T[] values)
{ {
for (var i = 0; i < values.Length; i++) for (var i = 0; i < values.Length; i++) Write(type, color, values[i], DefaultTarget);
{
Write(type, color, values[i], DefaultTarget);
}
} }
/// <summary> /// <summary>
/// Writes one line to the log. /// Writes one line to the log.
/// </summary> /// </summary>
public static void Write<T>(LogType type, T value, LogTarget target = LogTarget.Default) => public static void Write<T>(LogType type, T value, LogTarget target = LogTarget.Default)
Write<T>(type.ToString(), Colors[type], value, target); {
Write(type.ToString(), Colors[type], value, target);
}
/// <summary> /// <summary>
/// Writes one line to the log. /// 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)
{ {
@ -215,17 +227,17 @@ namespace SM.Base
/// <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,15 +1,14 @@
using SM.OGL.Mesh; #region usings
using SM.OGL.Mesh;
#endregion
namespace SM.Base.Objects namespace SM.Base.Objects
{ {
/// <inheritdoc /> /// <inheritdoc />
public class Mesh : GenericMesh public class Mesh : GenericMesh
{ {
/// <summary>
/// Contains vertex colors
/// </summary>
public virtual VBO Color { get; }
/// <summary> /// <summary>
/// While initializing, it will add the <see cref="Color" /> to the data index. /// While initializing, it will add the <see cref="Color" /> to the data index.
/// </summary> /// </summary>
@ -17,5 +16,10 @@ namespace SM.Base.Objects
{ {
AttribDataIndex.Add(3, Color); AttribDataIndex.Add(3, Color);
} }
/// <summary>
/// Contains vertex colors
/// </summary>
public virtual VBO Color { get; }
} }
} }

View file

@ -1,8 +1,11 @@
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>
@ -15,13 +18,19 @@ namespace SM.Base.Objects.Static
/// </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,8 +1,14 @@
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>
@ -10,6 +16,11 @@ namespace SM.Base
/// </summary> /// </summary>
public class SMRenderer public class SMRenderer
{ {
/// <summary>
/// Defines, how many instances the 'SM_base_vertex_basic'-extension can handle.
/// </summary>
public const int MaxInstances = 32;
/// <summary> /// <summary>
/// The default mesh. /// The default mesh.
/// </summary> /// </summary>
@ -25,9 +36,19 @@ namespace SM.Base
/// </summary> /// </summary>
public static Deltatime DefaultDeltatime = new Deltatime(); public static Deltatime DefaultDeltatime = new Deltatime();
public static MaterialShader DefaultMaterialShader;
/// <summary>
/// Shows more information onto the log system.
/// </summary>
public static bool AdvancedDebugging = false;
/// <summary> /// <summary>
/// Current Frame /// 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,4 +1,8 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Scene namespace SM.Base.Scene
{ {
@ -11,10 +15,12 @@ namespace SM.Base.Scene
/// 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>
@ -32,6 +38,11 @@ namespace SM.Base.Scene
/// </summary> /// </summary>
public Matrix4 World => Orthographic ? OrthographicWorld : PerspectiveWorld; public Matrix4 World => Orthographic ? OrthographicWorld : PerspectiveWorld;
/// <summary>
/// Represents if the camera is orthographic.
/// </summary>
public abstract bool Orthographic { get; }
/// <summary> /// <summary>
/// Calculates the view matrix. /// Calculates the view matrix.
/// </summary> /// </summary>
@ -45,13 +56,12 @@ 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>
/// Represents if the camera is orthographic.
/// </summary>
public abstract bool Orthographic { get; }
/// <summary> /// <summary>
/// This will calculate the world. /// This will calculate the world.
/// <para>This is called on <see cref="GenericWindow{TScene,TCamera}.ViewportCamera" /> to calculate the world.</para> /// <para>This is called on <see cref="GenericWindow{TScene,TCamera}.ViewportCamera" /> to calculate the world.</para>

View file

@ -1,6 +1,10 @@
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>
@ -22,6 +26,30 @@ 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>
@ -43,30 +71,6 @@ 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>
@ -76,14 +80,12 @@ namespace SM.Base.Scene
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;
} }
@ -105,10 +107,10 @@ namespace SM.Base.Scene
/// </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);
} }

View file

@ -1,8 +1,11 @@
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>
@ -24,6 +27,7 @@ namespace SM.Base.Scene
_background = value; _background = value;
} }
} }
public bool IsInitialized { get; private set; }
/// <summary> /// <summary>
/// Updates this scene. /// Updates this scene.
@ -31,7 +35,6 @@ namespace SM.Base.Scene
/// <param name="context"></param> /// <param name="context"></param>
public virtual void Update(UpdateContext context) public virtual void Update(UpdateContext context)
{ {
} }
/// <summary> /// <summary>
@ -39,7 +42,6 @@ namespace SM.Base.Scene
/// </summary> /// </summary>
public virtual void Draw(DrawContext context) public virtual void Draw(DrawContext context)
{ {
} }
/// <summary> /// <summary>
@ -47,14 +49,27 @@ namespace SM.Base.Scene
/// </summary> /// </summary>
internal void Activate() internal void Activate()
{ {
if (!IsInitialized)
{
OnInitialization();
IsInitialized = true;
}
OnActivating(); OnActivating();
} }
/// <summary>
/// Called, when the user activates the scene for the first time.
/// </summary>
protected virtual void OnInitialization()
{ }
/// <summary> /// <summary>
/// Called, when the user activates the scene. /// Called, when the user activates the scene.
/// </summary> /// </summary>
protected virtual void OnActivating() protected virtual void OnActivating()
{ } {
}
} }
/// <summary> /// <summary>
@ -68,18 +83,25 @@ 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>
/// A collection for cameras to switch easier to different cameras.
/// </summary>
public Dictionary<string, TCamera> Cameras = new Dictionary<string, TCamera>();
/// <summary> /// <summary>
/// The active camera, that is used if the context doesn't force the viewport camera. /// 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> /// <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>
@ -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

@ -5,6 +5,5 @@
/// </summary> /// </summary>
public interface IBackgroundItem : IShowItem public interface IBackgroundItem : IShowItem
{ {
} }
} }

View file

@ -1,6 +1,10 @@
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>

View file

@ -1,6 +1,10 @@
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>
@ -28,6 +32,7 @@ namespace SM.Base.Scene
/// </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>
@ -38,6 +43,7 @@ namespace SM.Base.Scene
/// 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>

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,4 +1,8 @@
using System; #region usings
using System;
#endregion
namespace SM.Base.Text namespace SM.Base.Text
{ {
@ -12,6 +16,7 @@ namespace SM.Base.Text
/// 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>
@ -21,6 +26,7 @@ namespace SM.Base.Text
/// 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>

View file

@ -1,13 +1,13 @@
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
{ {
@ -16,29 +16,28 @@ namespace SM.Base.Text
/// </summary> /// </summary>
public class Font : Texture public class Font : Texture
{ {
/// <inheritdoc /> /// <summary>
public override TextureWrapMode WrapMode { get; set; } = TextureWrapMode.ClampToEdge; /// The char set for the font.
/// <para>Default: <see cref="FontCharStorage.SimpleUTF8" /></para>
/// </summary>
public ICollection<char> CharSet = FontCharStorage.SimpleUTF8;
/// <summary> /// <summary>
/// The font family, that is used to find the right font. /// The font family, that is used to find the right font.
/// </summary> /// </summary>
public FontFamily FontFamily; public FontFamily FontFamily;
/// <summary>
/// The font style.
/// <para>Default: <see cref="System.Drawing.FontStyle.Regular"/></para>
/// </summary>
public FontStyle FontStyle = FontStyle.Regular;
/// <summary> /// <summary>
/// The font size. /// The font size.
/// <para>Default: 12</para> /// <para>Default: 12</para>
/// </summary> /// </summary>
public float FontSize = 12; public float FontSize = 12;
/// <summary> /// <summary>
/// The char set for the font. /// The font style.
/// <para>Default: <see cref="FontCharStorage.SimpleUTF8"/></para> /// <para>Default: <see cref="System.Drawing.FontStyle.Regular" /></para>
/// </summary> /// </summary>
public ICollection<char> CharSet = FontCharStorage.SimpleUTF8; public FontStyle FontStyle = FontStyle.Regular;
/// <summary> /// <summary>
/// This contains all information for the different font character. /// This contains all information for the different font character.
@ -51,7 +50,7 @@ namespace SM.Base.Text
/// <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];
} }
@ -64,6 +63,10 @@ namespace SM.Base.Text
{ {
FontFamily = font; FontFamily = font;
} }
/// <inheritdoc />
public override TextureWrapMode WrapMode { get; set; } = TextureWrapMode.ClampToEdge;
/// <summary> /// <summary>
/// Regenerates the texture. /// Regenerates the texture.
/// </summary> /// </summary>
@ -74,18 +77,18 @@ 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});
@ -101,15 +104,15 @@ namespace SM.Base.Text
} }
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,

View file

@ -8,21 +8,22 @@
/// <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,9 +1,12 @@
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
{ {
@ -18,11 +21,27 @@ namespace SM.Base.Text
/// 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>
/// 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> /// <summary>
/// The font. /// The font.
/// </summary> /// </summary>
@ -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)
@ -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,7 +114,7 @@ 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
{ {

View file

@ -1,9 +1,13 @@
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>
@ -11,26 +15,32 @@ namespace SM.Base.Textures
/// </summary> /// </summary>
public class Texture : TextureBase public class Texture : TextureBase
{ {
/// <summary>
/// The texture as bitmap.
/// </summary>
public Bitmap Map;
/// <summary> /// <summary>
/// Decides if the bitmap will automatically dispose itself. /// Decides if the bitmap will automatically dispose itself.
/// </summary> /// </summary>
public bool AutoDispose = false; public bool AutoDispose = false;
/// <summary>
/// The texture as bitmap.
/// </summary>
public Bitmap Map;
/// <summary> /// <summary>
/// Empty constructor /// Empty constructor
/// </summary> /// </summary>
protected Texture() {} protected Texture()
{
}
/// <summary> /// <summary>
/// Creates a texture with only the map. /// Creates a texture with only the map.
/// <para>Sets the filter to Linear and WrapMode to Repeat.</para> /// <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>
@ -69,15 +79,16 @@ namespace SM.Base.Textures
/// <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,
@ -103,6 +114,9 @@ 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,6 +1,10 @@
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>
@ -24,7 +28,8 @@ 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();
} }

View file

@ -1,6 +1,10 @@
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>
@ -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,7 +1,10 @@
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>
@ -9,21 +12,6 @@ namespace SM.Base.Time
/// </summary> /// </summary>
public class Timer : Stopwatch public class Timer : Stopwatch
{ {
/// <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;
/// <summary> /// <summary>
/// Creates a timer with specified seconds. /// Creates a timer with specified seconds.
/// </summary> /// </summary>
@ -42,6 +30,21 @@ namespace SM.Base.Time
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()
{ {
@ -65,6 +68,7 @@ namespace SM.Base.Time
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>

View file

@ -1,8 +1,10 @@
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>
@ -10,70 +12,65 @@ namespace SM.Base.Types
/// </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>
/// The X-component.
/// </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> /// <summary>
/// Creates a vector by setting every component to the same value. /// 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;
} }
/// <summary>
/// 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 #region Set
/// <summary> /// <summary>
/// Sets the X and Y-component. /// Sets the X and Y-component.
/// </summary> /// </summary>
@ -82,10 +79,11 @@ namespace SM.Base.Types
_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);
} }
@ -103,7 +101,7 @@ namespace SM.Base.Types
/// 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);
} }
@ -120,10 +118,11 @@ namespace SM.Base.Types
/// <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
@ -131,7 +130,7 @@ namespace SM.Base.Types
/// <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;
@ -140,7 +139,7 @@ namespace SM.Base.Types
/// <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;
@ -150,7 +149,7 @@ 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,10 +1,36 @@
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>
@ -13,6 +39,7 @@
get => _X; get => _X;
set => _X = value; set => _X = value;
} }
/// <summary> /// <summary>
/// Y-component /// Y-component
/// </summary> /// </summary>
@ -22,35 +49,30 @@
set => _Y = value; set => _Y = value;
} }
/// <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>
/// Sets the X and Y-component. /// Sets the X and Y-component.
/// </summary> /// </summary>
public new void Set(float x, float y) => base.Set(x, y); public new void Set(float x, float y)
{
base.Set(x, 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>
public new void Set(OpenTK.Vector2 vector) => base.Set(vector); public new void Set(Vector2 vector)
{
base.Set(vector);
}
/// <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>
public new void Add(OpenTK.Vector2 vector) => base.Add(vector); public new void Add(Vector2 vector)
{
base.Add(vector);
}
public static implicit operator CVector2(Vector2 v) => new CVector2(v.X,v.Y);
} }
} }

View file

@ -1,7 +1,9 @@
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>
@ -9,6 +11,21 @@ namespace SM.Base.Types
/// </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>
@ -18,29 +35,28 @@ namespace SM.Base.Types
set => _Z = value; set => _Z = value;
} }
/// <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>
/// Sets the X, Y and Z-component. /// Sets the X, Y and Z-component.
/// </summary> /// </summary>
public new void Set(float x, float y, float z) => base.Set(x, y, z); public new void Set(float x, float y, float z)
{
base.Set(x, y, 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>
public new void Set(Vector3 vector) => base.Set(vector); 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,4 +1,8 @@
using OpenTK; #region usings
using OpenTK;
#endregion
namespace SM.Base.Types namespace SM.Base.Types
{ {
@ -7,15 +11,6 @@ namespace SM.Base.Types
/// </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)
{ {
@ -26,17 +21,37 @@ namespace SM.Base.Types
{ {
} }
/// <summary>
/// W-component
/// </summary>
public float W
{
get => _W;
set => _W = value;
}
/// <summary> /// <summary>
/// Sets the X, Y, Z and W-component. /// Sets the X, Y, Z and W-component.
/// </summary> /// </summary>
public new void Set(float x, float y, float z, float w) => base.Set(x, y, z, w); public new void Set(float x, float y, float z, float w)
{
base.Set(x, y, z, 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>
public new void Set(Vector4 vector) => base.Set(vector); public new void Set(Vector4 vector)
{
base.Set(vector);
}
/// <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>
public new void Add(Vector4 vector) => base.Add(vector); public new void Add(Vector4 vector)
{
base.Add(vector);
}
} }
} }

View file

@ -1,7 +1,11 @@
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>
@ -15,14 +19,20 @@ namespace SM.Utility
/// <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>
@ -31,13 +41,20 @@ namespace SM.Utility
/// <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

@ -5,20 +5,6 @@
/// </summary> /// </summary>
public class Deltatime public class Deltatime
{ {
/// <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>
/// If true, it uses <see cref="RenderDelta"/>, otherwise <see cref="UpdateDelta"/>.
/// <para>Default: false</para>
/// </summary>
public bool UseRender;
/// <summary> /// <summary>
/// Scaling of the delta time. /// Scaling of the delta time.
/// <para>Default: 1</para> /// <para>Default: 1</para>
@ -26,21 +12,38 @@
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">
/// If true, it uses <see cref="RenderDelta" />, otherwise <see cref="UpdateDelta" />. Default:
/// false
/// </param>
public Deltatime(float scale = 1, bool useRender = false) 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,4 +1,8 @@
using System; #region usings
using System;
#endregion
namespace SM.Utility namespace SM.Utility
{ {
@ -16,38 +20,65 @@ namespace SM.Utility
/// 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()
{
return Randomizer.Next();
}
/// <summary> /// <summary>
/// Generates a integer with a maximum. /// Generates a integer with a maximum.
/// </summary> /// </summary>
public static int GetInt(int max) { return Randomizer.Next(max); } public static int GetInt(int max)
{
return Randomizer.Next(max);
}
/// <summary> /// <summary>
/// Generates a integer with a minimum and maximum /// Generates a integer with a minimum and maximum
/// </summary> /// </summary>
public static int GetInt(int min, int max) { return Randomizer.Next(min, max); } public static int GetInt(int min, int max)
{
return Randomizer.Next(min, max);
}
/// <summary> /// <summary>
/// Generates a float between 0 and 1. /// Generates a float between 0 and 1.
/// </summary> /// </summary>
public static float GetFloat() { return (float)Randomizer.NextDouble(); } public static float GetFloat()
{
return (float) Randomizer.NextDouble();
}
/// <summary> /// <summary>
/// Generates a float between 0 and the specified maximum. /// Generates a float between 0 and the specified maximum.
/// </summary> /// </summary>
public static float GetFloat(float max) { return (float)Randomizer.NextDouble() * max; } public static float GetFloat(float max)
{
return (float) Randomizer.NextDouble() * max;
}
/// <summary> /// <summary>
/// Generates a float between the specified minimum and the specified maximum. /// Generates a float between the specified minimum and the specified maximum.
/// </summary> /// </summary>
public static float GetFloat(float min, float max) { return (float)Randomizer.NextDouble() * max + min; } public static float GetFloat(float min, float max)
{
return (float) Randomizer.NextDouble() * max + min;
}
} }
} }

View file

@ -1,6 +1,10 @@
using System; #region usings
using System;
using OpenTK; using OpenTK;
#endregion
namespace SM.Utility namespace SM.Utility
{ {
/// <summary> /// <summary>

View file

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

View file

@ -1,8 +1,11 @@
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>
@ -19,14 +22,17 @@ namespace SM.Base.Contexts
/// 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>
@ -37,6 +43,7 @@ namespace SM.Base.Contexts
/// The mesh. /// The mesh.
/// </summary> /// </summary>
public GenericMesh Mesh; public GenericMesh Mesh;
/// <summary> /// <summary>
/// The material. /// The material.
/// </summary> /// </summary>
@ -54,8 +61,11 @@ namespace SM.Base.Contexts
/// <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,5 +1,8 @@
using OpenTK.Input; #region usings
using SM.Utility;
using OpenTK.Input;
#endregion
namespace SM.Base.Contexts namespace SM.Base.Contexts
{ {

View file

@ -1,17 +1,24 @@
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>
@ -19,35 +26,61 @@ namespace SM.Base
/// </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;
@ -75,21 +108,24 @@ namespace SM.Base
/// </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()
@ -126,6 +162,31 @@ namespace SM.Base
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>
@ -137,10 +198,17 @@ namespace SM.Base
where TScene : GenericScene, new() where TScene : GenericScene, new()
where TCamera : GenericCamera, new() where TCamera : GenericCamera, new()
{ {
/// <inheritdoc />
protected GenericWindow()
{
ViewportCamera = new TCamera();
}
/// <summary> /// <summary>
/// The viewport camera. /// The viewport camera.
/// </summary> /// </summary>
public TCamera ViewportCamera { get; } public TCamera ViewportCamera { get; }
/// <summary> /// <summary>
/// This forces the render to use the viewport camera. /// This forces the render to use the viewport camera.
/// </summary> /// </summary>
@ -156,12 +224,6 @@ namespace SM.Base
/// </summary> /// </summary>
public RenderPipeline<TScene> RenderPipeline { get; private set; } public RenderPipeline<TScene> RenderPipeline { get; private set; }
/// <inheritdoc />
protected GenericWindow()
{
ViewportCamera = new TCamera();
}
/// <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,6 +270,10 @@ 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>

View file

@ -1,8 +1,13 @@
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>
@ -10,7 +15,6 @@ namespace SM.Base
/// </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>
@ -19,22 +23,32 @@ namespace SM.Base
/// <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.
@ -48,10 +62,6 @@ namespace SM.Base
/// </summary> /// </summary>
protected internal virtual void Unload() protected internal virtual void Unload()
{ {
foreach (Framebuffer framebuffer in _framebuffers)
{
framebuffer.Dispose();
}
} }
} }
@ -62,7 +72,6 @@ namespace SM.Base
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>

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,9 +67,10 @@ 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);
@ -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,10 +1,11 @@
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
{ {
@ -16,17 +17,13 @@ namespace SM.OGL
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>
@ -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>
/// Default action for 'DebugAction'.
/// </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> /// <summary>
/// Checks for OpenGL errors. /// 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,6 +1,10 @@
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>
@ -12,6 +16,7 @@ namespace SM.OGL
/// 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>
@ -49,16 +54,16 @@ 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.
@ -84,6 +89,9 @@ namespace SM.OGL
/// 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,29 +1,29 @@
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>
@ -35,6 +35,7 @@ namespace SM.OGL
/// </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>

View file

@ -1,7 +1,10 @@
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>
@ -9,28 +12,22 @@ namespace SM.OGL.Mesh
/// </summary> /// </summary>
public class BoundingBox public class BoundingBox
{ {
/// <summary>
/// The minimum corner.
/// </summary>
public Vector3 Min = Vector3.Zero;
/// <summary> /// <summary>
/// The maximum corner. /// 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
@ -43,13 +40,23 @@ namespace SM.OGL.Mesh
Max = max; Max = max;
} }
/// <summary>
/// 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> /// <summary>
/// Updates the bounding box. /// 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]);
@ -62,7 +69,7 @@ namespace SM.OGL.Mesh
/// <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,7 +1,10 @@
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
{ {
@ -10,6 +13,19 @@ namespace SM.OGL.Mesh
/// </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;
@ -26,10 +42,12 @@ namespace SM.OGL.Mesh
/// 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>
@ -50,19 +68,6 @@ namespace SM.OGL.Mesh
/// </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,10 +1,12 @@
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>
@ -16,36 +18,61 @@ namespace SM.OGL.Mesh
/// 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>
/// Specifies the data type of each component in the array.
/// </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> /// <summary>
/// Normalise floats? /// 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>
/// Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4.
/// </summary>
public int PointerSize;
/// <summary>
/// Specifies the byte offset between consecutive generic vertex attributes.
/// </summary>
public int PointerStride;
/// <summary>
/// Specifies the data type of each component in the array.
/// </summary>
public VertexAttribPointerType PointerType;
/// <summary> /// <summary>
/// Generates a VBO for inserting mesh data. /// Generates a VBO for inserting mesh data.
/// </summary> /// </summary>
/// <param name="bufferUsageHint">Specifies the expected usage pattern of the data store. <para>Default: StaticDraw</para></param> /// <param name="bufferUsageHint">
/// <param name="pointerType">Specifies the data type of each component in the array. <para>Default: Float</para></param> /// Specifies the expected usage pattern of the data store.
/// <param name="pointerSize">Specifies the number of components per generic vertex attribute. Must be 1, 2, 3, 4. <para>Default: 3</para></param> /// <para>Default: StaticDraw</para>
/// <param name="pointerStride">Specifies the byte offset between consecutive generic vertex attributes. <para>Default: 0</para></param> /// </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="pointerType">
/// <param name="normalised">Normalise floats? <para>Default: false</para></param> /// 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)
@ -61,44 +88,83 @@ 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)
{
AddRange(new[] {x, y});
}
/// <summary> /// <summary>
/// Adds three values to the VBO. /// Adds three values to the VBO.
/// </summary> /// </summary>
public void Add(float x, float y, float z) => AddRange(new[] {x,y,z}); public void Add(float x, float y, float z)
{
AddRange(new[] {x, y, z});
}
/// <summary> /// <summary>
/// Adds four values to the VBO. /// Adds four values to the VBO.
/// </summary> /// </summary>
public void Add(float x, float y, float z, float w) => AddRange(new[] {x,y,z,w}); public void Add(float x, float y, float z, float w)
{
AddRange(new[] {x, y, z, w});
}
/// <summary> /// <summary>
/// Adds a Vector2. /// Adds a Vector2.
/// </summary> /// </summary>
public void Add(Vector2 vector) => Add(vector.X, vector.Y); public void Add(Vector2 vector)
{
Add(vector.X, vector.Y);
}
/// <summary> /// <summary>
/// Adds a Vector2 and a value. /// Adds a Vector2 and a value.
/// </summary> /// </summary>
public void Add(Vector2 vector, float z) => Add(vector.X, vector.Y, z); public void Add(Vector2 vector, float z)
{
Add(vector.X, vector.Y, z);
}
/// <summary> /// <summary>
/// Adds a Vector2 and two values. /// Adds a Vector2 and two values.
/// </summary> /// </summary>
public void Add(Vector2 vector, float z, float w) => Add(vector.X, vector.Y, z, w); public void Add(Vector2 vector, float z, float w)
{
Add(vector.X, vector.Y, z, w);
}
/// <summary> /// <summary>
/// Adds a Vector3. /// Adds a Vector3.
/// </summary> /// </summary>
public void Add(Vector3 vector) => Add(vector.X, vector.Y, vector.Z); public void Add(Vector3 vector)
{
Add(vector.X, vector.Y, vector.Z);
}
/// <summary> /// <summary>
/// Adds a Vector3 and a value. /// Adds a Vector3 and a value.
/// </summary> /// </summary>
public void Add(Vector3 vector, float w) => Add(vector.X, vector.Y, vector.Z, w); public void Add(Vector3 vector, float w)
{
Add(vector.X, vector.Y, vector.Z, w);
}
/// <summary> /// <summary>
/// Adds a vector4. /// Adds a vector4.
/// </summary> /// </summary>
/// <param name="vector"></param> /// <param name="vector"></param>
public void Add(Vector4 vector) => Add(vector.X, vector.Y, vector.Z, vector.W); public void Add(Vector4 vector)
{
Add(vector.X, vector.Y, vector.Z, vector.W);
}
/// <summary> /// <summary>
/// Adds a color. /// Adds a color.
/// </summary> /// </summary>
public void Add(Color4 color) => Add(color.R, color.G, color.B, color.A); public void Add(Color4 color)
{
Add(color.R, color.G, color.B, color.A);
}
/// <summary> /// <summary>
/// Binds the buffer to the active VAO. /// Binds the buffer to the active VAO.
@ -106,9 +172,9 @@ namespace SM.OGL.Mesh
/// <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,5 +1,9 @@
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
{ {
@ -8,18 +12,19 @@ namespace SM.OGL.Shaders
/// </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 />
@ -70,15 +66,14 @@ namespace SM.OGL.Shaders
/// <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>

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,7 +1,11 @@
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>
@ -11,17 +15,20 @@ namespace SM.OGL.Shaders
{ {
private string _data; private string _data;
/// <inheritdoc /> /// <summary>
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Shader; /// Contains other shader files to allow access to their functions.
/// </summary>
public List<ShaderFile> GLSLExtensions = new List<ShaderFile>();
/// <summary>
/// Gets/Sets the name for this shader file.
/// </summary>
public new string Name;
/// <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 overrides, that can be used to import values from the CPU to the shader before it is been send to the GPU.
/// </summary> /// </summary>
public Dictionary<string, string> StringOverrides = new Dictionary<string, string>(); public Dictionary<string, string> StringOverrides = new Dictionary<string, string>();
/// <summary>
/// Contains other shader files to allow access to their functions.
/// </summary>
public List<ShaderFile> GLSLExtensions = new List<ShaderFile>();
/// <summary> /// <summary>
/// Creates a file. /// Creates a file.
@ -32,10 +39,27 @@ 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;
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); _data = _data.Replace("//!" + kvp.Key, kvp.Value);
} }
@ -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,7 +1,9 @@
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>
@ -13,10 +15,12 @@ namespace SM.OGL.Shaders
/// 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>
@ -27,7 +31,10 @@ namespace SM.OGL.Shaders
/// </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.
@ -59,9 +66,11 @@ namespace SM.OGL.Shaders
/// <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,24 +1,32 @@
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> /// <summary>
/// This contains the Parent collection of this uniform. /// This contains the Parent collection of this uniform.
/// </summary> /// </summary>
internal UniformCollection Parent; public UniformCollection Parent { get; }
public Uniform(int location) : this(location, null)
{
}
/// <summary> /// <summary>
/// This create a new uniform manager /// This create a new uniform manager
@ -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,13 +392,31 @@ 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
@ -187,11 +442,15 @@ namespace SM.OGL.Shaders
checkUniform.SetUniform1(texture != null); checkUniform.SetUniform1(texture != null);
if (texture != null) SetTexture(texture); if (texture != null) SetTexture(texture);
} }
/// <summary> /// <summary>
/// Sets the texture to the next possible position. /// Sets the texture to the next possible position.
/// </summary> /// </summary>
/// <param name="texture"></param> /// <param name="texture"></param>
public void SetTexture(TextureBase texture) => SetTexture(texture, Parent.NextTexture++); public void SetTexture(TextureBase texture)
{
if (Parent != null) SetTexture(texture, Parent.NextTexture++);
}
/// <summary> /// <summary>
/// Sets the texture to the specified position. /// Sets the texture to the specified position.
@ -209,6 +468,9 @@ namespace SM.OGL.Shaders
/// 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 base[key]; return (Uniform) base[key];
} }
catch (KeyNotFoundException) catch (KeyNotFoundException)
{ {
Console.WriteLine("[Error] Uniform '"+key+"' was not found. Tried to recreate it."); GLCustomActions.AtWarning?.Invoke("Uniform '" + KeyString + key + "' was not found. Tried to recreate it.");
Uniform u = new Uniform(GL.GetUniformLocation(_parentShader, key), this); var u = new Uniform(GL.GetUniformLocation(ParentShader, KeyString + key), this);
Add(key, u); Add(key, u);
return u; return u;
} }
} }
public UniformArray GetArray(string key)
{
try
{
return (UniformArray) base[key];
} }
/// <summary> catch (KeyNotFoundException)
/// Adds a uniform with a location. {
/// </summary> throw new Exception("UniformArray '"+key+"' wasn't found");
/// <param name="key"></param> }
/// <param name="location"></param> }
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,4 +1,8 @@
using OpenTK.Graphics.OpenGL4; #region usings
using OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Texture namespace SM.OGL.Texture
{ {
@ -29,6 +33,7 @@ namespace SM.OGL.Texture
/// 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>

View file

@ -9,6 +9,7 @@
/// The major version. /// The major version.
/// </summary> /// </summary>
public int MajorVersion; public int MajorVersion;
/// <summary> /// <summary>
/// The minor version. /// The minor version.
/// </summary> /// </summary>
@ -31,7 +32,7 @@
/// <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]);
} }

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,17 +18,6 @@ namespace SM2D.Drawing
{ {
private Material _material = new Material(); private Material _material = new Material();
public Color4 Color
{
get => _material.Tint;
set => _material.Tint = value;
}
public TextureBase Texture
{
get => _material.Texture;
set => _material.Texture = value;
}
public DrawBackground(Color4 color) public DrawBackground(Color4 color)
{ {
Color = color; Color = color;
@ -44,12 +34,25 @@ namespace SM2D.Drawing
Texture = (Texture) texture; Texture = (Texture) texture;
} }
public Color4 Color
{
get => _material.Tint;
set => _material.Tint = value;
}
public TextureBase Texture
{
get => _material.Texture;
set => _material.Texture = value;
}
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,13 +1,36 @@
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 DrawPolygon(Polygon polygon) : this(polygon, Color4.White)
{
}
public DrawPolygon(Polygon polygon, Bitmap map) : this(polygon, map, Color4.White)
{
}
public DrawPolygon(Polygon polygon, Color4 color) : base(color)
{
_mesh = polygon;
}
public DrawPolygon(Polygon polygon, Bitmap map, Color4 tint) : base(tint)
{
_mesh = polygon;
_material.Texture = new Texture(map);
}
public Polygon Polygon public Polygon Polygon
{ {
get => (Polygon) _mesh; get => (Polygon) _mesh;
@ -19,20 +42,5 @@ namespace SM2D.Drawing
get => (Texture) _material.Texture; get => (Texture) _material.Texture;
set => _material.Texture = value; 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)
{
_mesh = polygon;
}
public DrawPolygon(Polygon polygon, Bitmap map, Color4 tint) : base(tint)
{
_mesh = polygon;
_material.Texture = new Texture(map);
}
} }
} }

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