05.01.2021

+ Bloom effect
+ PixelInformation
+ Many Summaries
+ Add-methods for CVectors
+ Exposure-Field in GenericCamera for HDR.

~ ColorAttachments now can have PixelInformation
~ Transformed MeshAttributes to a own class
~ Fixed the non-applying of transformations at texts
~ Added more information to the context
~ Improved Pipeline-Process.
~ Changed how Uniform takes arrays

- Light system
This commit is contained in:
Michel Fedde 2021-01-06 17:04:15 +01:00
parent 9b917ac181
commit 4c18127c88
52 changed files with 697 additions and 373 deletions

View file

@ -8,31 +8,64 @@ using SM.OGL.Texture;
namespace SM.OGL.Framebuffer
{
/// <summary>
/// Represents a Framebuffer-Color Attachment.
/// <para>Can be use like a texture.</para>
/// </summary>
public class ColorAttachment : TextureBase
{
public ColorAttachment(int attachmentId)
/// <summary>
/// Creates a attachment with a specific id.
/// </summary>
/// <param name="attachmentId"></param>
public ColorAttachment(int attachmentId) : this(attachmentId, PixelInformation.RGBA_LDR)
{ }
public ColorAttachment(int attachmentID, PixelInformation pixelInformation)
{
AttachmentID = attachmentId;
AttachmentID = attachmentID;
PixelInformation = pixelInformation;
}
/// <summary>
/// The ID the attachment was given.
/// </summary>
public int AttachmentID { get; }
/// <summary>
/// Returns the <see cref="OpenTK.Graphics.OpenGL4.FramebufferAttachment"/> of this ColorAttachment.
/// </summary>
public FramebufferAttachment FramebufferAttachment => FramebufferAttachment.ColorAttachment0 + AttachmentID;
/// <summary>
/// Returns the <see cref="OpenTK.Graphics.OpenGL4.DrawBufferMode"/> of this ColorAttachment.
/// </summary>
public DrawBufferMode DrawBufferMode => DrawBufferMode.ColorAttachment0 + AttachmentID;
/// <summary>
/// Returns the <see cref="OpenTK.Graphics.OpenGL4.ReadBufferMode"/> of this ColorAttachment.
/// </summary>
public ReadBufferMode ReadBufferMode => ReadBufferMode.ColorAttachment0 + AttachmentID;
/// <summary>
/// Returns the <see cref="OpenTK.Graphics.OpenGL4.DrawBuffersEnum"/> of this ColorAttachment.
/// </summary>
public DrawBuffersEnum DrawBuffersEnum => DrawBuffersEnum.ColorAttachment0 + AttachmentID;
/// <summary>
/// Generates the attachment.
/// </summary>
/// <param name="f"></param>
public void Generate(Framebuffer f)
{
_id = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, _id);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8,
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInformation.InternalFormat,
(int) f.Size.X, (int) f.Size.Y,
0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
0, PixelInformation.Format, PixelInformation.DataType, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
(int) TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
(int) TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS,
(int) TextureParameterName.ClampToEdge);

View file

@ -9,9 +9,14 @@ using OpenTK.Graphics.OpenGL4;
namespace SM.OGL.Framebuffer
{
// TODO: Write summeries for framebuffer-system.
/// <summary>
/// Represents a OpenGL Framebuffer.
/// </summary>
public class Framebuffer : GLObject
{
/// <summary>
/// Represents the screen buffer.
/// </summary>
public static readonly Framebuffer Screen = new Framebuffer
{
_id = 0,
@ -23,10 +28,18 @@ namespace SM.OGL.Framebuffer
private INativeWindow _window;
private float _windowScale;
/// <summary>
/// Creates a buffer without any options.
/// </summary>
public Framebuffer()
{
}
/// <summary>
/// Creates a buffer, while always respecting the screen.
/// </summary>
/// <param name="window"></param>
/// <param name="scale"></param>
public Framebuffer(INativeWindow window, float scale = 1) : this(new Vector2(window.Width * scale,
window.Height * scale))
{
@ -34,18 +47,30 @@ namespace SM.OGL.Framebuffer
_windowScale = scale;
}
/// <summary>
/// Creates a buffer, with a specified size.
/// </summary>
/// <param name="size"></param>
public Framebuffer(Vector2 size)
{
Size = size;
}
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Framebuffer;
/// <summary>
/// Contains the size of the framebuffer.
/// </summary>
public Vector2 Size { get; private set; }
/// <summary>
/// Contains all color attachments.
/// </summary>
public Dictionary<string, ColorAttachment> ColorAttachments { get; private set; } =
new Dictionary<string, ColorAttachment>();
/// <inheritdoc />
public override void Compile()
{
if (!_canBeCompiled) return;
@ -78,6 +103,7 @@ namespace SM.OGL.Framebuffer
GL.BindTexture(TextureTarget.Texture2D, 0);
}
/// <inheritdoc />
public override void Dispose()
{
base.Dispose();
@ -85,32 +111,76 @@ namespace SM.OGL.Framebuffer
GL.DeleteFramebuffer(this);
}
/// <summary>
/// Appends a color attachment.
/// </summary>
public void Append(string key, int pos) => Append(key, new ColorAttachment(pos));
/// <summary>
/// Appends a color attachment.
/// </summary>
public void Append(string key, ColorAttachment value)
{
ColorAttachments.Add(key, value);
}
/// <summary>
/// Activates the framebuffer without clearing the buffer.
/// </summary>
public void Activate()
{
Activate(FramebufferTarget.Framebuffer, ClearBufferMask.None);
}
/// <summary>
/// Activates the framebuffer for the specific target framebuffer and without clearing.
/// </summary>
/// <param name="target"></param>
public void Activate(FramebufferTarget target)
{
Activate(target, ClearBufferMask.None);
}
/// <summary>
/// Activates the framebuffer while clearing the specified buffer.
/// </summary>
/// <param name="clearMask"></param>
public void Activate(ClearBufferMask clearMask)
{
Activate(FramebufferTarget.Framebuffer, clearMask);
}
/// <summary>
/// Activates the framebuffer for the specific target and with clearing.
/// </summary>
/// <param name="target"></param>
/// <param name="clear"></param>
public void Activate(FramebufferTarget target, ClearBufferMask clear)
{
GL.BindFramebuffer(target, this);
GL.Clear(clear);
}
public static Framebuffer GetCurrentlyActive(FramebufferTarget target = FramebufferTarget.Framebuffer)
{
Framebuffer buffer = new Framebuffer()
{
_canBeCompiled = false,
};
switch (target)
{
case FramebufferTarget.ReadFramebuffer:
GL.GetInteger(GetPName.ReadFramebufferBinding, out buffer._id);
break;
case FramebufferTarget.DrawFramebuffer:
GL.GetInteger(GetPName.DrawFramebufferBinding, out buffer._id);
break;
case FramebufferTarget.Framebuffer:
GL.GetInteger(GetPName.FramebufferBinding, out buffer._id);
break;
}
return buffer;
}
}
}

View file

@ -7,6 +7,9 @@ using OpenTK.Graphics.OpenGL4;
namespace SM.OGL
{
/// <summary>
/// Allows the system to send custom actions.
/// </summary>
public class GLCustomActions
{
/// <summary>

View file

@ -63,6 +63,11 @@ namespace SM.OGL
return hasError;
}
/// <summary>
/// Checks for OpenGL errors, while allowing to put stuff before and behind it.
/// </summary>
/// <param name="formating"></param>
/// <returns></returns>
public static bool CheckGLErrors(string formating)
{
var hasError = false;

View file

@ -54,6 +54,7 @@ namespace SM.OGL
/// <summary>
/// The action, that is called, when "ID" tries to compile something.
/// </summary>
[DebuggerStepThrough]
public virtual void Compile()
{
}

View file

@ -1,7 +1,13 @@
namespace SM.OGL
{
/// <summary>
/// Settings that are only accountable for SM.OGL
/// </summary>
public class GLSettings
{
/// <summary>
/// Send a <see cref="GLCustomActions.AtInfo"/>, for each uniform from a shader.
/// </summary>
public static bool InfoEveryUniform = false;
/// <summary>
@ -10,6 +16,9 @@
/// </summary>
public static Version ForcedVersion { get; set; } = new Version();
/// <summary>
/// Allows to disable/enable preprocessing for shaders.
/// </summary>
public static bool ShaderPreProcessing { get; set; } = false;
}
}

View file

@ -75,9 +75,10 @@ namespace SM.OGL.Mesh
_id = GL.GenVertexArray();
GL.BindVertexArray(_id);
if (Attributes == null) throw new Exception("[Critical] The model requires attributes.");
if (Attributes == null || Attributes.Count == 0) throw new Exception("[Critical] The model requires attributes.");
foreach (var kvp in Attributes) kvp.ConnectedVBO?.BindBuffer(kvp.Index);
foreach (var kvp in Attributes)
kvp.ConnectedVBO?.BindBuffer(kvp.Index);
GL.BindVertexArray(0);
}

View file

@ -1,9 +1,21 @@
namespace SM.OGL.Mesh
{
public struct MeshAttribute
/// <summary>
/// This represents a attribute of a mesh.
/// </summary>
public class MeshAttribute
{
/// <summary>
/// Index of attribute
/// </summary>
public int Index;
/// <summary>
/// Name of the attribute
/// </summary>
public string Name;
/// <summary>
/// Connected buffer object.
/// </summary>
public VBO ConnectedVBO;
public MeshAttribute(int index, string name, VBO buffer)

View file

@ -4,8 +4,14 @@ using System.Runtime.InteropServices;
namespace SM.OGL.Mesh
{
/// <summary>
/// List of mesh attributes.
/// </summary>
public class MeshAttributeList : List<MeshAttribute>
{
/// <summary>
/// Returns the VBO (or null) that is connected to the specified name.
/// </summary>
public VBO this[string name]
{
get
@ -20,11 +26,28 @@ namespace SM.OGL.Mesh
return null;
}
set
{
for (int i = 0; i < Count; i++)
{
if (this[i].Name == name)
{
this[i].ConnectedVBO = value;
return;
}
}
}
}
/// <summary>
/// Adds a new attribute.
/// </summary>
/// <param name="id"></param>
/// <param name="name"></param>
/// <param name="vbo"></param>
public void Add(int id, string name, VBO vbo)
{
if (vbo == null) return;
//if (vbo == null) return;
Add(new MeshAttribute(id, name, vbo));
}
}

View file

@ -21,8 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>
</DocumentationFile>
<DocumentationFile>bin\Debug\SM.OGL.xml</DocumentationFile>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@ -64,6 +63,7 @@
<Compile Include="Shaders\Uniform.cs" />
<Compile Include="Shaders\UniformArray.cs" />
<Compile Include="Shaders\UniformCollection.cs" />
<Compile Include="Texture\PixelInformation.cs" />
<Compile Include="Texture\TextureBase.cs" />
<Compile Include="Version.cs" />
</ItemGroup>

View file

@ -14,6 +14,7 @@ namespace SM.OGL.Shaders
/// </summary>
public abstract class GenericShader : GLObject
{
/// <inheritdoc />
protected override bool AutoCompile { get; } = true;
/// <summary>
@ -26,6 +27,10 @@ namespace SM.OGL.Shaders
/// </summary>
protected UniformCollection Uniforms;
/// <summary>
///
/// </summary>
/// <param name="combinedData"></param>
protected GenericShader(string combinedData)
{
int firstPos = combinedData.IndexOf("//# region ", StringComparison.Ordinal);
@ -106,7 +111,6 @@ namespace SM.OGL.Shaders
/// </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(GenericMesh mesh, int amount = 1)
{
if (mesh.Indices != null)

View file

@ -1,7 +1,13 @@
namespace SM.OGL.Shaders
{
/// <summary>
/// Uniform interface
/// </summary>
public interface IUniform
{
/// <summary>
/// Location of the uniforms
/// </summary>
int Location { get; }
}
}

View file

@ -8,16 +8,33 @@ using System.Reflection;
namespace SM.OGL.Shaders
{
/// <summary>
/// Holder for shader extensions
/// </summary>
public class ShaderExtensions
{
/// <summary>
/// Holds the extensions.
/// </summary>
public static Dictionary<string, ShaderFile> Extensions { get; private set; } =
new Dictionary<string, ShaderFile>();
/// <summary>
/// Adds extensions from the calling assembly
/// </summary>
/// <param name="prefix">Prefix for the added extensions.</param>
/// <param name="path">Path, where the extensions are located.</param>
public static void AddAssemblyExtensions(string prefix, string path)
{
AddAssemblyExtensions(prefix, Assembly.GetCallingAssembly(), path);
}
/// <summary>
/// Adds extensions from the specific assembly
/// </summary>
/// <param name="prefix">Prefix for the added extensions.</param>
/// <param name="assembly">The specific assembly</param>
/// <param name="path">Path, where the extensions are located.</param>
public static void AddAssemblyExtensions(string prefix, Assembly assembly, string path)
{
var paths = assembly.GetManifestResourceNames();

View file

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

View file

@ -7,8 +7,14 @@ using System.Collections.Generic;
namespace SM.OGL.Shaders
{
/// <summary>
/// Holds Actions for the preprocessor.
/// </summary>
public class ShaderPreProcess
{
/// <summary>
/// Holds actions for the preprocessor.
/// </summary>
public static Dictionary<string, Action<ShaderFile, string>> Actions =
new Dictionary<string, Action<ShaderFile, string>>
{

View file

@ -24,14 +24,29 @@ namespace SM.OGL.Shaders
/// </summary>
public UniformCollection Parent { get; }
/// <summary>
/// This creates a new uniform manager, that has a null parent.
/// </summary>
/// <param name="location"></param>
public Uniform(int location) : this(location, null)
{
}
/// <summary>
/// This creates a new uniform manager, that get the location from the provided shader and with a null parent.
/// </summary>
/// <param name="name"></param>
/// <param name="shader"></param>
public Uniform(string name, GenericShader shader) : this(GL.GetUniformLocation(shader, name), null)
{
}
/// <summary>
/// This creates a new uniform manager, that get the location from the provided shader and with a parent.
/// </summary>
/// <param name="name"></param>
/// <param name="shader"></param>
/// <param name="parent"></param>
public Uniform(string name, GenericShader shader, UniformCollection parent) : this(GL.GetUniformLocation(shader, name), parent)
{
@ -60,9 +75,9 @@ namespace SM.OGL.Shaders
GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params int[] values)
public void SetUniform1(params int[] values)
{
GL.Uniform1(Location, count, values);
GL.Uniform1(Location, values.Length, values);
}
public void SetUniform1(int count, ref int values)
@ -76,9 +91,9 @@ namespace SM.OGL.Shaders
GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params uint[] values)
public void SetUniform1(params uint[] values)
{
GL.Uniform1(Location, count, values);
GL.Uniform1(Location, values.Length, values);
}
public void SetUniform1(int count, ref uint values)
@ -92,9 +107,9 @@ namespace SM.OGL.Shaders
GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params float[] values)
public void SetUniform1(params float[] values)
{
GL.Uniform1(Location, count, values);
GL.Uniform1(Location, values.Length, values);
}
public void SetUniform1(int count, ref float value)
@ -108,9 +123,9 @@ namespace SM.OGL.Shaders
GL.Uniform1(Location, value);
}
public void SetUniform1(int count, params double[] values)
public void SetUniform1(params double[] values)
{
GL.Uniform1(Location, count, values);
GL.Uniform1(Location, values.Length, values);
}
public void SetUniform1(int count, ref double value)
@ -142,24 +157,24 @@ namespace SM.OGL.Shaders
GL.Uniform2(Location, x, y);
}
public void SetUniform2(int count, params float[] values)
public void SetUniform2(params float[] values)
{
GL.Uniform2(Location, count, values);
GL.Uniform2(Location, values.Length / 2, values);
}
public void SetUniform2(int count, params double[] values)
public void SetUniform2(params double[] values)
{
GL.Uniform2(Location, count, values);
GL.Uniform2(Location, values.Length / 2, values);
}
public void SetUniform2(int count, params int[] values)
public void SetUniform2(params int[] values)
{
GL.Uniform2(Location, count, values);
GL.Uniform2(Location, values.Length / 2, values);
}
public void SetUniform2(int count, params uint[] values)
public void SetUniform2(params uint[] values)
{
GL.Uniform2(Location, count, values);
GL.Uniform2(Location, values.Length / 2, values);
}
public void SetUniform2(int count, ref float values)
@ -211,24 +226,24 @@ namespace SM.OGL.Shaders
GL.Uniform3(Location, x, y, z);
}
public void SetUniform3(int count, params float[] values)
public void SetUniform3(params float[] values)
{
GL.Uniform3(Location, count, values);
GL.Uniform3(Location, values.Length / 3, values);
}
public void SetUniform3(int count, params double[] values)
public void SetUniform3(params double[] values)
{
GL.Uniform3(Location, count, values);
GL.Uniform3(Location, values.Length / 3, values);
}
public void SetUniform3(int count, params int[] values)
public void SetUniform3(params int[] values)
{
GL.Uniform3(Location, count, values);
GL.Uniform3(Location, values.Length / 3, values);
}
public void SetUniform3(int count, params uint[] values)
public void SetUniform3(params uint[] values)
{
GL.Uniform3(Location, count, values);
GL.Uniform3(Location, values.Length / 3, values);
}
public void SetUniform3(int count, ref float values)
@ -280,24 +295,24 @@ namespace SM.OGL.Shaders
GL.Uniform4(Location, x, y, z, w);
}
public void SetUniform4(int count, params float[] values)
public void SetUniform4(params float[] values)
{
GL.Uniform4(Location, count, values);
GL.Uniform4(Location, values.Length / 4, values);
}
public void SetUniform4(int count, params double[] values)
public void SetUniform4(params double[] values)
{
GL.Uniform4(Location, count, values);
GL.Uniform4(Location, values.Length / 4, values);
}
public void SetUniform4(int count, params int[] values)
public void SetUniform4(params int[] values)
{
GL.Uniform4(Location, count, values);
GL.Uniform4(Location, values.Length / 4, values);
}
public void SetUniform4(int count, params uint[] values)
public void SetUniform4(params uint[] values)
{
GL.Uniform4(Location, count, values);
GL.Uniform4(Location, values.Length / 4, values);
}
public void SetUniform4(int count, ref float values)

View file

@ -74,6 +74,16 @@ namespace SM.OGL.Shaders
if (key.Contains("["))
{
var keySplits = key.Split('[', ']');
if (keySplits[2] == "")
{
if (keySplits[1] == "0")
{
Add(keySplits[0], loc);
}
continue;
}
if (keySplits[0] != lastArrayKey)
{
if (arrayFilled) Add(lastArrayKey, array);

View file

@ -0,0 +1,23 @@
using OpenTK.Graphics.OpenGL4;
namespace SM.OGL.Texture
{
public struct PixelInformation
{
public static PixelInformation RGB_LDR = new PixelInformation(PixelInternalFormat.Rgb, PixelFormat.Rgb, PixelType.UnsignedByte);
public static PixelInformation RGB_HDR = new PixelInformation(PixelInternalFormat.Rgb16f, PixelFormat.Rgb, PixelType.Float);
public static PixelInformation RGBA_LDR = new PixelInformation(PixelInternalFormat.Rgba, PixelFormat.Rgba, PixelType.UnsignedByte);
public static PixelInformation RGBA_HDR = new PixelInformation(PixelInternalFormat.Rgba16f, PixelFormat.Rgba, PixelType.Float);
public PixelInternalFormat InternalFormat { get; }
public PixelFormat Format { get; }
public PixelType DataType { get; }
public PixelInformation(PixelInternalFormat internalFormat, PixelFormat format, PixelType dataType)
{
InternalFormat = internalFormat;
Format = format;
DataType = dataType;
}
}
}

View file

@ -17,6 +17,8 @@ namespace SM.OGL.Texture
/// <inheritdoc />
public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Texture;
public PixelInformation PixelInformation;
/// <summary>
/// The texture filter.
/// <para>Default: <see cref="TextureMinFilter.Linear" /></para>