void INativeShaderPart.LoadSource(string sourceCode, ShaderType type) { DefaultOpenTKBackendPlugin.GuardSingleThreadState(); this.type = type; if (this.handle == 0) { this.handle = GL.CreateShader(GetOpenTKShaderType(type)); } GL.ShaderSource(this.handle, sourceCode); GL.CompileShader(this.handle); // Log all errors and warnings from the info log string infoLog = GL.GetShaderInfoLog(this.handle); if (!string.IsNullOrWhiteSpace(infoLog)) { using (StringReader reader = new StringReader(infoLog)) { while (true) { string line = reader.ReadLine(); if (line == null) { break; } if (string.IsNullOrWhiteSpace(line)) { continue; } if (line.IndexOf("warning", StringComparison.InvariantCultureIgnoreCase) != -1) { Logs.Core.WriteWarning("{0}", line); } else if (line.IndexOf("error", StringComparison.InvariantCultureIgnoreCase) != -1) { Logs.Core.WriteError("{0}", line); } else { Logs.Core.Write("{0}", line); } } } } // If compilation failed, throw an exception int result; GL.GetShader(this.handle, ShaderParameter.CompileStatus, out result); if (result == 0) { throw new BackendException(string.Format("Failed to compile {0} shader:{2}{1}", type, infoLog, Environment.NewLine)); } }
private static GLShaderType GetOpenTKShaderType(ShaderType type) { switch (type) { default: case ShaderType.Vertex: return(GLShaderType.VertexShader); case ShaderType.Fragment: return(GLShaderType.FragmentShader); } }
private static uint GetOpenTKShaderType(ShaderType type) { switch (type) { default: case ShaderType.Vertex: return(WebGLRenderingContextBase.VERTEX_SHADER); case ShaderType.Fragment: return(WebGLRenderingContextBase.FRAGMENT_SHADER); } }
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) { 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")) 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 "SAMPLER2D": varType = ShaderFieldType.Sampler2D; break; } curLineSplit = curLineSplit[2].Split(new char[] {'[', ']'}, StringSplitOptions.RemoveEmptyEntries); arrayLength = (curLineSplit.Length > 1) ? int.Parse(curLineSplit[1]) : 1; varInfoList.Add(new ShaderFieldInfo(curLineSplit[0], varType, scope, arrayLength)); } this.fields = varInfoList.ToArray(); }
private static GLShaderType GetOpenTKShaderType(ShaderType type) { switch (type) { case ShaderType.Vertex: return GLShaderType.VertexShader; case ShaderType.Fragment: return GLShaderType.FragmentShader; } return GLShaderType.VertexShader; }
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(); }