diff --git a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj index b0296f6f..e3b162d9 100644 --- a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj +++ b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline.csproj @@ -34,6 +34,7 @@ + diff --git a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_Linux.csproj b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_Linux.csproj index 8d02a7b5..a72dc7ed 100644 --- a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_Linux.csproj +++ b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_Linux.csproj @@ -34,6 +34,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_PSVita.csproj b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_PSVita.csproj index 9958592f..23c288f7 100644 --- a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_PSVita.csproj +++ b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_PSVita.csproj @@ -34,6 +34,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_WindowsMetro.csproj b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_WindowsMetro.csproj index d346edae..2e4cd1b1 100644 --- a/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_WindowsMetro.csproj +++ b/ANX.Framework.Content.Pipeline/ANX.Framework.Content.Pipeline_WindowsMetro.csproj @@ -36,6 +36,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ANX.Framework.Content.Pipeline/Graphics/AnimationKeyframe.cs b/ANX.Framework.Content.Pipeline/Graphics/AnimationKeyframe.cs index 4fd83a4e..f1b8c876 100644 --- a/ANX.Framework.Content.Pipeline/Graphics/AnimationKeyframe.cs +++ b/ANX.Framework.Content.Pipeline/Graphics/AnimationKeyframe.cs @@ -1,10 +1,4 @@ -#region Using Statements -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -#endregion +using System; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. @@ -12,40 +6,59 @@ using System.Text; namespace ANX.Framework.Content.Pipeline.Graphics { - public sealed class AnimationKeyframe : IComparable - { - private TimeSpan time; - private Matrix transform; + public sealed class AnimationKeyframe : IComparable + { + #region Private + [ContentSerializer(ElementName = "Time")] + private TimeSpan time; + [ContentSerializer(ElementName = "Transform")] + private Matrix transform; + #endregion - public AnimationKeyframe(TimeSpan time, Matrix transform) - { - this.time = time; - this.transform = transform; - } + #region Public + [ContentSerializerIgnore] + public TimeSpan Time + { + get + { + return time; + } + } - public TimeSpan Time - { - get - { - return this.time; - } - } + [ContentSerializerIgnore] + public Matrix Transform + { + get + { + return transform; + } + set + { + transform = value; + } + } + #endregion - public Matrix Transform - { - get - { - return this.transform; - } - set - { - this.transform = value; - } - } + #region Constructor + /// + /// The default constructor is hidden. + /// + private AnimationKeyframe() + { + } - public int CompareTo(AnimationKeyframe other) - { - return time.CompareTo(other.time); - } - } + public AnimationKeyframe(TimeSpan setTime, Matrix setTransform) + { + time = setTime; + transform = setTransform; + } + #endregion + + #region CompareTo + public int CompareTo(AnimationKeyframe other) + { + return time.CompareTo(other.time); + } + #endregion + } } diff --git a/ANX.Framework.Content.Pipeline/Graphics/BoneWeight.cs b/ANX.Framework.Content.Pipeline/Graphics/BoneWeight.cs new file mode 100644 index 00000000..e478979d --- /dev/null +++ b/ANX.Framework.Content.Pipeline/Graphics/BoneWeight.cs @@ -0,0 +1,52 @@ +using System; + +// 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.Graphics +{ + public struct BoneWeight + { + #region Private + private string boneName; + private float weight; + #endregion + + #region Public + public string BoneName + { + get + { + return boneName; + } + } + + public float Weight + { + get + { + return weight; + } + } + #endregion + + #region Constructor + public BoneWeight(string boneName, float weight) + { + if (string.IsNullOrEmpty(boneName)) + { + throw new ArgumentNullException("boneName"); + } + + if (weight < 0f || weight > 1f) + { + throw new ArgumentOutOfRangeException("weight"); + } + + this.boneName = boneName; + this.weight = weight; + } + #endregion + } +} diff --git a/ANX.Framework.ContentPipeline/EffectProcessor.cs b/ANX.Framework.ContentPipeline/EffectProcessor.cs index 4348642d..aadefe9b 100644 --- a/ANX.Framework.ContentPipeline/EffectProcessor.cs +++ b/ANX.Framework.ContentPipeline/EffectProcessor.cs @@ -39,10 +39,10 @@ namespace ANX.Framework.ContentPipeline case EffectProcessorOutputFormat.XNA_BYTE_CODE: return processor.Process(input, context); case EffectProcessorOutputFormat.DX10_HLSL: - DX10_EffectProcessor dx10EffectProcessor = new DX10_EffectProcessor(); + var dx10EffectProcessor = new DX10_EffectProcessor(); return dx10EffectProcessor.Process(input, context); case EffectProcessorOutputFormat.OPEN_GL3_GLSL: - GL3_EffectProcessor gl3EffectProcessor = new GL3_EffectProcessor(); + var gl3EffectProcessor = new GL3_EffectProcessor(); return gl3EffectProcessor.Process(input, context); default: throw new NotSupportedException("Currently it is not possible to create effect with format '" + outputFormat.ToString() + "'"); diff --git a/ANX.Framework.sln b/ANX.Framework.sln index 16b5e169..4adad981 100644 --- a/ANX.Framework.sln +++ b/ANX.Framework.sln @@ -158,6 +158,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.PlatformSystem.PsVita", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.Framework.Content.Pipeline", "ANX.Framework.Content.Pipeline\ANX.Framework.Content.Pipeline.csproj", "{2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParser", "Tools\HLSLParser\HLSLParser\HLSLParser.csproj", "{9588B0C3-E03A-4C71-89A4-2C8685D426F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParserTests", "Tools\HLSLParser\HLSLParserTests\HLSLParserTests.csproj", "{F9177943-1590-49AE-987D-D6FAE30D96DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -596,6 +600,26 @@ Global {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|x86.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|x86.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|x86.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|x86.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -604,6 +628,8 @@ Global {9D8DC781-2E0D-4348-BAD9-745F91428A3F} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {B5209A04-B2F8-4033-A5E7-545BE771214C} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {D73E5FF4-AE88-4637-8159-120FBDA564BF} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {9588B0C3-E03A-4C71-89A4-2C8685D426F1} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {F9177943-1590-49AE-987D-D6FAE30D96DD} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {5BE49183-2F6F-4527-AC90-D816911FCF90} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {EB8258E0-6741-4DB9-B756-1EBDF67B1ED6} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {B30DE9C2-0926-46B6-8351-9AF276C472D5} = {D421509A-9AE3-4D7E-881B-EAFED598B028} diff --git a/ANX.Framework_Linux.sln b/ANX.Framework_Linux.sln index ba9af734..a0f1c419 100644 --- a/ANX.Framework_Linux.sln +++ b/ANX.Framework_Linux.sln @@ -158,6 +158,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.PlatformSystem.PsVita", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.Framework.Content.Pipeline", "ANX.Framework.Content.Pipeline\ANX.Framework.Content.Pipeline_Linux.csproj", "{2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParser", "Tools\HLSLParser\HLSLParser\HLSLParser.csproj", "{9588B0C3-E03A-4C71-89A4-2C8685D426F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParserTests", "Tools\HLSLParser\HLSLParserTests\HLSLParserTests.csproj", "{F9177943-1590-49AE-987D-D6FAE30D96DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -596,6 +600,26 @@ Global {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|x86.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|x86.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|x86.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|x86.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -604,6 +628,8 @@ Global {9D8DC781-2E0D-4348-BAD9-745F91428A3F} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {B5209A04-B2F8-4033-A5E7-545BE771214C} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {D73E5FF4-AE88-4637-8159-120FBDA564BF} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {9588B0C3-E03A-4C71-89A4-2C8685D426F1} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {F9177943-1590-49AE-987D-D6FAE30D96DD} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {5BE49183-2F6F-4527-AC90-D816911FCF90} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {EB8258E0-6741-4DB9-B756-1EBDF67B1ED6} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {B30DE9C2-0926-46B6-8351-9AF276C472D5} = {D421509A-9AE3-4D7E-881B-EAFED598B028} diff --git a/ANX.Framework_PSVita.sln b/ANX.Framework_PSVita.sln index 3cab5b78..40f36fa4 100644 --- a/ANX.Framework_PSVita.sln +++ b/ANX.Framework_PSVita.sln @@ -158,6 +158,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.PlatformSystem.PsVita", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.Framework.Content.Pipeline", "ANX.Framework.Content.Pipeline\ANX.Framework.Content.Pipeline_PSVita.csproj", "{2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParser", "Tools\HLSLParser\HLSLParser\HLSLParser.csproj", "{9588B0C3-E03A-4C71-89A4-2C8685D426F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParserTests", "Tools\HLSLParser\HLSLParserTests\HLSLParserTests.csproj", "{F9177943-1590-49AE-987D-D6FAE30D96DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -596,6 +600,26 @@ Global {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|x86.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|x86.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|x86.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|x86.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -604,6 +628,8 @@ Global {9D8DC781-2E0D-4348-BAD9-745F91428A3F} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {B5209A04-B2F8-4033-A5E7-545BE771214C} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {D73E5FF4-AE88-4637-8159-120FBDA564BF} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {9588B0C3-E03A-4C71-89A4-2C8685D426F1} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {F9177943-1590-49AE-987D-D6FAE30D96DD} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {5BE49183-2F6F-4527-AC90-D816911FCF90} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {EB8258E0-6741-4DB9-B756-1EBDF67B1ED6} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {B30DE9C2-0926-46B6-8351-9AF276C472D5} = {D421509A-9AE3-4D7E-881B-EAFED598B028} diff --git a/ANX.Framework_WindowsMetro.sln b/ANX.Framework_WindowsMetro.sln index 91dadec2..224778db 100644 --- a/ANX.Framework_WindowsMetro.sln +++ b/ANX.Framework_WindowsMetro.sln @@ -158,6 +158,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.PlatformSystem.PsVita", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ANX.Framework.Content.Pipeline", "ANX.Framework.Content.Pipeline\ANX.Framework.Content.Pipeline_WindowsMetro.csproj", "{2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParser", "Tools\HLSLParser\HLSLParser\HLSLParser.csproj", "{9588B0C3-E03A-4C71-89A4-2C8685D426F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParserTests", "Tools\HLSLParser\HLSLParserTests\HLSLParserTests.csproj", "{F9177943-1590-49AE-987D-D6FAE30D96DD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -596,6 +600,26 @@ Global {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|Mixed Platforms.Build.0 = Release|Any CPU {2DAFDFC1-223B-4741-87BB-BE3D0A7617DB}.Release|x86.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|x86.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|x86.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|x86.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Mixed Platforms.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|x86.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -604,6 +628,8 @@ Global {9D8DC781-2E0D-4348-BAD9-745F91428A3F} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {B5209A04-B2F8-4033-A5E7-545BE771214C} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {D73E5FF4-AE88-4637-8159-120FBDA564BF} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {9588B0C3-E03A-4C71-89A4-2C8685D426F1} = {B24A8593-562A-4A25-BB08-46C163F10F3F} + {F9177943-1590-49AE-987D-D6FAE30D96DD} = {B24A8593-562A-4A25-BB08-46C163F10F3F} {5BE49183-2F6F-4527-AC90-D816911FCF90} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {EB8258E0-6741-4DB9-B756-1EBDF67B1ED6} = {D421509A-9AE3-4D7E-881B-EAFED598B028} {B30DE9C2-0926-46B6-8351-9AF276C472D5} = {D421509A-9AE3-4D7E-881B-EAFED598B028} diff --git a/Tools/HLSLParser/HLSLParser.sln b/Tools/HLSLParser/HLSLParser.sln new file mode 100644 index 00000000..d9ac7c5f --- /dev/null +++ b/Tools/HLSLParser/HLSLParser.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParser", "HLSLParser\HLSLParser.csproj", "{9588B0C3-E03A-4C71-89A4-2C8685D426F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HLSLParserTests", "HLSLParserTests\HLSLParserTests.csproj", "{F9177943-1590-49AE-987D-D6FAE30D96DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9588B0C3-E03A-4C71-89A4-2C8685D426F1}.Release|Any CPU.Build.0 = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9177943-1590-49AE-987D-D6FAE30D96DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Tools/HLSLParser/HLSLParser.suo b/Tools/HLSLParser/HLSLParser.suo new file mode 100644 index 00000000..676ec5ac Binary files /dev/null and b/Tools/HLSLParser/HLSLParser.suo differ diff --git a/Tools/HLSLParser/HLSLParser/CommentRemover.cs b/Tools/HLSLParser/HLSLParser/CommentRemover.cs new file mode 100644 index 00000000..3bcc51ec --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/CommentRemover.cs @@ -0,0 +1,89 @@ +using System; + +namespace HLSLParser +{ + public static class CommentRemover + { + #region Remove + public static string Remove(string source) + { + if (source == null) + { + return null; + } + + source = RemoveMultilineComments(source); + source = RemoveSingleLineComments(source); + + return source; + } + #endregion + + #region RemoveMultilineComments + private static string RemoveMultilineComments(string source) + { + int currentIndex = 0; + int textLength = source.Length; + while (currentIndex < textLength) + { + currentIndex = source.IndexOf("/*", currentIndex); + if (currentIndex == -1) + { + break; + } + + int endIndex = source.IndexOf("*/", currentIndex); + source = source.Remove(currentIndex, endIndex - currentIndex + 2); + textLength = source.Length; + } + return source; + } + #endregion + + #region RemoveSingleLineComments + private static string RemoveSingleLineComments(string source) + { + string[] lines = SplitLines(source); + + for (int index = 0; index < lines.Length; index++) + { + string line = lines[index]; + int commentIndex = line.IndexOf("//"); + if (commentIndex == -1) + continue; + + lines[index] = line.Substring(0, commentIndex); + } + + return MergeLines(lines); + } + #endregion + + #region SplitLines + internal static string[] SplitLines(string source) + { + source = source.Replace('\r', '\n'); + return source.Split(new char[] { '\n' }, + StringSplitOptions.RemoveEmptyEntries); + } + #endregion + + #region MergeLines + internal static string MergeLines(string[] lines) + { + string result = ""; + + foreach (string line in lines) + { + if (line == null) + continue; + + if (String.IsNullOrEmpty(line.Trim()) == false) + result += line + "\n"; + } + + return result.TrimEnd('\n'); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/EffectBuffer.cs b/Tools/HLSLParser/HLSLParser/EffectBuffer.cs new file mode 100644 index 00000000..e57333ee --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/EffectBuffer.cs @@ -0,0 +1,58 @@ +using System; + +namespace HLSLParser +{ + public class EffectBuffer + { + #region Public + public string Name + { + get; + private set; + } + + public string Type + { + get; + private set; + } + #endregion + + #region Constructor + public EffectBuffer(ParseTextWalker walker) + { + string text = walker.Text; + + int typeStartIndex = text.IndexOf('<') + 1; + int typeEndIndex = text.IndexOf('>'); + Type = text.Substring(typeStartIndex, typeEndIndex - typeStartIndex); + + typeEndIndex++; + + int semicolonIndex = text.IndexOf(';'); + Name = text.Substring(typeEndIndex, semicolonIndex - typeEndIndex).Trim(); + + walker.Seek(semicolonIndex + 1); + } + #endregion + + #region ParseIfBuffer + public static EffectBuffer ParseIfBuffer(ParseTextWalker walker) + { + if (walker.Text.StartsWith("Buffer")) + { + return new EffectBuffer(walker); + } + + return null; + } + #endregion + + #region ToString + public override string ToString() + { + return "Buffer<" + Type + "> " + Name + ";"; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/EffectFile.cs b/Tools/HLSLParser/HLSLParser/EffectFile.cs new file mode 100644 index 00000000..8923707c --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/EffectFile.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.IO; + +namespace HLSLParser +{ + public class EffectFile + { + #region Public + public string Source + { + get; + private set; + } + + public string Result; + + public List Variables + { + get; + private set; + } + + public List Structures + { + get; + private set; + } + + public List TypeDefs + { + get; + private set; + } + + public List Techniques + { + get; + private set; + } + + public List Buffers + { + get; + private set; + } + + public List Samplers + { + get; + private set; + } + + public List Methods + { + get; + private set; + } + #endregion + + #region Constructor + public EffectFile(string filepath) + { + Source = File.ReadAllText(filepath); + Variables = new List(); + Structures = new List(); + TypeDefs = new List(); + Techniques = new List(); + Buffers = new List(); + Samplers = new List(); + Methods = new List(); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/HLSLParser.csproj b/Tools/HLSLParser/HLSLParser/HLSLParser.csproj new file mode 100644 index 00000000..051e8bf2 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/HLSLParser.csproj @@ -0,0 +1,59 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {9588B0C3-E03A-4C71-89A4-2C8685D426F1} + Library + Properties + HLSLParser + HLSLParser + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Tools/HLSLParser/HLSLParser/Method.cs b/Tools/HLSLParser/HLSLParser/Method.cs new file mode 100644 index 00000000..dd6a5445 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Method.cs @@ -0,0 +1,149 @@ +using System; + +namespace HLSLParser +{ + public class Method + { + #region Public + public string StorageClass + { + get; + private set; + } + + public string ReturnType + { + get; + private set; + } + + public string Name + { + get; + private set; + } + + public string Semantic + { + get; + private set; + } + + public string Arguments + { + get; + private set; + } + + public string Body + { + get; + private set; + } + #endregion + + #region Constructor + public Method(ParseTextWalker walker) + { + string text = walker.Text; + if (text.StartsWith("inline")) + { + StorageClass = "inline"; + walker.Seek("inline".Length); + text = walker.Text; + } + + int indexOfOpenParenthesis = text.IndexOf('('); + int indexOfCloseParenthesis = text.IndexOf(')'); + + string headerPart = text.Substring(0, indexOfOpenParenthesis).Trim(); + headerPart = walker.RemoveUnneededChars(headerPart); + + string[] parts = headerPart.Split(new char[] { ' ' }, + StringSplitOptions.RemoveEmptyEntries); + + ReturnType = parts[0].Trim(); + Name = parts[1].Trim(); + + Arguments = text.Substring(indexOfOpenParenthesis + 1, + indexOfCloseParenthesis - indexOfOpenParenthesis - 1); + + walker.Seek(indexOfCloseParenthesis + 1); + text = walker.Text; + + int indexOfMethodBodyStart = text.IndexOf('{'); + + if (text.StartsWith(":")) + { + Semantic = text.Substring(1, indexOfMethodBodyStart - 1).Trim(); + Semantic = walker.RemoveUnneededChars(Semantic); + } + + walker.Seek(indexOfMethodBodyStart + 1); + + GetMethodBody(walker); + } + #endregion + + #region GetMethodBody + private void GetMethodBody(ParseTextWalker walker) + { + string text = walker.Text; + + int numberOfOpenBraces = 0; + int searchBodyEndIndex = 0; + while (searchBodyEndIndex < text.Length) + { + char currentChar = text[searchBodyEndIndex]; + if (currentChar == '{') + numberOfOpenBraces++; + else if (currentChar == '}') + numberOfOpenBraces--; + + if (numberOfOpenBraces == -1) + break; + + searchBodyEndIndex++; + } + + Body = text.Substring(0, searchBodyEndIndex - 1); + Body = Body.TrimEnd('\n', '\r', '\t'); + + walker.Seek(searchBodyEndIndex + 1); + } + #endregion + + #region ParseIfMethod + public static Method ParseIfMethod(ParseTextWalker walker) + { + if(walker.Text.StartsWith("inline ") || + CheckIfMethodHeaderExists(walker)) + { + return new Method(walker); + } + + return null; + } + #endregion + + #region CheckIfMethodHeaderExists + private static bool CheckIfMethodHeaderExists(ParseTextWalker walker) + { + string text = walker.Text; + int indexOfOpenParenthesis = text.IndexOf('('); + if (indexOfOpenParenthesis == -1) + return false; + + string headerPart = text.Substring(0, indexOfOpenParenthesis).Trim(); + headerPart = headerPart.Replace("\n", ""); + headerPart = headerPart.Replace("\r", ""); + headerPart = headerPart.Replace("\t", ""); + + string[] parts = headerPart.Split(new char[] { ' ' }, + StringSplitOptions.RemoveEmptyEntries); + + return parts.Length == 2; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/ParseTextWalker.cs b/Tools/HLSLParser/HLSLParser/ParseTextWalker.cs new file mode 100644 index 00000000..e09a4ef0 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/ParseTextWalker.cs @@ -0,0 +1,36 @@ +using System; + +namespace HLSLParser +{ + public class ParseTextWalker + { + public string Text + { + get; + private set; + } + + public ParseTextWalker(string setText) + { + Text = setText; + Seek(0); + } + + public void Seek(int length) + { + Text = Text.Substring(length); + string text = Text; + text = text.TrimStart(' ', '\n', '\r', '\t'); + length = Text.Length - text.Length; + Text = Text.Substring(length); + } + + public string RemoveUnneededChars(string text) + { + text = text.Replace("\n", ""); + text = text.Replace("\r", ""); + text = text.Replace("\t", ""); + return text; + } + } +} diff --git a/Tools/HLSLParser/HLSLParser/Parser.cs b/Tools/HLSLParser/HLSLParser/Parser.cs new file mode 100644 index 00000000..2d612afb --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Parser.cs @@ -0,0 +1,118 @@ +using System; +using System.IO; + +namespace HLSLParser +{ + /// + /// Spec: + /// http://msdn.microsoft.com/en-us/library/windows/desktop/bb509615%28v=vs.85%29.aspx + /// + public class Parser + { + #region Public + public EffectFile Effect + { + get; + private set; + } + #endregion + + #region Load + public void Load(string filepath) + { + ValidateFilepath(filepath); + + Effect = new EffectFile(filepath); + } + #endregion + + #region Parse + public void Parse() + { + Effect.Result = CommentRemover.Remove(Effect.Source); + + WalkText(); + } + #endregion + + #region WalkText + private void WalkText() + { + var textWalker = new ParseTextWalker(Effect.Result); + + while (textWalker.Text.Length > 0) + { + int beforeLength = textWalker.Text.Length; + + var newMethod = Method.ParseIfMethod(textWalker); + if (newMethod != null) + { + Effect.Methods.Add(newMethod); + continue; + } + + var newStruct = Structure.ParseIfStructure(textWalker); + if (newStruct != null) + { + Effect.Structures.Add(newStruct); + continue; + } + + var newTypeDef = TypeDef.ParseIfTypeDef(textWalker); + if (newTypeDef != null) + { + Effect.TypeDefs.Add(newTypeDef); + continue; + } + + var result = Sampler.ParseIfSampler(textWalker); + if (result != null) + { + Effect.Samplers.Add(result); + continue; + } + + var newTechnique = Technique.ParseIfTechnique(textWalker); + if (newTechnique != null) + { + Effect.Techniques.Add(newTechnique); + continue; + } + + var newBuffer = EffectBuffer.ParseIfBuffer(textWalker); + if (newBuffer != null) + { + Effect.Buffers.Add(newBuffer); + continue; + } + + var newVariable = Variable.ParseIfVariable(textWalker); + if (newVariable != null) + { + Effect.Variables.Add(newVariable); + continue; + } + + if (textWalker.Text.Length == beforeLength) + textWalker.Seek(1); + } + } + #endregion + + #region ValidateFilepath + private void ValidateFilepath(string filepath) + { + if (String.IsNullOrEmpty(filepath)) + { + throw new ArgumentException("filepath"); + } + + if (File.Exists(filepath) == false) + { + throw new FileNotFoundException( + "Unable to load missing file '" + filepath + "'!"); + } + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/Pass.cs b/Tools/HLSLParser/HLSLParser/Pass.cs new file mode 100644 index 00000000..d4785872 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Pass.cs @@ -0,0 +1,134 @@ +using System; + +namespace HLSLParser +{ + public class Pass + { + #region Public + public string Name + { + get; + private set; + } + + public string VertexShader + { + get; + private set; + } + + public string PixelShader + { + get; + private set; + } + #endregion + + #region Constructor + public Pass(ParseTextWalker walker) + { + string text = walker.Text; + + int indexOfNameStart = text.IndexOf(' ') + 1; + int indexOfNameEnd = text.IndexOf('{'); + + Name = text.Substring(indexOfNameStart, indexOfNameEnd - indexOfNameStart); + Name = Name.TrimEnd('\n', '\r', '\t', ' '); + + string passContentText = text.Substring(indexOfNameEnd + 1); + if (text.Contains("SetVertexShader")) + { + passContentText = passContentText.Replace("\t", "").Replace(" ", ""); + passContentText = passContentText.Replace(",", ", "); + ParseDx10Pass(passContentText); + } + else + { + ParseDx9Pass(passContentText); + } + + walker.Seek(text.IndexOf('}') + 1); + } + #endregion + + #region ParseDx10Pass + private void ParseDx10Pass(string text) + { + int indexOfVertexShaderStart = text.IndexOf("SetVertexShader(") + + "SetVertexShader(".Length; + int indexOfVertexShaderEnd = text.IndexOf(");", indexOfVertexShaderStart); + VertexShader = text.Substring(indexOfVertexShaderStart, + indexOfVertexShaderEnd - indexOfVertexShaderStart); + + int indexOfPixelShaderStart = text.IndexOf("SetPixelShader(") + + "SetPixelShader(".Length; + int indexOfPixelShaderEnd = text.IndexOf(");", indexOfPixelShaderStart); + PixelShader = text.Substring(indexOfPixelShaderStart, + indexOfPixelShaderEnd - indexOfPixelShaderStart); + } + #endregion + + #region ParseDx9Pass + private void ParseDx9Pass(string text) + { + int indexOfVertexShaderStart = text.IndexOf("VertexShader"); + indexOfVertexShaderStart = text.IndexOf("compile ", indexOfVertexShaderStart); + int indexOfVertexShaderEnd = text.IndexOf(';', indexOfVertexShaderStart); + VertexShader = text.Substring(indexOfVertexShaderStart, + indexOfVertexShaderEnd - indexOfVertexShaderStart); + VertexShader = VertexShader.Replace(" (", "("); + VertexShader = VertexShader.Replace("( ", "("); + VertexShader = VertexShader.Replace(" )", ")"); + VertexShader = VertexShader.Replace(") ", ")"); + + int indexOfPixelShaderStart = text.IndexOf("PixelShader"); + indexOfPixelShaderStart = text.IndexOf("compile ", indexOfPixelShaderStart); + int indexOfPixelShaderEnd = text.IndexOf(';', indexOfPixelShaderStart); + PixelShader = text.Substring(indexOfPixelShaderStart, + indexOfPixelShaderEnd - indexOfPixelShaderStart); + PixelShader = PixelShader.Replace(" (", "("); + PixelShader = PixelShader.Replace("( ", "("); + PixelShader = PixelShader.Replace(" )", ")"); + PixelShader = PixelShader.Replace(") ", ")"); + } + #endregion + + #region ParseIfPass + public static Pass ParseIfPass(ParseTextWalker walker) + { + if (walker.Text.StartsWith("pass ")) + { + return new Pass(walker); + } + + return null; + } + #endregion + + #region ToString + public override string ToString() + { + return ToStringIndented(0); + } + #endregion + + #region ToStringIndented + public string ToStringIndented(int tabs) + { + string idention = ""; + for (int tabIndex = 0; tabIndex < tabs; tabIndex++) + { + idention += "\t"; + } + + string text = idention + "pass " + Name + "\n" + idention + "{\n"; + + text += idention + "\tSetVertexShader(" + VertexShader + ");\n"; + text += idention + "\tSetGeometryShader(NULL);\n"; + text += idention + "\tSetPixelShader(" + PixelShader + ");\n"; + + return text + idention + "}"; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/Properties/AssemblyInfo.cs b/Tools/HLSLParser/HLSLParser/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..99222b56 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Properties/AssemblyInfo.cs @@ -0,0 +1,38 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("HLSLParser")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("HLSLParser")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("687e726e-bdc9-4e22-bf3a-b7cc686e95cd")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + +[assembly: InternalsVisibleTo("HLSLParserTests")] \ No newline at end of file diff --git a/Tools/HLSLParser/HLSLParser/Sampler.cs b/Tools/HLSLParser/HLSLParser/Sampler.cs new file mode 100644 index 00000000..b51e5782 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Sampler.cs @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using StringPair = System.Collections.Generic.KeyValuePair; + +namespace HLSLParser +{ + public class Sampler + { + #region Public + public string Type + { + get; + private set; + } + + public string Name + { + get; + private set; + } + + public string Register + { + get; + private set; + } + + public List States + { + get; + private set; + } + #endregion + + #region Constructor + public Sampler(ParseTextWalker walker) + { + States = new List(); + + ParseType(walker); + ParseName(walker); + ParseRegister(walker); + ParseStates(walker); + } + #endregion + + #region ParseType + private void ParseType(ParseTextWalker walker) + { + string text = walker.Text; + int indexOfTypeEndSpace = text.IndexOf(' '); + Type = text.Substring(0, indexOfTypeEndSpace); + walker.Seek(indexOfTypeEndSpace + 1); + } + #endregion + + #region ParseName + private void ParseName(ParseTextWalker walker) + { + string text = walker.Text; + Name = ""; + int nameParseIndex = 0; + while (nameParseIndex < text.Length) + { + char currentChar = text[nameParseIndex]; + if (currentChar == ' ' || + currentChar == '{' || + currentChar == ':' || + currentChar == '=') + { + break; + } + + Name += currentChar; + nameParseIndex++; + } + + Name = Name.Trim(' ', '\t', '\n', '\r'); + + walker.Seek(nameParseIndex); + } + #endregion + + #region ParseRegister + private void ParseRegister(ParseTextWalker walker) + { + string text = walker.Text; + if (text.StartsWith(":")) + { + text = text.Substring(1).TrimStart(' ', '\t'); + Register = ""; + int registerParseIndex = 0; + while (registerParseIndex < text.Length) + { + char currentChar = text[registerParseIndex]; + if (currentChar == ' ' || + currentChar == '{' || + currentChar == ';' || + currentChar == '=') + { + break; + } + + Register += currentChar; + registerParseIndex++; + } + + Register = Register.Trim(' ', '\t', '\n', '\r'); + + walker.Seek(registerParseIndex); + } + } + #endregion + + #region ParseStates + private void ParseStates(ParseTextWalker walker) + { + string text = walker.Text; + + int searchStatesStartIndex = 0; + while (searchStatesStartIndex < text.Length) + { + char currentChar = text[searchStatesStartIndex]; + if (currentChar == ';') + return; + + if (currentChar == '{') + break; + + searchStatesStartIndex++; + } + + walker.Seek(searchStatesStartIndex + 1); + + text = walker.Text; + + int indexOfStatesEndBrace = text.IndexOf('}'); + string statesSubText = text.Substring(0, indexOfStatesEndBrace); + statesSubText = statesSubText.Replace("\n", ""); + statesSubText = statesSubText.Replace("\r", ""); + statesSubText = statesSubText.Replace("\t", ""); + + indexOfStatesEndBrace = text.IndexOf(';', indexOfStatesEndBrace); + walker.Seek(indexOfStatesEndBrace + 1); + + string[] parts = statesSubText.Split(new char[] { '=', ';' }, + StringSplitOptions.RemoveEmptyEntries); + for (int partIndex = 0; partIndex < parts.Length; partIndex += 2) + { + States.Add(new StringPair(parts[partIndex].Trim(), parts[partIndex + 1].Trim())); + } + } + #endregion + + #region ParseIfSampler + public static Sampler ParseIfSampler(ParseTextWalker walker) + { + if (walker.Text.StartsWith("sampler") || + walker.Text.StartsWith("SamplerComparisonState") || + walker.Text.StartsWith("SamplerState")) + { + return new Sampler(walker); + } + + return null; + } + #endregion + + #region ToString + public override string ToString() + { + string result = Type + " " + Name; + + if (String.IsNullOrEmpty(Register) == false) + { + result += " : " + Register; + } + else + { + result += "\n{"; + + foreach (StringPair state in States) + { + result += "\n\t" + state.Key + " = " + state.Value + ";"; + } + + result += "\n}"; + } + + return result + ";"; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/Structure.cs b/Tools/HLSLParser/HLSLParser/Structure.cs new file mode 100644 index 00000000..b410ade3 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Structure.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; + +namespace HLSLParser +{ + public class Structure + { + #region Public + public string Name + { + get; + private set; + } + + public List Variables + { + get; + private set; + } + #endregion + + #region Constructor + public Structure(ParseTextWalker walker) + { + Variables = new List(); + + string currentText = walker.Text; + + int indexOfStructOpenBrace = currentText.IndexOf('{'); + walker.Seek(indexOfStructOpenBrace + 1); + + Name = currentText.Substring(0, indexOfStructOpenBrace); + Name = Name.Replace("struct ", "").Trim(); + + Variable newVariable = null; + while ((newVariable = Variable.ParseIfVariable(walker)) != null) + { + Variables.Add(newVariable); + } + + currentText = walker.Text; + int indexOfStructCloseBrace = currentText.IndexOf("};"); + walker.Seek(indexOfStructCloseBrace + 2); + } + #endregion + + #region ParseIfStructure + public static Structure ParseIfStructure(ParseTextWalker walker) + { + string currentText = walker.Text; + if (currentText.StartsWith("struct")) + { + return new Structure(walker); + } + + return null; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/Technique.cs b/Tools/HLSLParser/HLSLParser/Technique.cs new file mode 100644 index 00000000..fcf93cba --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Technique.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; + +namespace HLSLParser +{ + public class Technique + { + #region Public + public string Name + { + get; + private set; + } + + public List Passes + { + get; + private set; + } + #endregion + + #region Constructor + public Technique(ParseTextWalker walker) + { + Passes = new List(); + + string text = walker.Text; + + int indexOfNameStart = text.IndexOf(' ') + 1; + int indexOfNameEnd = text.IndexOf('{'); + + Name = text.Substring(indexOfNameStart, indexOfNameEnd - indexOfNameStart); + Name = Name.TrimEnd('\n', '\r', '\t', ' '); + + walker.Seek(indexOfNameEnd + 1); + + Pass newPass = null; + while ((newPass = Pass.ParseIfPass(walker)) != null) + { + Passes.Add(newPass); + } + + walker.Seek(walker.Text.IndexOf('}') + 1); + } + #endregion + + #region ParseIfTechnique + public static Technique ParseIfTechnique(ParseTextWalker walker) + { + if (walker.Text.StartsWith("technique")) + { + return new Technique(walker); + } + + return null; + } + #endregion + + #region ToString + public override string ToString() + { + string text = "technique10 " + Name + "\n{"; + + foreach (Pass pass in Passes) + { + text += "\n" + pass.ToStringIndented(1); + } + + return text + "\n}"; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/TypeDef.cs b/Tools/HLSLParser/HLSLParser/TypeDef.cs new file mode 100644 index 00000000..063d8cdc --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/TypeDef.cs @@ -0,0 +1,50 @@ +using System; + +namespace HLSLParser +{ + public class TypeDef + { + #region Constants + private const string TypedefKeyword = "typedef "; + #endregion + + #region Public + public string Value + { + get; + private set; + } + #endregion + + #region Constructor + public TypeDef(ParseTextWalker walker) + { + string text = walker.Text; + int indexOfTypedefEnd = text.IndexOf(';'); + Value = text.Substring(0, indexOfTypedefEnd); + + walker.Seek(indexOfTypedefEnd + 1); + } + #endregion + + #region ParseIfTypeDef + public static TypeDef ParseIfTypeDef(ParseTextWalker walker) + { + if (walker.Text.StartsWith("typedef ")) + { + walker.Seek(TypedefKeyword.Length); + return new TypeDef(walker); + } + + return null; + } + #endregion + + #region ToString + public override string ToString() + { + return "typedef " + Value + ";"; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParser/Variable.cs b/Tools/HLSLParser/HLSLParser/Variable.cs new file mode 100644 index 00000000..77042a39 --- /dev/null +++ b/Tools/HLSLParser/HLSLParser/Variable.cs @@ -0,0 +1,491 @@ +using System; +using System.Collections.Generic; + +namespace HLSLParser +{ + /// + /// http://msdn.microsoft.com/en-us/library/windows/desktop/bb509706%28v=vs.85%29.aspx + /// + public class Variable + { + #region Constants + private static char[] SemanticEndChars = new char[] + { + ' ', ':', '<', ';', '=' + }; + + private static readonly List AllTypeModifiers = new List( + new string[] + { + "const", + "row_major", + "column_major", + "extern", + "nointerpolation", + "precise", + "shared", + "groupshared", + "static", + "uniform", + "volatile", + + // struct additions + "linear", + "centroid", + "noperspective", + "sample" + }); + + private static readonly List AllTypeNames = new List( + new string[] + { + "int", + "bool", + "uint", + "dword", + "half", + "float", + "double", + // "min16float", + // "min10float", + // "min16int", + // "min12int", + // "min16uint", + + // vector + "vector", + // matrix + "matrix", + + "texture", + "Texture2D", + }); + #endregion + + #region Public + public string[] TypeModifiers + { + get; + private set; + } + + public string Name + { + get; + private set; + } + + public string InitialValue + { + get; + private set; + } + + public int ArraySize + { + get; + private set; + } + + public string Type + { + get; + private set; + } + + public string Annotations + { + get; + private set; + } + + public string Semantic + { + get; + private set; + } + + public string Packoffset + { + get; + private set; + } + + public string Register + { + get; + private set; + } + + public int[] Dimensions + { + get; + private set; + } + #endregion + + #region Constructor + protected Variable(ParseTextWalker walker) + { + ParseType(walker); + ReadNameAndArraySize(walker); + ParseExtraParameters(walker); + ParseAnnotations(walker); + ReadInitialValue(walker); + + if (walker.Text.StartsWith(";")) + { + walker.Seek(1); + } + } + #endregion + + #region ParseType + private void ParseType(ParseTextWalker walker) + { + string currentText = walker.Text; + + int nextSpaceIndex = FindInitialTypeEndSpace(currentText); + string variableType = currentText.Substring(0, nextSpaceIndex); + walker.Seek(nextSpaceIndex + 1); + + variableType = ResolveMatrixAndArraySyntax(variableType); + ParseDimensions(variableType); + } + #endregion + + #region FindInitialTypeEndSpace + private int FindInitialTypeEndSpace(string text) + { + int searchScope = 0; + if (text.StartsWith("vector") || + text.StartsWith("matrix")) + { + searchScope = text.IndexOf('>'); + } + return text.IndexOf(' ', searchScope); + } + #endregion + + #region ResolveMatrixAndArraySyntax + private string ResolveMatrixAndArraySyntax(string text) + { + if (text.Contains("<") && + text.StartsWith("matrix") || + text.StartsWith("vector")) + { + text = text.Substring(text.IndexOf('<') + 1); + text = text.Trim().TrimEnd('>'); + string[] parts = text.Split(','); + text = parts[0].Trim(); + for (int index = 1; index < parts.Length; index++) + { + text += (index > 1 ? "x" : "") + parts[index].Trim(); + } + } + + return text; + } + #endregion + + #region ParseDimensions + private void ParseDimensions(string typeText) + { + List dimensions = new List(); + Type = typeText; + int numeralRemoverIndex = typeText.Length - 1; + while (numeralRemoverIndex >= 1) + { + if (Char.IsDigit(Type[numeralRemoverIndex])) + { + dimensions.Insert(0, int.Parse(Type[numeralRemoverIndex].ToString())); + Type = Type.Substring(0, numeralRemoverIndex); + } + else if (Type[numeralRemoverIndex] == 'x' && + Char.IsDigit(Type[numeralRemoverIndex - 1])) + { + Type = Type.Substring(0, numeralRemoverIndex); + } + else + { + break; + } + + numeralRemoverIndex--; + } + + Dimensions = dimensions.ToArray(); + } + #endregion + + #region ReadNameAndArraySize + private void ReadNameAndArraySize(ParseTextWalker walker) + { + string currentText = walker.Text; + + int nameIndex = 0; + while (nameIndex < currentText.Length) + { + char currentChar = currentText[nameIndex]; + if (currentChar == ' ' || + currentChar == ':' || + currentChar == '<' || + currentChar == ';' || + currentChar == '=') + { + break; + } + Name += currentChar; + nameIndex++; + } + + if (Name.Contains("[")) + { + Name = Name.TrimEnd(']'); + int openBraceIndex = Name.IndexOf('['); + ArraySize = int.Parse(Name.Substring(openBraceIndex + 1)); + Name = Name.Substring(0, openBraceIndex); + } + + walker.Seek(nameIndex); + } + #endregion + + #region ParseExtraParameters + private void ParseExtraParameters(ParseTextWalker walker) + { + string currentText = walker.Text; + + char currentChar = currentText[0]; + if (currentChar == '<' || + currentChar == ';' || + currentChar == '=') + { + return; + } + + int afterColonIndex = 1; + string extraText = currentText.Substring(afterColonIndex); + + if (extraText.Trim().StartsWith("packoffset")) + { + int endIndex = extraText.IndexOf(')') + 1; + Packoffset = extraText.Substring(0, endIndex).Trim(); + walker.Seek(endIndex + afterColonIndex); + } + else if (extraText.Trim().StartsWith("register")) + { + int endIndex = extraText.IndexOf(')') + 1; + Register = extraText.Substring(0, endIndex).Trim(); + walker.Seek(endIndex + afterColonIndex); + } + else + { + int beforeLength = extraText.Length; + extraText = extraText.TrimStart(' '); + int lowestEndIndex = -1; + foreach (char semanticEndChar in SemanticEndChars) + { + int indexOfEndChar = extraText.IndexOf(semanticEndChar); + if (indexOfEndChar != -1 && + (lowestEndIndex == -1 || + indexOfEndChar < lowestEndIndex)) + { + lowestEndIndex = indexOfEndChar; + } + } + + Semantic = extraText.Substring(0, lowestEndIndex).Trim(); + walker.Seek(lowestEndIndex + afterColonIndex + (beforeLength - extraText.Length)); + } + } + #endregion + + #region ParseAnnotations + private void ParseAnnotations(ParseTextWalker walker) + { + string currentText = walker.Text; + if (currentText[0] != '<') + return; + + int endIndex = currentText.IndexOf('>'); + Annotations = currentText.Substring(1, endIndex - 1); + + walker.Seek(endIndex + 1); + } + #endregion + + #region ReadInitialValue + private void ReadInitialValue(ParseTextWalker walker) + { + string currentText = walker.Text; + + int equalSignSearchIndex = 0; + while (equalSignSearchIndex < currentText.Length) + { + char currentChar = currentText[equalSignSearchIndex]; + if (currentChar == '<' || + currentChar == ';' || + currentChar == ':') + { + return; + } + + if (currentChar == '=') + break; + + equalSignSearchIndex++; + } + + int afterEqualSignIndex = equalSignSearchIndex + 1; + int valueEndIndex = currentText.IndexOf(';', afterEqualSignIndex); + InitialValue = currentText.Substring(afterEqualSignIndex, + valueEndIndex - afterEqualSignIndex); + InitialValue = InitialValue.Trim(); + } + #endregion + + #region GetTypeModifiers + public static string[] GetTypeModifiers(ParseTextWalker walker) + { + if (walker == null) + return new string[0]; + + if (String.IsNullOrEmpty(walker.Text)) + return new string[0]; + + string currentText = walker.Text; + + int firstSpaceIndex = currentText.IndexOf(' '); + if (firstSpaceIndex == -1) + { + return AllTypeModifiers.Contains(currentText) ? + new string[] { currentText } : + new string[0]; + } + + var result = new List(); + while (firstSpaceIndex != -1) + { + string currentElement = currentText.Substring(0, firstSpaceIndex); + + if (AllTypeModifiers.Contains(currentElement)) + { + result.Add(currentElement); + } + else + { + break; + } + + walker.Seek(firstSpaceIndex + 1); + currentText = walker.Text; + firstSpaceIndex = currentText.IndexOf(' '); + } + + return result.ToArray(); + } + #endregion + + #region IsVariableFollowing + public static bool IsVariableFollowing(ParseTextWalker walker) + { + string currentText = walker.Text; + + foreach (string typeName in AllTypeNames) + { + if (currentText.StartsWith(typeName)) + return true; + } + + return false; + } + #endregion + + #region ParseIfVariable + public static Variable ParseIfVariable(ParseTextWalker walker) + { + string[] typeModifiersFound = GetTypeModifiers(walker); + + if (IsVariableFollowing(walker)) + { + return new Variable(walker) + { + TypeModifiers = typeModifiersFound, + }; + } + else + return null; + } + #endregion + + #region ToString + public override string ToString() + { + string result = ""; + result = AddTypeModifiersToString(result); + result += Type; + result = AddDimensionsToString(result); + result += " " + Name; + + if (ArraySize > 0) + { + result += "[" + ArraySize + "]"; + } + + if (String.IsNullOrEmpty(Semantic) == false) + { + result += " : " + Semantic; + } + + if (String.IsNullOrEmpty(Packoffset) == false) + { + result += " : " + Packoffset; + } + + if (String.IsNullOrEmpty(Register) == false) + { + result += " : " + Register; + } + + if (String.IsNullOrEmpty(Annotations) == false) + { + result += " <" + Annotations + ">"; + } + + if (String.IsNullOrEmpty(InitialValue) == false) + { + result += " = " + InitialValue; + } + + result += ";"; + + return result; + } + #endregion + + #region AddTypeModifiersToString + private string AddTypeModifiersToString(string text) + { + foreach (string modifier in TypeModifiers) + { + text += modifier + " "; + } + + return text; + } + #endregion + + #region AddDimensionsToString + private string AddDimensionsToString(string text) + { + for (int index = 0; index < Dimensions.Length; index++) + { + text += (index > 0 ? "x" : "") + Dimensions[index]; + } + + return text; + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/BufferTests.cs b/Tools/HLSLParser/HLSLParserTests/BufferTests.cs new file mode 100644 index 00000000..c8f28f1f --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/BufferTests.cs @@ -0,0 +1,45 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class BufferTests + { + #region TestParseIfBuffer + [Test] + public static void TestParseIfBuffer() + { + var text = new ParseTextWalker("Buffer g_Buffer;"); + var result = EffectBuffer.ParseIfBuffer(text); + + Assert.NotNull(result); + Assert.AreEqual("g_Buffer", result.Name); + Assert.AreEqual("float4", result.Type); + } + #endregion + + #region TestParseIfBufferWithoutCode + [Test] + public static void TestParseIfBufferWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = EffectBuffer.ParseIfBuffer(text); + + Assert.Null(result); + } + #endregion + + #region TestToString + [Test] + public static void TestToString() + { + string text = "Buffer g_Buffer;"; + var walker = new ParseTextWalker(text); + var result = EffectBuffer.ParseIfBuffer(walker); + + Assert.AreEqual(text, result.ToString()); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/CommentRemoverTests.cs b/Tools/HLSLParser/HLSLParserTests/CommentRemoverTests.cs new file mode 100644 index 00000000..895cd90c --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/CommentRemoverTests.cs @@ -0,0 +1,123 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class CommentRemoverTests + { + #region TestEmptySource + [Test] + public static void TestEmptySource() + { + Assert.AreEqual(CommentRemover.Remove(null), null); + Assert.AreEqual(CommentRemover.Remove(""), ""); + } + #endregion + + #region TestMultilineComment + [Test] + public static void TestMultilineComment() + { + string source = "/* comment line */"; + Assert.AreEqual(CommentRemover.Remove(source), ""); + source = "/* comment line\nline two*/"; + Assert.AreEqual(CommentRemover.Remove(source), ""); + } + #endregion + + #region TestCascadedMultilineComments + [Test] + public static void TestCascadedMultilineComments() + { + string source = "/* /*comment line */"; + Assert.AreEqual(CommentRemover.Remove(source), ""); + source = "/* comment /* //line\nline two*/"; + Assert.AreEqual(CommentRemover.Remove(source), ""); + } + #endregion + + #region TestMultilineCommentWithCodeInFront + [Test] + public static void TestMultilineCommentWithCodeInFront() + { + string source = "aaa/*comment*/"; + Assert.AreEqual(CommentRemover.Remove(source), "aaa"); + } + #endregion + + #region TestMultipleMultilineComments + [Test] + public static void TestMultipleMultilineComments() + { + string source = "/*blub*/aaa/*comment*/"; + Assert.AreEqual(CommentRemover.Remove(source), "aaa"); + } + #endregion + + #region TestMultilineCommentWithCodeAfter + [Test] + public static void TestMultilineCommentWithCodeAfter() + { + string source = "/*comment*/bbb"; + Assert.AreEqual(CommentRemover.Remove(source), "bbb"); + } + #endregion + + #region TestSingleLineComment + [Test] + public static void TestSingleLineComment() + { + string source = "// comment line"; + Assert.AreEqual(CommentRemover.Remove(source), ""); + source = "// comment line\n//test"; + Assert.AreEqual(CommentRemover.Remove(source), ""); + } + #endregion + + #region TestSingleLineCommentWithCode + [Test] + public static void TestSingleLineCommentWithCode() + { + string source = + @"// comment line +float4x4 matrix;"; + Assert.AreEqual(CommentRemover.Remove(source), "float4x4 matrix;"); + } + #endregion + + #region TestSingleLineCommentWithCodeInFront + [Test] + public static void TestSingleLineCommentWithCodeInFront() + { + string source = "float value;// comment line"; + Assert.AreEqual(CommentRemover.Remove(source), "float value;"); + } + #endregion + + #region TestSplitLines + [Test] + public static void TestSplitLines() + { + string source = "aa\nbbb"; + Assert.AreEqual(CommentRemover.SplitLines(source), new string[] { "aa", "bbb" }); + source = @"aa +bbb"; + Assert.AreEqual(CommentRemover.SplitLines(source), new string[] { "aa", "bbb" }); + source = "aa\n\rbbb"; + Assert.AreEqual(CommentRemover.SplitLines(source), new string[] { "aa", "bbb" }); + } + #endregion + + #region TestMergeLines + [Test] + public static void TestMergeLines() + { + string[] lines = new string[] { "aa", "bbb" }; + Assert.AreEqual(CommentRemover.MergeLines(lines), "aa\nbbb"); + lines = new string[] { "aa", "", null, "bbb" }; + Assert.AreEqual(CommentRemover.MergeLines(lines), "aa\nbbb"); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/HLSLParserTests.csproj b/Tools/HLSLParser/HLSLParserTests/HLSLParserTests.csproj new file mode 100644 index 00000000..4a578f8b --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/HLSLParserTests.csproj @@ -0,0 +1,66 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {F9177943-1590-49AE-987D-D6FAE30D96DD} + Library + Properties + HLSLParserTests + HLSLParserTests + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + {9588B0C3-E03A-4C71-89A4-2C8685D426F1} + HLSLParser + + + + + \ No newline at end of file diff --git a/Tools/HLSLParser/HLSLParserTests/HlslTestFile.cs b/Tools/HLSLParser/HLSLParserTests/HlslTestFile.cs new file mode 100644 index 00000000..28c4dc17 --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/HlslTestFile.cs @@ -0,0 +1,66 @@ +using System; +using System.IO; + +namespace HLSLParserTests +{ + public static class HlslTestFile + { + private const string Source = +@"// 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 + +uniform extern float4x4 MatrixTransform; + +Texture2D Texture : register(t0); + sampler TextureSampler : register(s0); + +struct VertexShaderInput +{ + float4 pos : POSITION; + float4 col : COLOR; + float2 tex : TEXCOORD0; +}; + +struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float4 col : COLOR; + float2 tex : TEXCOORD0; +}; + +PixelShaderInput SpriteVertexShader( VertexShaderInput input ) +{ + PixelShaderInput output = (PixelShaderInput)0; + + output.pos = mul(input.pos, MatrixTransform); + output.col = input.col; + output.tex = input.tex; + + return output; +} + +float4 SpritePixelShader( PixelShaderInput input ) : SV_Target +{ + return Texture.Sample(TextureSampler, input.tex) * input.col; +} + +technique10 SpriteTechnique +{ + pass SpriteColorPass + { + SetGeometryShader( 0 ); + SetVertexShader( CompileShader( vs_4_0, SpriteVertexShader() ) ); + SetPixelShader( CompileShader( ps_4_0, SpritePixelShader() ) ); + } +} +"; + + public static string WriteTestFile() + { + string testFilepath = Path.GetTempFileName() + ".fx"; + File.WriteAllText(testFilepath, HlslTestFile.Source); + return testFilepath; + } + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/MethodTests.cs b/Tools/HLSLParser/HLSLParserTests/MethodTests.cs new file mode 100644 index 00000000..d34bf9b5 --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/MethodTests.cs @@ -0,0 +1,127 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class MethodTests + { + #region Constants + private const string TestMethod = + @"float4 PSPointSprite(PSSceneIn input) : SV_Target +{ + return g_txDiffuse.Sample(g_samLinear, input.tex) * input.color; +}"; + + private const string TestMethodWithBodyBraces = + @"float4 PSPointSprite(PSSceneIn input) : SV_Target +{ + if(true) + { + return g_txDiffuse.Sample(g_samLinear, input.tex) * input.color; + } + else + { + return g_txDiffuse.Sample(g_samLinear, input.tex); + } +}"; + + private const string TestMethodInline = + @"inline float4 PSPointSprite(PSSceneIn input) : SV_Target +{ + return g_txDiffuse.Sample(g_samLinear, input.tex) * input.color; +}"; + #endregion + + #region TestParseIfMethod + [Test] + public static void TestParseIfMethod() + { + var text = new ParseTextWalker(TestMethod); + var result = Method.ParseIfMethod(text); + + Assert.NotNull(result); + Assert.AreEqual("PSPointSprite", result.Name); + Assert.AreEqual("float4", result.ReturnType); + Assert.AreEqual("PSSceneIn input", result.Arguments); + Assert.AreEqual("SV_Target", result.Semantic); + Assert.AreEqual( + "return g_txDiffuse.Sample(g_samLinear, input.tex) * input.color;", + result.Body); + } + #endregion + + #region TestParseIfMethodWithBodyBraces + [Test] + public static void TestParseIfMethodWithBodyBraces() + { + var text = new ParseTextWalker(TestMethodWithBodyBraces); + var result = Method.ParseIfMethod(text); + + Assert.NotNull(result); + Assert.AreEqual("PSPointSprite", result.Name); + Assert.AreEqual("float4", result.ReturnType); + + string expected = + @"if(true) + { + return g_txDiffuse.Sample(g_samLinear, input.tex) * input.color; + } + else + { + return g_txDiffuse.Sample(g_samLinear, input.tex); + }"; + + Assert.AreEqual(expected, result.Body); + } + #endregion + + #region TestParseIfMethodInline + [Test] + public static void TestParseIfMethodInline() + { + var text = new ParseTextWalker(TestMethodInline); + var result = Method.ParseIfMethod(text); + + Assert.NotNull(result); + Assert.AreEqual("PSPointSprite", result.Name); + Assert.AreEqual("float4", result.ReturnType); + Assert.AreEqual("inline", result.StorageClass); + } + #endregion + + #region TestParseIfMethodWithVariable + [Test] + public static void TestParseIfMethodWithVariable() + { + var text = new ParseTextWalker("float4 value;"); + var result = Method.ParseIfMethod(text); + + Assert.Null(result); + } + #endregion + + #region TestParseIfMethodWithoutCode + [Test] + public static void TestParseIfMethodWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = Method.ParseIfMethod(text); + + Assert.Null(result); + } + #endregion + + //#region TestToString + //[Test] + //public static void TestToString() + //{ + // string text = "typedef matrix bool1x1;"; + // var walker = new ParseTextWalker(text); + // var result = TypeDef.ParseIfTypeDef(walker); + + // Assert.AreEqual(text, result.ToString()); + //} + //#endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/ParseTextWalkerTests.cs b/Tools/HLSLParser/HLSLParserTests/ParseTextWalkerTests.cs new file mode 100644 index 00000000..4a9b807b --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/ParseTextWalkerTests.cs @@ -0,0 +1,28 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class ParseTextWalkerTests + { + [Test] + public static void TestCreateTextWalker() + { + string text = "Testtext"; + ParseTextWalker walker = new ParseTextWalker(text); + + Assert.AreEqual(walker.Text, text); + } + + [Test] + public static void TestSeeking() + { + string text = "Testtext"; + ParseTextWalker walker = new ParseTextWalker(text); + + walker.Seek(4); + Assert.AreEqual(walker.Text, "text"); + } + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/ParserTests.cs b/Tools/HLSLParser/HLSLParserTests/ParserTests.cs new file mode 100644 index 00000000..04a69113 --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/ParserTests.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; +using HLSLParser; +using NUnit.Framework; + +namespace HLSLParserTests +{ + public static class ParserTests + { + #region TestCreation + [Test] + public static void TestCreation() + { + Assert.DoesNotThrow(delegate + { + Parser parser = new Parser(); + }); + } + #endregion + + #region TestLoadThrowsOnEmptyFilepath + [Test] + public static void TestLoadThrowsOnEmptyFilepath() + { + Assert.Throws(typeof(ArgumentException), delegate + { + Parser parser = new Parser(); + parser.Load(""); + }); + } + #endregion + + #region TestLoadThrowsOnMissingFile + [Test] + public static void TestLoadThrowsOnMissingFile() + { + Assert.Throws(typeof(FileNotFoundException), delegate + { + Parser parser = new Parser(); + parser.Load("testfile.fx"); + }); + } + #endregion + + #region TestWriteTestFile + [Test] + public static void TestWriteTestFile() + { + string testFilepath = HlslTestFile.WriteTestFile(); + Assert.True(File.Exists(testFilepath)); + File.Delete(testFilepath); + } + #endregion + + #region TestLoadFile + [Test] + public static void TestLoadFile() + { + string testFilepath = HlslTestFile.WriteTestFile(); + Parser parser = new Parser(); + + parser.Load(testFilepath); + + Assert.NotNull(parser.Effect); + Assert.NotNull(parser.Effect.Source); + Assert.AreNotEqual(parser.Effect.Source, ""); + Assert.AreEqual(parser.Effect.Result, null); + + File.Delete(testFilepath); + } + #endregion + + #region TestParseFile + [Test] + public static void TestParseFile() + { + string testFilepath = HlslTestFile.WriteTestFile(); + Parser parser = new Parser(); + + parser.Load(testFilepath); + + parser.Parse(); + + Assert.AreNotEqual("", parser.Effect.Result); + Assert.Greater(parser.Effect.Result.Length, 0); + + Assert.AreEqual(2, parser.Effect.Variables.Count); + Assert.AreEqual(1, parser.Effect.Techniques.Count); + Assert.AreEqual(2, parser.Effect.Methods.Count); + Assert.AreEqual(2, parser.Effect.Structures.Count); + Assert.AreEqual(1, parser.Effect.Samplers.Count); + Assert.AreEqual(0, parser.Effect.TypeDefs.Count); + Assert.AreEqual(0, parser.Effect.Buffers.Count); + + File.Delete(testFilepath); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/PassTests.cs b/Tools/HLSLParser/HLSLParserTests/PassTests.cs new file mode 100644 index 00000000..f72f355f --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/PassTests.cs @@ -0,0 +1,85 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class PassTests + { + #region Constants + private const string TestPass = + @"pass P0 +{ + SetVertexShader( CompileShader( vs_4_0, VS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, PS() ) ); +}"; + + private const string TestPassDx9 = + @"pass P0 +{ + VertexShader = compile vs_2_0 RenderSceneVS( 1, true, true ); + PixelShader = compile ps_2_0 RenderScenePS( true ); +}"; + #endregion + + #region ParseIfPass + [Test] + public static void ParseIfPass() + { + var text = new ParseTextWalker(TestPass); + var result = Pass.ParseIfPass(text); + + Assert.NotNull(result); + Assert.AreEqual("P0", result.Name); + Assert.AreEqual("CompileShader(vs_4_0, VS())", result.VertexShader); + Assert.AreEqual("CompileShader(ps_4_0, PS())", result.PixelShader); + } + #endregion + + #region ParseIfPassDx9 + [Test] + public static void ParseIfPassDx9() + { + var text = new ParseTextWalker(TestPassDx9); + var result = Pass.ParseIfPass(text); + + Assert.NotNull(result); + Assert.AreEqual("P0", result.Name); + Assert.AreEqual("compile vs_2_0 RenderSceneVS(1, true, true)", + result.VertexShader); + Assert.AreEqual("compile ps_2_0 RenderScenePS(true)", result.PixelShader); + } + #endregion + + #region TestParseIfTypeDefWithoutCode + [Test] + public static void TestParseIfTypeDefWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = Pass.ParseIfPass(text); + + Assert.Null(result); + } + #endregion + + #region TestToString + [Test] + public static void TestToString() + { + var text = new ParseTextWalker(TestPass); + var result = Pass.ParseIfPass(text); + + string expected = + @"pass P0 +{ + SetVertexShader(CompileShader(vs_4_0, VS())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, PS())); +}"; + + Assert.AreEqual(expected.Replace("\r", ""), result.ToString()); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/Properties/AssemblyInfo.cs b/Tools/HLSLParser/HLSLParserTests/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..e76d3b2e --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Allgemeine Informationen über eine Assembly werden über die folgenden +// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, +// die mit einer Assembly verknüpft sind. +[assembly: AssemblyTitle("HLSLParserTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("HLSLParserTests")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar +// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von +// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest. +[assembly: ComVisible(false)] + +// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird +[assembly: Guid("4222de4b-ae10-4ae3-8e2e-8adce5ed6ac8")] + +// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: +// +// Hauptversion +// Nebenversion +// Buildnummer +// Revision +// +// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern +// übernehmen, indem Sie "*" eingeben: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Tools/HLSLParser/HLSLParserTests/SamplerTests.cs b/Tools/HLSLParser/HLSLParserTests/SamplerTests.cs new file mode 100644 index 00000000..59123ae0 --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/SamplerTests.cs @@ -0,0 +1,122 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class SamplerTests + { + #region Constants + private const string TestSampler = + @"SamplerState MeshTextureSampler +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; +};"; + + private const string TestSamplerDx9 = + @"sampler MeshTextureSampler = +sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; +};"; + #endregion + + #region ParseIfPass + [Test] + public static void ParseIfPass() + { + var text = new ParseTextWalker(TestSampler); + var result = Sampler.ParseIfSampler(text); + + Assert.NotNull(result); + Assert.AreEqual("MeshTextureSampler", result.Name); + Assert.AreEqual("SamplerState", result.Type); + + Assert.AreEqual("Filter", result.States[0].Key); + Assert.AreEqual("MIN_MAG_MIP_LINEAR", result.States[0].Value); + Assert.AreEqual("AddressU", result.States[1].Key); + Assert.AreEqual("Wrap", result.States[1].Value); + Assert.AreEqual("AddressV", result.States[2].Key); + Assert.AreEqual("Wrap", result.States[2].Value); + } + #endregion + + #region ParseIfPassDx9 + [Test] + public static void ParseIfPassDx9() + { + var text = new ParseTextWalker(TestSamplerDx9); + var result = Sampler.ParseIfSampler(text); + + Assert.NotNull(result); + Assert.AreEqual("MeshTextureSampler", result.Name); + Assert.AreEqual("sampler", result.Type); + + Assert.AreEqual("Texture", result.States[0].Key); + Assert.AreEqual("", result.States[0].Value); + } + #endregion + + #region ParseIfPassHasRegister + [Test] + public static void ParseIfPassHasRegister() + { + var text = new ParseTextWalker("sampler TextureSampler : register(s0);"); + var result = Sampler.ParseIfSampler(text); + + Assert.NotNull(result); + Assert.AreEqual("TextureSampler", result.Name); + Assert.AreEqual("sampler", result.Type); + Assert.AreEqual("register(s0)", result.Register); + } + #endregion + + #region TestParseIfTypeDefWithoutCode + [Test] + public static void TestParseIfTypeDefWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = Sampler.ParseIfSampler(text); + + Assert.Null(result); + } + #endregion + + #region TestToString + [Test] + public static void TestToString() + { + var text = new ParseTextWalker(TestSampler); + var result = Sampler.ParseIfSampler(text); + + string expected = + @"SamplerState MeshTextureSampler +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Wrap; + AddressV = Wrap; +};"; + + Assert.AreEqual(expected.Replace("\r", ""), result.ToString()); + } + #endregion + + #region TestToStringWithRegister + [Test] + public static void TestToStringWithRegister() + { + var text = new ParseTextWalker("sampler TextureSampler : register(s0);"); + var result = Sampler.ParseIfSampler(text); + + string expected = "sampler TextureSampler : register(s0);"; + + Assert.AreEqual(expected, result.ToString()); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/StructureTests.cs b/Tools/HLSLParser/HLSLParserTests/StructureTests.cs new file mode 100644 index 00000000..d0202d5d --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/StructureTests.cs @@ -0,0 +1,42 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class StructureTests + { + private const string TestStructure = + @"struct PixelShaderInput +{ + float4 pos : SV_POSITION; + float4 col : COLOR; + float2 tex : TEXCOORD0; +};"; + + #region TestParseIfStructure + [Test] + public static void TestParseIfStructure() + { + var text = new ParseTextWalker(TestStructure); + var result = Structure.ParseIfStructure(text); + + Assert.NotNull(result); + Assert.AreEqual("PixelShaderInput", result.Name); + Assert.AreEqual(3, result.Variables.Count); + Assert.AreEqual("", text.Text); + } + #endregion + + #region TestParseIfStructureWithoutCode + [Test] + public static void TestParseIfStructureWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = Structure.ParseIfStructure(text); + + Assert.Null(result); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/TechniqueTests.cs b/Tools/HLSLParser/HLSLParserTests/TechniqueTests.cs new file mode 100644 index 00000000..be21d8ef --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/TechniqueTests.cs @@ -0,0 +1,99 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class TechniqueTests + { + #region Constants + private const string TestTechnique = + @"technique10 Render +{ + pass P0 + { + SetVertexShader( CompileShader( vs_4_0, VS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, PS() ) ); + } +}"; + + private const string TestTechniqueMultipass = + @"technique Render +{ + pass P0 + { + SetVertexShader( CompileShader( vs_4_0, VS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, PS() ) ); + } + + pass P1 + { + SetVertexShader( CompileShader( vs_4_0, VS() ) ); + SetGeometryShader( NULL ); + SetPixelShader( CompileShader( ps_4_0, PS() ) ); + } +}"; + #endregion + + #region ParseIfTechnique + [Test] + public static void ParseIfTechnique() + { + var text = new ParseTextWalker(TestTechnique); + var result = Technique.ParseIfTechnique(text); + + Assert.NotNull(result); + Assert.AreEqual("Render", result.Name); + Assert.AreEqual(1, result.Passes.Count); + } + #endregion + + #region TestParseIfTypeDefWithoutCode + [Test] + public static void TestParseIfTypeDefWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = Technique.ParseIfTechnique(text); + + Assert.Null(result); + } + #endregion + + #region ParseTechniqueWithMultiplePasses + [Test] + public static void ParseTechniqueWithMultiplePasses() + { + var text = new ParseTextWalker(TestTechniqueMultipass); + var result = Technique.ParseIfTechnique(text); + + Assert.NotNull(result); + Assert.AreEqual("Render", result.Name); + Assert.AreEqual(2, result.Passes.Count); + } + #endregion + + #region TestToString + [Test] + public static void TestToString() + { + var text = new ParseTextWalker(TestTechnique); + var result = Technique.ParseIfTechnique(text); + + string expected = + @"technique10 Render +{ + pass P0 + { + SetVertexShader(CompileShader(vs_4_0, VS())); + SetGeometryShader(NULL); + SetPixelShader(CompileShader(ps_4_0, PS())); + } +}"; + + Assert.AreEqual(expected.Replace("\r", ""), result.ToString()); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/TypeDefTests.cs b/Tools/HLSLParser/HLSLParserTests/TypeDefTests.cs new file mode 100644 index 00000000..4a55ae92 --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/TypeDefTests.cs @@ -0,0 +1,44 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class TypeDefTests + { + #region TestParseIfTypeDef + [Test] + public static void TestParseIfTypeDef() + { + var text = new ParseTextWalker("typedef matrix bool1x1;"); + var result = TypeDef.ParseIfTypeDef(text); + + Assert.NotNull(result); + Assert.AreEqual("matrix bool1x1", result.Value); + } + #endregion + + #region TestParseIfTypeDefWithoutCode + [Test] + public static void TestParseIfTypeDefWithoutCode() + { + var text = new ParseTextWalker("testtest"); + var result = TypeDef.ParseIfTypeDef(text); + + Assert.Null(result); + } + #endregion + + #region TestToString + [Test] + public static void TestToString() + { + string text = "typedef matrix bool1x1;"; + var walker = new ParseTextWalker(text); + var result = TypeDef.ParseIfTypeDef(walker); + + Assert.AreEqual(text, result.ToString()); + } + #endregion + } +} diff --git a/Tools/HLSLParser/HLSLParserTests/VariableTests.cs b/Tools/HLSLParser/HLSLParserTests/VariableTests.cs new file mode 100644 index 00000000..764c7d3e --- /dev/null +++ b/Tools/HLSLParser/HLSLParserTests/VariableTests.cs @@ -0,0 +1,398 @@ +using System; +using NUnit.Framework; +using HLSLParser; + +namespace HLSLParserTests +{ + public static class VariableTests + { + #region TestGetTypeModifiersFromEmptyString + [Test] + public static void TestGetTypeModifiersFromEmptyString() + { + Assert.AreEqual(Variable.GetTypeModifiers(null), new string[0]); + Assert.AreEqual(Variable.GetTypeModifiers(new ParseTextWalker("")), + new string[0]); + } + #endregion + + #region TestGetTypeModifiersStringWithoutElement + [Test] + public static void TestGetTypeModifiersStringWithoutElement() + { + var text = new ParseTextWalker("aaa"); + string[] result = Variable.GetTypeModifiers(text); + Assert.AreEqual(0, result.Length); + } + #endregion + + #region TestGetTypeModifiersFromStringWithoutSpace + [Test] + public static void TestGetTypeModifiersFromStringWithoutSpace() + { + var text = new ParseTextWalker("uniform"); + string[] result = Variable.GetTypeModifiers(text); + Assert.AreEqual(1, result.Length); + Assert.AreEqual("uniform", result[0]); + } + #endregion + + #region TestGetStorageClassesFrom + [Test] + public static void TestGetStorageClassesFrom() + { + var text = new ParseTextWalker("uniform extern float4x4 MatrixTransform;"); + string[] result = Variable.GetTypeModifiers(text); + Assert.AreEqual(2, result.Length); + Assert.AreEqual("uniform", result[0]); + Assert.AreEqual("extern", result[1]); + } + #endregion + + #region TestIsVariableFollowing + [Test] + public static void TestIsVariableFollowing() + { + var text = new ParseTextWalker("int value;"); + bool result = Variable.IsVariableFollowing(text); + Assert.True(result); + + text = new ParseTextWalker("int4x4 value;"); + result = Variable.IsVariableFollowing(text); + Assert.True(result); + + text = new ParseTextWalker("const int value;"); + result = Variable.IsVariableFollowing(text); + Assert.False(result); + } + #endregion + + #region TestParseIfVariable + [Test] + public static void TestParseIfVariable() + { + var text = new ParseTextWalker("int value;"); + var result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + + text = new ParseTextWalker("uniform const int value;"); + result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + + text = new ParseTextWalker("uniform extern float4x4 MatrixTransform;"); + result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + + text = new ParseTextWalker("PS_IN VS(VS_IN in) { }"); + result = Variable.ParseIfVariable(text); + Assert.Null(result); + } + #endregion + + #region TestParseTwoVariables + [Test] + public static void TestParseTwoVariables() + { + string source = + @"uniform extern float4x4 MatrixTransform; + +Texture2D Texture : register(t0);"; + + var text = new ParseTextWalker(source); + var result = Variable.ParseIfVariable(text); + + Assert.NotNull(result); + Assert.AreEqual("uniform extern float4x4 MatrixTransform;", result.ToString()); + } + #endregion + + #region TestParseIfVariableWithGenericTexture2D + [Test] + public static void TestParseIfVariableWithGenericTexture2D() + { + string variableSource = "Texture2D Texture : register(t0);"; + var text = new ParseTextWalker(variableSource); + var result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + Assert.AreEqual("Texture2D", result.Type); + Assert.AreEqual("Texture", result.Name); + Assert.AreEqual("register(t0)", result.Register); + Assert.AreEqual(variableSource, result.ToString()); + } + #endregion + + #region TestfloatVariableParsing + [Test] + public static void TestfloatVariableParsing() + { + var text = new ParseTextWalker("uniform const float value;"); + var result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + Assert.AreEqual(2, result.TypeModifiers.Length); + Assert.AreEqual("float", result.Type); + } + #endregion + + #region TestVectorVariableParsing + [Test] + public static void TestVectorVariableParsing() + { + var text = new ParseTextWalker("vector value;"); + var result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + Assert.AreEqual("float", result.Type); + Assert.AreEqual(1, result.Dimensions.Length); + Assert.AreEqual(1, result.Dimensions[0]); + + text = new ParseTextWalker("float4 value;"); + result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + Assert.AreEqual("float", result.Type); + Assert.AreEqual(1, result.Dimensions.Length); + Assert.AreEqual(4, result.Dimensions[0]); + } + #endregion + + #region TestMatrixVariableParsing + [Test] + public static void TestMatrixVariableParsing() + { + var text = new ParseTextWalker("matrix value;"); + var result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + Assert.AreEqual("float", result.Type); + Assert.AreEqual(2, result.Dimensions.Length); + Assert.AreEqual(1, result.Dimensions[0]); + Assert.AreEqual(3, result.Dimensions[1]); + + text = new ParseTextWalker("int4x4 value;"); + result = Variable.ParseIfVariable(text); + Assert.NotNull(result); + Assert.AreEqual("int", result.Type); + Assert.AreEqual(2, result.Dimensions.Length); + Assert.AreEqual(4, result.Dimensions[0]); + Assert.AreEqual(4, result.Dimensions[1]); + } + #endregion + + #region TestNameParsing + [Test] + public static void TestNameParsing() + { + var text = new ParseTextWalker("matrix value;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + } + #endregion + + #region TestArrayParsing + [Test] + public static void TestArrayParsing() + { + var text = new ParseTextWalker("int value[15];"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual(15, result.ArraySize); + } + #endregion + + #region TestInitialValueParsing + [Test] + public static void TestInitialValueParsing() + { + var text = new ParseTextWalker("int value = 4;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("4", result.InitialValue); + } + #endregion + + #region TestInitialValueParsingWithoutValueText + [Test] + public static void TestInitialValueParsingWithoutValueText() + { + var text = new ParseTextWalker("int value;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual(null, result.InitialValue); + } + #endregion + + #region TestAnnotationsParsing + [Test] + public static void TestAnnotationsParsing() + { + var text = new ParseTextWalker("int value;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("float y=1.3;", result.Annotations); + } + #endregion + + #region TestAnnotationsParsingWithInitialValue + [Test] + public static void TestAnnotationsParsingWithInitialValue() + { + var text = new ParseTextWalker("int value = 4;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("float y=1.3;", result.Annotations); + Assert.AreEqual("4", result.InitialValue); + } + #endregion + + #region TestSemanticParsing + [Test] + public static void TestSemanticParsing() + { + var text = new ParseTextWalker("int value : COLOR;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("COLOR", result.Semantic); + } + #endregion + + #region TestSemanticParsingWithAnnotations + [Test] + public static void TestSemanticParsingWithAnnotations() + { + var text = new ParseTextWalker("int value : COLOR;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("COLOR", result.Semantic); + Assert.AreEqual("float y=1.3;", result.Annotations); + } + #endregion + + #region TestSemanticParsingWithInitialValue + [Test] + public static void TestSemanticParsingWithInitialValue() + { + var text = new ParseTextWalker("int value : COLOR = 5;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("COLOR", result.Semantic); + Assert.AreEqual("5", result.InitialValue); + } + #endregion + + #region TestSemanticParsingWithoutSpaces + [Test] + public static void TestSemanticParsingWithoutSpaces() + { + var text = new ParseTextWalker("int value:COLOR;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("COLOR", result.Semantic); + } + #endregion + + #region TestPackoffsetParsing + [Test] + public static void TestPackoffsetParsing() + { + var text = new ParseTextWalker("int value : packoffset(c0);"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("packoffset(c0)", result.Packoffset); + } + #endregion + + #region TestRegisterParsing + [Test] + public static void TestRegisterParsing() + { + var text = new ParseTextWalker("int value : register( ps_5_0, s );"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("register( ps_5_0, s )", result.Register); + } + #endregion + + #region TestRegisterAndAnnotationParsing + [Test] + public static void TestRegisterAndAnnotationParsing() + { + var text = new ParseTextWalker( + "int value : register( ps_5_0, s ) ;"); + var result = Variable.ParseIfVariable(text); + + Assert.AreEqual("value", result.Name); + Assert.AreEqual("register( ps_5_0, s )", result.Register); + Assert.AreEqual("float y=1.3;", result.Annotations); + } + #endregion + + #region TestToString + [Test] + public static void TestToString() + { + string variableText = "uniform const int value : COLOR = 5;"; + var walker = new ParseTextWalker(variableText); + var result = Variable.ParseIfVariable(walker); + + Assert.AreEqual(variableText, result.ToString()); + } + #endregion + + #region TestToStringWithArraySize + [Test] + public static void TestToStringWithArraySize() + { + string variableText = "uniform const int value[7];"; + var walker = new ParseTextWalker(variableText); + var result = Variable.ParseIfVariable(walker); + + Assert.AreEqual(variableText, result.ToString()); + } + #endregion + + #region TestToStringWithPackoffset + [Test] + public static void TestToStringWithPackoffset() + { + string variableText = "uniform const int value : packoffset(c0) = 5;"; + var walker = new ParseTextWalker(variableText); + var result = Variable.ParseIfVariable(walker); + + Assert.AreEqual(variableText, result.ToString()); + } + #endregion + + #region TestToStringWithRegister + [Test] + public static void TestToStringWithRegister() + { + string variableText = "uniform const int value : register( vs, s[8] ) = 5;"; + var walker = new ParseTextWalker(variableText); + var result = Variable.ParseIfVariable(walker); + + Assert.AreEqual(variableText, result.ToString()); + } + #endregion + + #region TestToStringWithDimensions + [Test] + public static void TestToStringWithDimensions() + { + string variableText = "float4x4 matrix;"; + var walker = new ParseTextWalker(variableText); + var result = Variable.ParseIfVariable(walker); + + Assert.AreEqual(variableText, result.ToString()); + } + #endregion + } +} diff --git a/shader/DX11/SpriteBatch.fx b/shader/DX11/SpriteBatch.fx index bb65c2f3..94c0c37a 100644 --- a/shader/DX11/SpriteBatch.fx +++ b/shader/DX11/SpriteBatch.fx @@ -1,45 +1,6 @@ -// -// This file is part of the ANX.Framework created by the "ANX.Framework developer group". -// -// This file is released under the Ms-PL license. -// -// -// -// Microsoft Public License (Ms-PL) -// -// This license governs use of the accompanying software. If you use the software, you accept this license. -// If you do not accept the license, do not use the software. -// -// 1.Definitions -// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning -// here as under U.S. copyright law. -// A "contribution" is the original software, or any additions or changes to the software. -// A "contributor" is any person that distributes its contribution under this license. -// "Licensed patents" are a contributor's patent claims that read directly on its contribution. -// -// 2.Grant of Rights -// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations -// in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to -// reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution -// or any derivative works that you create. -// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in -// section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed -// patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution -// in the software or derivative works of the contribution in the software. -// -// 3.Conditions and Limitations -// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. -// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your -// patent license from such contributor to the software ends automatically. -// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution -// notices that are present in the software. -// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including -// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or -// object code form, you may only do so under a license that complies with this license. -// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees, -// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the -// extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a -// particular purpose and non-infringement. +// 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 uniform extern float4x4 MatrixTransform;