示例#1
0
        public static bool TryParseEffect(string shaderName, Dictionary <string, ShaderViewModel> shaders, out ParsedShader result)
        {
            result = null;

            var resultRef = new ParsedShaderRef();
            var success   = TryParseEffect(shaderName, shaders, resultRef);

            Debug.Assert(resultRef.ParentShaders.Count == 0);
            if (success)
            {
                result = resultRef.ParsedShader;
            }
            return(success);
        }
示例#2
0
        private static bool TryParseEffect(string shaderName, Dictionary <string, ShaderViewModel> shaders, ParsedShaderRef resultRef)
        {
            lock (parserCacheLock)
            {
                if (parserCache.TryGetValue(shaderName, out var localResult))
                {
                    if (resultRef.ParsedShader == null)
                    {
                        resultRef.ParsedShader = localResult;
                    }
                    else
                    {
                        foreach (var parentShader in resultRef.ParentShaders)
                        {
                            parentShader.AddBaseShader(localResult);

                            // also add all base shaders of this base shader
                            foreach (var baseShader in localResult.BaseShaders)
                            {
                                parentShader.AddBaseShader(baseShader);
                            }
                        }
                    }

                    return(true);
                }

                try
                {
                    // SDSL
                    var macros = new[]
                    {
                        new ShaderMacro("class", "shader")
                    };

                    // get source code
                    var code          = File.ReadAllText(shaders[shaderName].Path);
                    var inputFileName = shaderName + ".sdsl";

                    var parsingResult = StrideShaderParser.TryPreProcessAndParse(code, inputFileName, macros);

                    if (parsingResult.HasErrors || parsingResult.Shader.GetFirstClassDecl() == null)
                    {
                        return(false);
                    }
                    else //success
                    {
                        localResult = new ParsedShader(parsingResult.Shader);

                        foreach (var parentShader in resultRef.ParentShaders)
                        {
                            parentShader.AddBaseShader(localResult);
                        }

                        // original shader
                        if (resultRef.ParsedShader == null)
                        {
                            resultRef.ParsedShader = localResult;
                        }

                        resultRef.ParentShaders.Push(localResult);
                        try
                        {
                            // base shaders
                            var baseShaders = localResult.ShaderClass?.BaseClasses ?? Enumerable.Empty <TypeName>();
                            foreach (var baseClass in baseShaders)
                            {
                                var baseShaderName = baseClass.Name.Text;
                                TryParseEffect(baseShaderName, shaders, resultRef);
                            }
                        }
                        finally
                        {
                            resultRef.ParentShaders.Pop();
                        }

                        parserCache[shaderName] = localResult;
                        return(true);
                    }
                }
                catch (Exception)
                {
                    return(false);
                }
            }
        }