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); } }
public ShaderFieldInfo(string name, ShaderFieldType type, ShaderFieldScope scope, int arrayLength = 1) { this.name = name; this.type = type; this.scope = scope; this.arrayLength = arrayLength; }
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] == '_'; }
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; }
public static Type GetElementPrimitive(this ShaderFieldType type) { switch (type) { default: return(typeof(float)); case ShaderFieldType.Int: return(typeof(int)); } }
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] == '_'; }
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(); }
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(); }
/// <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)); }