/// <summary> /// Compiles a VertexShader and FragmentShader to a usable shader program. /// </summary> /// <param name="VS">The input VertexShader code.</param> /// <param name="FS">The input FragmentShader code.</param> /// <param name="vars">All variables to include.</param> /// <param name="geom">The input GeometryShader code, if any.</param> /// <returns>The internal OpenGL program ID.</returns> public int CompileToProgram(string VS, string FS, string[] vars, string geom) { for (int i = 0; i < vars.Length; i++) { if (vars[i].Length > 0) { VS = VS.Replace("#define " + vars[i] + " 0", "#define " + vars[i] + " 1"); FS = FS.Replace("#define " + vars[i] + " 0", "#define " + vars[i] + " 1"); if (geom != null) { geom = geom.Replace("#define " + vars[i] + " 0", "#define " + vars[i] + " 1"); } } } int gObj = -1; VS = Includes(VS); FS = Includes(FS); if (geom != null) { geom = Includes(geom); gObj = GL.CreateShader(ShaderType.GeometryShader); GL.ShaderSource(gObj, geom); GL.CompileShader(gObj); string GS_Info = GL.GetShaderInfoLog(gObj); GL.GetShader(gObj, ShaderParameter.CompileStatus, out int GS_Status); if (GS_Status != 1) { throw new Exception("Error creating GeometryShader. Error status: " + GS_Status + ", info: " + GS_Info); } } int VertexObject = GL.CreateShader(ShaderType.VertexShader); GL.ShaderSource(VertexObject, VS); GL.CompileShader(VertexObject); string VS_Info = GL.GetShaderInfoLog(VertexObject); GL.GetShader(VertexObject, ShaderParameter.CompileStatus, out int VS_Status); if (VS_Status != 1) { throw new Exception("Error creating VertexShader. Error status: " + VS_Status + ", info: " + VS_Info); } int FragmentObject = GL.CreateShader(ShaderType.FragmentShader); GL.ShaderSource(FragmentObject, FS); GL.CompileShader(FragmentObject); string FS_Info = GL.GetShaderInfoLog(FragmentObject); GL.GetShader(FragmentObject, ShaderParameter.CompileStatus, out int FS_Status); if (FS_Status != 1) { throw new Exception("Error creating FragmentShader. Error status: " + FS_Status + ", info: " + FS_Info); } int Program = GL.CreateProgram(); GL.AttachShader(Program, FragmentObject); GL.AttachShader(Program, VertexObject); if (geom != null) { GL.AttachShader(Program, gObj); } GL.LinkProgram(Program); string str = GL.GetProgramInfoLog(Program); if (str.Length != 0) { SysConsole.Output(OutputType.INFO, "Linked shader with message: '" + str + "'" + " -- FOR: variables: " + string.Join(",", vars)); } GL.DeleteShader(FragmentObject); GL.DeleteShader(VertexObject); if (geom != null) { GL.DeleteShader(gObj); } GraphicsUtil.CheckError("Shader - Compile"); return(Program); }