Loads and loads of small improvements I added while developing on my game

This commit is contained in:
Michel Fedde 2021-03-02 19:54:19 +01:00
parent 41421b1df9
commit a7c71e7ea1
107 changed files with 2278 additions and 1023 deletions

View file

@ -0,0 +1,19 @@
#region usings
using SM.OGL.Shaders;
#endregion
namespace SM.Base.ShaderExtension
{
internal class ExtensionManager
{
internal static void InitExtensions()
{
ShaderExtensions.AddAssemblyExtensions("SM_base", "SM.Base.Shaders.Extensions");
ShaderExtensions.Extensions["SM_base_vertex_basic"].StringOverrides["instanceMax"] =
SMRenderer.MaxInstances.ToString();
}
}
}

View file

@ -0,0 +1,71 @@
#version 330
// Permute
vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
vec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}
// Classic Perlin 2D Noise
// by Stefan Gustavson
vec2 fade(vec2 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);}
float ClassicPerlinNoise(vec2 P){
vec4 Pi = floor(P.xyxy) + vec4(0.0, 0.0, 1.0, 1.0);
vec4 Pf = fract(P.xyxy) - vec4(0.0, 0.0, 1.0, 1.0);
Pi = mod(Pi, 289.0); // To avoid truncation effects in permutation
vec4 ix = Pi.xzxz;
vec4 iy = Pi.yyww;
vec4 fx = Pf.xzxz;
vec4 fy = Pf.yyww;
vec4 i = permute(permute(ix) + iy);
vec4 gx = 2.0 * fract(i * 0.0243902439) - 1.0; // 1/41 = 0.024...
vec4 gy = abs(gx) - 0.5;
vec4 tx = floor(gx + 0.5);
gx = gx - tx;
vec2 g00 = vec2(gx.x,gy.x);
vec2 g10 = vec2(gx.y,gy.y);
vec2 g01 = vec2(gx.z,gy.z);
vec2 g11 = vec2(gx.w,gy.w);
vec4 norm = 1.79284291400159 - 0.85373472095314 *
vec4(dot(g00, g00), dot(g01, g01), dot(g10, g10), dot(g11, g11));
g00 *= norm.x;
g01 *= norm.y;
g10 *= norm.z;
g11 *= norm.w;
float n00 = dot(g00, vec2(fx.x, fy.x));
float n10 = dot(g10, vec2(fx.y, fy.y));
float n01 = dot(g01, vec2(fx.z, fy.z));
float n11 = dot(g11, vec2(fx.w, fy.w));
vec2 fade_xy = fade(Pf.xy);
vec2 n_x = mix(vec2(n00, n01), vec2(n10, n11), fade_xy.x);
float n_xy = mix(n_x.x, n_x.y, fade_xy.y);
return 2.3 * n_xy;
}
// Simplex 2D noise
float SimplexNoise(vec2 v){
const vec4 C = vec4(0.211324865405187, 0.366025403784439,
-0.577350269189626, 0.024390243902439);
vec2 i = floor(v + dot(v, C.yy) );
vec2 x0 = v - i + dot(i, C.xx);
vec2 i1;
i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;
i = mod(i, 289.0);
vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))
+ i.x + vec3(0.0, i1.x, 1.0 ));
vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),
dot(x12.zw,x12.zw)), 0.0);
m = m*m ;
m = m*m ;
vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;
m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}

View file

@ -0,0 +1,8 @@
#version 330
uniform float Gamma;
vec4 texture2DGamma(sampler2D s, vec2 P) {
vec4 tex = texture2D(s, P);
return vec4(pow(tex.rgb, vec3(Gamma)), tex.a);
}

View file

@ -0,0 +1,35 @@
#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;
out vec4 vColor;
out vec3 FragPos;
void ApplyTexModifier() {
vTexture = aTex * Instances[gl_InstanceID].TextureScale + Instances[gl_InstanceID].TextureOffset;
}
void CheckVertexColor() {
if (HasVColor) vColor = aColor;
else vColor = vec4(1);
}
void ApplyModelTransformation() {
gl_Position = MVP * Instances[gl_InstanceID].ModelMatrix * vec4(aPos, 1);
FragPos = vec3(vec4(aPos, 1));
}

