static public ShaderInfo FromFile (string path, Options options, IEffectCompilerOutput output)
		{
            
			var effectSource = File.ReadAllText (path);
			if (options.Profile == ShaderProfile.PureGLSL)
				return PureGLSLFromString (effectSource, path, options, output);
			return null;
			//return FromString(effectSource, path, options, output);
		}
Exemple #2
0
        public static string Preprocess(
            string effectCode, string filePath, IDictionary<string, string> defines, List<string> dependencies,
            IEffectCompilerOutput output)
        {
            var fullPath = Path.GetFullPath(filePath);

            var pp = new CppNet.Preprocessor();

            pp.EmitExtraLineInfo = false;
            pp.addFeature(Feature.LINEMARKERS);
            pp.setListener(new MGErrorListener(output));
            pp.setFileSystem(new MGFileSystem(dependencies));
            pp.setQuoteIncludePath(new List<string> { Path.GetDirectoryName(fullPath) });

            foreach (var define in defines)
                pp.addMacro(define.Key, define.Value);

            pp.addInput(new MGStringLexerSource(effectCode, true, fullPath));

            var result = new StringBuilder();

            var endOfStream = false;
            while (!endOfStream)
            {
                var token = pp.token();
                switch (token.getType())
                {
                    case CppNet.Token.EOF:
                        endOfStream = true;
                        break;
                    case CppNet.Token.CPPCOMMENT:
                        break;
                    case CppNet.Token.CCOMMENT:
                    {
                        var tokenText = token.getText();
                        if (tokenText != null)
                        {
                            // Need to preserve line breaks so that line numbers are correct.
                            foreach (var c in tokenText)
                                if (c == '\n')
                                    result.Append(c);
                        }
                        break;
                    }
                    default:
                    {
                        var tokenText = token.getText();
                        if (tokenText != null)
                            result.Append(tokenText);
                        break;
                    }
                }
            }

            return result.ToString();
        }
Exemple #3
0
        static public ShaderInfo FromFile(string path, Options options, IEffectCompilerOutput output)
        {
            var effectSource = File.ReadAllText(path);

            if (options.Profile == ShaderProfile.PureGLSL)
            {
                return(PureGLSLFromString(effectSource, path, options, output));
            }
            return(null);
            //return FromString(effectSource, path, options, output);
        }
Exemple #4
0
        public static string Preprocess(
            string effectCode, string filePath, IDictionary <string, string> defines, List <string> dependencies,
            IEffectCompilerOutput output)
        {
            var fullPath = Path.GetFullPath(filePath);

            var pp = new CppNet.Preprocessor();

            pp.EmitExtraLineInfo = false;
            pp.addFeature(Feature.LINEMARKERS);
            pp.setListener(new MGErrorListener(fullPath, output));
            pp.setFileSystem(new MGFileSystem(dependencies));
            pp.setQuoteIncludePath(new List <string> {
                Path.GetDirectoryName(fullPath)
            });

            foreach (var define in defines)
            {
                pp.addMacro(define.Key, define.Value);
            }

            pp.addInput(new StringLexerSource(effectCode, true, fullPath));

            var result = new StringBuilder();

            var endOfStream = false;

            while (!endOfStream)
            {
                var token = pp.token();
                switch (token.getType())
                {
                case CppNet.Token.EOF:
                    endOfStream = true;
                    break;

                case CppNet.Token.CCOMMENT:
                case CppNet.Token.CPPCOMMENT:
                    break;

                default:
                    var tokenText = token.getText();
                    if (tokenText != null)
                    {
                        result.Append(tokenText);
                    }
                    break;
                }
            }

            return(result.ToString());
        }
