示例#1
0
        public static int GetElementCount(this ShaderFieldType type)
        {
            switch (type)
            {
            default:
                return(1);

            case ShaderFieldType.Vec2:
                return(2);

            case ShaderFieldType.Vec3:
                return(3);

            case ShaderFieldType.Vec4:
                return(4);

            case ShaderFieldType.Mat2:
                return(4);

            case ShaderFieldType.Mat3:
                return(9);

            case ShaderFieldType.Mat4:
                return(16);
            }
        }
示例#2
0
 public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength = 1)
 {
     this.name = name;
     this.type = type;
     this.scope = scope;
     this.arrayLength = arrayLength;
 }
示例#3
0
 public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength = 1)
 {
     this.name        = name;
     this.type        = type;
     this.scope       = scope;
     this.arrayLength = arrayLength;
 }
示例#4
0
 public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength = 1)
 {
     this.name        = name;
     this.type        = type;
     this.scope       = scope;
     this.arrayLength = arrayLength;
     this.isPrivate   = string.IsNullOrEmpty(name) || name[0] == '_';
 }
示例#5
0
		public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength = 1)
		{
			this.name = name;
			this.type = type;
			this.scope = scope;
			this.arrayLength = arrayLength;
			this.isPrivate = 
				string.IsNullOrEmpty(name) || 
				name[0] == '_' || 
				BuiltinShaderFields.GetIndex(name) != BuiltinShaderFields.InvalidIndex;
		}
示例#6
0
        public static Type GetElementPrimitive(this ShaderFieldType type)
        {
            switch (type)
            {
            default:
                return(typeof(float));

            case ShaderFieldType.Int:
                return(typeof(int));
            }
        }
示例#7
0
 public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength = 1)
 {
     this.name        = name;
     this.type        = type;
     this.scope       = scope;
     this.arrayLength = arrayLength;
     this.isPrivate   =
         string.IsNullOrEmpty(name) ||
         name[0] == '_' ||
         BuiltinShaderFields.GetIndex(name) != BuiltinShaderFields.InvalidIndex;
 }
示例#8
0
 public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength, string editorTypeTag, string description, float minValue, float maxValue)
 {
     this.name          = name;
     this.type          = type;
     this.scope         = scope;
     this.arrayLength   = arrayLength;
     this.editorTypeTag = editorTypeTag;
     this.description   = description;
     this.minValue      = minValue;
     this.maxValue      = maxValue;
     this.isPrivate     = string.IsNullOrEmpty(name) || name[0] == '_';
 }