View file

@ -0,0 +1,62 @@
#region usings
using OpenTK.Graphics.OpenGL4;
using SM.Base;
using SM.Base.Windows;
using SM.OGL.Mesh;
using SM.OGL.Shaders;
#endregion
namespace SM.Base.Drawing
{
/// <summary>
/// A general class to work with material shaders properly.
/// </summary>
public abstract class MaterialShader : GenericShader
{
/// <inheritdoc />
protected MaterialShader(string combinedData) : base(combinedData)
{}
/// <inheritdoc />
protected MaterialShader(string vertex, string fragment) : base(vertex, fragment)
{
}
/// <inheritdoc />
protected MaterialShader(ShaderFileCollection shaderFileFiles) : base(shaderFileFiles)
{
}
/// <summary>
/// Prepares the context for the drawing.
/// </summary>
/// <param name="context">The context</param>
public virtual void Draw(DrawContext context)
{
context.Shader.Activate();
context.Mesh.Activate();
if (context.Mesh is ILineMesh lineMesh)
GL.LineWidth(context.Material.ShaderArguments.Get("LineWidth", lineMesh.LineWidth));
if (context.Material.Blending)
{
GL.Enable(EnableCap.Blend);
GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
} else GL.Disable(EnableCap.Blend);
DrawProcess(context);
CleanUp();
}
/// <summary>
/// Draws the context.
/// </summary>
/// <param name="context"></param>
protected abstract void DrawProcess(DrawContext context);
}
}

View file

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using SM.Base.Windows;
using SM.OGL.Shaders;
using SM.Utility;
namespace SM.Base.Drawing
{
public class SimpleShader : MaterialShader
{
public static Dictionary<string, Tuple<ShaderFile, Action<UniformCollection, DrawContext>>> VertexFiles =
new Dictionary<string, Tuple<ShaderFile, Action<UniformCollection, DrawContext>>>();
static ShaderFile _extensionDefineFile = new ShaderFile("#define SM_SIMPLE_EXTENSION");
static SimpleShader()
{
VertexFiles.Add("basic", new Tuple<ShaderFile, Action<UniformCollection, DrawContext>>(
new ShaderFile(AssemblyUtility.ReadAssemblyFile("SM.Base.Shaders.SimpleShaderPresets.basic_vertex.glsl"))
{
StringOverrides = {["extension"] = "0"}
},
BasicSetUniforms
));
VertexFiles.Add("E_basic", new Tuple<ShaderFile, Action<UniformCollection, DrawContext>>(
new ShaderFile(AssemblyUtility.ReadAssemblyFile("SM.Base.Shaders.SimpleShaderPresets.basic_vertex.glsl"))
{
StringOverrides = {["extension"] = "1"}
},
BasicSetUniforms
));
VertexFiles.Add("instanced", new Tuple<ShaderFile, Action<UniformCollection, DrawContext>>(
new ShaderFile(
AssemblyUtility.ReadAssemblyFile("SM.Base.Shaders.SimpleShaderPresets.instanced_vertex.glsl"))
{
StringOverrides = { ["instanceMax"] = SMRenderer.MaxInstances.ToString(), ["extension"] = "0" }
},
InstancedSetUniforms
));
VertexFiles.Add("E_instanced", new Tuple<ShaderFile, Action<UniformCollection, DrawContext>>(
new ShaderFile(
AssemblyUtility.ReadAssemblyFile("SM.Base.Shaders.SimpleShaderPresets.instanced_vertex.glsl"))
{
StringOverrides = { ["instanceMax"] = SMRenderer.MaxInstances.ToString(), ["extension"] = "0" }
},
InstancedSetUniforms
));
}
static void BasicSetUniforms(UniformCollection uniforms, DrawContext context)
{
// Vertex Uniforms
uniforms["MVP"].SetMatrix4(context.Instances[0].ModelMatrix * context.ModelMatrix * context.View * context.World);
uniforms["MasterTextureMatrix"].SetMatrix3(context.Instances[0].TextureMatrix * context.TextureMatrix);
uniforms["HasVColor"]
.SetUniform1(context.Mesh.Attributes.Has("color"));
DrawObject(context.Mesh);
}
static void InstancedSetUniforms(UniformCollection uniforms, DrawContext context)
{
uniforms["MVP"].SetMatrix4(context.ModelMatrix * context.View * context.World);
uniforms["MasterTextureMatrix"].SetMatrix3(context.TextureMatrix);
uniforms["HasVColor"]
.SetUniform1(context.Mesh.Attributes.Has("color"));
UniformArray instances = uniforms.GetArray("Instances");
int shaderInstanceI = 0;
for (int i = 0; i < context.Instances.Count; i++)
{
if (shaderInstanceI > instances.Length - 1)
{
DrawObject(context.Mesh, instances.Length);
shaderInstanceI = 0;
}
var shaderInstance = instances[shaderInstanceI];
var instance = context.Instances[i];
if (instance == null) continue;
shaderInstance["ModelMatrix"].SetMatrix4(instance.ModelMatrix);
shaderInstance["TextureMatrix"].SetMatrix3(instance.TextureMatrix);
shaderInstanceI++;
}
DrawObject(context.Mesh, shaderInstanceI);
}
private string _vertexPreset;
public Action<UniformCollection, DrawContext> SetUniform;
public SimpleShader(string vertexPreset, string fragment, Action<UniformCollection, DrawContext> setUniform) : base(new ShaderFileCollection(VertexFiles[vertexPreset].Item1, new ShaderFile(fragment)))
{
_vertexPreset = vertexPreset;
SetUniform = setUniform;
}
public SimpleShader(string vertexPreset, string vertexExtension, string fragment,
Action<UniformCollection, DrawContext> setUniform) : base(new ShaderFileCollection(
new[] {VertexFiles["E_"+vertexPreset].Item1, new ShaderFile(vertexExtension)},
new[] {new ShaderFile(fragment),}))
{
_vertexPreset = vertexPreset;
SetUniform = setUniform;
}
protected override void DrawProcess(DrawContext context)
{
SetUniform?.Invoke(Uniforms, context);
VertexFiles[_vertexPreset].Item2(Uniforms, context);
}
}
}

