From 4c18127c88944585a08f00f363660c5277f30b4b Mon Sep 17 00:00:00 2001 From: Michel Fedde Date: Wed, 6 Jan 2021 17:04:15 +0100 Subject: [PATCH] 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 --- SMCode/SM.Base/Drawing/DrawingBasis.cs | 8 ++ .../SM.Base/Drawing/Text/TextDrawingBasis.cs | 1 + SMCode/SM.Base/Objects/InstancedMesh.cs | 30 +++++ SMCode/SM.Base/Objects/Mesh.cs | 2 +- SMCode/SM.Base/PostEffects/BloomEffect.cs | 82 ++++++++++++++ .../PostEffects/Shaders/bloom_blur.glsl | 30 +++++ .../PostEffects/Shaders/bloom_merge.glsl | 21 ++++ .../PostProcess/DefaultFiles/extensions.frag | 4 + .../SM.Base/PostProcess/PostProcessEffect.cs | 28 ++--- SMCode/SM.Base/SM.Base.csproj | 4 + SMCode/SM.Base/Scene/GenericCamera.cs | 2 + SMCode/SM.Base/Scene/GenericScene.cs | 24 ++-- SMCode/SM.Base/Types/CVector1.cs | 22 ++-- SMCode/SM.Base/Types/CVector2.cs | 17 +++ SMCode/SM.Base/Types/CVector3.cs | 17 +++ SMCode/SM.Base/Window/Contexts/DrawContext.cs | 104 ++++++++++-------- SMCode/SM.Base/Window/GenericWindow.cs | 31 ++++-- SMCode/SM.Base/Window/RenderPipeline.cs | 25 +++-- SMCode/SM.OGL/Framebuffer/ColorAttachment.cs | 41 ++++++- SMCode/SM.OGL/Framebuffer/Framebuffer.cs | 72 +++++++++++- SMCode/SM.OGL/GLCustomActions.cs | 3 + SMCode/SM.OGL/GLDebugging.cs | 5 + SMCode/SM.OGL/GLObject.cs | 1 + SMCode/SM.OGL/GLSettings.cs | 9 ++ SMCode/SM.OGL/Mesh/GenericMesh.cs | 5 +- SMCode/SM.OGL/Mesh/MeshAttribute.cs | 14 ++- SMCode/SM.OGL/Mesh/MeshAttributeList.cs | 25 ++++- SMCode/SM.OGL/SM.OGL.csproj | 4 +- SMCode/SM.OGL/Shaders/GenericShader.cs | 6 +- SMCode/SM.OGL/Shaders/IUniform.cs | 6 + SMCode/SM.OGL/Shaders/ShaderExtensions.cs | 17 +++ SMCode/SM.OGL/Shaders/ShaderFileCollection.cs | 1 + SMCode/SM.OGL/Shaders/ShaderPreProcess.cs | 6 + SMCode/SM.OGL/Shaders/Uniform.cs | 79 +++++++------ SMCode/SM.OGL/Shaders/UniformCollection.cs | 10 ++ SMCode/SM.OGL/Texture/PixelInformation.cs | 23 ++++ SMCode/SM.OGL/Texture/TextureBase.cs | 2 + SMCode/SM2D/Controls/Mouse2D.cs | 1 + SMCode/SM2D/Drawing/DrawObject2D.cs | 3 - SMCode/SM2D/Light/LightObjects/LightObject.cs | 25 ----- SMCode/SM2D/Light/LightObjects/PointLight.cs | 23 ---- SMCode/SM2D/Light/LightPostEffect.cs | 49 --------- SMCode/SM2D/Light/LightSceneExtension.cs | 12 -- SMCode/SM2D/Light/light.frag | 81 -------------- SMCode/SM2D/Pipelines/Basic2DPipeline.cs | 6 +- SMCode/SM2D/Pipelines/Default2DPipeline.cs | 24 +--- SMCode/SM2D/SM2D.csproj | 7 -- SMCode/SM2D/Scene/Scene.cs | 4 - SMCode/SM2D/Shader/ShaderFiles/default.glsl | 4 +- SM_TEST/Program.cs | 10 +- SM_TEST/SM_TEST.csproj | 1 + SM_TEST/TestRenderPipeline.cs | 39 +++++++ 52 files changed, 697 insertions(+), 373 deletions(-) create mode 100644 SMCode/SM.Base/Objects/InstancedMesh.cs create mode 100644 SMCode/SM.Base/PostEffects/BloomEffect.cs create mode 100644 SMCode/SM.Base/PostEffects/Shaders/bloom_blur.glsl create mode 100644 SMCode/SM.Base/PostEffects/Shaders/bloom_merge.glsl create mode 100644 SMCode/SM.OGL/Texture/PixelInformation.cs delete mode 100644 SMCode/SM2D/Light/LightObjects/LightObject.cs delete mode 100644 SMCode/SM2D/Light/LightObjects/PointLight.cs delete mode 100644 SMCode/SM2D/Light/LightPostEffect.cs delete mode 100644 SMCode/SM2D/Light/LightSceneExtension.cs delete mode 100644 SMCode/SM2D/Light/light.frag create mode 100644 SM_TEST/TestRenderPipeline.cs diff --git a/SMCode/SM.Base/Drawing/DrawingBasis.cs b/SMCode/SM.Base/Drawing/DrawingBasis.cs index fe1fa39..63bde5e 100644 --- a/SMCode/SM.Base/Drawing/DrawingBasis.cs +++ b/SMCode/SM.Base/Drawing/DrawingBasis.cs @@ -32,10 +32,17 @@ namespace SM.Base.Drawing /// public ICollection Flags { get; set; } + + /// + /// This value determents if the object should draw something. + /// + public bool Active = true; /// public void Draw(DrawContext context) { + if (!Active) return; + context.Material = _material; context.Mesh = _mesh; @@ -76,6 +83,7 @@ namespace SM.Base.Drawing /// protected override void DrawContext(ref DrawContext context) { + base.DrawContext(ref context); context.ModelMaster *= Transform.GetMatrix(); } } diff --git a/SMCode/SM.Base/Drawing/Text/TextDrawingBasis.cs b/SMCode/SM.Base/Drawing/Text/TextDrawingBasis.cs index 9c08ffe..76fa790 100644 --- a/SMCode/SM.Base/Drawing/Text/TextDrawingBasis.cs +++ b/SMCode/SM.Base/Drawing/Text/TextDrawingBasis.cs @@ -80,6 +80,7 @@ namespace SM.Base.Drawing.Text /// protected override void DrawContext(ref DrawContext context) { + base.DrawContext(ref context); if (_instances == null) GenerateMatrixes(); } diff --git a/SMCode/SM.Base/Objects/InstancedMesh.cs b/SMCode/SM.Base/Objects/InstancedMesh.cs new file mode 100644 index 0000000..22ce589 --- /dev/null +++ b/SMCode/SM.Base/Objects/InstancedMesh.cs @@ -0,0 +1,30 @@ +using System; +using OpenTK.Graphics.OpenGL4; +using SM.OGL.Mesh; + +namespace SM.Base.Objects +{ + public class InstancedMesh : Mesh + { + public InstancedMesh(PrimitiveType type, string[] enabledAttibute) : base(type) + { + Attributes["vertex"] = Vertex = new VBO(); + + foreach (string attribute in enabledAttibute) + { + switch (attribute) + { + case "uv": + Attributes["uv"] = UVs = new VBO(pointerSize: 2); + break; + case "normals": + Attributes["normal"] = Normals = new VBO(); + break; + case "color": + Attributes["color"] = Color = new VBO(pointerSize: 4); + break; + } + } + } + } +} \ No newline at end of file diff --git a/SMCode/SM.Base/Objects/Mesh.cs b/SMCode/SM.Base/Objects/Mesh.cs index 79c18d0..7d4a53a 100644 --- a/SMCode/SM.Base/Objects/Mesh.cs +++ b/SMCode/SM.Base/Objects/Mesh.cs @@ -13,7 +13,7 @@ namespace SM.Base.Objects /// /// While initializing, it will add the to the data index. /// - public Mesh(PrimitiveType type) + public Mesh(PrimitiveType type) : base() { PrimitiveType = type; Attributes.Add(3, "color", Color); diff --git a/SMCode/SM.Base/PostEffects/BloomEffect.cs b/SMCode/SM.Base/PostEffects/BloomEffect.cs new file mode 100644 index 0000000..e56d3f5 --- /dev/null +++ b/SMCode/SM.Base/PostEffects/BloomEffect.cs @@ -0,0 +1,82 @@ +using System.ComponentModel; +using OpenTK.Graphics.OpenGL4; +using SM.Base.Contexts; +using SM.Base.PostProcess; +using SM.OGL.Framebuffer; +using SM.OGL.Texture; +using SM.Utility; + +namespace SM.Base.PostEffects +{ + public class BloomEffect : PostProcessEffect + { + private Framebuffer _bloomBuffer1; + private Framebuffer _bloomBuffer2; + + private ColorAttachment _xBuffer; + private ColorAttachment _yBuffer; + + private PostProcessShader _shader = new PostProcessShader(AssemblyUtility.ReadAssemblyFile("SM.Base.PostEffects.Shaders.bloom_blur.glsl")); + private PostProcessShader _mergeShader = new PostProcessShader(AssemblyUtility.ReadAssemblyFile("SM.Base.PostEffects.Shaders.bloom_merge.glsl")); + + private int _bloomLocation; + private bool _hdr; + + public int Iterations = 5; + + public float[] Weights = { 0.227027f, 0.1945946f, 0.1216216f, 0.054054f, 0.016216f }; + + public BloomEffect(int bloomLocation, bool hdr = false) + { + _bloomLocation = bloomLocation; + _hdr = hdr; + } + + protected override void InitProcess() + { + Pipeline.MainFramebuffer.Append("bloom", new ColorAttachment(_bloomLocation, PixelInformation.RGBA_HDR)); + + _bloomBuffer1 = new Framebuffer(SMRenderer.CurrentWindow); + _bloomBuffer1.Append("xBuffer", _xBuffer = new ColorAttachment(0, PixelInformation.RGBA_HDR)); + _bloomBuffer1.Compile(); + _bloomBuffer2 = new Framebuffer(SMRenderer.CurrentWindow); + _bloomBuffer2.Append("yBuffer", _yBuffer = new ColorAttachment(0, PixelInformation.RGBA_HDR)); + _bloomBuffer2.Compile(); + + Pipeline.Framebuffers.Add(_bloomBuffer1); + Pipeline.Framebuffers.Add(_bloomBuffer2); + } + + public override void Draw(DrawContext context) + { + Framebuffer target = Framebuffer.GetCurrentlyActive(); + + bool first = true, hoz = true; + int iter = Iterations * 2; + for (int i = 0; i < iter; i++) + { + (hoz ? _bloomBuffer1 : _bloomBuffer2).Activate(); + + _shader.Draw(first ? Pipeline.MainFramebuffer.ColorAttachments["bloom"] : (hoz ? _yBuffer : _xBuffer), collection => + { + collection["Horizontal"].SetUniform1(hoz); + + collection["Weights"].SetUniform1(Weights); + collection["WeightCount"].SetUniform1(Weights.Length); + }); + + hoz = !hoz; + if (first) first = false; + } + + target.Activate(); + _mergeShader.Draw(Pipeline.MainFramebuffer.ColorAttachments["color"], collection => + { + collection["Bloom"].SetTexture(_yBuffer); + + collection["Exposure"].SetUniform1(context.UsedCamera.Exposure); + collection["HDR"].SetUniform1(_hdr); + }); + } + } +} \ No newline at end of file diff --git a/SMCode/SM.Base/PostEffects/Shaders/bloom_blur.glsl b/SMCode/SM.Base/PostEffects/Shaders/bloom_blur.glsl new file mode 100644 index 0000000..be3b543 --- /dev/null +++ b/SMCode/SM.Base/PostEffects/Shaders/bloom_blur.glsl @@ -0,0 +1,30 @@ +#version 330 + +uniform sampler2D renderedTexture; + +uniform bool Horizontal; + +uniform float[32] Weights; +uniform int WeightCount; + +layout(location = 0) out vec4 color; + +vec4 GetRenderColorOffset(vec2 offset); + +void main() { + vec2 tex_offset = 1.0 / textureSize(renderedTexture, 0); + vec3 result = GetRenderColorOffset(vec2(0)).rgb * Weights[0]; + + if (Horizontal) { + for(int i = 1; i < WeightCount; i++) { + result += GetRenderColorOffset(vec2(tex_offset.x * i, 0)).rgb * Weights[i]; + result += GetRenderColorOffset(vec2(-tex_offset.x * i, 0)).rgb * Weights[i]; + } + } else { + for(int i = 1; i < WeightCount; i++) { + result += GetRenderColorOffset(vec2(0, tex_offset.x * i)).rgb * Weights[i]; + result += GetRenderColorOffset(vec2(0, -tex_offset.x * i)).rgb * Weights[i]; + } + } + color = vec4(result, 1); +} \ No newline at end of file diff --git a/SMCode/SM.Base/PostEffects/Shaders/bloom_merge.glsl b/SMCode/SM.Base/PostEffects/Shaders/bloom_merge.glsl new file mode 100644 index 0000000..771015c --- /dev/null +++ b/SMCode/SM.Base/PostEffects/Shaders/bloom_merge.glsl @@ -0,0 +1,21 @@ +#version 330 + +in vec2 vTexture; + +uniform sampler2D renderedTexture; +uniform sampler2D Bloom; + +uniform float Exposure; +uniform bool HDR; + +layout(location = 0) out vec4 color; + +void main() { + vec3 result = texture(Bloom, vTexture).rgb; + if (!HDR) { + result = vec3(1.0) - exp(-result * Exposure); + } + result += texture(renderedTexture, vTexture).rgb; + + color = vec4(result, 1); +} \ No newline at end of file diff --git a/SMCode/SM.Base/PostProcess/DefaultFiles/extensions.frag b/SMCode/SM.Base/PostProcess/DefaultFiles/extensions.frag index c689d20..3b01527 100644 --- a/SMCode/SM.Base/PostProcess/DefaultFiles/extensions.frag +++ b/SMCode/SM.Base/PostProcess/DefaultFiles/extensions.frag @@ -6,4 +6,8 @@ uniform sampler2D renderedTexture; vec4 GetRenderColor() { return texture(renderedTexture, vTexture); +} + +vec4 GetRenderColorOffset(vec2 offset) { + return texture(renderedTexture, vTexture + offset); } \ No newline at end of file diff --git a/SMCode/SM.Base/PostProcess/PostProcessEffect.cs b/SMCode/SM.Base/PostProcess/PostProcessEffect.cs index 48f5ff1..eb7e739 100644 --- a/SMCode/SM.Base/PostProcess/PostProcessEffect.cs +++ b/SMCode/SM.Base/PostProcess/PostProcessEffect.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using OpenTK; using OpenTK.Graphics.OpenGL4; +using SM.Base.Contexts; using SM.Base.Objects.Static; using SM.Base.Scene; using SM.OGL.Framebuffer; @@ -18,27 +19,28 @@ namespace SM.Base.PostProcess internal static Matrix4 Mvp; internal static Matrix4 Model; + protected RenderPipeline Pipeline; + + /// + /// Initialize the effect. + /// + /// + public void Initilize(RenderPipeline pipeline) + { + Pipeline = pipeline; + InitProcess(); + } /// /// Method, to initialize the shader. /// - public virtual void Init() {} - - - /// - /// Method, to initialize the shader. - /// - public virtual void Init(Framebuffer main) - { - Init(); - } + protected virtual void InitProcess() {} + /// /// Method to draw the actual effect. /// - /// The framebuffer, that was used. - /// The framebuffer, the system should draw to. - public abstract void Draw(Framebuffer main, Framebuffer target); + public abstract void Draw(DrawContext context); /// /// Event, when the scene changed. diff --git a/SMCode/SM.Base/SM.Base.csproj b/SMCode/SM.Base/SM.Base.csproj index f813f4e..d030961 100644 --- a/SMCode/SM.Base/SM.Base.csproj +++ b/SMCode/SM.Base/SM.Base.csproj @@ -55,8 +55,10 @@ + + @@ -112,6 +114,8 @@ + + \ No newline at end of file diff --git a/SMCode/SM.Base/Scene/GenericCamera.cs b/SMCode/SM.Base/Scene/GenericCamera.cs index 1742330..f4e7520 100644 --- a/SMCode/SM.Base/Scene/GenericCamera.cs +++ b/SMCode/SM.Base/Scene/GenericCamera.cs @@ -43,6 +43,8 @@ namespace SM.Base.Scene /// public abstract bool Orthographic { get; } + public float Exposure = 1; + /// /// Calculates the view matrix. /// diff --git a/SMCode/SM.Base/Scene/GenericScene.cs b/SMCode/SM.Base/Scene/GenericScene.cs index 61bc3b7..1769e89 100644 --- a/SMCode/SM.Base/Scene/GenericScene.cs +++ b/SMCode/SM.Base/Scene/GenericScene.cs @@ -30,6 +30,18 @@ namespace SM.Base.Scene _background = value; } } + + /// + /// The active camera, that is used if the context doesn't force the viewport camera. + /// If none set, it automaticly uses the viewport camera. + /// + internal GenericCamera _camera { get; set; } + + /// + /// A collection for cameras to switch easier to different cameras. + /// + public Dictionary Cameras = new Dictionary(); + /// /// If true, the scene was already initialized. /// @@ -50,7 +62,7 @@ namespace SM.Base.Scene public virtual void Draw(DrawContext context) { } - + /// /// Adds a extension to the scene. /// @@ -102,8 +114,7 @@ namespace SM.Base.Scene /// Called, when the user activates the scene. /// protected virtual void OnActivating() - { - } + { } } /// @@ -125,16 +136,11 @@ namespace SM.Base.Scene /// public bool ShowAxisHelper { get; set; } = false; - /// - /// A collection for cameras to switch easier to different cameras. - /// - public Dictionary Cameras = new Dictionary(); - /// /// The active camera, that is used if the context doesn't force the viewport camera. /// If none set, it automaticly uses the viewport camera. /// - public TCamera Camera { get; set; } + public TCamera Camera => (TCamera) _camera; /// /// A camera to control the background. diff --git a/SMCode/SM.Base/Types/CVector1.cs b/SMCode/SM.Base/Types/CVector1.cs index 26041c3..62687d4 100644 --- a/SMCode/SM.Base/Types/CVector1.cs +++ b/SMCode/SM.Base/Types/CVector1.cs @@ -35,14 +35,7 @@ namespace SM.Base.Types X = x; } - /// - /// Sets the X-Component. - /// - /// X-Component - public virtual void Set(float x) - { - X = x; - } + /// /// Get the length of the vector. @@ -66,6 +59,19 @@ namespace SM.Base.Types NormalizationProcess(length); } + /// + /// Sets the X-Component. + /// + /// X-Component + public virtual void Set(float uniform) + { + X = uniform; + } + + public virtual void Add(float uniform) + { + X += uniform; + } /// /// Conversion into diff --git a/SMCode/SM.Base/Types/CVector2.cs b/SMCode/SM.Base/Types/CVector2.cs index 1af021f..00ec717 100644 --- a/SMCode/SM.Base/Types/CVector2.cs +++ b/SMCode/SM.Base/Types/CVector2.cs @@ -70,6 +70,23 @@ namespace SM.Base.Types Y = y; } + public override void Add(float uniform) + { + base.Add(uniform); + Y += uniform; + } + + public void Add(Vector2 vector) + { + Add(vector.X, vector.Y); + } + + public void Add(float x, float y) + { + base.Add(x); + Y += y; + } + /// /// Converts to /// diff --git a/SMCode/SM.Base/Types/CVector3.cs b/SMCode/SM.Base/Types/CVector3.cs index f04b015..f139743 100644 --- a/SMCode/SM.Base/Types/CVector3.cs +++ b/SMCode/SM.Base/Types/CVector3.cs @@ -63,6 +63,23 @@ namespace SM.Base.Types Set(vector.X, vector.Y, vector.Z); } + public override void Add(float uniform) + { + base.Add(uniform); + Z += uniform; + } + + public void Add(Vector3 vector) + { + Add(vector.X, vector.Y, vector.Z); + } + + public void Add(float x, float y, float z) + { + base.Add(x,y); + Z += z; + } + /// /// Converts to /// diff --git a/SMCode/SM.Base/Window/Contexts/DrawContext.cs b/SMCode/SM.Base/Window/Contexts/DrawContext.cs index 8e7d68d..a3c42a1 100644 --- a/SMCode/SM.Base/Window/Contexts/DrawContext.cs +++ b/SMCode/SM.Base/Window/Contexts/DrawContext.cs @@ -21,6 +21,65 @@ namespace SM.Base.Contexts /// public bool ForceViewport; + /// + /// Contains the currently used render pipeline. + /// + public RenderPipeline ActivePipeline; + + public GenericScene ActiveScene; + public GenericWindow Window; + + + public GenericCamera UsedCamera => + ForceViewport || ActiveScene._camera == null ? Window._viewportCamera : ActiveScene._camera; + + + + /// + /// The mesh. + /// + public GenericMesh Mesh; + + /// + /// The material. + /// + public Material Material; + + /// + /// The drawing instances. + /// If there is only one, it's index 0 + /// + public IList Instances; + + + + /// + /// The current world scale. + /// + public Vector2 WorldScale; + + /// + /// The last collection the context was passed though. + /// + public object LastPassthough; + + + + /// + /// Returns the appropriate shader. + /// + /// Returns the material shader, if available, otherwise it will take the default shader from the render + /// pipeline. + /// + /// + public MaterialShader Shader => Material.CustomShader ?? ActivePipeline._defaultShader; + /// + /// Arguments for shaders + /// + public IDictionary ShaderArguments; + + + /// /// The current world matrix. /// @@ -40,50 +99,5 @@ namespace SM.Base.Contexts /// The master model matrix. /// public Matrix4 ModelMaster; - - /// - /// The drawing instances. - /// If there is only one, it's index 0 - /// - public IList Instances; - - /// - /// The mesh. - /// - public GenericMesh Mesh; - - /// - /// The material. - /// - public Material Material; - - /// - /// Contains the currently used render pipeline. - /// - public RenderPipeline ActivePipeline; - - /// - /// The current world scale. - /// - public Vector2 WorldScale; - - /// - /// The last collection the context was passed though. - /// - public object LastPassthough; - - /// - /// Arguments for shaders - /// - public IDictionary ShaderArguments; - - /// - /// Returns the appropriate shader. - /// - /// Returns the material shader, if available, otherwise it will take the default shader from the render - /// pipeline. - /// - /// - public MaterialShader Shader => Material.CustomShader ?? ActivePipeline._defaultShader; } } \ No newline at end of file diff --git a/SMCode/SM.Base/Window/GenericWindow.cs b/SMCode/SM.Base/Window/GenericWindow.cs index ae5e984..0a4cb36 100644 --- a/SMCode/SM.Base/Window/GenericWindow.cs +++ b/SMCode/SM.Base/Window/GenericWindow.cs @@ -49,6 +49,8 @@ namespace SM.Base /// public bool ReactWhileUnfocused = false; + internal GenericCamera _viewportCamera; + /// protected GenericWindow() : this(1280, 720, "Generic OGL Title", GameWindowFlags.Default) { @@ -223,13 +225,16 @@ namespace SM.Base /// protected GenericWindow() { - ViewportCamera = new TCamera(); + _viewportCamera = new TCamera(); } /// /// The viewport camera. /// - public TCamera ViewportCamera { get; } + public TCamera ViewportCamera { + get => (TCamera)_viewportCamera; + set => _viewportCamera = value; + } /// /// This forces the render to use the viewport camera. @@ -258,29 +263,37 @@ namespace SM.Base { if (!ReactWhileUnfocused && !Focused) return; + if (CurrentScene == null) return; + SMRenderer.CurrentFrame++; Deltatime.RenderDelta = (float) e.Time; var drawContext = new DrawContext { - World = ViewportCamera.World, - View = ViewportCamera.CalculateViewMatrix(), - ModelMaster = Matrix4.Identity, + ForceViewport = ForceViewportCamera, + ActiveScene = CurrentScene, + Window = this, + Instances = new[] { new Instance {ModelMatrix = Matrix4.Identity, TexturePosition = Vector2.Zero, TextureScale = Vector2.One} }, - ShaderArguments = new Dictionary(), Mesh = Plate.Object, - ForceViewport = ForceViewportCamera, + WorldScale = _worldScale, - LastPassthough = this + LastPassthough = this, + + ShaderArguments = new Dictionary(), + + World = ViewportCamera.World, + View = ViewportCamera.CalculateViewMatrix(), + ModelMaster = Matrix4.Identity }; base.OnRenderFrame(e); - RenderPipeline.Render(ref drawContext, CurrentScene); + RenderPipeline.Render(ref drawContext); SwapBuffers(); diff --git a/SMCode/SM.Base/Window/RenderPipeline.cs b/SMCode/SM.Base/Window/RenderPipeline.cs index b492540..c24a8db 100644 --- a/SMCode/SM.Base/Window/RenderPipeline.cs +++ b/SMCode/SM.Base/Window/RenderPipeline.cs @@ -29,12 +29,14 @@ namespace SM.Base /// /// The framebuffers, that are used in this Pipeline. /// - protected virtual List _framebuffers { get; } + public virtual List Framebuffers { get; private set; } /// /// The default shader for the pipeline. /// - protected internal virtual MaterialShader _defaultShader { get; } = SMRenderer.DefaultMaterialShader; + protected internal virtual MaterialShader _defaultShader { get; set; } + + public virtual Framebuffer MainFramebuffer { get; protected set; }= Framebuffer.Screen; /// /// Occurs, when the window is loading. @@ -48,14 +50,14 @@ namespace SM.Base /// protected internal virtual void Resize() { - if (_framebuffers == null) return; + if (Framebuffers == null) return; - foreach (var framebuffer in _framebuffers) + foreach (var framebuffer in Framebuffers) framebuffer.Dispose(); Thread.Sleep(50); - foreach (Framebuffer framebuffer in _framebuffers) + foreach (Framebuffer framebuffer in Framebuffers) { framebuffer.Compile(); } @@ -67,7 +69,13 @@ namespace SM.Base if (!IsInitialized) { + if (_defaultShader == null) _defaultShader = SMRenderer.DefaultMaterialShader; + Framebuffers = new List(); + Initialization(window); + + Framebuffers.Add(MainFramebuffer); + IsInitialized = true; } @@ -106,7 +114,6 @@ namespace SM.Base { Framebuffer framebuffer = new Framebuffer(window: SMRenderer.CurrentWindow); framebuffer.Append("color", 0); - framebuffer.Compile(); return framebuffer; } } @@ -121,11 +128,15 @@ namespace SM.Base /// /// The system to render stuff. /// - protected internal virtual void Render(ref DrawContext context, TScene scene) + internal void Render(ref DrawContext context) { context.ActivePipeline = this; + + RenderProcess(ref context, (TScene)context.ActiveScene); } + protected abstract void RenderProcess(ref DrawContext context, TScene scene); + /// /// Event, that triggers, when the scene in the current window changes. /// diff --git a/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs b/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs index 39927dd..75d98ad 100644 --- a/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs +++ b/SMCode/SM.OGL/Framebuffer/ColorAttachment.cs @@ -8,31 +8,64 @@ using SM.OGL.Texture; namespace SM.OGL.Framebuffer { + /// + /// Represents a Framebuffer-Color Attachment. + /// Can be use like a texture. + /// public class ColorAttachment : TextureBase { - public ColorAttachment(int attachmentId) + /// + /// Creates a attachment with a specific id. + /// + /// + public ColorAttachment(int attachmentId) : this(attachmentId, PixelInformation.RGBA_LDR) + { } + + public ColorAttachment(int attachmentID, PixelInformation pixelInformation) { - AttachmentID = attachmentId; + + AttachmentID = attachmentID; + PixelInformation = pixelInformation; } + /// + /// The ID the attachment was given. + /// public int AttachmentID { get; } + /// + /// Returns the of this ColorAttachment. + /// public FramebufferAttachment FramebufferAttachment => FramebufferAttachment.ColorAttachment0 + AttachmentID; + /// + /// Returns the of this ColorAttachment. + /// public DrawBufferMode DrawBufferMode => DrawBufferMode.ColorAttachment0 + AttachmentID; + /// + /// Returns the of this ColorAttachment. + /// public ReadBufferMode ReadBufferMode => ReadBufferMode.ColorAttachment0 + AttachmentID; + /// + /// Returns the of this ColorAttachment. + /// public DrawBuffersEnum DrawBuffersEnum => DrawBuffersEnum.ColorAttachment0 + AttachmentID; + /// + /// Generates the attachment. + /// + /// 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); diff --git a/SMCode/SM.OGL/Framebuffer/Framebuffer.cs b/SMCode/SM.OGL/Framebuffer/Framebuffer.cs index 2ff3b78..ca5610f 100644 --- a/SMCode/SM.OGL/Framebuffer/Framebuffer.cs +++ b/SMCode/SM.OGL/Framebuffer/Framebuffer.cs @@ -9,9 +9,14 @@ using OpenTK.Graphics.OpenGL4; namespace SM.OGL.Framebuffer { - // TODO: Write summeries for framebuffer-system. + /// + /// Represents a OpenGL Framebuffer. + /// public class Framebuffer : GLObject { + /// + /// Represents the screen buffer. + /// public static readonly Framebuffer Screen = new Framebuffer { _id = 0, @@ -23,10 +28,18 @@ namespace SM.OGL.Framebuffer private INativeWindow _window; private float _windowScale; + /// + /// Creates a buffer without any options. + /// public Framebuffer() { } + /// + /// Creates a buffer, while always respecting the screen. + /// + /// + /// 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; } + /// + /// Creates a buffer, with a specified size. + /// + /// public Framebuffer(Vector2 size) { Size = size; } + /// public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Framebuffer; + /// + /// Contains the size of the framebuffer. + /// public Vector2 Size { get; private set; } + /// + /// Contains all color attachments. + /// public Dictionary ColorAttachments { get; private set; } = new Dictionary(); + /// public override void Compile() { if (!_canBeCompiled) return; @@ -78,6 +103,7 @@ namespace SM.OGL.Framebuffer GL.BindTexture(TextureTarget.Texture2D, 0); } + /// public override void Dispose() { base.Dispose(); @@ -85,32 +111,76 @@ namespace SM.OGL.Framebuffer GL.DeleteFramebuffer(this); } + /// + /// Appends a color attachment. + /// public void Append(string key, int pos) => Append(key, new ColorAttachment(pos)); + /// + /// Appends a color attachment. + /// public void Append(string key, ColorAttachment value) { ColorAttachments.Add(key, value); } + /// + /// Activates the framebuffer without clearing the buffer. + /// public void Activate() { Activate(FramebufferTarget.Framebuffer, ClearBufferMask.None); } + /// + /// Activates the framebuffer for the specific target framebuffer and without clearing. + /// + /// public void Activate(FramebufferTarget target) { Activate(target, ClearBufferMask.None); } + /// + /// Activates the framebuffer while clearing the specified buffer. + /// + /// public void Activate(ClearBufferMask clearMask) { Activate(FramebufferTarget.Framebuffer, clearMask); } + /// + /// Activates the framebuffer for the specific target and with clearing. + /// + /// + /// 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; + } } } \ No newline at end of file diff --git a/SMCode/SM.OGL/GLCustomActions.cs b/SMCode/SM.OGL/GLCustomActions.cs index 97eac9d..0357604 100644 --- a/SMCode/SM.OGL/GLCustomActions.cs +++ b/SMCode/SM.OGL/GLCustomActions.cs @@ -7,6 +7,9 @@ using OpenTK.Graphics.OpenGL4; namespace SM.OGL { + /// + /// Allows the system to send custom actions. + /// public class GLCustomActions { /// diff --git a/SMCode/SM.OGL/GLDebugging.cs b/SMCode/SM.OGL/GLDebugging.cs index a3ce393..d333be3 100644 --- a/SMCode/SM.OGL/GLDebugging.cs +++ b/SMCode/SM.OGL/GLDebugging.cs @@ -63,6 +63,11 @@ namespace SM.OGL return hasError; } + /// + /// Checks for OpenGL errors, while allowing to put stuff before and behind it. + /// + /// + /// public static bool CheckGLErrors(string formating) { var hasError = false; diff --git a/SMCode/SM.OGL/GLObject.cs b/SMCode/SM.OGL/GLObject.cs index bf0e28a..d7b77ca 100644 --- a/SMCode/SM.OGL/GLObject.cs +++ b/SMCode/SM.OGL/GLObject.cs @@ -54,6 +54,7 @@ namespace SM.OGL /// /// The action, that is called, when "ID" tries to compile something. /// + [DebuggerStepThrough] public virtual void Compile() { } diff --git a/SMCode/SM.OGL/GLSettings.cs b/SMCode/SM.OGL/GLSettings.cs index c1bbbdf..0bcc73f 100644 --- a/SMCode/SM.OGL/GLSettings.cs +++ b/SMCode/SM.OGL/GLSettings.cs @@ -1,7 +1,13 @@ namespace SM.OGL { + /// + /// Settings that are only accountable for SM.OGL + /// public class GLSettings { + /// + /// Send a , for each uniform from a shader. + /// public static bool InfoEveryUniform = false; /// @@ -10,6 +16,9 @@ /// public static Version ForcedVersion { get; set; } = new Version(); + /// + /// Allows to disable/enable preprocessing for shaders. + /// public static bool ShaderPreProcessing { get; set; } = false; } } \ No newline at end of file diff --git a/SMCode/SM.OGL/Mesh/GenericMesh.cs b/SMCode/SM.OGL/Mesh/GenericMesh.cs index fcb3e41..45cabac 100644 --- a/SMCode/SM.OGL/Mesh/GenericMesh.cs +++ b/SMCode/SM.OGL/Mesh/GenericMesh.cs @@ -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); } diff --git a/SMCode/SM.OGL/Mesh/MeshAttribute.cs b/SMCode/SM.OGL/Mesh/MeshAttribute.cs index f7833f0..4777e95 100644 --- a/SMCode/SM.OGL/Mesh/MeshAttribute.cs +++ b/SMCode/SM.OGL/Mesh/MeshAttribute.cs @@ -1,9 +1,21 @@ namespace SM.OGL.Mesh { - public struct MeshAttribute + /// + /// This represents a attribute of a mesh. + /// + public class MeshAttribute { + /// + /// Index of attribute + /// public int Index; + /// + /// Name of the attribute + /// public string Name; + /// + /// Connected buffer object. + /// public VBO ConnectedVBO; public MeshAttribute(int index, string name, VBO buffer) diff --git a/SMCode/SM.OGL/Mesh/MeshAttributeList.cs b/SMCode/SM.OGL/Mesh/MeshAttributeList.cs index d5c2364..5c1c94c 100644 --- a/SMCode/SM.OGL/Mesh/MeshAttributeList.cs +++ b/SMCode/SM.OGL/Mesh/MeshAttributeList.cs @@ -4,8 +4,14 @@ using System.Runtime.InteropServices; namespace SM.OGL.Mesh { + /// + /// List of mesh attributes. + /// public class MeshAttributeList : List { + /// + /// Returns the VBO (or null) that is connected to the specified name. + /// 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; + } + } + } } + /// + /// Adds a new attribute. + /// + /// + /// + /// public void Add(int id, string name, VBO vbo) { - if (vbo == null) return; + //if (vbo == null) return; Add(new MeshAttribute(id, name, vbo)); } } diff --git a/SMCode/SM.OGL/SM.OGL.csproj b/SMCode/SM.OGL/SM.OGL.csproj index c65abb9..7a25b52 100644 --- a/SMCode/SM.OGL/SM.OGL.csproj +++ b/SMCode/SM.OGL/SM.OGL.csproj @@ -21,8 +21,7 @@ DEBUG;TRACE prompt 4 - - + bin\Debug\SM.OGL.xml latest @@ -64,6 +63,7 @@ + diff --git a/SMCode/SM.OGL/Shaders/GenericShader.cs b/SMCode/SM.OGL/Shaders/GenericShader.cs index afb8409..cde9326 100644 --- a/SMCode/SM.OGL/Shaders/GenericShader.cs +++ b/SMCode/SM.OGL/Shaders/GenericShader.cs @@ -14,6 +14,7 @@ namespace SM.OGL.Shaders /// public abstract class GenericShader : GLObject { + /// protected override bool AutoCompile { get; } = true; /// @@ -26,6 +27,10 @@ namespace SM.OGL.Shaders /// protected UniformCollection Uniforms; + /// + /// + /// + /// protected GenericShader(string combinedData) { int firstPos = combinedData.IndexOf("//# region ", StringComparison.Ordinal); @@ -106,7 +111,6 @@ namespace SM.OGL.Shaders /// /// The mesh. /// The amounts for instancing. - /// Binds the vertex array for the mesh. protected void DrawObject(GenericMesh mesh, int amount = 1) { if (mesh.Indices != null) diff --git a/SMCode/SM.OGL/Shaders/IUniform.cs b/SMCode/SM.OGL/Shaders/IUniform.cs index b7f2113..a17a415 100644 --- a/SMCode/SM.OGL/Shaders/IUniform.cs +++ b/SMCode/SM.OGL/Shaders/IUniform.cs @@ -1,7 +1,13 @@ namespace SM.OGL.Shaders { + /// + /// Uniform interface + /// public interface IUniform { + /// + /// Location of the uniforms + /// int Location { get; } } } \ No newline at end of file diff --git a/SMCode/SM.OGL/Shaders/ShaderExtensions.cs b/SMCode/SM.OGL/Shaders/ShaderExtensions.cs index b96784b..b25f285 100644 --- a/SMCode/SM.OGL/Shaders/ShaderExtensions.cs +++ b/SMCode/SM.OGL/Shaders/ShaderExtensions.cs @@ -8,16 +8,33 @@ using System.Reflection; namespace SM.OGL.Shaders { + /// + /// Holder for shader extensions + /// public class ShaderExtensions { + /// + /// Holds the extensions. + /// public static Dictionary Extensions { get; private set; } = new Dictionary(); + /// + /// Adds extensions from the calling assembly + /// + /// Prefix for the added extensions. + /// Path, where the extensions are located. public static void AddAssemblyExtensions(string prefix, string path) { AddAssemblyExtensions(prefix, Assembly.GetCallingAssembly(), path); } + /// + /// Adds extensions from the specific assembly + /// + /// Prefix for the added extensions. + /// The specific assembly + /// Path, where the extensions are located. public static void AddAssemblyExtensions(string prefix, Assembly assembly, string path) { var paths = assembly.GetManifestResourceNames(); diff --git a/SMCode/SM.OGL/Shaders/ShaderFileCollection.cs b/SMCode/SM.OGL/Shaders/ShaderFileCollection.cs index aaba513..2f18f97 100644 --- a/SMCode/SM.OGL/Shaders/ShaderFileCollection.cs +++ b/SMCode/SM.OGL/Shaders/ShaderFileCollection.cs @@ -31,6 +31,7 @@ namespace SM.OGL.Shaders /// /// The vertex source file. /// The fragment source file. + /// The geometry source file. public ShaderFileCollection(string vertex, string fragment, string geometry = "") : this(new ShaderFile(vertex), new ShaderFile(fragment), geometry != "" ? new ShaderFile(geometry) : null) { diff --git a/SMCode/SM.OGL/Shaders/ShaderPreProcess.cs b/SMCode/SM.OGL/Shaders/ShaderPreProcess.cs index ac6c58c..e4cdd30 100644 --- a/SMCode/SM.OGL/Shaders/ShaderPreProcess.cs +++ b/SMCode/SM.OGL/Shaders/ShaderPreProcess.cs @@ -7,8 +7,14 @@ using System.Collections.Generic; namespace SM.OGL.Shaders { + /// + /// Holds Actions for the preprocessor. + /// public class ShaderPreProcess { + /// + /// Holds actions for the preprocessor. + /// public static Dictionary> Actions = new Dictionary> { diff --git a/SMCode/SM.OGL/Shaders/Uniform.cs b/SMCode/SM.OGL/Shaders/Uniform.cs index 2136aa1..46f8dc4 100644 --- a/SMCode/SM.OGL/Shaders/Uniform.cs +++ b/SMCode/SM.OGL/Shaders/Uniform.cs @@ -24,14 +24,29 @@ namespace SM.OGL.Shaders /// public UniformCollection Parent { get; } + /// + /// This creates a new uniform manager, that has a null parent. + /// + /// public Uniform(int location) : this(location, null) { } + /// + /// This creates a new uniform manager, that get the location from the provided shader and with a null parent. + /// + /// + /// public Uniform(string name, GenericShader shader) : this(GL.GetUniformLocation(shader, name), null) { } + /// + /// This creates a new uniform manager, that get the location from the provided shader and with a parent. + /// + /// + /// + /// 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) diff --git a/SMCode/SM.OGL/Shaders/UniformCollection.cs b/SMCode/SM.OGL/Shaders/UniformCollection.cs index e033861..f0a8785 100644 --- a/SMCode/SM.OGL/Shaders/UniformCollection.cs +++ b/SMCode/SM.OGL/Shaders/UniformCollection.cs @@ -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); diff --git a/SMCode/SM.OGL/Texture/PixelInformation.cs b/SMCode/SM.OGL/Texture/PixelInformation.cs new file mode 100644 index 0000000..ead9d7b --- /dev/null +++ b/SMCode/SM.OGL/Texture/PixelInformation.cs @@ -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; + } + } +} \ No newline at end of file diff --git a/SMCode/SM.OGL/Texture/TextureBase.cs b/SMCode/SM.OGL/Texture/TextureBase.cs index cc8630d..0eb354d 100644 --- a/SMCode/SM.OGL/Texture/TextureBase.cs +++ b/SMCode/SM.OGL/Texture/TextureBase.cs @@ -17,6 +17,8 @@ namespace SM.OGL.Texture /// public override ObjectLabelIdentifier TypeIdentifier { get; } = ObjectLabelIdentifier.Texture; + public PixelInformation PixelInformation; + /// /// The texture filter. /// Default: diff --git a/SMCode/SM2D/Controls/Mouse2D.cs b/SMCode/SM2D/Controls/Mouse2D.cs index 2dd3cba..0385dcf 100644 --- a/SMCode/SM2D/Controls/Mouse2D.cs +++ b/SMCode/SM2D/Controls/Mouse2D.cs @@ -4,6 +4,7 @@ using OpenTK; using OpenTK.Input; using SM.Base.Controls; using SM2D.Scene; +using SM2D.Types; #endregion diff --git a/SMCode/SM2D/Drawing/DrawObject2D.cs b/SMCode/SM2D/Drawing/DrawObject2D.cs index d1c8540..f04b141 100644 --- a/SMCode/SM2D/Drawing/DrawObject2D.cs +++ b/SMCode/SM2D/Drawing/DrawObject2D.cs @@ -16,8 +16,6 @@ namespace SM2D.Drawing { public int ZIndex { get; set; } - public bool ShadowCaster = false; - public Texture Texture { get => (Texture) _material.Texture; @@ -33,7 +31,6 @@ namespace SM2D.Drawing protected override void DrawContext(ref DrawContext context) { base.DrawContext(ref context); - context.ShaderArguments["occluder"] = ShadowCaster; context.Shader.Draw(context); } diff --git a/SMCode/SM2D/Light/LightObjects/LightObject.cs b/SMCode/SM2D/Light/LightObjects/LightObject.cs deleted file mode 100644 index d460c84..0000000 --- a/SMCode/SM2D/Light/LightObjects/LightObject.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using OpenTK; -using OpenTK.Graphics; -using SM.Base; -using SM.Base.Types; -using SM.OGL.Shaders; - -namespace SM2D.Light -{ - public abstract class LightObject - { - private Vector2 _posNorm => Vector2.Divide(Position, (SMRenderer.CurrentWindow as GLWindow2D).WorldScale); - internal abstract int Type { get; } - - public CVector2 Position = new CVector2(0); - public Color4 Color = Color4.White; - - internal virtual void SetUniforms(Dictionary uniforms) - { - uniforms["Type"].SetUniform1(Type); - uniforms["Position"].SetUniform2(Position); - uniforms["Color"].SetUniform4(Color); - } - } -} \ No newline at end of file diff --git a/SMCode/SM2D/Light/LightObjects/PointLight.cs b/SMCode/SM2D/Light/LightObjects/PointLight.cs deleted file mode 100644 index ae4f1e7..0000000 --- a/SMCode/SM2D/Light/LightObjects/PointLight.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; -using SM.OGL.Shaders; - -namespace SM2D.Light -{ - public class PointLight : LightObject - { - internal override int Type { get; } = 0; - - public float Power = 5; - public float InnerCircle = 1; - public float OuterCircle = 1; - - internal override void SetUniforms(Dictionary uniforms) - { - base.SetUniforms(uniforms); - - uniforms["Power"].SetUniform1(Power); - uniforms["Inner"].SetUniform1(1 / InnerCircle); - uniforms["Outer"].SetUniform1(1 / OuterCircle); - } - } -} \ No newline at end of file diff --git a/SMCode/SM2D/Light/LightPostEffect.cs b/SMCode/SM2D/Light/LightPostEffect.cs deleted file mode 100644 index f052211..0000000 --- a/SMCode/SM2D/Light/LightPostEffect.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Reflection; -using SM.Base; -using SM.Base.PostProcess; -using SM.Base.Scene; -using SM.OGL.Framebuffer; -using SM.OGL.Shaders; -using SM.Utility; -using SM2D.Scene; - -namespace SM2D.Light -{ - public class LightPostEffect : PostProcessEffect - { - private PostProcessShader _shader = new PostProcessShader(AssemblyUtility.ReadAssemblyFile("SM2D.Light.light.frag")); - private LightSceneExtension sceneExtension; - - public override void Init(Framebuffer main) - { - base.Init(main); - main.Append("occluder", 1); - } - - public override void Draw(Framebuffer main, Framebuffer target) - { - _shader.Draw(main.ColorAttachments["color"], collection => - { - collection["FragSize"].SetUniform2((SMRenderer.CurrentWindow as GLWindow2D).WorldScale); - - collection["Ambient"].SetUniform4(sceneExtension.Ambient); - collection["LightCount"].SetUniform1(sceneExtension.Lights.Count); - collection["OccluderMap"].SetTexture(main.ColorAttachments["occluder"]); - collection["ShadowSensitivty"].SetUniform1(1f); - - UniformArray array = collection.GetArray("Lights"); - - for (int i = 0; i < sceneExtension.Lights.Count; i++) - { - sceneExtension.Lights[i].SetUniforms(array[i]); - } - }); - } - - public override void SceneChanged(GenericScene scene) - { - base.SceneChanged(scene); - sceneExtension = scene.GetExtension(); - } - } -} \ No newline at end of file diff --git a/SMCode/SM2D/Light/LightSceneExtension.cs b/SMCode/SM2D/Light/LightSceneExtension.cs deleted file mode 100644 index 23c2a8b..0000000 --- a/SMCode/SM2D/Light/LightSceneExtension.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.Collections.Generic; -using OpenTK.Graphics; - -namespace SM2D.Light -{ - public class LightSceneExtension - { - public Color4 Ambient = Color4.White; - - public List Lights = new List(); - } -} \ No newline at end of file diff --git a/SMCode/SM2D/Light/light.frag b/SMCode/SM2D/Light/light.frag deleted file mode 100644 index 8d45503..0000000 --- a/SMCode/SM2D/Light/light.frag +++ /dev/null @@ -1,81 +0,0 @@ -#version 330 -#define PI 3.14159265359 - -struct Light { - int Type; - vec2 Position; - vec4 Color; - - // pointStuff; - float Power; - float Inner; - float Outer; -}; - -in vec2 vTexture; -in vec2 FragPos; - -uniform vec2 FragSize; - -uniform vec4 Ambient = vec4(1); -uniform Light[24] Lights; -uniform int LightCount; - -uniform float ShadowSensitivty; -uniform sampler2D OccluderMap; - -layout(location = 0) out vec4 color; - -vec4 GetRenderColor(); - -vec3 calcPointLight(Light light) { - vec2 diff = light.Position - FragPos; - - float dif = 20 / length(diff); - float intensity = light.Power * (dif) * (dif * dif); - - return vec3(light.Color * intensity); -} - -float occluded(Light light) { - float occluder = 1 - length(texture(OccluderMap, vTexture).rgb); - - if (occluder != 0) { - vec2 diff = light.Position - FragPos; - vec2 dir = normalize(diff); - - float steps = length(diff) / ShadowSensitivty; - - vec2 curPos = FragPos; - for(int i = 0; i < steps; i++) { - curPos += dir * i * ShadowSensitivty; - } - } - return occluder; -} - -vec3 calcLight() { - vec3 addedLight = vec3(0); - - for(int i = 0; i < LightCount; i++) { - Light light = Lights[i]; - - vec3 lightColor; - switch(light.Type) { - case 0: - lightColor += calcPointLight(light); - break; - } - addedLight += lightColor * occluded(light); - } - - return addedLight; -} - -void main() { - vec4 render = GetRenderColor(); - - color = render * Ambient; - - color += vec4(calcLight(), 1); -} \ No newline at end of file diff --git a/SMCode/SM2D/Pipelines/Basic2DPipeline.cs b/SMCode/SM2D/Pipelines/Basic2DPipeline.cs index 4d2f60e..408a840 100644 --- a/SMCode/SM2D/Pipelines/Basic2DPipeline.cs +++ b/SMCode/SM2D/Pipelines/Basic2DPipeline.cs @@ -12,16 +12,14 @@ namespace SM2D.Pipelines { public static Basic2DPipeline Pipeline = new Basic2DPipeline(); - protected override MaterialShader _defaultShader { get; } = Basic2DShader.Shader; private Basic2DPipeline() { - Console.WriteLine(); + _defaultShader = Basic2DShader.Shader; } - protected override void Render(ref DrawContext context, Scene.Scene scene) + protected override void RenderProcess(ref DrawContext context, Scene.Scene scene) { - base.Render(ref context, scene); Framebuffer.Screen.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); if (scene != null) scene.Draw(context); diff --git a/SMCode/SM2D/Pipelines/Default2DPipeline.cs b/SMCode/SM2D/Pipelines/Default2DPipeline.cs index cb41d6e..e4aced1 100644 --- a/SMCode/SM2D/Pipelines/Default2DPipeline.cs +++ b/SMCode/SM2D/Pipelines/Default2DPipeline.cs @@ -6,7 +6,6 @@ using SM.Base; using SM.Base.Contexts; using SM.Base.Scene; using SM.OGL.Framebuffer; -using SM2D.Light; using SM2D.Shader; #endregion @@ -17,11 +16,7 @@ namespace SM2D.Pipelines { public static Default2DPipeline Pipeline = new Default2DPipeline(); - private Framebuffer _tempWindow; - private Light.LightPostEffect _lightEffect; - - protected override List _framebuffers { get; } = new List(); - + private Default2DPipeline() { @@ -29,27 +24,19 @@ namespace SM2D.Pipelines protected override void Initialization(GenericWindow window) { - _tempWindow = CreateWindowFramebuffer(); - _lightEffect = new LightPostEffect(); - - _framebuffers.Add(_tempWindow); - - _lightEffect.Init(_tempWindow); + MainFramebuffer = CreateWindowFramebuffer(); } - protected override void Render(ref DrawContext context, Scene.Scene scene) + protected override void RenderProcess(ref DrawContext context, Scene.Scene scene) { - base.Render(ref context, scene); - if (scene != null) { - _tempWindow.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + MainFramebuffer.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); scene.DrawBackground(context); scene.DrawMainObjects(context); - + Framebuffer.Screen.Activate(); - _lightEffect.Draw(_tempWindow, Framebuffer.Screen); scene.DrawHUD(context); scene.DrawDebug(context); @@ -59,7 +46,6 @@ namespace SM2D.Pipelines protected override void SceneChanged(Scene.Scene scene) { base.SceneChanged(scene); - _lightEffect.SceneChanged(scene); } } } \ No newline at end of file diff --git a/SMCode/SM2D/SM2D.csproj b/SMCode/SM2D/SM2D.csproj index d33d248..c54202c 100644 --- a/SMCode/SM2D/SM2D.csproj +++ b/SMCode/SM2D/SM2D.csproj @@ -45,10 +45,6 @@ - - - - @@ -81,9 +77,6 @@ 3.2.1 - - - diff --git a/SMCode/SM2D/Scene/Scene.cs b/SMCode/SM2D/Scene/Scene.cs index 09f58aa..64b6953 100644 --- a/SMCode/SM2D/Scene/Scene.cs +++ b/SMCode/SM2D/Scene/Scene.cs @@ -6,7 +6,6 @@ using SM.Base.Contexts; using SM.Base.Objects.Static; using SM.Base.Scene; using SM2D.Drawing; -using SM2D.Light; #endregion @@ -17,7 +16,6 @@ namespace SM2D.Scene private static DrawObject2D _axisHelper; public float AxisHelperSize = 100; - public LightSceneExtension LightInformations; static Scene() { _axisHelper = new DrawObject2D(); @@ -27,8 +25,6 @@ namespace SM2D.Scene public Scene() { _Background = new DrawBackground(Color4.Black); - - SetExtension(LightInformations = new LightSceneExtension()); } diff --git a/SMCode/SM2D/Shader/ShaderFiles/default.glsl b/SMCode/SM2D/Shader/ShaderFiles/default.glsl index 97734bf..b02f716 100644 --- a/SMCode/SM2D/Shader/ShaderFiles/default.glsl +++ b/SMCode/SM2D/Shader/ShaderFiles/default.glsl @@ -24,11 +24,9 @@ uniform bool UseTexture; uniform sampler2D Texture; layout(location = 0) out vec4 color; -layout(location = 1) out vec4 occluder; +layout(location = 1) out vec4 bloom; void fmain() { color = vColor * Tint; if (UseTexture) color *= texture(Texture, vTexture); - - occluder = vec4(occlude,0,0,1); } \ No newline at end of file diff --git a/SM_TEST/Program.cs b/SM_TEST/Program.cs index 9829818..bc333a5 100644 --- a/SM_TEST/Program.cs +++ b/SM_TEST/Program.cs @@ -39,7 +39,7 @@ namespace SM_TEST window = new GLWindow2D {Scaling = new Vector2(0, 1000)}; //window.GrabCursor(); - window.SetRenderPipeline(Basic2DPipeline.Pipeline); + window.SetRenderPipeline(new TestRenderPipeline()); window.SetScene(scene = new Scene()); window.Load += WindowOnLoad; window.RenderFrame += WindowOnUpdateFrame; @@ -60,16 +60,12 @@ namespace SM_TEST { scene.ShowAxisHelper = true; - DrawObject2D kasten = new DrawObject2D(); - kasten.ShadowCaster = true; - kasten.Texture = new Texture(new Bitmap("herosword.png")); - kasten.Transform.ApplyTextureSize(kasten.Texture, 500); - scene.Objects.Add(kasten); //scene.Background.Color = Color4.White; DrawText text = new DrawText(font, "Text"); - text.Transform.Position.Set(0, 500); + text.Transform.Position.Set(0, 0); + text.Transform.Size.Set(2); scene.Objects.Add(text); light = new PointLight diff --git a/SM_TEST/SM_TEST.csproj b/SM_TEST/SM_TEST.csproj index bbf8af9..5006629 100644 --- a/SM_TEST/SM_TEST.csproj +++ b/SM_TEST/SM_TEST.csproj @@ -49,6 +49,7 @@ + diff --git a/SM_TEST/TestRenderPipeline.cs b/SM_TEST/TestRenderPipeline.cs new file mode 100644 index 0000000..25336f5 --- /dev/null +++ b/SM_TEST/TestRenderPipeline.cs @@ -0,0 +1,39 @@ +using System.Collections.Generic; +using OpenTK.Graphics.OpenGL4; +using SM.Base; +using SM.Base.Contexts; +using SM.Base.Drawing; +using SM.Base.PostEffects; +using SM.OGL.Framebuffer; +using SM2D.Scene; + +namespace SM_TEST +{ + public class TestRenderPipeline : RenderPipeline + { + private BloomEffect _bloom; + + protected override void Initialization(GenericWindow window) + { + base.Initialization(window); + _bloom = new BloomEffect(1); + + MainFramebuffer = CreateWindowFramebuffer(); + + _bloom.Initilize(this); + } + + protected override void RenderProcess(ref DrawContext context, Scene scene) + { + MainFramebuffer.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + scene.DrawBackground(context); + scene.DrawMainObjects(context); + + Framebuffer.Screen.Activate(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + _bloom.Draw(context); + + scene.DrawHUD(context); + scene.DrawDebug(context); + } + } +} \ No newline at end of file