Exemple #5
0
 public MGErrorListener(string fullPath, IEffectCompilerOutput output)
 {
     _fullPath = fullPath;
     _output = output;
 }
        static public ShaderResult FromString(string effectSource, string filePath, Options options, IEffectCompilerOutput output)
        {
            var macros = new Dictionary <string, string>();

            macros.Add("MGFX", "1");

            options.Profile.AddMacros(macros);

            // If we're building shaders for debug set that flag too.
            if (options.Debug)
            {
                macros.Add("DEBUG", "1");
            }

            if (!string.IsNullOrEmpty(options.Defines))
            {
                var defines = options.Defines.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var define in defines)
                {
                    var name  = define;
                    var value = "1";
                    if (define.Contains("="))
                    {
                        var parts = define.Split('=');

                        if (parts.Length > 0)
                        {
                            name = parts[0].Trim();
                        }

                        if (parts.Length > 1)
                        {
                            value = parts[1].Trim();
                        }
                    }

                    macros.Add(name, value);
                }
            }

            // Use the D3DCompiler to pre-process the file resolving
            // all #includes and macros.... this even works for GLSL.
            string newFile;
            var    fullPath     = Path.GetFullPath(filePath);
            var    dependencies = new List <string>();

            newFile = Preprocessor.Preprocess(effectSource, fullPath, macros, dependencies, output);

            // Parse the resulting file for techniques and passes.
            var tree = new Parser(new Scanner()).Parse(newFile, fullPath);

            if (tree.Errors.Count > 0)
            {
                var errors = String.Empty;
                foreach (var error in tree.Errors)
                {
                    errors += string.Format("{0}({1},{2}) : {3}\r\n", error.File, error.Line, error.Column, error.Message);
                }

                throw new Exception(errors);
            }

            // Evaluate the results of the parse tree.
            var shaderInfo = tree.Eval() as ShaderInfo;

            // Remove the samplers and techniques so that the shader compiler
            // gets a clean file without any FX file syntax in it.
            var cleanFile = newFile;

            WhitespaceNodes(TokenType.Technique_Declaration, tree.Nodes, ref cleanFile);
            WhitespaceNodes(TokenType.Sampler_Declaration_States, tree.Nodes, ref cleanFile);

            // Setup the rest of the shader info.
            ShaderResult result = new ShaderResult();

            result.ShaderInfo   = shaderInfo;
            result.Dependencies = dependencies;
            result.FilePath     = fullPath;
            result.FileContent  = cleanFile;
            if (!string.IsNullOrEmpty(options.OutputFile))
            {
                result.OutputFilePath = Path.GetFullPath(options.OutputFile);
            }
            result.AdditionalOutputFiles = new List <string>();

            // Remove empty techniques.
            for (var i = 0; i < shaderInfo.Techniques.Count; i++)
            {
                var tech = shaderInfo.Techniques[i];
                if (tech.Passes.Count <= 0)
                {
                    shaderInfo.Techniques.RemoveAt(i);
                    i--;
                }
            }

            // We must have at least one technique.
            if (shaderInfo.Techniques.Count <= 0)
            {
                throw new Exception("The effect must contain at least one technique and pass!");
            }

            result.Profile = options.Profile;
            result.Debug   = options.Debug;

            return(result);
        }
        static public ShaderResult FromFile(string path, Options options, IEffectCompilerOutput output)
        {
            var effectSource = File.ReadAllText(path);

            return(FromString(effectSource, path, options, output));
        }
Exemple #8
0
 public MGErrorListener(IEffectCompilerOutput output)
 {
     _output = output;
 }
Exemple #9
0
 public MGErrorListener(IEffectCompilerOutput output)
 {
     _output = output;
 }
        public static string Preprocess(
            string effectCode, string filePath, IDictionary <string, string> defines, List <string> dependencies,
            IEffectCompilerOutput output)
        {
            var fullPath = Path.GetFullPath(filePath);

            var pp = new CppNet.Preprocessor();

            pp.EmitExtraLineInfo = false;
            pp.addFeature(Feature.LINEMARKERS);
            pp.setListener(new MGErrorListener(output));
            pp.setFileSystem(new MGFileSystem(dependencies));
            pp.setQuoteIncludePath(new List <string> {
                Path.GetDirectoryName(fullPath)
            });

            foreach (var define in defines)
            {
                pp.addMacro(define.Key, define.Value);
            }

            effectCode = effectCode.Replace("#line", "//--WORKAROUND#line");

            pp.addInput(new MGStringLexerSource(effectCode, true, fullPath));

            var result = new StringBuilder();

            var endOfStream = false;

            while (!endOfStream)
            {
                var token = pp.token();
                switch (token.getType())
                {
                case CppNet.Token.EOF:
                    endOfStream = true;
                    break;

                case CppNet.Token.CPPCOMMENT:
                    if (token.getText().StartsWith("//--WORKAROUND#line"))
                    {
                        result.Append(token.getText().Replace("//--WORKAROUND#line", "#line"));
                    }
                    break;

                case CppNet.Token.CCOMMENT:
                {
                    var tokenText = token.getText();
                    if (tokenText != null)
                    {
                        // Need to preserve line breaks so that line numbers are correct.
                        foreach (var c in tokenText)
                        {
                            if (c == '\n')
                            {
                                result.Append(c);
                            }
                        }
                    }
                    break;
                }

                default:
                {
                    var tokenText = token.getText();
                    if (tokenText != null)
                    {
                        result.Append(tokenText);
                    }
                    break;
                }
                }
            }

            return(result.ToString());
        }
