Exemple #1
0
        /// <summary>
        /// Processes an ifdef/else/endif block where Interpret denotes the success of the if statement. Returns true if exited on an endif or false
        /// if exited on an else.
        /// </summary>
        private static bool _ProcessBlock(IEnumerator<string> LineEnumerator, Path File, PrecompilerInput Input, StringBuilder Output, bool Interpret)
        {
            while (LineEnumerator.MoveNext())
            {
                string line = LineEnumerator.Current;

                // Does this line contain a directive?
                if (line.Length > 0)
                {
                    if (line[0] == '#')
                    {
                        string[] lineparts = line.Split(' ');
                        if (lineparts[0] == "#ifdef")
                        {
                            if (Interpret)
                            {
                                bool contains = Input.Constants.ContainsKey(lineparts[1]);
                                if (!_ProcessBlock(LineEnumerator, File, Input, Output, contains))
                                {
                                    _ProcessBlock(LineEnumerator, File, Input, Output, !contains);
                                }
                            }
                            else
                            {
                                if (!_ProcessBlock(LineEnumerator, File, Input, Output, false))
                                {
                                    _ProcessBlock(LineEnumerator, File, Input, Output, false);
                                }
                            }
                            continue;
                        }
                        if (lineparts[0] == "#include")
                        {
                            if (Interpret)
                            {
                                string filepath = lineparts[1].Substring(1, lineparts[1].Length - 2);
                                BuildSource(File.Parent.Lookup(filepath), Input, Output);
                            }
                            continue;
                        }
                        if (lineparts[0] == "#else")
                        {
                            return false;
                        }
                        if (lineparts[0] == "#endif")
                        {
                            return true;
                        }
                        if (Interpret)
                        {
                            if (lineparts[0] == "#define")
                            {
                                if (lineparts.Length > 2)
                                {
                                    Input.Define(lineparts[1], lineparts[2]);
                                }
                                else
                                {
                                    Input.Define(lineparts[1]);
                                }
                                continue;
                            }
                            if (lineparts[0] == "#undef")
                            {
                                Input.Undefine(lineparts[1]);
                                continue;
                            }

                            Output.AppendLine(line);
                        }
                    }
                    else
                    {
                        if (Interpret)
                        {
                            // Replace constants
                            Dictionary<int, KeyValuePair<int, string>> matches = new Dictionary<int, KeyValuePair<int, string>>();
                            foreach (KeyValuePair<string, string> constant in Input.Constants)
                            {
                                int ind = line.IndexOf(constant.Key);
                                while (ind >= 0)
                                {
                                    int size = constant.Key.Length;
                                    KeyValuePair<int, string> lastmatch;
                                    if (matches.TryGetValue(ind, out lastmatch))
                                    {
                                        if (lastmatch.Key < size)
                                        {
                                            matches[ind] = new KeyValuePair<int, string>(size, constant.Value);
                                        }
                                    }
                                    else
                                    {
                                        matches[ind] = new KeyValuePair<int, string>(size, constant.Value);
                                    }
                                    ind = line.IndexOf(constant.Key, ind + 1);
                                }
                            }
                            if (matches.Count > 0)
                            {
                                int c = 0;

                                var orderedmatches = new List<KeyValuePair<int, KeyValuePair<int, string>>>(matches);
                                orderedmatches.Sort(delegate(KeyValuePair<int, KeyValuePair<int, string>> a, KeyValuePair<int, KeyValuePair<int, string>> b)
                                {
                                    if (a.Key > b.Key)
                                        return 1;
                                    if (a.Key < b.Key)
                                        return -1;
                                    return 0;
                                });
                                foreach (KeyValuePair<int, KeyValuePair<int, string>> match in orderedmatches)
                                {
                                    Output.Append(line.Substring(c, match.Key - c));
                                    Output.Append(match.Value.Value);
                                    c = match.Key + match.Value.Key;
                                }
                                Output.AppendLine(line.Substring(c));
                            }
                            else
                            {
                                Output.AppendLine(line);
                            }
                        }
                    }
                }
            }

            return true;
        }
Exemple #2
0
 /// <summary>
 /// Precompiles the source code defined by the lines with the specified constants defined. Outputs the precompiled source
 /// to the given stringbuilder.
 /// </summary>
 public static void BuildSource(Path File, PrecompilerInput Input, StringBuilder Output)
 {
     string[] lines = Input.GetFile(File);
     _ProcessBlock(((IEnumerable<string>)lines).GetEnumerator(), File, Input, Output, true);
 }
Exemple #3
0
        /// <summary>
        /// Loads a shader from the specified file using the specified input.
        /// </summary>
        public static Shader Load(Path File, PrecompilerInput Input)
        {
            int vshade = GL.CreateShader(ShaderType.VertexShader);
            int fshade = GL.CreateShader(ShaderType.FragmentShader);

            StringBuilder vshadesource = new StringBuilder();
            StringBuilder fshadesource = new StringBuilder();
            PrecompilerInput vpce = Input.Copy();
            PrecompilerInput fpce = Input.Copy();
            vpce.Define("_VERTEX_", "1");
            fpce.Define("_FRAGMENT_", "1");

            BuildSource(File, vpce, vshadesource);
            GL.ShaderSource(vshade, vshadesource.ToString());
            GL.CompileShader(vshade);

            string vinfo = GL.GetShaderInfoLog(vshade);

            BuildSource(File, fpce, fshadesource);
            GL.ShaderSource(fshade, fshadesource.ToString());
            GL.CompileShader(fshade);

            string finfo = GL.GetShaderInfoLog(fshade);

            if (false)
            {
                if (finfo.Length > 0 || vinfo.Length > 0)
                {
                    throw new Exception("Shader error");
                }
            }

            Shader shade = new Shader();
            shade.Program = GL.CreateProgram();
            GL.AttachShader(shade.Program, vshade);
            GL.AttachShader(shade.Program, fshade);
            GL.LinkProgram(shade.Program);
            return shade;
        }