func (*backend) LinkProgram(p *gg.Program) error { pv := p.Value.(uint32) gl.LinkProgram(pv) var status int32 gl.GetProgramiv(pv, gl.LINK_STATUS, &status) if status == gl.TRUE { return nil } var logLength int32 gl.GetProgramiv(pv, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(pv, logLength, nil, gl.Str(log)) return fmt.Errorf("link program: %s", log) }
func (s *Shader) compile() error { gl.LinkProgram(s.program) var result int32 gl.GetProgramiv(s.program, gl.LINK_STATUS, &result) if result == 0 { return s.getProgramInfoLog("shader compilation error") } gl.ValidateProgram(s.program) gl.GetProgramiv(s.program, gl.VALIDATE_STATUS, &result) if result == 0 { return s.getProgramInfoLog("shader compilation error: %s") } return nil }
func initResources() (uint32, int32) { vs := CreateShader("triangle.v.glsl", gl.VERTEX_SHADER) fs := CreateShader("triangle.f.glsl", gl.FRAGMENT_SHADER) var linkOk int32 program := gl.CreateProgram() gl.AttachShader(program, vs) gl.AttachShader(program, fs) gl.LinkProgram(program) gl.GetProgramiv(program, gl.LINK_STATUS, &linkOk) if linkOk == 0 { log.Fatal("gl.LinkProgram") } gl.GenBuffers(1, &vboTriangle) gl.BindBuffer(gl.ARRAY_BUFFER, vboTriangle) gl.BufferData(gl.ARRAY_BUFFER, 4*len(triangleVertices), gl.Ptr(triangleVertices), gl.STATIC_DRAW) attribName := "coord2d\x00" attribCoord2d := gl.GetAttribLocation(program, gl.Str(attribName)) if attribCoord2d == -1 { log.Fatal("failed to bind attribute") } return program, attribCoord2d }
func initResources() uint32 { vs := CreateShader("triangle.v.glsl", gl.VERTEX_SHADER) fs := CreateShader("triangle.f.glsl", gl.FRAGMENT_SHADER) var linkOk int32 program := gl.CreateProgram() gl.AttachShader(program, vs) gl.AttachShader(program, fs) gl.LinkProgram(program) gl.GetProgramiv(program, gl.LINK_STATUS, &linkOk) if linkOk == 0 { log.Fatal("gl.LinkProgram") } gl.GenBuffers(1, &vboTriangle) gl.BindBuffer(gl.ARRAY_BUFFER, vboTriangle) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(triangleAttributes), gl.Ptr(triangleAttributes), gl.STATIC_DRAW) attributeCoord2d = gl.GetAttribLocation(program, gl.Str("coord2d\x00")) if attributeCoord2d == -1 { log.Fatal("failed to bind attribute") } attributeVColor = gl.GetAttribLocation(program, gl.Str("v_color\x00")) if attributeVColor == -1 { log.Fatal("could not bind attribute v_color") } uniformFade = gl.GetUniformLocation(program, gl.Str("fade\x00")) if uniformFade == -1 { log.Fatal("could not bind uniform fade") } return program }
func (s *Shader) getProgramInfoLog(context string) error { var logLength int32 gl.GetProgramiv(s.program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(s.program, logLength, nil, gl.Str(log)) return fmt.Errorf("%s: %s", context, log) }
func (s *Shader) getProgramInfoLog(context string) error { var logLength int32 gl.GetProgramiv(s.program, gl.INFO_LOG_LENGTH, &logLength) cLog, free := gl.Strs(strings.Repeat("\x00", int(logLength+1))) defer free() gl.GetProgramInfoLog(s.program, logLength, nil, *cLog) return fmt.Errorf("%s: %s", context, cLog) }
// GetProgramInfoLog returns the information log for a program. // // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetProgramInfoLog.xhtml func GetProgramInfoLog(p Program) string { var logLength int32 gl.GetProgramiv(p.Value, gl.INFO_LOG_LENGTH, &logLength) if logLength == 0 { return "" } logBuffer := make([]uint8, logLength) gl.GetProgramInfoLog(p.Value, logLength, nil, &logBuffer[0]) return gl.GoStr(&logBuffer[0]) }
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 }
func uniforms(id uint32) map[string]Uniform { var maxlength int32 gl.GetProgramiv(id, gl.ACTIVE_UNIFORM_MAX_LENGTH, &maxlength) var numuniforms int32 gl.GetProgramiv(id, gl.ACTIVE_UNIFORMS, &numuniforms) buf := make([]byte, maxlength) m := make(map[string]Uniform) for index := uint32(0); index < uint32(numuniforms); index++ { name, dt, siz := uniform(id, index, buf) loc := gl.GetUniformLocation(id, &buf[0]) if loc == -1 { panic(fmt.Errorf("Expected location for indexed uniform '%s'", name)) } m[name] = Uniform{ name: name, location: loc, typ: dt, siz: siz, } } return m }
func (c *Context) NewProgram(shaders []Shader) (Program, error) { p := gl.CreateProgram() if p == 0 { return 0, errors.New("glCreateProgram failed") } for _, shader := range shaders { gl.AttachShader(p, uint32(shader)) } gl.LinkProgram(p) var v int32 gl.GetProgramiv(p, gl.LINK_STATUS, &v) if v == gl.FALSE { return 0, errors.New("program error") } return Program(p), nil }
// PrintLog prints the error log for an object func PrintLog(object uint32) { var logLength int32 if gl.IsShader(object) { gl.GetShaderiv(object, gl.INFO_LOG_LENGTH, &logLength) } else if gl.IsProgram(object) { gl.GetProgramiv(object, gl.INFO_LOG_LENGTH, &logLength) } else { log.Fatal("PrintLog: not a shader or program") } infoLog := strings.Repeat("\x00", int(logLength+1)) if gl.IsShader(object) { gl.GetShaderInfoLog(object, logLength, nil, gl.Str(infoLog)) } else if gl.IsProgram(object) { gl.GetProgramInfoLog(object, logLength, nil, gl.Str(infoLog)) } log.Fatal(infoLog) }
func createProgram(vertShaderSrc string, fragShaderSrc string) uint32 { vertShader := loadShader(gl.VERTEX_SHADER, vertShaderSrc) fragShader := loadShader(gl.FRAGMENT_SHADER, fragShaderSrc) prog := gl.CreateProgram() gl.AttachShader(prog, vertShader) gl.AttachShader(prog, fragShader) gl.LinkProgram(prog) var status int32 gl.GetProgramiv(prog, gl.LINK_STATUS, &status) if status != gl.TRUE { //log := gl.GetInfoLogARB(prog) panic(fmt.Errorf("Failed to link program: , ")) } return prog }
func initResources() (uint32, int32) { vSrc0 := fixupSrc(vShaderSrc) vSrc := gl.Str(vSrc0) vs := gl.CreateShader(gl.VERTEX_SHADER) gl.ShaderSource(vs, 1, &vSrc, nil) gl.CompileShader(vs) var vok int32 gl.GetShaderiv(vs, gl.COMPILE_STATUS, &vok) if vok == 0 { log.Fatal("error in vertex shader") } fSrc := gl.Str(fShaderSrc) fs := gl.CreateShader(gl.FRAGMENT_SHADER) gl.ShaderSource(fs, 1, &fSrc, nil) gl.CompileShader(fs) var fok int32 gl.GetShaderiv(vs, gl.COMPILE_STATUS, &fok) if fok == 0 { log.Fatal("error in fragment shader") } var linkOk int32 program := gl.CreateProgram() gl.AttachShader(program, vs) gl.AttachShader(program, fs) gl.LinkProgram(program) gl.GetProgramiv(program, gl.LINK_STATUS, &linkOk) if linkOk == 0 { log.Fatal("gl.LinkProgram") } attribName := fixupSrc("coord2d") attribCoord2d := gl.GetAttribLocation(program, gl.Str(attribName)) if attribCoord2d == -1 { log.Fatal("failed to bind attribute") } return program, attribCoord2d }
func (c *Context) NewProgram(shaders []Shader) (Program, error) { var program Program if err := c.runOnContextThread(func() error { p := gl.CreateProgram() if p == 0 { return errors.New("opengl: glCreateProgram failed") } for _, shader := range shaders { gl.AttachShader(p, uint32(shader)) } gl.LinkProgram(p) var v int32 gl.GetProgramiv(p, gl.LINK_STATUS, &v) if v == gl.FALSE { return errors.New("opengl: program error") } program = Program(p) return nil }); err != nil { return 0, err } return program, nil }
// GetProgrami returns a parameter value for a program. // // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetProgramiv.xhtml func GetProgrami(p Program, pname Enum) int { var result int32 gl.GetProgramiv(p.Value, uint32(pname), &result) return int(result) }