Exemple #11
0
 public MGErrorListener(string fullPath, IEffectCompilerOutput output)
 {
     _fullPath = fullPath;
     _output   = output;
 }
		static public ShaderInfo PureGLSLFromString (string effectSource, string filePath, Options options, IEffectCompilerOutput output)
		{

			ShaderInfo shaderInfo = new ShaderInfo ();
			shaderInfo.FilePath = options.SourceFile;
			XmlDocument doc = new XmlDocument ();
			doc.LoadXml (effectSource);
			XmlElement effectElement;
			XmlNode current = doc.FirstChild;
			while (current != null && current.NodeType != XmlNodeType.Element) {
				current = current.NextSibling;
			}
			effectElement = (XmlElement)current;
			shaderInfo.Techniques = new List<TechniqueInfo> ();
			foreach (XmlElement technique in effectElement.ChildNodes.OfType<XmlElement>()) {
				TechniqueInfo info = new TechniqueInfo ();
				info.name = technique.GetAttribute ("name");
				info.Passes = new List<PassInfo> ();
				foreach (XmlElement pass in technique.ChildNodes.OfType<XmlElement>()) {
					PassInfo pi = new PassInfo ();
					pi.name = pass.GetAttribute ("name");
					foreach (XmlElement sh in pass.ChildNodes) {
						if (sh.Name == "Shader") {
							if (sh.GetAttribute ("type") == "PixelShader") {
								pi.psFileName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(shaderInfo.FilePath),sh.GetAttribute ("filename"));
								shaderInfo.Dependencies.Add (pi.psFileName);
								pi.psShaderXML = sh.OuterXml;
							} else if (sh.GetAttribute ("type") == "VertexShader") {
								pi.vsFilename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(shaderInfo.FilePath),sh.GetAttribute ("filename"));
								shaderInfo.Dependencies.Add (pi.vsFilename);
								pi.vsShaderXML = sh.OuterXml;
							} else {
								throw new PipelineException ("Unsupported Shader type detected");
							}
						} else if (sh.Name == "BlendState") {
							pi.blendState = ParseBlendState (sh);

						} else if (sh.Name == "DepthStencilState") {
							pi.depthStencilState = ParseDepthStencilState (sh);
						} else if (sh.Name == "RasterizerState") {
							pi.rasterizerState = ParseRasterizerState (sh);
						} else {
							throw new PipelineException ("'" + sh.Name + "' element not recognized");
						}
					}
					info.Passes.Add (pi);
				}
				shaderInfo.Techniques.Add (info);
			}

			shaderInfo.Profile = options.Profile;
			shaderInfo.Debug = options.Debug;

			shaderInfo.OutputFilePath = options.OutputFile;

			return shaderInfo;
		}
