public bool TryBuild(out GLShaderProgram program)
        {
            if (mHasBuilt)
            {
                Trace.TraceError("Attempted to build shader program twice");

                program = null;
                return(false);
            }

            // link program
            GL.LinkProgram(mShaderProgramId);

            // check for linking errors
            GL.GetProgram(mShaderProgramId, GetProgramParameterName.LinkStatus, out int linkStatus);

            if (linkStatus == 0)
            {
                Trace.TraceError("Shader program linking failed");

                // print info log
                GL.GetProgram(mShaderProgramId, GetProgramParameterName.InfoLogLength, out int infoLogLength);
                if (infoLogLength > 0)
                {
                    GL.GetProgramInfoLog(mShaderProgramId, infoLogLength + 1, out int length, out var log);

                    Trace.TraceError(log);
                    Trace.TraceError("");
                }

                program = null;
                return(false);
            }
            else
            {
                // print info log
                GL.GetProgram(mShaderProgramId, GetProgramParameterName.InfoLogLength, out int infoLogLength);
                if (infoLogLength > 0)
                {
                    GL.GetProgramInfoLog(mShaderProgramId, infoLogLength + 1, out int length, out var log);

                    Trace.TraceInformation($"Shader program info log:");
                    Trace.TraceInformation(log);
                    Trace.TraceInformation("");
                }
            }

            DeleteAttachedShaders();

            program   = new GLShaderProgram(mShaderProgramId);
            mHasBuilt = true;

            return(true);
        }
        public static bool TryCreate(string vertexShaderFilepath, string fragmentShaderFilepath, out GLShaderProgram program)
        {
            var vertexShaderSource   = File.ReadAllText(vertexShaderFilepath);
            var fragmentShaderSource = File.ReadAllText(fragmentShaderFilepath);

            using (var builder = new GLShaderProgramBuilder())
            {
                if (!builder.TryAttachShader(ShaderType.VertexShader, vertexShaderSource))
                {
                    program = null;
                    return(false);
                }

                if (!builder.TryAttachShader(ShaderType.FragmentShader, fragmentShaderSource))
                {
                    program = null;
                    return(false);
                }

                if (!builder.TryBuild(out program))
                {
                    return(false);
                }

                return(true);
            }
        }