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,25 +1,30 @@
using System;
#region usings
using OpenTK.Graphics.OpenGL4;
using SM.OGL.Mesh;
#endregion
namespace SM.OGL.Shaders
{
/// <summary>
/// Abstract class, that is used to create graphic shader.
/// Abstract class, that is used to create graphic shader.
/// </summary>
public abstract class GenericShader : GLObject
{
protected override bool AutoCompile { get; } = true;
/// <summary>
/// Contains the different files for the shader.
/// Contains the different files for the shader.
/// </summary>
protected ShaderFileCollection ShaderFileFiles;
/// <summary>
/// Contains and manage the uniforms from the shader.
/// Contains and manage the uniforms from the shader.
/// </summary>
protected UniformCollection Uniforms;
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Program;
protected GenericShader(string vertex, string fragment) : this(new ShaderFileCollection(vertex, fragment)){}
/// <inheritdoc />
protected GenericShader(ShaderFileCollection shaderFileFiles)
@ -27,35 +32,26 @@ namespace SM.OGL.Shaders
ShaderFileFiles = shaderFileFiles;
}
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Program;
/// <summary>
/// Loads the shader to the GPU.
/// Loads the shader to the GPU.
/// </summary>
public void Load()
{
_id = GL.CreateProgram();
ShaderFileFiles.Append(this);
GL.LinkProgram(_id);
this.Name(GetType().Name);
Name(GetType().Name);
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._parentShader = this;
for (int i = 0; i < uniformCount; i++)
{
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);
}
Uniforms.ParentShader = this;
Uniforms.Import(this);
GLDebugging.CheckGLErrors($"A error occured at shader creation for '{GetType()}': %code%");
}
/// <inheritdoc />
@ -65,22 +61,21 @@ namespace SM.OGL.Shaders
}
/// <summary>
/// Draws the mesh.
/// Draws the mesh.
/// </summary>
/// <param name="mesh">The mesh.</param>
/// <param name="amount">The amounts for instancing.</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)
GL.DrawElementsInstanced(mesh.PrimitiveType, 0, DrawElementsType.UnsignedInt, mesh.Indices, amount);
else
else
GL.DrawArraysInstanced(mesh.PrimitiveType, 0, mesh.Vertex.Count, amount);
}
/// <summary>
/// Resets the shader specific settings to ensure proper workings.
/// Resets the shader specific settings to ensure proper workings.
/// </summary>
protected void CleanUp()
{

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,27 +1,35 @@
using OpenTK;
#region usings
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL4;
using SM.OGL.Texture;
#endregion
namespace SM.OGL.Shaders
{
/// <summary>
/// Manages the uniforms.
/// Manages the uniforms.
/// </summary>
public struct Uniform
public struct Uniform : IUniform
{
/// <summary>
/// This contains the location for the uniform.
/// This contains the location for the uniform.
/// </summary>
private int Location;
/// <summary>
/// This contains the Parent collection of this uniform.
/// </summary>
internal UniformCollection Parent;
public int Location { get; internal set; }
/// <summary>
/// This create a new uniform manager
/// This contains the Parent collection of this uniform.
/// </summary>
public UniformCollection Parent { get; }
public Uniform(int location) : this(location, null)
{
}
/// <summary>
/// This create a new uniform manager
/// </summary>
/// <param name="location">Location id</param>
/// <param name="parent">Parent collection</param>
@ -38,114 +46,343 @@ namespace SM.OGL.Shaders
GL.Uniform1(Location, value ? 1 : 0);
}
public void SetUniform1(int value) { 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(int value)
{
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(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(uint value)
{
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(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(float 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(int count, params double[] values) { GL.Uniform1(Location, count, values); }
public void SetUniform1(int count, ref double value) { GL.Uniform1(Location, count, ref value); }
public void SetUniform1(double 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
#region Uniform2
public void SetUniform2(float x, float y) { GL.Uniform2(Location, x, 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); }
public void SetUniform2(int x, int y) { GL.Uniform2(Location, x, y); }
public void SetUniform2(float x, float y)
{
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(double x, double y)
{
GL.Uniform2(Location, x, y);
}
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(uint x, uint y)
{
GL.Uniform2(Location, x, y);
}
public void SetUniform2(Vector2 vector2) { GL.Uniform2(Location, vector2); }
public void SetUniform2(ref Vector2 vector2) { GL.Uniform2(Location, ref vector2); }
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(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
#region Uniform3
public void SetUniform3(float x, float y, float z) { GL.Uniform3(Location, x, y, 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); }
public void SetUniform3(int x, int y, int z) { GL.Uniform3(Location, x, y, z); }
public void SetUniform3(float x, float y, float z)
{
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(double x, double y, double z)
{
GL.Uniform3(Location, x, y, z);
}
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(uint x, uint y, uint z)
{
GL.Uniform3(Location, x, y, z);
}
public void SetUniform3(Vector3 vector) { GL.Uniform3(Location, vector); }
public void SetUniform3(ref Vector3 vector) { GL.Uniform3(Location, ref vector); }
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(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
#region Uniform4
public void SetUniform4(float x, float y, float z, float w) { GL.Uniform4(Location, x, y, z, 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); }
public void SetUniform4(int x, int y, int z, int w) { GL.Uniform4(Location, x, y, z, w); }
public void SetUniform4(float x, float y, float z, float w)
{
GL.Uniform4(Location, x, y, z, w);
}
public void SetUniform4(int count, params float[] values) { 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(double x, double y, double z, double w)
{
GL.Uniform4(Location, x, y, z, w);
}
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(uint x, uint y, uint z, uint w)
{
GL.Uniform4(Location, x, y, z, w);
}
public void SetUniform4(Vector4 vector) { GL.Uniform4(Location, vector); }
public void SetUniform4(ref Vector4 vector) { GL.Uniform4(Location, ref vector); }
public void SetUniform4(int x, int y, int z, int w)
{
GL.Uniform4(Location, x, y, z, w);
}
public void SetUniform4(Color4 color) { GL.Uniform4(Location, color); }
public void SetUniform4(Quaternion quaternion) { GL.Uniform4(Location, quaternion); }
public void SetUniform4(int count, params float[] values)
{
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
#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 float value, bool transpose = false) { GL.UniformMatrix2(Location, count, transpose, ref value); }
public void SetMatrix2(int count, ref double value, bool transpose = false)
{
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); }
public void SetMatrix2(int count, ref float value, bool transpose = false)
{
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
#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 float value, bool transpose = false) { GL.UniformMatrix3(Location, count, transpose, ref value); }
public void SetMatrix3(int count, ref double value, bool transpose = false)
{
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); }
public void SetMatrix3(int count, ref float value, bool transpose = false)
{
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
@ -155,18 +392,36 @@ namespace SM.OGL.Shaders
{
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(int count, ref float value, bool transpose = false) { GL.UniformMatrix4(Location, count, transpose, ref value); }
public void SetMatrix4(ref Matrix4 matrix, bool transpose = false)
{
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, float[] value, bool transpose = false) { GL.UniformMatrix4(Location, count, transpose, value); }
public void SetMatrix4(int count, ref double value, bool transpose = false)
{
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
/// <summary>
/// Try to sets the texture at the next possible position and tells the checkUniform, if worked or not.
/// Try to sets the texture at the next possible position and tells the checkUniform, if worked or not.
/// </summary>
/// <param name="texture">The texture you want to add</param>
/// <param name="checkUniform">The check uniform.</param>
@ -177,7 +432,7 @@ namespace SM.OGL.Shaders
}
/// <summary>
/// Try to sets the texture at the specified position and tells the checkUniform, if worked or not.
/// Try to sets the texture at the specified position and tells the checkUniform, if worked or not.
/// </summary>
/// <param name="texture">The texture you want to add</param>
/// <param name="pos">The position</param>
@ -187,14 +442,18 @@ namespace SM.OGL.Shaders
checkUniform.SetUniform1(texture != null);
if (texture != null) SetTexture(texture);
}
/// <summary>
/// Sets the texture to the next possible position.
/// </summary>
/// <param name="texture"></param>
public void SetTexture(TextureBase texture) => SetTexture(texture, Parent.NextTexture++);
/// <summary>
/// Sets the texture to the specified position.
/// Sets the texture to the next possible position.
/// </summary>
/// <param name="texture"></param>
public void SetTexture(TextureBase texture)
{
if (Parent != null) SetTexture(texture, Parent.NextTexture++);
}
/// <summary>
/// Sets the texture to the specified position.
/// </summary>
/// <param name="texture"></param>
/// <param name="texturePos"></param>
@ -206,9 +465,12 @@ namespace SM.OGL.Shaders
}
/// <summary>
/// Returns the location from the uniform
/// Returns the location from the uniform
/// </summary>
/// <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 OpenTK.Graphics.OpenGL4;
#endregion
namespace SM.OGL.Shaders
{
/// <summary>
/// Contains and manages the uniform of the parent shader.
/// </summary>
public class UniformCollection : Dictionary<string, Uniform>
public class UniformCollection : Dictionary<string, IUniform>
{
/// <summary>
/// The next texture id for the uniform.
/// </summary>
internal int NextTexture = 0;
internal string KeyString = "";
public GenericShader ParentShader { get; internal set; }
/// <summary>
/// The parent shader.
/// </summary>
internal GenericShader _parentShader;
public new Uniform this[string key] => Get(key);
/// <summary>
/// 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]
public Uniform Get(string key)
{
get
try
{
try
{
return base[key];
}
catch (KeyNotFoundException)
{
Console.WriteLine("[Error] Uniform '"+key+"' was not found. Tried to recreate it.");
Uniform u = new Uniform(GL.GetUniformLocation(_parentShader, key), this);
Add(key, u);
return u;
}
return (Uniform) base[key];
}
catch (KeyNotFoundException)
{
GLCustomActions.AtWarning?.Invoke("Uniform '" + KeyString + key + "' was not found. Tried to recreate it.");
var u = new Uniform(GL.GetUniformLocation(ParentShader, KeyString + key), this);
Add(key, u);
return u;
}
}
/// <summary>
/// Adds a uniform with a location.
/// </summary>
/// <param name="key"></param>
/// <param name="location"></param>
public UniformArray GetArray(string key)
{
try
{
return (UniformArray) base[key];
}
catch (KeyNotFoundException)
{
throw new Exception("UniformArray '"+key+"' wasn't found");
}
}
public void Add(string key, int location)
{
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);
}
}
}