Exemple #13
0
        static public ShaderInfo PureGLSLFromString(string effectSource, string filePath, Options options, IEffectCompilerOutput output)
        {
            ShaderInfo shaderInfo = new ShaderInfo();

            shaderInfo.FilePath = options.SourceFile;
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(effectSource);
            XmlElement effectElement;
            XmlNode    current = doc.FirstChild;

            while (current != null && current.NodeType != XmlNodeType.Element)
            {
                current = current.NextSibling;
            }
            effectElement         = (XmlElement)current;
            shaderInfo.Techniques = new List <TechniqueInfo> ();
            foreach (XmlElement technique in effectElement.ChildNodes.OfType <XmlElement>())
            {
                TechniqueInfo info = new TechniqueInfo();
                info.name   = technique.GetAttribute("name");
                info.Passes = new List <PassInfo> ();
                foreach (XmlElement pass in technique.ChildNodes.OfType <XmlElement>())
                {
                    PassInfo pi = new PassInfo();
                    pi.name = pass.GetAttribute("name");
                    foreach (XmlElement sh in pass.ChildNodes)
                    {
                        if (sh.Name == "Shader")
                        {
                            if (sh.GetAttribute("type") == "PixelShader")
                            {
                                pi.psFileName = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(shaderInfo.FilePath), sh.GetAttribute("filename"));
                                shaderInfo.Dependencies.Add(pi.psFileName);
                                pi.psShaderXML = sh.OuterXml;
                            }
                            else if (sh.GetAttribute("type") == "VertexShader")
                            {
                                pi.vsFilename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(shaderInfo.FilePath), sh.GetAttribute("filename"));
                                shaderInfo.Dependencies.Add(pi.vsFilename);
                                pi.vsShaderXML = sh.OuterXml;
                            }
                            else
                            {
                                throw new PipelineException("Unsupported Shader type detected");
                            }
                        }
                        else if (sh.Name == "BlendState")
                        {
                            pi.blendState = ParseBlendState(sh);
                        }
                        else if (sh.Name == "DepthStencilState")
                        {
                            pi.depthStencilState = ParseDepthStencilState(sh);
                        }
                        else if (sh.Name == "RasterizerState")
                        {
                            pi.rasterizerState = ParseRasterizerState(sh);
                        }
                        else
                        {
                            throw new PipelineException("'" + sh.Name + "' element not recognized");
                        }
                    }
                    info.Passes.Add(pi);
                }
                shaderInfo.Techniques.Add(info);
            }

            shaderInfo.Profile = options.Profile;
            shaderInfo.Debug   = options.Debug;

            shaderInfo.OutputFilePath = options.OutputFile;

            return(shaderInfo);
        }
Exemple #14
0
		static public ShaderInfo FromString(string effectSource, string filePath, Options options, IEffectCompilerOutput output)
		{
			var macros = new Dictionary<string, string>();
			macros.Add("MGFX", "1");

			// Under the DX11 profile we pass a few more macros.
			if (options.Profile == ShaderProfile.DirectX_11)
			{
				macros.Add("HLSL", "1");
				macros.Add("SM4", "1");
			}
            else if (options.Profile == ShaderProfile.OpenGL)
            {
                macros.Add("GLSL", "1");
                macros.Add("OPENGL", "1");
            }
            else if (options.Profile == ShaderProfile.PlayStation4)
            {
                throw new NotSupportedException("PlayStation 4 support isn't available in this build.");
            }

			// If we're building shaders for debug set that flag too.
			if (options.Debug)
				macros.Add("DEBUG", "1");

		    if (!string.IsNullOrEmpty(options.Defines))
		    {
		        var defines = options.Defines.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var define in defines)
                    macros.Add(define, "1");
		    }

		    // Use the D3DCompiler to pre-process the file resolving 
			// all #includes and macros.... this even works for GLSL.
			string newFile;
		    var fullPath = Path.GetFullPath(filePath);
		    var dependencies = new List<string>();
		    newFile = Preprocessor.Preprocess(effectSource, fullPath, macros, dependencies, output);

			// Parse the resulting file for techniques and passes.
            var tree = new Parser(new Scanner()).Parse(newFile, fullPath);
			if (tree.Errors.Count > 0)
			{
                var errors = String.Empty;
                foreach (var error in tree.Errors)
                    errors += string.Format("{0}({1},{2}) : {3}\r\n", error.File, error.Line, error.Column, error.Message);

				throw new Exception(errors);
			}

            // Evaluate the results of the parse tree.
            var result = tree.Eval() as ShaderInfo;
            result.Dependencies = dependencies;
            result.FilePath = fullPath;
            result.FileContent = newFile;
            if (!string.IsNullOrEmpty(options.OutputFile))
                result.OutputFilePath = Path.GetFullPath(options.OutputFile);
            result.AdditionalOutputFiles = new List<string>();

            // Remove empty techniques.
            for (var i=0; i < result.Techniques.Count; i++)
            {
                var tech = result.Techniques[i];
                if (tech.Passes.Count <= 0)
                {
                    result.Techniques.RemoveAt(i);
                    i--;
                }
            }

            // We must have at least one technique.
            if (result.Techniques.Count <= 0)
                throw new Exception("The effect must contain at least one technique and pass!");

            // Finally remove the techniques from the file.
            //
            // TODO: Do we really need to do this, or will the HLSL 
            // compiler just ignore it as we compile shaders?
            //
			/*
			var extra = 2;
			var offset = 0;
			foreach (var tech in result.Techniques)
			{
				// Remove the technique from the file.
				newFile = newFile.Remove(tech.startPos + offset, tech.length + extra);
				offset -= tech.length + extra;

				techniques.Add(tech);
			}
			*/

			result.Profile = options.Profile;
			result.Debug = options.Debug;

			return result;
		}
