From fd53c73fa7b7132f1a459b2d12f66610ec3098d9 Mon Sep 17 00:00:00 2001 From: Michel Fedde Date: Sun, 13 Dec 2020 14:21:06 +0100 Subject: [PATCH] Fixed Shader Instancing (with that particles and Text, aswell) --- .../SM.Base/ShaderExtension/vertex/basic.vert | 10 +++- SMCode/SM.Base/Textures/Texture.cs | 12 +++-- SMCode/SM.OGL/Shaders/Uniform.cs | 9 ++++ SMCode/SM.OGL/Shaders/UniformArray.cs | 51 +++++++------------ SMCode/SM.OGL/Shaders/UniformCollection.cs | 12 ++--- SMCode/SM2D/Drawing/DrawBackground.cs | 2 +- SMCode/SM2D/Shader/Default2DShader.cs | 18 +++---- SM_TEST/Program.cs | 7 ++- 8 files changed, 60 insertions(+), 61 deletions(-) diff --git a/SMCode/SM.Base/ShaderExtension/vertex/basic.vert b/SMCode/SM.Base/ShaderExtension/vertex/basic.vert index 0007f9f..0087f7e 100644 --- a/SMCode/SM.Base/ShaderExtension/vertex/basic.vert +++ b/SMCode/SM.Base/ShaderExtension/vertex/basic.vert @@ -1,12 +1,18 @@ #version 330 #define maxInstances //!instanceMax +struct Instance { + mat4 ModelMatrix; + vec2 TextureOffset; + vec2 TextureScale; +}; layout(location = 0) in vec3 aPos; layout(location = 1) in vec2 aTex; layout(location = 3) in vec4 aColor; uniform mat4 MVP; +uniform Instance[maxInstances] Instances; uniform bool HasVColor; out vec2 vTexture; @@ -14,7 +20,7 @@ out vec4 vColor; out vec3 FragPos; void ApplyTexModifier() { - vTexture = aTex; + vTexture = aTex * Instances[gl_InstanceID].TextureScale + Instances[gl_InstanceID].TextureOffset; } void CheckVertexColor() { @@ -23,7 +29,7 @@ void CheckVertexColor() { } void ApplyModelTransformation() { - gl_Position = MVP * vec4(aPos, 1); + gl_Position = MVP * Instances[gl_InstanceID].ModelMatrix * vec4(aPos, 1); FragPos = vec3(vec4(aPos, 1)); } \ No newline at end of file diff --git a/SMCode/SM.Base/Textures/Texture.cs b/SMCode/SM.Base/Textures/Texture.cs index 135e31b..f8eea33 100644 --- a/SMCode/SM.Base/Textures/Texture.cs +++ b/SMCode/SM.Base/Textures/Texture.cs @@ -15,6 +15,9 @@ namespace SM.Base.Textures /// public class Texture : TextureBase { + private int? _width; + private int? _height; + /// /// Decides if the bitmap will automatically dispose itself. /// @@ -28,16 +31,15 @@ namespace SM.Base.Textures /// public override int Width { - get => Map.Width; - protected set - { } + get => _width ?? Map.Width; + protected set => _width = value; } /// public override int Height { - get => Map.Height; - protected set {} + get => _height ?? Map.Height; + protected set => _height = value; } public float Aspect { get; private set; } diff --git a/SMCode/SM.OGL/Shaders/Uniform.cs b/SMCode/SM.OGL/Shaders/Uniform.cs index 01c99b0..9d21661 100644 --- a/SMCode/SM.OGL/Shaders/Uniform.cs +++ b/SMCode/SM.OGL/Shaders/Uniform.cs @@ -28,6 +28,15 @@ namespace SM.OGL.Shaders { } + public Uniform(string name, GenericShader shader) : this(GL.GetUniformLocation(shader, name), null) + { + + } + public Uniform(string name, GenericShader shader, UniformCollection parent) : this(GL.GetUniformLocation(shader, name), parent) + { + + } + /// /// This create a new uniform manager /// diff --git a/SMCode/SM.OGL/Shaders/UniformArray.cs b/SMCode/SM.OGL/Shaders/UniformArray.cs index 8406882..2a86480 100644 --- a/SMCode/SM.OGL/Shaders/UniformArray.cs +++ b/SMCode/SM.OGL/Shaders/UniformArray.cs @@ -1,50 +1,33 @@ -#region usings - -using System; -using System.Collections.Generic; - -#endregion +using System.Collections.Generic; +using OpenTK.Graphics.OpenGL; namespace SM.OGL.Shaders { public class UniformArray : IUniform { - internal UniformCollection collection; + private Dictionary> storedUniforms = new Dictionary>(); + internal List uniformNames = new List(); - internal Dictionary Offsets = new Dictionary(); - 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 UniformCollection Parent { get; internal set; } + public GenericShader ParentShader { get; internal set; } - public UniformArray() + public Dictionary this[int index] => Get(index); + + public Dictionary Get(int index) { - collection = new UniformCollection() + if (!storedUniforms.ContainsKey(index)) { - ParentShader = Parent - }; - } + Dictionary dic = storedUniforms[index] = new Dictionary(); - public void Set(Action setAction) - { - for (var i = 0; i < Size; i++) setAction(i, new Uniform(Location + i)); - } - - public void Set(Func 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; + for (int i = 0; i < uniformNames.Count; i++) + { + dic.Add(uniformNames[i], new Uniform(Name + $"[{index}]." + uniformNames[i], ParentShader, Parent)); + } } + + return storedUniforms[index]; } } } \ No newline at end of file diff --git a/SMCode/SM.OGL/Shaders/UniformCollection.cs b/SMCode/SM.OGL/Shaders/UniformCollection.cs index 9cc5bb3..310536c 100644 --- a/SMCode/SM.OGL/Shaders/UniformCollection.cs +++ b/SMCode/SM.OGL/Shaders/UniformCollection.cs @@ -82,20 +82,16 @@ namespace SM.OGL.Shaders { Location = loc, Name = keySplits[0], - Parent = ParentShader, - Struct = keySplits.Length > 2 + Parent = this, + ParentShader = ParentShader }; 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); + if (keySplits[1] == "0") + array.uniformNames.Add(keySplits[2].Substring(1)); } else { diff --git a/SMCode/SM2D/Drawing/DrawBackground.cs b/SMCode/SM2D/Drawing/DrawBackground.cs index 4522442..13162b0 100644 --- a/SMCode/SM2D/Drawing/DrawBackground.cs +++ b/SMCode/SM2D/Drawing/DrawBackground.cs @@ -60,7 +60,7 @@ namespace SM2D.Drawing context.Material = _material; context.Mesh = Plate.Object; - context.Instances[0].ModelMatrix = Matrix4.CreateScale(context.WorldScale.X, context.WorldScale.Y, 1); + context.ModelMaster = Matrix4.CreateScale(context.WorldScale.X, context.WorldScale.Y, 1); context.Shader.Draw(context); } diff --git a/SMCode/SM2D/Shader/Default2DShader.cs b/SMCode/SM2D/Shader/Default2DShader.cs index 62e8411..0b770da 100644 --- a/SMCode/SM2D/Shader/Default2DShader.cs +++ b/SMCode/SM2D/Shader/Default2DShader.cs @@ -27,18 +27,16 @@ namespace SM2D.Shader Uniforms["MVP"].SetMatrix4(context.ModelMaster * context.View * context.World); Uniforms["HasVColor"] .SetUniform1(context.Mesh.Attributes["color"] != null); - /* - Uniforms.GetArray("Instances").Set((i, uniforms) => + + UniformArray instances = Uniforms.GetArray("Instances"); + for (int i = 0; i < context.Instances.Count; i++) { - if (i >= context.Instances.Count) return false; - + var shaderInstance = instances[i]; var instance = context.Instances[i]; - uniforms["ModelMatrix"].SetMatrix4(instance.ModelMatrix); - uniforms["TextureOffset"].SetUniform2(instance.TexturePosition); - uniforms["TextureScale"].SetUniform2(instance.TextureScale); - - return true; - });*/ + shaderInstance["ModelMatrix"].SetMatrix4(instance.ModelMatrix); + shaderInstance["TextureOffset"].SetUniform2(instance.TexturePosition); + shaderInstance["TextureScale"].SetUniform2(instance.TextureScale); + } // Fragment Uniforms Uniforms["Tint"].SetUniform4(context.Material.Tint); diff --git a/SM_TEST/Program.cs b/SM_TEST/Program.cs index be18419..9f6e1d7 100644 --- a/SM_TEST/Program.cs +++ b/SM_TEST/Program.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Runtime.InteropServices; using System.Security.Authentication.ExtendedProtection.Configuration; @@ -52,13 +53,17 @@ namespace SM_TEST private static void WindowOnLoad(object sender, EventArgs e) { - scene.ShowAxisHelper = true; + //scene.ShowAxisHelper = true; DrawObject2D kasten = new DrawObject2D(); kasten.Texture = new Texture(new Bitmap("herosword.png")); kasten.Transform.ApplyTextureSize(kasten.Texture, 500); scene.Objects.Add(kasten); + DrawText text = new DrawText(font, "Text"); + text.Transform.Position.Set(0, 500); + scene.Objects.Add(text); + //particles.Trigger(); } }