示例#9
0
        void INativeShaderPart.LoadSource(string sourceCode, ShaderType type)
        {
            // Removed thread guards because of performance
            //DefaultOpenTKBackendPlugin.GuardSingleThreadState();

            if (this.handle == 0)
            {
                this.handle = GL.CreateShader(GetOpenTKShaderType(type));
            }
            GL.ShaderSource(this.handle, sourceCode);
            GL.CompileShader(this.handle);

            int result;

            GL.GetShader(this.handle, ShaderParameter.CompileStatus, out result);
            if (result == 0)
            {
                string infoLog = GL.GetShaderInfoLog(this.handle);
                throw new BackendException(string.Format("{0} Compiler error:{2}{1}", type, infoLog, Environment.NewLine));
            }

            // Remove comments from source code before extracting variables
            string sourceWithoutComments;
            {
                const string blockComments   = @"/\*(.*?)\*/";
                const string lineComments    = @"//(.*?)\r?\n";
                const string strings         = @"""((\\[^\n]|[^""\n])*)""";
                const string verbatimStrings = @"@(""[^""]*"")+";
                sourceWithoutComments = Regex.Replace(sourceCode,
                                                      blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings,
                                                      match => {
                    if (match.Value.StartsWith("/*") || match.Value.StartsWith("//"))
                    {
                        return(match.Value.StartsWith("//") ? Environment.NewLine : "");
                    }
                    else
                    {
                        return(match.Value);
                    }
                },
                                                      RegexOptions.Singleline);
            }

            // Scan remaining code chunk for variable declarations
            List <ShaderFieldInfo> varInfoList = new List <ShaderFieldInfo>();

            string[] lines = sourceWithoutComments.Split(new[] { ';', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string t in lines)
            {
                string curLine = t.TrimStart();

                ShaderFieldScope scope;
                int arrayLength;

                if (curLine.StartsWith("uniform"))
                {
                    scope = ShaderFieldScope.Uniform;
                }
                else if (curLine.StartsWith("attribute") || curLine.StartsWith("in"))
                {
                    scope = ShaderFieldScope.Attribute;
                }
                else
                {
                    continue;
                }

                string[]        curLineSplit = curLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                ShaderFieldType varType      = ShaderFieldType.Unknown;
                switch (curLineSplit[1].ToUpper())
                {
                case "FLOAT": varType = ShaderFieldType.Float; break;

                case "VEC2": varType = ShaderFieldType.Vec2; break;

                case "VEC3": varType = ShaderFieldType.Vec3; break;

                case "VEC4": varType = ShaderFieldType.Vec4; break;

                case "MAT2": varType = ShaderFieldType.Mat2; break;

                case "MAT3": varType = ShaderFieldType.Mat3; break;

                case "MAT4": varType = ShaderFieldType.Mat4; break;

                case "INT": varType = ShaderFieldType.Int; break;

                case "BOOL": varType = ShaderFieldType.Bool; break;

                case "SAMPLER2D": varType = ShaderFieldType.Sampler2D; break;
                }

                curLineSplit = curLineSplit[2].Split(new[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
                arrayLength  = (curLineSplit.Length > 1) ? int.Parse(curLineSplit[1]) : 1;

                varInfoList.Add(new ShaderFieldInfo(curLineSplit[0], varType, scope, arrayLength));
            }

            this.fields = varInfoList.ToArray();
        }
示例#10
0
        void INativeShaderPart.LoadSource(string sourceCode, ShaderType type)
        {
            // Remove shader version
            sourceCode = Regex.Replace(sourceCode, "(\\s*)#version(.*)", "");

            if (type == ShaderType.Vertex)
            {
                // Rewrite keywords
                sourceCode = Regex.Replace(sourceCode, "(\\s)in\\s", "$1attribute ");
                sourceCode = Regex.Replace(sourceCode, "(\\s)out\\s", "$1varying ");
            }
            else if (type == ShaderType.Fragment)
            {
                // Rewrite keywords
                sourceCode = Regex.Replace(sourceCode, "(\\s)in\\s", "$1varying ");
                sourceCode = Regex.Replace(sourceCode, "(\\s)out\\s(.*)", "");

                sourceCode = Regex.Replace(sourceCode, "texture\\(", "texture2D(");

                // Remove multi render targets
                sourceCode = Regex.Replace(sourceCode, "vFragColor\\[0\\]", "gl_FragColor");
                sourceCode = Regex.Replace(sourceCode, "vFragColor\\[(\\d*)\\](\\s*)=([^;]*);", "");
                sourceCode = Regex.Replace(sourceCode, "vFragColor", "gl_FragColor");
            }

            //Console.WriteLine("###\n" + sourceCode + "\n###");

            if (this.handle == null)
            {
                this.handle = GraphicsBackend.GL.CreateShader(GetOpenTKShaderType(type));
            }
            GraphicsBackend.GL.ShaderSource(this.handle, sourceCode);
            GraphicsBackend.GL.CompileShader(this.handle);

            bool result = (bool)GraphicsBackend.GL.GetShaderParameter(this.handle, WebGLRenderingContextBase.COMPILE_STATUS);

            if (!result)
            {
                string infoLog = GraphicsBackend.GL.GetShaderInfoLog(this.handle);
                throw new BackendException(string.Format("{0} Compiler error:{2}{1}", type, infoLog, Environment.NewLine));
            }

            // Remove comments from source code before extracting variables
            string sourceWithoutComments;
            {
                const string blockComments   = @"/\*(.*?)\*/";
                const string lineComments    = @"//(.*?)\r?\n";
                const string strings         = @"""((\\[^\n]|[^""\n])*)""";
                const string verbatimStrings = @"@(""[^""]*"")+";
                sourceWithoutComments = Regex.Replace(sourceCode,
                                                      blockComments + "|" + lineComments + "|" + strings + "|" + verbatimStrings,
                                                      match => {
                    if (match.Value.StartsWith("/*") || match.Value.StartsWith("//"))
                    {
                        return(match.Value.StartsWith("//") ? Environment.NewLine : "");
                    }
                    else
                    {
                        return(match.Value);
                    }
                },
                                                      RegexOptions.Singleline);
            }

            // Scan remaining code chunk for variable declarations
            List <ShaderFieldInfo> varInfoList = new List <ShaderFieldInfo>();

            string[] lines = sourceWithoutComments.Split(new[] { ';', '\n' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string t in lines)
            {
                string curLine = t.TrimStart();

                ShaderFieldScope scope;
                int arrayLength;

                if (curLine.StartsWith("uniform"))
                {
                    scope = ShaderFieldScope.Uniform;
                }
                else if (curLine.StartsWith("attribute") || curLine.StartsWith("in"))
                {
                    scope = ShaderFieldScope.Attribute;
                }
                else
                {
                    continue;
                }

                string[]        curLineSplit = curLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                ShaderFieldType varType      = ShaderFieldType.Unknown;
                switch (curLineSplit[1].ToUpper())
                {
                case "FLOAT": varType = ShaderFieldType.Float; break;

                case "VEC2": varType = ShaderFieldType.Vec2; break;

                case "VEC3": varType = ShaderFieldType.Vec3; break;

                case "VEC4": varType = ShaderFieldType.Vec4; break;

                case "MAT2": varType = ShaderFieldType.Mat2; break;

                case "MAT3": varType = ShaderFieldType.Mat3; break;

                case "MAT4": varType = ShaderFieldType.Mat4; break;

                case "INT": varType = ShaderFieldType.Int; break;

                case "BOOL": varType = ShaderFieldType.Bool; break;

                case "SAMPLER2D": varType = ShaderFieldType.Sampler2D; break;
                }

                curLineSplit = curLineSplit[2].Split(new[] { '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
                arrayLength  = (curLineSplit.Length > 1) ? int.Parse(curLineSplit[1]) : 1;

                varInfoList.Add(new ShaderFieldInfo(curLineSplit[0], varType, scope, arrayLength));
            }

            this.fields = varInfoList.ToArray();
        }
示例#11
0
        /// <summary>
        /// Parses a single shader field declaration and aggregates it with the specified list of metadata
        /// directives into a single <see cref="ShaderFieldInfo"/>. Returns null, if the specified line is
        /// not a field declaration.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="fieldMetadata"></param>
        private ShaderFieldInfo ParseFieldDeclaration(string line, IReadOnlyList <string> fieldMetadata)
        {
            // Parse the field scope and detect whether the line is a field declaration at all
            ShaderFieldScope scope;

            if (RegexUniformLine.IsMatch(line))
            {
                scope = ShaderFieldScope.Uniform;
            }
            else if (RegexAttributeLine.IsMatch(line))
            {
                scope = ShaderFieldScope.Attribute;
            }
            else
            {
                return(null);
            }

            string[] lineToken = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            string   typeToken = lineToken[1];
            string   nameToken = lineToken[2];

            // Parse the field type
            ShaderFieldType varType = ShaderFieldType.Unknown;

            switch (typeToken.ToUpper())
            {
            case "FLOAT": varType = ShaderFieldType.Float; break;

            case "VEC2": varType = ShaderFieldType.Vec2; break;

            case "VEC3": varType = ShaderFieldType.Vec3; break;

            case "VEC4": varType = ShaderFieldType.Vec4; break;

            case "MAT2": varType = ShaderFieldType.Mat2; break;

            case "MAT3": varType = ShaderFieldType.Mat3; break;

            case "MAT4": varType = ShaderFieldType.Mat4; break;

            case "INT": varType = ShaderFieldType.Int; break;

            case "BOOL": varType = ShaderFieldType.Bool; break;

            case "SAMPLER2D": varType = ShaderFieldType.Sampler2D; break;
            }

            // Parse the array token, if one exists
            int arrayLength = 1;
            int arrayStart  = nameToken.IndexOf('[');
            int arrayEnd    = nameToken.IndexOf(']');

            if (arrayStart != -1 && arrayEnd != -1)
            {
                string arrayLengthToken = nameToken.Substring(arrayStart + 1, arrayEnd - arrayStart - 1).Trim();
                arrayLength = int.Parse(arrayLengthToken);
            }

            // Parse the name token
            string name =
                (arrayStart == -1) ?
                nameToken :
                nameToken.Substring(0, arrayStart);

            // Parse field metadata for known properties
            string       description        = null;
            string       editorTypeTag      = null;
            float        minValue           = float.MinValue;
            float        maxValue           = float.MaxValue;
            const string unableToParseError = "Unable to parse shader field metadata property '{0}'. Ignoring value '{1}'";

            foreach (string metadata in fieldMetadata)
            {
                int propertyEnd = metadata.IndexOf(' ');
                if (propertyEnd == -1)
                {
                    continue;
                }
                if (propertyEnd == metadata.Length - 1)
                {
                    continue;
                }

                string property = metadata.Substring(0, propertyEnd);
                string value    = metadata.Substring(propertyEnd + 1, metadata.Length - propertyEnd - 1);
                if (property == "description")
                {
                    int descStart = value.IndexOf('"');
                    int descEnd   = value.LastIndexOf('"');
                    if (descStart == -1 || descEnd == -1)
                    {
                        Logs.Core.WriteWarning(unableToParseError, property, value);
                        continue;
                    }
                    description = value.Substring(descStart + 1, descEnd - descStart - 1);
                }
                else if (property == "editorType")
                {
                    editorTypeTag = value.Trim();
                }
                else if (property == "minValue")
                {
                    float parsedValue;
                    if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out parsedValue))
                    {
                        Logs.Core.WriteWarning(unableToParseError, property, value);
                        continue;
                    }
                    minValue = parsedValue;
                }
                else if (property == "maxValue")
                {
                    float parsedValue;
                    if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out parsedValue))
                    {
                        Logs.Core.WriteWarning(unableToParseError, property, value);
                        continue;
                    }
                    maxValue = parsedValue;
                }
                else
                {
                    Logs.Core.WriteWarning(
                        "Unknown shader field metadata property '{0}'. Ignoring value '{1}'",
                        property,
                        value);
                }
            }

            return(new ShaderFieldInfo(
                       name,
                       varType,
                       scope,
                       arrayLength,
                       editorTypeTag,
                       description,
                       minValue,
                       maxValue));
        }