Exemple #15
0
        static public ShaderInfo FromFile(string path, Options options, IEffectCompilerOutput output)
		{
			var effectSource = File.ReadAllText(path);
			return FromString(effectSource, path, options, output);
		}
Exemple #16
0
        static public ShaderInfo FromString(string effectSource, string filePath, Options options, IEffectCompilerOutput output)
        {
            var macros = new Dictionary <string, string>();

            macros.Add("MGFX", "1");

            // Under the DX11 profile we pass a few more macros.
            if (options.Profile == ShaderProfile.DirectX_11)
            {
                macros.Add("HLSL", "1");
                macros.Add("SM4", "1");
            }
            else if (options.Profile == ShaderProfile.OpenGL)
            {
                macros.Add("GLSL", "1");
                macros.Add("OPENGL", "1");
            }
            else if (options.Profile == ShaderProfile.PlayStation4)
            {
                throw new NotSupportedException("PlayStation 4 support isn't available in this build.");
            }

            // If we're building shaders for debug set that flag too.
            if (options.Debug)
            {
                macros.Add("DEBUG", "1");
            }

            if (!string.IsNullOrEmpty(options.Defines))
            {
                var defines = options.Defines.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var define in defines)
                {
                    macros.Add(define, "1");
                }
            }

            // Use the D3DCompiler to pre-process the file resolving
            // all #includes and macros.... this even works for GLSL.
            string newFile;
            var    fullPath     = Path.GetFullPath(filePath);
            var    dependencies = new List <string>();

            newFile = Preprocessor.Preprocess(effectSource, fullPath, macros, dependencies, output);

            // Parse the resulting file for techniques and passes.
            var tree = new Parser(new Scanner()).Parse(newFile, fullPath);

            if (tree.Errors.Count > 0)
            {
                var errors = String.Empty;
                foreach (var error in tree.Errors)
                {
                    errors += string.Format("{0}({1},{2}) : {3}\r\n", error.File, error.Line, error.Column, error.Message);
                }

                throw new Exception(errors);
            }

            // Evaluate the results of the parse tree.
            var result = tree.Eval() as ShaderInfo;

            result.Dependencies = dependencies;
            result.FilePath     = fullPath;
            result.FileContent  = newFile;
            if (!string.IsNullOrEmpty(options.OutputFile))
            {
                result.OutputFilePath = Path.GetFullPath(options.OutputFile);
            }
            result.AdditionalOutputFiles = new List <string>();

            // Remove empty techniques.
            for (var i = 0; i < result.Techniques.Count; i++)
            {
                var tech = result.Techniques[i];
                if (tech.Passes.Count <= 0)
                {
                    result.Techniques.RemoveAt(i);
                    i--;
                }
            }

            // We must have at least one technique.
            if (result.Techniques.Count <= 0)
            {
                throw new Exception("The effect must contain at least one technique and pass!");
            }

            // Finally remove the techniques from the file.
            //
            // TODO: Do we really need to do this, or will the HLSL
            // compiler just ignore it as we compile shaders?
            //

            /*
             * var extra = 2;
             * var offset = 0;
             * foreach (var tech in result.Techniques)
             * {
             *      // Remove the technique from the file.
             *      newFile = newFile.Remove(tech.startPos + offset, tech.length + extra);
             *      offset -= tech.length + extra;
             *
             *      techniques.Add(tech);
             * }
             */

            result.Profile = options.Profile;
            result.Debug   = options.Debug;

            return(result);
        }