04.10.2020

+ render pipeline system for more control about the renderering.
+ Log system
+ Framebuffer system

~ Default shader was moved to pipelines.
This commit is contained in:
Michel Fedde 2020-10-04 16:31:48 +02:00
parent 97e638d9d9
commit 820d6ce700
34 changed files with 660 additions and 106 deletions

View file

@ -0,0 +1,35 @@
using System;
using OpenTK.Graphics.OpenGL4;
using SM.OGL.Texture;
namespace SM.OGL.Framebuffer
{
public class ColorAttachment : TextureBase
{
public int AttachmentID { get; }
public FramebufferAttachment FramebufferAttachment => FramebufferAttachment.ColorAttachment0 + AttachmentID;
public DrawBufferMode DrawBufferMode => DrawBufferMode.ColorAttachment0 + AttachmentID;
public ReadBufferMode ReadBufferMode => ReadBufferMode.ColorAttachment0 + AttachmentID;
public DrawBuffersEnum DrawBuffersEnum => DrawBuffersEnum.ColorAttachment0 + AttachmentID;
public ColorAttachment(int attachmentId)
{
AttachmentID = attachmentId;
}
public void Generate(Framebuffer f)
{
_id = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, _id);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8,
(int) f.Size.X, (int) f.Size.Y,
0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureParameterName.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureParameterName.ClampToEdge);
}
}
}

View file

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

View file

@ -4,11 +4,12 @@ using System.Net.Http;
using System.Runtime.InteropServices;
using OpenTK.Graphics.OpenGL4;
using OpenTK.Platform.Egl;
using ErrorCode = OpenTK.Graphics.OpenGL4.ErrorCode;
namespace SM.OGL
{
/// <summary>
/// Contains everything that is needed to properly debug OpenGL
/// Contains everything that is needed to debug OpenGL
/// </summary>
public static class GLDebugging
{
@ -63,5 +64,26 @@ namespace SM.OGL
if (type == DebugType.DebugTypeError) throw new Exception(msg);
}
/// <summary>
/// A action, that is performed, when <see cref="GLDebugging.CheckGLErrors"/> find an error.
/// </summary>
public static Action<ErrorCode> GlErrorAction;
/// <summary>
/// Checks for OpenGL errors.
/// </summary>
public static bool CheckGLErrors()
{
bool hasError = false;
ErrorCode c;
while ((c = GL.GetError()) != ErrorCode.NoError)
{
hasError = true;
GlErrorAction?.Invoke(c);
}
return hasError;
}
}
}

View file

@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL4;
using System.Diagnostics;
using OpenTK.Graphics.OpenGL4;
namespace SM.OGL
{
@ -29,7 +30,7 @@ namespace SM.OGL
{
get
{
if (AutoCompile && !WasCompiled) Compile();
if (AutoCompile && !WasCompiled) PerformCompile();
return _id;
}
}
@ -39,10 +40,17 @@ namespace SM.OGL
/// </summary>
public abstract ObjectLabelIdentifier TypeIdentifier { get; }
[DebuggerStepThrough]
private void PerformCompile()
{
Compile();
}
/// <summary>
/// The action, that is called, when "ID" tries to compile something.
/// </summary>
protected virtual void Compile()
public virtual void Compile()
{
}
@ -50,7 +58,7 @@ namespace SM.OGL
/// <summary>
/// Is triggered, when something want to dispose this object.
/// </summary>
protected virtual void Dispose() {}
public virtual void Dispose() {}
/// <summary>
/// Re-compiles the object.
@ -72,10 +80,15 @@ namespace SM.OGL
if (GLSystem.Debugging) GL.ObjectLabel(TypeIdentifier, _id, name.Length, name);
}
protected virtual int GetID()
{
return _id;
}
/// <summary>
/// Returns the ID for the object.
/// </summary>
/// <param name="glo"></param>
public static implicit operator int(GLObject glo) => glo.ID;
public static implicit operator int(GLObject glo) => glo.GetID();
}
}

View file

@ -64,7 +64,7 @@ namespace SM.OGL.Mesh
}
/// <inheritdoc />
protected override void Compile()
public override void Compile()
{
_id = GL.GenVertexArray();
GL.BindVertexArray(_id);

View file

@ -46,6 +46,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Framebuffer\ColorAttachment.cs" />
<Compile Include="Framebuffer\Framebuffer.cs" />
<Compile Include="GLDebugging.cs" />
<Compile Include="GLObject.cs" />
<Compile Include="GLSystem.cs" />

View file

@ -59,7 +59,7 @@ namespace SM.OGL.Shaders
}
/// <inheritdoc />
protected override void Compile()
public override void Compile()
{
Load();
}
@ -70,7 +70,7 @@ namespace SM.OGL.Shaders
/// <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, bool bindVAO = false)
protected void DrawObject(Mesh.GenericMesh mesh, int amount = 1, bool bindVAO = false)
{
if (bindVAO) GL.BindVertexArray(mesh);

View file

@ -33,5 +33,11 @@ namespace SM.OGL.Texture
/// The height of the texture
/// </summary>
public int Height { get; protected set; }
public override void Dispose()
{
base.Dispose();
GL.DeleteTexture(_id);
}
}
}