From 163dadbe37ffde91326733264414dc87e5c3371b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Fri, 5 Mar 2021 16:40:45 +0100 Subject: [PATCH] Added EffectLibrary --- GlitchyEngine/src/Renderer/Effect.bf | 118 ++++++++++++++++++++++++++- Sandbox/src/SandboxApp.bf | 35 +++++--- 2 files changed, 136 insertions(+), 17 deletions(-) diff --git a/GlitchyEngine/src/Renderer/Effect.bf b/GlitchyEngine/src/Renderer/Effect.bf index ffd07aa..989a4a7 100644 --- a/GlitchyEngine/src/Renderer/Effect.bf +++ b/GlitchyEngine/src/Renderer/Effect.bf @@ -4,11 +4,97 @@ using System.Collections; namespace GlitchyEngine.Renderer { + public class EffectLibrary + { + private GraphicsContext _context ~ _?.ReleaseRef(); + private Dictionary _effects = new .() ~ delete _; + + private List _ownedStrings = new .() ~ DeleteContainerAndItems!(_); + + public this(GraphicsContext context) + { + _context = context..AddRef(); + } + + public ~this() + { + for(let pair in _effects) + { + pair.value.ReleaseRef(); + } + } + + public void Add(Effect effect, String effectName = null) + { + String name; + + if(effectName == null) + { + name = effect.Name; + } + else + { + name = new String(effectName); + _ownedStrings.Add(name); + } + + Log.EngineLogger.AssertDebug(!Exists(name), "Can't add two effects with the same name to library."); + + _effects.Add(name, effect..AddRef()); + } + + /** + * Loads the effect with the given file name. + * @param filepath The path to the effect file. + * @param effectName The optional custom effect name which will be used to identify the effect. + * @returns The loaded Effect. Note: This function will increment the reference counter of the effect, so the programmer must decrement it once it's not used anymore. + * If the return-value is not needed, use LoadNoRefInc instead. + */ + public Effect Load(String filepath, String effectName = null) + { + String name = effectName; + + if(name == null) + { + name = scope:: String(); + Path.GetFileNameWithoutExtension(filepath, name); + } + + Log.EngineLogger.AssertDebug(!Exists(name), "Can't add two effects with the same name to library."); + + Effect effect = new Effect(_context, filepath, name); + Add(effect); + + return effect; + } + + /** + * Loads the effect with the given file name. + * @param filepath The path to the effect file. + * @param effectName The optional custom effect name which will be used to identify the effect. + */ + public void LoadNoRefInc(String filepath, String effectName = null) + { + var v = Load(filepath, effectName); + v.ReleaseRef(); + } + + public Effect Get(String effectName) + { + Log.EngineLogger.AssertDebug(Exists(effectName), "Effect not found!"); + + return _effects.GetValue(effectName).Get()..AddRef(); + } + + public bool Exists(String effectName) => _effects.ContainsKey(effectName); + } + public class Effect : RefCounted { protected GraphicsContext _context ~ _?.ReleaseRef(); internal VertexShader _vs ~ _?.ReleaseRef(); internal PixelShader _ps ~ _?.ReleaseRef(); + protected String _name ~ delete _; BufferCollection _bufferCollection ~ delete _; @@ -41,6 +127,8 @@ namespace GlitchyEngine.Renderer public BufferCollection Buffers => _bufferCollection; public BufferVariableCollection Variables => _variables; + public String Name => _name; + public void ApplyChanges() { for(let buffer in _bufferCollection) @@ -65,13 +153,23 @@ namespace GlitchyEngine.Renderer { } - public this(GraphicsContext context, String filename, String vsEntry, String psEntry) + public this(GraphicsContext context, String filename, String vsEntry, String psEntry, String shaderName = null) { _context = context..AddRef(); CompileFromFile(filename, vsEntry, psEntry); + + if(shaderName == null) + { + _name = new String(shaderName); + } + else + { + _name = new String(); + Path.GetFileNameWithoutExtension(filename, _name); + } } - public this(GraphicsContext context, String filename) + public this(GraphicsContext context, String filename, String shaderName = null) { _context = context..AddRef(); @@ -83,13 +181,25 @@ namespace GlitchyEngine.Renderer Compile(fileContent, vsName, psName); MergeResources(); + + if(shaderName == null) + { + _name = new String(); + Path.GetFileNameWithoutExtension(filename, _name); + } + else + { + _name = new String(shaderName); + } } - public this(String vsPath, String vsEntry, String psPath, String psEntry) + public this(String shaderName, String vsPath, String vsEntry, String psPath, String psEntry) { Compile(vsPath, vsEntry, psPath, psEntry); + + _name = new String(shaderName); } - + private void CompileFromFile(String filename, String vsEntry, String psEntry) { let vs = Shader.FromFile!(_context, filename, vsEntry); diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index 1d8fe03..efac599 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -59,9 +59,6 @@ namespace Sandbox RasterizerState _rasterizerState ~ delete _; - Effect _effect ~ _?.ReleaseRef(); - Effect _textureEffect ~ _?.ReleaseRef(); - GraphicsContext _context ~ _?.ReleaseRef(); Texture2D _texture ~ _?.ReleaseRef(); @@ -70,6 +67,8 @@ namespace Sandbox BlendState _alphaBlendState ~ _?.ReleaseRef(); BlendState _opaqueBlendState ~ _?.ReleaseRef(); + EffectLibrary _effectLibrary ~ delete _; + private Vector3 CircleCoord(float angle) { return .(Math.Cos(angle), Math.Sin(angle), 0); @@ -80,13 +79,17 @@ namespace Sandbox { _context = Application.Get().Window.Context..AddRef(); - _effect = new Effect(_context, "content\\Shaders\\basicShader.hlsl"); + _effectLibrary = new EffectLibrary(_context); + + _effectLibrary.LoadNoRefInc("content\\Shaders\\basicShader.hlsl"); - _textureEffect = new Effect(_context, "content\\Shaders\\textureShader.hlsl"); + var textureEffect = _effectLibrary.Load("content\\Shaders\\textureShader.hlsl"); // Create Input Layout - _vertexLayout = new VertexLayout(_context, VertexColorTexture.VertexElements, _textureEffect.VertexShader); + _vertexLayout = new VertexLayout(_context, VertexColorTexture.VertexElements, textureEffect.VertexShader); + + textureEffect.ReleaseRef(); // Create hexagon { @@ -239,29 +242,35 @@ namespace Sandbox _opaqueBlendState.Bind(); + var basicEffect = _effectLibrary.Get("basicShader"); + var textureEffect = _effectLibrary.Get("textureShader"); + for(int x < 20) for(int y < 20) { if((x + y) % 2 == 0) - _effect.Variables["BaseColor"].SetData(_squareColor0); + basicEffect.Variables["BaseColor"].SetData(_squareColor0); else - _effect.Variables["BaseColor"].SetData(_squareColor1); + basicEffect.Variables["BaseColor"].SetData(_squareColor1); Matrix transform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f); - Renderer.Submit(_quadGeometryBinding, _effect, transform); + Renderer.Submit(_quadGeometryBinding, basicEffect, transform); } - _effect.Variables["BaseColor"].SetData(_squareColor1); - + basicEffect.Variables["BaseColor"].SetData(_squareColor1); + _texture.Bind(); - Renderer.Submit(_quadGeometryBinding, _textureEffect, .Scaling(1.5f)); + Renderer.Submit(_quadGeometryBinding, textureEffect, .Scaling(1.5f)); _alphaBlendState.Bind(); _ge_logo.Bind(); - Renderer.Submit(_quadGeometryBinding, _textureEffect, .Scaling(1.5f)); + Renderer.Submit(_quadGeometryBinding, textureEffect, .Scaling(1.5f)); Renderer.EndScene(); + + basicEffect.ReleaseRef(); + textureEffect.ReleaseRef(); } ColorRGBA _squareColor0 = ColorRGBA.CornflowerBlue;