func NewProgram(vertexSource, fragmentSource string) (*Program, error) { vertexId, err := newShader(vertexSource, gl.VERTEX_SHADER) if err != nil { return nil, err } fragmentId, err := newShader(fragmentSource, gl.FRAGMENT_SHADER) if err != nil { gl.DeleteShader(vertexId) return nil, err } id := gl.CreateProgram() if id == 0 { gl.DeleteShader(vertexId) gl.DeleteShader(fragmentId) return nil, fmt.Errorf("Unable to allocate program") } gl.AttachShader(id, vertexId) gl.AttachShader(id, fragmentId) gl.LinkProgram(id) var result int32 gl.GetProgramiv(id, gl.LINK_STATUS, &result) if result == int32(gl.FALSE) { var loglength int32 gl.GetProgramiv(id, gl.INFO_LOG_LENGTH, &loglength) log := make([]byte, loglength) var length int32 gl.GetProgramInfoLog(id, loglength, &length, &log[0]) gl.DeleteShader(vertexId) gl.DeleteShader(fragmentId) gl.DeleteProgram(id) return nil, fmt.Errorf("Unable to link program: %s", log[:length]) } return &Program{ id: id, vertId: vertexId, fragId: fragmentId, uniforms: uniforms(id), }, nil }
// CreateShader creates a shader object from a source file. func CreateShader(filename string, xtype uint32) uint32 { data, err := ioutil.ReadFile(filename) if err != nil { log.Fatal(err) } dataString := "#version 120\n" + string(data) + "\x00" dataSrc := gl.Str(dataString) res := gl.CreateShader(xtype) gl.ShaderSource(res, 1, &dataSrc, nil) gl.CompileShader(res) var compileOk int32 gl.GetShaderiv(res, gl.COMPILE_STATUS, &compileOk) if compileOk == gl.FALSE { PrintLog(res) gl.DeleteShader(res) } return res }
func newShader(source string, shaderType uint32) (uint32, error) { id := gl.CreateShader(shaderType) if id == 0 { return 0, fmt.Errorf("Unable to allocate shader") } ptr, free := convc.StringToC(source) defer free() gl.ShaderSource(id, 1, &ptr, nil) gl.CompileShader(id) var result int32 gl.GetShaderiv(id, gl.COMPILE_STATUS, &result) if result == int32(gl.FALSE) { var loglength int32 gl.GetShaderiv(id, gl.INFO_LOG_LENGTH, &loglength) log := make([]byte, loglength) var length int32 gl.GetShaderInfoLog(id, loglength, &length, &log[0]) gl.DeleteShader(id) return 0, fmt.Errorf("Unable to compile shader: %s", log[:length]) } return id, nil }
// DeleteShader deletes shader s. // // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteShader.xhtml func DeleteShader(s Shader) { gl.DeleteShader(s.Value) }
func (c *Context) DeleteShader(s Shader) { gl.DeleteShader(uint32(s)) }
// DeleteShader will free the shader memory. You should call this in case of // a compilation error to avoid leaking memory func (c *Context) DeleteShader(shader *Shader) { gl.DeleteShader(shader.uint32) }
func (c *Context) DeleteShader(s Shader) { _ = c.runOnContextThread(func() error { gl.DeleteShader(uint32(s)) return nil }) }
func (program *Program) Delete() { gl.DeleteProgram(program.id) gl.DeleteShader(program.vertId) gl.DeleteShader(program.fragId) }