diff --git a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj index da46e245..d04a9fa6 100644 --- a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj +++ b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj @@ -57,9 +57,9 @@ - + - + @@ -104,6 +104,7 @@ + @@ -184,6 +185,10 @@ {6899F0C9-70B9-4EB0-9DD3-E598D4BE3E35} ANX.Framework + + {EB8258E0-6741-4DB9-B756-1EBDF67B1ED6} + ANX.RenderSystem.Windows.GL3 + diff --git a/ANX.Framework.Content.Pipeline/EffectImporter.cs b/ANX.Framework.Content.Pipeline/EffectImporter.cs deleted file mode 100644 index 8e8749c4..00000000 --- a/ANX.Framework.Content.Pipeline/EffectImporter.cs +++ /dev/null @@ -1,34 +0,0 @@ -#region Using Statements -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using ANX.Framework.Content.Pipeline.Graphics; - -#endregion - -// This file is part of the ANX.Framework created by the -// "ANX.Framework developer group" and released under the Ms-PL license. -// For details see: http://anxframework.codeplex.com/license - -namespace ANX.Framework.Content.Pipeline -{ - [ContentImporter(new string[] { ".fx", ".fxg" })] - public class EffectImporter : ContentImporter - { - public EffectImporter() - { - } - - public override EffectContent Import(string filename, ContentImporterContext context) - { - EffectContent content = new EffectContent() - { - EffectCode = System.IO.File.ReadAllText(filename), - Identity = new ContentIdentity(filename, null, null), - }; - - return content; - } - } -} diff --git a/ANX.Framework.Content.Pipeline/Graphics/EffectContent.cs b/ANX.Framework.Content.Pipeline/Graphics/EffectContent.cs index 9049de1c..c841d79b 100644 --- a/ANX.Framework.Content.Pipeline/Graphics/EffectContent.cs +++ b/ANX.Framework.Content.Pipeline/Graphics/EffectContent.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using ANX.Framework.NonXNA; #endregion @@ -14,11 +15,13 @@ namespace ANX.Framework.Content.Pipeline.Graphics { public class EffectContent : ContentItem { - public EffectContent() + public string EffectCode { + get; + set; } - public string EffectCode + public EffectSourceLanguage SourceLanguage { get; set; diff --git a/ANX.Framework.Content.Pipeline/Importer/EffectImporter.cs b/ANX.Framework.Content.Pipeline/Importer/EffectImporter.cs new file mode 100644 index 00000000..5d6140f7 --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Importer/EffectImporter.cs @@ -0,0 +1,54 @@ +#region Using Statements +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ANX.Framework.Content.Pipeline.Graphics; +using System.IO; +using ANX.Framework.NonXNA; + +#endregion + +// This file is part of the ANX.Framework created by the +// "ANX.Framework developer group" and released under the Ms-PL license. +// For details see: http://anxframework.codeplex.com/license + +namespace ANX.Framework.Content.Pipeline +{ + [ContentImporter(new string[] { ".fx", ".fxg", ".hlsl", ".glsl" })] + public class EffectImporter : ContentImporter + { + public override EffectContent Import(string filename, ContentImporterContext context) + { + string fileExtension = Path.GetExtension(filename).ToLowerInvariant(); + EffectSourceLanguage sourceLanguage = EffectSourceLanguage.HLSL_FX; + + switch (fileExtension) + { + case ".fx": + sourceLanguage = EffectSourceLanguage.HLSL_FX; + break; + case ".fxg": + sourceLanguage = EffectSourceLanguage.GLSL_FX; + break; + case ".hlsl": + sourceLanguage = EffectSourceLanguage.HLSL; + break; + case ".glsl": + sourceLanguage = EffectSourceLanguage.GLSL; + break; + default: + throw new InvalidContentException("The EffectImporter is not able to import a file with extension '" + fileExtension + "'"); + } + + EffectContent content = new EffectContent() + { + EffectCode = System.IO.File.ReadAllText(filename), + Identity = new ContentIdentity(filename, null, null), + SourceLanguage = sourceLanguage, + }; + + return content; + } + } +} diff --git a/ANX.Framework.Content.Pipeline/FbxImporter.cs b/ANX.Framework.Content.Pipeline/Importer/FbxImporter.cs similarity index 100% rename from ANX.Framework.Content.Pipeline/FbxImporter.cs rename to ANX.Framework.Content.Pipeline/Importer/FbxImporter.cs diff --git a/ANX.Framework.Content.Pipeline/InvalidContentException.cs b/ANX.Framework.Content.Pipeline/InvalidContentException.cs new file mode 100644 index 00000000..7ebad62b --- /dev/null +++ b/ANX.Framework.Content.Pipeline/InvalidContentException.cs @@ -0,0 +1,20 @@ +#region Using Statements +using System; + +#endregion + +// This file is part of the ANX.Framework created by the +// "ANX.Framework developer group" and released under the Ms-PL license. +// For details see: http://anxframework.codeplex.com/license + +namespace ANX.Framework.Content.Pipeline +{ + public class InvalidContentException : Exception + { + public InvalidContentException(string message) + : base(message) + { + } + + } +} diff --git a/ANX.Framework.Content.Pipeline/Processors/CompiledEffectContent.cs b/ANX.Framework.Content.Pipeline/Processors/CompiledEffectContent.cs index 510255d2..965e71da 100644 --- a/ANX.Framework.Content.Pipeline/Processors/CompiledEffectContent.cs +++ b/ANX.Framework.Content.Pipeline/Processors/CompiledEffectContent.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; +using ANX.Framework.NonXNA; #endregion @@ -25,5 +26,11 @@ namespace ANX.Framework.Content.Pipeline.Processors { return effectCode; } + + public EffectSourceLanguage SourceLanguage + { + get; + set; + } } } diff --git a/ANX.Framework.Content.Pipeline/Processors/EffectProcessor.cs b/ANX.Framework.Content.Pipeline/Processors/EffectProcessor.cs index cc349d59..b74d1a2d 100644 --- a/ANX.Framework.Content.Pipeline/Processors/EffectProcessor.cs +++ b/ANX.Framework.Content.Pipeline/Processors/EffectProcessor.cs @@ -6,6 +6,7 @@ using System.Text; using ANX.Framework.Content.Pipeline.Graphics; using System.IO; using System.ComponentModel; +using ANX.RenderSystem.Windows.GL3; #endregion @@ -48,15 +49,31 @@ namespace ANX.Framework.Content.Pipeline.Processors public override CompiledEffectContent Process(EffectContent input, ContentProcessorContext context) { - HLSLCompiler compiler = hlslCompilerFactory.Compilers.Last(); + byte[] effectCompiledCode = null; - byte[] effectCompiledCode = compiler.Compile(input.EffectCode, DebugMode, TargetProfile); + if (input.SourceLanguage == NonXNA.EffectSourceLanguage.HLSL_FX) + { + HLSLCompiler compiler = hlslCompilerFactory.Compilers.Last(); + effectCompiledCode = compiler.Compile(input.EffectCode, DebugMode, TargetProfile); + } + else if (input.SourceLanguage == NonXNA.EffectSourceLanguage.GLSL_FX) + { + //TODO: parse and split the effect code and save two effect globs + // if we do it this way, we don't need to parse the glsl source at runtime when loading it. + + effectCompiledCode = ShaderHelper.SaveShaderCode(input.EffectCode); + } + else + { + throw new InvalidContentException("EffectProcessor is unable to process content with format '" + input.SourceLanguage.ToString() + "'"); + } return new CompiledEffectContent(effectCompiledCode) { Identity = input.Identity, Name = input.Name, - OpaqueData = input.OpaqueData + OpaqueData = input.OpaqueData, + SourceLanguage = input.SourceLanguage, }; } diff --git a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs index d51e59ab..aaf07c6a 100644 --- a/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs +++ b/ANX.Framework.Content.Pipeline/Serialization/Compiler/GraphicTypeWriters/EffectWriter.cs @@ -34,6 +34,7 @@ namespace ANX.Framework.Content.Pipeline.Serialization.Compiler } byte[] effectCode = value.GetEffectCode(); + output.Write((byte)value.SourceLanguage); // ANX Extensions !!! output.Write(effectCode.Length); output.Write(effectCode); } diff --git a/ANX.Framework/ANX.Framework.csproj b/ANX.Framework/ANX.Framework.csproj index 5db940fb..30f72a0e 100644 --- a/ANX.Framework/ANX.Framework.csproj +++ b/ANX.Framework/ANX.Framework.csproj @@ -414,6 +414,7 @@ + diff --git a/ANX.Framework/Content/ContentReader.cs b/ANX.Framework/Content/ContentReader.cs index b9291dd1..ce64d37d 100644 --- a/ANX.Framework/Content/ContentReader.cs +++ b/ANX.Framework/Content/ContentReader.cs @@ -124,7 +124,7 @@ namespace ANX.Framework.Content if (magicVA != 'A' || magicVN != 'N' || magicVX != 'X') { - throw new ContentLoadException("Not an ANX.Framework version 1.0 XNB file."); + throw new ContentLoadException("Not an ANX.Framework version 1.0 XNB file or this is an unsupported past XNA 4.0 XNB file."); } anxExtensions = true; diff --git a/ANX.Framework/Content/GraphicTypeReaders/EffectReader.cs b/ANX.Framework/Content/GraphicTypeReaders/EffectReader.cs index 8f02ce51..2709bc7f 100644 --- a/ANX.Framework/Content/GraphicTypeReaders/EffectReader.cs +++ b/ANX.Framework/Content/GraphicTypeReaders/EffectReader.cs @@ -18,6 +18,7 @@ namespace ANX.Framework.Content protected internal override Effect Read(ContentReader input, Effect existingInstance) { IServiceProvider service = input.ContentManager.ServiceProvider; + EffectSourceLanguage sourceLanguageFormat = EffectSourceLanguage.HLSL_FX; var rfc = service.GetService(typeof(IRenderSystemCreator)) as IRenderSystemCreator; if (rfc == null) @@ -31,6 +32,11 @@ namespace ANX.Framework.Content throw new ContentLoadException("Service not found IGraphicsDeviceService"); } + if (input.AnxExtensions) + { + sourceLanguageFormat = (EffectSourceLanguage)input.ReadByte(); + } + int totalLength = input.ReadInt32(); byte magicA = input.ReadByte(); @@ -47,7 +53,7 @@ namespace ANX.Framework.Content var memStream = new MemoryStream(effectCode); // the XNA Way - return new Effect(gds.GraphicsDevice, effectCode); + return new Effect(gds.GraphicsDevice, effectCode, sourceLanguageFormat); // the ANX Way //return rfc.CreateEffect(gds.GraphicsDevice, memStream); @@ -72,7 +78,7 @@ namespace ANX.Framework.Content case EffectProcessorOutputFormat.OPEN_GL3_GLSL: //return rfc.CreateEffect(gds.GraphicsDevice, new MemoryStream(vertexShaderByteCode, false), new MemoryStream(pixelShaderByteCode, false)); //return rfc.CreateEffect(gds.GraphicsDevice, new MemoryStream(effectByteCode, false)); - return new Effect(gds.GraphicsDevice, effectByteCode); + return new Effect(gds.GraphicsDevice, effectByteCode, sourceLanguageFormat); default: throw new NotImplementedException("loading of ANX-Effect format with type '" + format.ToString() + "' not yet implemented."); } diff --git a/ANX.Framework/Graphics/Effect.cs b/ANX.Framework/Graphics/Effect.cs index a19a1b73..f3aa9044 100644 --- a/ANX.Framework/Graphics/Effect.cs +++ b/ANX.Framework/Graphics/Effect.cs @@ -23,6 +23,7 @@ namespace ANX.Framework.Graphics private EffectTechnique currentTechnique; private EffectParameterCollection parameterCollection; private byte[] byteCode; + private EffectSourceLanguage sourceLanguage; #endregion // Private Members @@ -32,6 +33,11 @@ namespace ANX.Framework.Graphics } public Effect(GraphicsDevice graphicsDevice, byte[] byteCode) + : this(graphicsDevice, byteCode, EffectSourceLanguage.HLSL_FX) + { + } + + public Effect(GraphicsDevice graphicsDevice, byte[] byteCode, EffectSourceLanguage sourceLanguage) : base(graphicsDevice) { this.byteCode = new byte[byteCode.Length]; @@ -40,9 +46,11 @@ namespace ANX.Framework.Graphics base.GraphicsDevice.ResourceCreated += GraphicsDevice_ResourceCreated; base.GraphicsDevice.ResourceDestroyed += GraphicsDevice_ResourceDestroyed; - CreateNativeEffect(); + CreateNativeEffect(sourceLanguage); this.currentTechnique = this.techniqueCollection[0]; + + this.sourceLanguage = sourceLanguage; } ~Effect() @@ -60,7 +68,7 @@ namespace ANX.Framework.Graphics nativeEffect = null; } - CreateNativeEffect(); + CreateNativeEffect(this.sourceLanguage); } private void GraphicsDevice_ResourceDestroyed(object sender, ResourceDestroyedEventArgs e) @@ -83,7 +91,7 @@ namespace ANX.Framework.Graphics { if (nativeEffect == null) { - CreateNativeEffect(); + CreateNativeEffect(this.sourceLanguage); } return this.nativeEffect; @@ -132,12 +140,21 @@ namespace ANX.Framework.Graphics throw new NotImplementedException(); } - private void CreateNativeEffect() + private void CreateNativeEffect(EffectSourceLanguage sourceLanguage) { - this.nativeEffect = AddInSystemFactory.Instance.GetDefaultCreator().CreateEffect(GraphicsDevice, this, new MemoryStream(this.byteCode, false)); + IRenderSystemCreator creator = AddInSystemFactory.Instance.GetDefaultCreator(); - this.techniqueCollection = new EffectTechniqueCollection(this, this.nativeEffect); - this.parameterCollection = new EffectParameterCollection(this, this.nativeEffect); + if (creator.IsLanguageSupported(sourceLanguage)) + { + this.nativeEffect = creator.CreateEffect(GraphicsDevice, this, new MemoryStream(this.byteCode, false)); + + this.techniqueCollection = new EffectTechniqueCollection(this, this.nativeEffect); + this.parameterCollection = new EffectParameterCollection(this, this.nativeEffect); + } + else + { + throw new InvalidOperationException("couldn't create " + sourceLanguage.ToString() + " native effect using RenderSystem " + creator.Name); + } } } } diff --git a/ANX.Framework/NonXNA/EffectSourceLanguage.cs b/ANX.Framework/NonXNA/EffectSourceLanguage.cs new file mode 100644 index 00000000..fdbd7dae --- /dev/null +++ b/ANX.Framework/NonXNA/EffectSourceLanguage.cs @@ -0,0 +1,19 @@ +#region Using Statements +using System; + +#endregion + +// This file is part of the ANX.Framework created by the +// "ANX.Framework developer group" and released under the Ms-PL license. +// For details see: http://anxframework.codeplex.com/license + +namespace ANX.Framework.NonXNA +{ + public enum EffectSourceLanguage + { + HLSL, + HLSL_FX, + GLSL, + GLSL_FX, + } +} diff --git a/ANX.Framework/NonXNA/RenderSystem/IRenderSystemCreator.cs b/ANX.Framework/NonXNA/RenderSystem/IRenderSystemCreator.cs index d14f1161..fb452da0 100644 --- a/ANX.Framework/NonXNA/RenderSystem/IRenderSystemCreator.cs +++ b/ANX.Framework/NonXNA/RenderSystem/IRenderSystemCreator.cs @@ -35,6 +35,8 @@ namespace ANX.Framework.NonXNA INativeEffect CreateEffect(GraphicsDevice graphics, Effect managedEffect, Stream vertexShaderByteCode, Stream pixelShaderByteCode); + bool IsLanguageSupported(EffectSourceLanguage sourceLanguage); + INativeBlendState CreateBlendState(); INativeRasterizerState CreateRasterizerState(); INativeDepthStencilState CreateDepthStencilState(); diff --git a/RenderSystems/ANX.Framework.Windows.DX10/Creator.cs b/RenderSystems/ANX.Framework.Windows.DX10/Creator.cs index 153f0e06..895af477 100644 --- a/RenderSystems/ANX.Framework.Windows.DX10/Creator.cs +++ b/RenderSystems/ANX.Framework.Windows.DX10/Creator.cs @@ -222,5 +222,10 @@ namespace ANX.RenderSystem.Windows.DX10 AddInSystemFactory.Instance.PreventSystemChange(AddInType.RenderSystem); } #endregion - } + + public bool IsLanguageSupported(EffectSourceLanguage sourceLanguage) + { + return sourceLanguage == EffectSourceLanguage.HLSL_FX || sourceLanguage == EffectSourceLanguage.HLSL; + } + } } diff --git a/RenderSystems/ANX.Framework.Windows.GL3/Creator.cs b/RenderSystems/ANX.Framework.Windows.GL3/Creator.cs index 508b880c..2a63d02e 100644 --- a/RenderSystems/ANX.Framework.Windows.GL3/Creator.cs +++ b/RenderSystems/ANX.Framework.Windows.GL3/Creator.cs @@ -302,5 +302,11 @@ namespace ANX.RenderSystem.Windows.GL3 preferredDepthFormat, preferredMultiSampleCount, usage); } #endregion - } + + public bool IsLanguageSupported(EffectSourceLanguage sourceLanguage) + { + return sourceLanguage == EffectSourceLanguage.GLSL_FX || sourceLanguage == EffectSourceLanguage.GLSL; + } + + } } diff --git a/RenderSystems/ANX.RenderSystem.PsVita/Creator.cs b/RenderSystems/ANX.RenderSystem.PsVita/Creator.cs index 20bd3455..a6b4e330 100644 --- a/RenderSystems/ANX.RenderSystem.PsVita/Creator.cs +++ b/RenderSystems/ANX.RenderSystem.PsVita/Creator.cs @@ -136,5 +136,12 @@ namespace ANX.RenderSystem.PsVita { throw new NotImplementedException(); } + + public bool IsLanguageSupported(EffectSourceLanguage sourceLanguage) + { + //TODO: implement supported sourceLanguages + return false; + } + } } diff --git a/RenderSystems/ANX.RenderSystem.Windows.DX11/Creator.cs b/RenderSystems/ANX.RenderSystem.Windows.DX11/Creator.cs index ff65f7c6..b4a29970 100644 --- a/RenderSystems/ANX.RenderSystem.Windows.DX11/Creator.cs +++ b/RenderSystems/ANX.RenderSystem.Windows.DX11/Creator.cs @@ -218,5 +218,11 @@ namespace ANX.RenderSystem.Windows.DX11 return new RenderTarget2D_DX11(graphics, width, height, mipMap, preferredFormat, preferredDepthFormat, preferredMultiSampleCount, usage); } + + public bool IsLanguageSupported(EffectSourceLanguage sourceLanguage) + { + return sourceLanguage == EffectSourceLanguage.HLSL_FX || sourceLanguage == EffectSourceLanguage.HLSL; + } + } } diff --git a/Tools/ContentBuilder/Program.cs b/Tools/ContentBuilder/Program.cs index 04887c59..c82dd4f0 100644 --- a/Tools/ContentBuilder/Program.cs +++ b/Tools/ContentBuilder/Program.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using ANX.Framework.Content.Pipeline.Tasks; using ANX.Framework.Content.Pipeline; +using System.IO; #endregion @@ -29,14 +30,21 @@ namespace ContentBuilder { if (!arg.StartsWith("/") && !arg.StartsWith("-")) { - BuildItem buildItem = new BuildItem(); - buildItem.ImporterName = ImporterManager.GuessImporterByFileExtension(arg); - //TODO: set configured processor name - buildItem.SourceFilename = arg; - buildItem.AssetName = System.IO.Path.GetFileNameWithoutExtension(arg); - buildItem.OutputFilename = String.Format("{0}.xnb", buildItem.AssetName); + if (File.Exists(arg)) + { + BuildItem buildItem = new BuildItem(); + buildItem.ImporterName = ImporterManager.GuessImporterByFileExtension(arg); + //TODO: set configured processor name + buildItem.SourceFilename = arg; + buildItem.AssetName = System.IO.Path.GetFileNameWithoutExtension(arg); + buildItem.OutputFilename = String.Format("{0}.xnb", buildItem.AssetName); - itemsToBuild.Add(buildItem); + itemsToBuild.Add(buildItem); + } + else + { + buildContentTask.BuildLogger.LogMessage("could not find file '{0}' to import. skipping.", arg); + } } else {