From acea7b2e728787a0d83bbf83c8c1f042d2c32e7e Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Mon, 3 Jun 2024 10:15:45 +0800 Subject: + plugins project --- .../Effects/EffectResource.cs | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 Plugins/MonoGame.Extended/source/MonoGame.Extended.Graphics/Effects/EffectResource.cs (limited to 'Plugins/MonoGame.Extended/source/MonoGame.Extended.Graphics/Effects/EffectResource.cs') diff --git a/Plugins/MonoGame.Extended/source/MonoGame.Extended.Graphics/Effects/EffectResource.cs b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Graphics/Effects/EffectResource.cs new file mode 100644 index 0000000..43bd535 --- /dev/null +++ b/Plugins/MonoGame.Extended/source/MonoGame.Extended.Graphics/Effects/EffectResource.cs @@ -0,0 +1,119 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace MonoGame.Extended.Graphics.Effects +{ + /// + /// Reperesents the bytecode of an that is encapsulated inside a compiled assembly. + /// + /// + /// + /// Files that are encapsulated inside a compiled assembly are commonly known as Manifiest or embedded resources. + /// Since embedded resources are added to the assembly at compiled time, they can not be accidentally deleted or + /// misplaced. However, if the file needs to be changed, the assembly will need to be re-compiled with the changed + /// file. + /// + /// + /// To add an embedded resource file to an assembly, first add it to the project and then change the Build Action + /// in the Properties of the file to Embedded Resource. The next time the project is compiled, the + /// compiler will add the file to the assembly as an embedded resource. The compiler adds namespace(s) to the + /// embedded resource so it matches with the path of where the file was added to the project. + /// + /// + public class EffectResource + { + private static EffectResource _defaultEffect; + private static string _shaderExtension; + + /// + /// Gets the embedded into the MonoGame.Extended.Graphics library. + /// + public static EffectResource DefaultEffect => _defaultEffect ?? (_defaultEffect = new EffectResource($"MonoGame.Extended.Graphics.Effects.Resources.DefaultEffect.{_shaderExtension}.mgfxo")); + + static EffectResource() + { + DetermineShaderExtension(); + } + + private static void DetermineShaderExtension() + { + // use reflection to figure out if Shader.Profile is OpenGL (0) or DirectX (1), + // may need to be changed / fixed for future shader profiles + + var assembly = typeof(Game).GetTypeInfo().Assembly; + Debug.Assert(assembly != null); + + var shaderType = assembly.GetType("Microsoft.Xna.Framework.Graphics.Shader"); + Debug.Assert(shaderType != null); + var shaderTypeInfo = shaderType.GetTypeInfo(); + Debug.Assert(shaderTypeInfo != null); + + // https://github.com/MonoGame/MonoGame/blob/develop/MonoGame.Framework/Graphics/Shader/Shader.cs#L47 + var profileProperty = shaderTypeInfo.GetDeclaredProperty("Profile"); + var value = (int)profileProperty.GetValue(null); + + switch (value) + { + case 0: + // OpenGL + _shaderExtension = "ogl"; + break; + case 1: + // DirectX + _shaderExtension = "dx11"; + break; + default: + throw new InvalidOperationException("Unknown shader profile."); + } + } + + private readonly string _resourceName; + private volatile byte[] _bytecode; + private readonly Assembly _assembly; + + /// + /// Gets the bytecode of the file. + /// + /// + /// The bytecode of the file. + /// + public byte[] Bytecode + { + get + { + if (_bytecode != null) + return _bytecode; + + lock (this) + { + if (_bytecode != null) + return _bytecode; + + var stream = _assembly.GetManifestResourceStream(_resourceName); + using (var memoryStream = new MemoryStream()) + { + stream.CopyTo(memoryStream); + _bytecode = memoryStream.ToArray(); + } + } + + return _bytecode; + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The name of the embedded resource. This must include the namespace(s). + /// The assembly which the embedded resource is apart of. + public EffectResource(string resourceName, Assembly assembly = null) + { + _resourceName = resourceName; + _assembly = assembly ?? typeof(EffectResource).GetTypeInfo().Assembly; + } + } +} \ No newline at end of file -- cgit v1.1-26-g67d0