View file

@ -0,0 +1,32 @@
#version 330
#define SM_SIMPLE_EXTENSION //!extension
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_Texture;
layout(location = 3) in vec4 a_Color;
uniform bool HasVColor;
uniform mat4 MVP;
uniform mat3 MasterTextureMatrix;
out vec3 v_VertexPosition;
out vec2 v_TexCoords;
out vec4 v_Color;
#if (SM_SIMPLE_EXTENSION == 1)
void v_Extension();
#endif
void main() {
v_Color = vec4(1);
if (HasVColor) v_Color = a_Color;
v_TexCoords = vec2(MasterTextureMatrix * vec3(a_Texture, 1));
v_VertexPosition = a_Position;
gl_Position = MVP * vec4(a_Position, 1);
#if (SM_SIMPLE_EXTENSION == 1)
v_Extension();
#endif
}

View file

@ -0,0 +1,39 @@
#version 330
#define maxInstances //!instanceMax
#define SM_SIMPLE_EXTENSION //!extension
struct Instance {
mat4 ModelMatrix;
mat3 TextureMatrix;
};
layout(location = 0) in vec3 a_Position;
layout(location = 1) in vec2 a_Texture;
layout(location = 3) in vec4 a_Color;
uniform mat4 MVP;
uniform mat3 MasterTextureMatrix;
uniform Instance[maxInstances] Instances;
uniform bool HasVColor;
out vec3 v_VertexPosition;
out vec2 v_TexCoords;
out vec4 v_Color;
#if (SM_SIMPLE_EXTENSION == 1)
void v_Extension();
#endif
void main() {
v_Color = vec4(1);
if (HasVColor) v_Color = a_Color;
v_TexCoords = vec2(MasterTextureMatrix * Instances[gl_InstanceID].TextureMatrix * vec3(a_Texture, 1));
v_VertexPosition = a_Position;
gl_Position = MVP * Instances[gl_InstanceID].ModelMatrix * vec4(a_Position, 1);
#if (SM_SIMPLE_EXTENSION == 1)
v_Extension();
#endif
}