/// <summary> /// Compiles the ShaderProgram. This is done automatically when loading the ShaderProgram /// or when binding it. /// </summary> public void Compile() { if (this.native == null) { this.native = DualityApp.GraphicsBackend.CreateShaderProgram(); } // Assure both shaders are compiled this.CompileIfRequired(this.vert.Res); this.CompileIfRequired(this.frag.Res); // Load the program with both shaders attached INativeShaderPart nativeVert = this.vert.Res != null ? this.vert.Res.Native : null; INativeShaderPart nativeFrag = this.frag.Res != null ? this.frag.Res.Native : null; try { this.native.LoadProgram(nativeVert, nativeFrag); this.fields = this.native.GetFields(); } catch (Exception e) { this.fields = new ShaderFieldInfo[0]; Console.WriteLine("Error loading ShaderProgram {0}:{2}{1}", this.FullName, /*Log.Exception(*/ e /*)*/, Environment.NewLine); } // Even if we failed, we tried to compile it. Don't do it again and again. this.compiled = true; }
/// <summary> /// Compiles the internal shader program of this <see cref="DrawTechnique"/>. This is /// done automatically on load and only needs to be invoked manually when the technique /// or one of its shader dependencies changed. /// </summary> public void Compile() { if (this.nativeShader == null) { this.nativeShader = DualityApp.GraphicsBackend.CreateShaderProgram(); } // Assure both shaders are compiled this.CompileIfRequired(this.vertexShader.Res); this.CompileIfRequired(this.fragmentShader.Res); // Load the program with both shaders attached INativeShaderPart nativeVert = this.vertexShader.Res != null ? this.vertexShader.Res.Native : null; INativeShaderPart nativeFrag = this.fragmentShader.Res != null ? this.fragmentShader.Res.Native : null; // Load the program with all shader parts attached try { this.nativeShader.LoadProgram(nativeVert, nativeFrag); this.shaderFields = this.nativeShader.GetFields(); } catch (Exception e) { this.shaderFields = new ShaderFieldInfo[0]; Console.WriteLine("Failed to compile DrawTechnique:{1}{0}", e, Environment.NewLine); } // Even if we failed, we tried to compile it. Don't do it again and again. this.compiled = true; }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="Duality.Resources.ShaderProgram"/>. /// </summary> public void Compile() { if (this.compiled) { return; } if (String.IsNullOrEmpty(this.source)) { return; } if (this.native == null) { this.native = DualityApp.GraphicsBackend.CreateShaderPart(); } try { this.native.LoadSource(this.source, this.Type); } catch (Exception e) { Log.Core.WriteError("Error loading Shader {0}:{2}{1}", this.FullName, Log.Exception(e), Environment.NewLine); } this.compiled = true; }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="Duality.Resources.ShaderProgram"/>. /// </summary> public void Compile() { if (string.IsNullOrEmpty(this.source)) { throw new InvalidOperationException("Can't compile a shader without any source code specified."); } if (this.native == null) { this.native = DualityApp.GraphicsBackend.CreateShaderPart(); } try { this.native.LoadSource(this.source, this.Type); } catch (Exception e) { Log.Write(LogType.Error, ""); Log.Write(LogType.Error, "Error loading Shader:"); Log.Write(LogType.Error, e.ToString()); Log.Write(LogType.Verbose, "```glsl"); Log.Write(LogType.Verbose, this.source); Log.Write(LogType.Verbose, "```"); } this.compiled = true; }
protected override void OnDisposing(bool manually) { base.OnDisposing(manually); if (this.native != null) { this.native.Dispose(); this.native = null; } }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="DrawTechnique"/>. /// </summary> public void Compile() { Logs.Core.Write("Compiling {0} shader '{1}'...", this.Type, this.FullName); Logs.Core.PushIndent(); if (string.IsNullOrEmpty(this.source)) { Logs.Core.PopIndent(); throw new InvalidOperationException("Can't compile a shader without any source code specified."); } if (this.native == null) { this.native = CoheeApp.GraphicsBackend.CreateShaderPart(); } // Preprocess the source code to include builtin shader functions string processedSource = null; ShaderFieldInfo[] fields = null; try { ShaderSourceBuilder builder = new ShaderSourceBuilder(); string typeConditional = string.Format("SHADERTYPE_{0}", this.Type).ToUpperInvariant(); builder.SetConditional(typeConditional, true); builder.SetMainChunk(this.source); foreach (string sharedChunk in CommonSourceChunks) { builder.AddSharedChunk(sharedChunk); } processedSource = builder.Build(); fields = builder.Fields.ToArray(); } catch (Exception e) { Logs.Core.WriteError("Failed to preprocess shader:{1}{0}", LogFormat.Exception(e), Environment.NewLine); } // Load the shader on the backend side if (processedSource != null) { try { this.native.LoadSource(processedSource, this.Type); } catch (Exception e) { Logs.Core.WriteError("Failed to compile shader:{1}{0}", LogFormat.Exception(e), Environment.NewLine); } } this.fields = fields; this.compiled = true; Logs.Core.PopIndent(); }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="Duality.Resources.ShaderProgram"/>. /// </summary> public void Compile() { if (string.IsNullOrEmpty(this.source)) throw new InvalidOperationException("Can't compile a shader without any source code specified."); if (this.native == null) this.native = DualityApp.GraphicsBackend.CreateShaderPart(); try { this.native.LoadSource(this.source, this.Type); } catch (Exception e) { Log.Core.WriteError("Error loading Shader {0}:{2}{1}", this.FullName, Log.Exception(e), Environment.NewLine); } this.compiled = true; }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="Duality.Resources.ShaderProgram"/>. /// </summary> public void Compile() { if (string.IsNullOrEmpty(this.source)) { throw new InvalidOperationException("Can't compile a shader without any source code specified."); } if (this.native == null) { this.native = DualityApp.GraphicsBackend.CreateShaderPart(); } try { this.native.LoadSource(this.source, this.Type); } catch (Exception e) { Console.WriteLine("Error loading Shader {0}:{2}{1}", this.FullName, /*Log.Exception(*/ e /*)*/, Environment.NewLine); } this.compiled = true; }
/// <summary> /// Compiles the ShaderProgram. This is done automatically when loading the ShaderProgram /// or when binding it. /// </summary> /// <param name="force">If true, the program is recompiled even if it already was compiled before.</param> public void Compile(bool force = false) { if (!force && this.compiled) { return; } if (this.native == null) { this.native = DualityApp.GraphicsBackend.CreateShaderProgram(); } // Assure both shaders are compiled if (this.vert.IsAvailable) { this.vert.Res.Compile(); } if (this.frag.IsAvailable) { this.frag.Res.Compile(); } // Load the program with both shaders attached INativeShaderPart nativeVert = this.vert.Res != null ? this.vert.Res.Native : null; INativeShaderPart nativeFrag = this.frag.Res != null ? this.frag.Res.Native : null; try { this.native.LoadProgram(nativeVert, nativeFrag); } catch (Exception e) { Log.Core.WriteError("Error loading ShaderProgram {0}:{2}{1}", this.FullName, Log.Exception(e), Environment.NewLine); } // Determine actual variable locations this.fields = this.native.GetFields(); this.compiled = true; }
void INativeShaderProgram.LoadProgram(INativeShaderPart vertex, INativeShaderPart fragment) { }
/// <summary> /// Compiles the shader. This is done automatically when loading the shader /// or attaching it to a <see cref="Duality.Resources.ShaderProgram"/>. /// </summary> public void Compile() { if (this.compiled) return; if (String.IsNullOrEmpty(this.source)) return; if (this.native == null) this.native = DualityApp.GraphicsBackend.CreateShaderPart(); try { this.native.LoadSource(this.source, this.Type); } catch (Exception e) { Log.Core.WriteError("Error loading Shader {0}:{2}{1}", this.FullName, Log.Exception(e), Environment.NewLine); } this.compiled = true; }
void INativeShaderProgram.LoadProgram(INativeShaderPart vertex, INativeShaderPart fragment) { DefaultOpenTKBackendPlugin.GuardSingleThreadState(); if (this.handle == 0) { this.handle = GL.CreateProgram(); } else { this.DetachShaders(); } // Attach both shaders if (vertex != null) { GL.AttachShader(this.handle, (vertex as NativeShaderPart).Handle); } if (fragment != null) { GL.AttachShader(this.handle, (fragment as NativeShaderPart).Handle); } // Link the shader program GL.LinkProgram(this.handle); int result; GL.GetProgram(this.handle, GetProgramParameterName.LinkStatus, out result); if (result == 0) { string errorLog = GL.GetProgramInfoLog(this.handle); this.RollbackAtFault(); throw new BackendException(string.Format("Linker error:{1}{0}", errorLog, Environment.NewLine)); } // Collect variable infos from sub programs { NativeShaderPart vert = vertex as NativeShaderPart; NativeShaderPart frag = fragment as NativeShaderPart; ShaderFieldInfo[] fragVarArray = frag != null ? frag.Fields : null; ShaderFieldInfo[] vertVarArray = vert != null ? vert.Fields : null; if (fragVarArray != null && vertVarArray != null) { this.fields = vertVarArray.Union(fragVarArray).ToArray(); } else if (vertVarArray != null) { this.fields = vertVarArray.ToArray(); } else { this.fields = fragVarArray.ToArray(); } } // Determine each variables location this.fieldLocations = new int[this.fields.Length]; for (int i = 0; i < this.fields.Length; i++) { if (this.fields[i].Scope == ShaderFieldScope.Uniform) { this.fieldLocations[i] = GL.GetUniformLocation(this.handle, this.fields[i].Name); } else { this.fieldLocations[i] = GL.GetAttribLocation(this.handle, this.fields[i].Name); } } }
void INativeShaderProgram.LoadProgram(INativeShaderPart vertex, INativeShaderPart fragment) { // Removed thread guards because of performance //DefaultOpenTKBackendPlugin.GuardSingleThreadState(); if (this.handle == null) { this.handle = GraphicsBackend.GL.CreateProgram(); } else { this.DetachShaders(); } if (vertex == null) { vertex = VertexShader.Minimal.Res.Native; } if (fragment == null) { fragment = FragmentShader.Minimal.Res.Native; } // Attach both shaders GraphicsBackend.GL.AttachShader(this.handle, (vertex as NativeShaderPart).Handle); GraphicsBackend.GL.AttachShader(this.handle, (fragment as NativeShaderPart).Handle); // Link the shader program GraphicsBackend.GL.LinkProgram(this.handle); bool result = (bool)GraphicsBackend.GL.GetProgramParameter(this.handle, WebGLRenderingContextBase.LINK_STATUS); if (!result) { string errorLog = GraphicsBackend.GL.GetProgramInfoLog(this.handle); this.RollbackAtFault(); throw new BackendException(string.Format("Linker error:{1}{0}", errorLog, Environment.NewLine)); } // Collect variable infos from sub programs { NativeShaderPart vert = vertex as NativeShaderPart; NativeShaderPart frag = fragment as NativeShaderPart; ShaderFieldInfo[] fragVarArray = frag != null ? frag.Fields : null; ShaderFieldInfo[] vertVarArray = vert != null ? vert.Fields : null; if (fragVarArray != null && vertVarArray != null) { this.fields = vertVarArray.Union(fragVarArray).ToArray(); } else if (vertVarArray != null) { this.fields = vertVarArray.ToArray(); } else { this.fields = fragVarArray.ToArray(); } } // Determine each variables location this.fieldLocations = new FieldLocation[this.fields.Length]; for (int i = 0; i < this.fields.Length; i++) { if (this.fields[i].Scope == ShaderFieldScope.Uniform) { this.fieldLocations[i].Uniform = GraphicsBackend.GL.GetUniformLocation(this.handle, this.fields[i].Name); } else { this.fieldLocations[i].Attrib = GraphicsBackend.GL.GetAttribLocation(this.handle, this.fields[i].Name); } } }
void INativeShaderProgram.LoadProgram(INativeShaderPart vertex, INativeShaderPart fragment) { DefaultOpenTKBackendPlugin.GuardSingleThreadState(); if (this.handle == 0) this.handle = GL.CreateProgram(); else this.DetachShaders(); // Attach both shaders if (vertex != null) GL.AttachShader(this.handle, (vertex as NativeShaderPart).Handle); if (fragment != null) GL.AttachShader(this.handle, (fragment as NativeShaderPart).Handle); // Link the shader program GL.LinkProgram(this.handle); int result; GL.GetProgram(this.handle, GetProgramParameterName.LinkStatus, out result); if (result == 0) { string errorLog = GL.GetProgramInfoLog(this.handle); this.RollbackAtFault(); throw new BackendException(string.Format("Linker error:{1}{0}", errorLog, Environment.NewLine)); } // Collect variable infos from sub programs { NativeShaderPart vert = vertex as NativeShaderPart; NativeShaderPart frag = fragment as NativeShaderPart; ShaderFieldInfo[] fragVarArray = frag != null ? frag.Fields : null; ShaderFieldInfo[] vertVarArray = vert != null ? vert.Fields : null; if (fragVarArray != null && vertVarArray != null) this.fields = vertVarArray.Union(fragVarArray).ToArray(); else if (vertVarArray != null) this.fields = vertVarArray.ToArray(); else this.fields = fragVarArray.ToArray(); } // Determine each variables location this.fieldLocations = new int[this.fields.Length]; for (int i = 0; i < this.fields.Length; i++) { if (this.fields[i].Scope == ShaderFieldScope.Uniform) this.fieldLocations[i] = GL.GetUniformLocation(this.handle, this.fields[i].Name); else this.fieldLocations[i] = GL.GetAttribLocation(this.handle, this.fields[i].Name); } // Determine whether we're using builtin shader variables this.builtinIndex = new int[this.fields.Length]; bool anyBuildinUsed = false; for (int i = 0; i < this.fields.Length; i++) { if (this.fields[i].Scope == ShaderFieldScope.Uniform) { this.builtinIndex[i] = BuiltinShaderFields.GetIndex(this.fields[i].Name); if (this.builtinIndex[i] != BuiltinShaderFields.InvalidIndex) anyBuildinUsed = true; } else { this.builtinIndex[i] = BuiltinShaderFields.InvalidIndex; } } if (!anyBuildinUsed) this.builtinIndex = new int[0]; }