// CreateProgram creates, compiles, and links a gl.Program. func CreateProgram(vertexSrc, fragmentSrc string) (gl.Program, error) { program := gl.CreateProgram() if !program.Valid() { return gl.Program{}, fmt.Errorf("glutil: no programs available") } vertexShader, err := loadShader(gl.VERTEX_SHADER, vertexSrc) if err != nil { return gl.Program{}, err } fragmentShader, err := loadShader(gl.FRAGMENT_SHADER, fragmentSrc) if err != nil { gl.DeleteShader(vertexShader) return gl.Program{}, err } gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) // Flag shaders for deletion when program is unlinked. gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) if gl.GetProgrami(program, gl.LINK_STATUS) == 0 { defer gl.DeleteProgram(program) return gl.Program{}, fmt.Errorf("glutil: %s", gl.GetProgramInfoLog(program)) } return program, nil }
func (s *glShader) deleteShader() { if s.program.Valid() { gl.DeleteProgram(s.program) } if s.vertex.Valid() { gl.DeleteShader(s.vertex) } if s.fragment.Valid() { gl.DeleteShader(s.fragment) } }
func loadShader(shaderType gl.Enum, src string) (gl.Shader, error) { shader := gl.CreateShader(shaderType) if !shader.Valid() { return gl.Shader{}, fmt.Errorf("glutil: could not create shader (type %v)", shaderType) } gl.ShaderSource(shader, src) gl.CompileShader(shader) if gl.GetShaderi(shader, gl.COMPILE_STATUS) == 0 { defer gl.DeleteShader(shader) return gl.Shader{}, fmt.Errorf("shader compile: %s", gl.GetShaderInfoLog(shader)) } return shader, nil }