func DetachShader( program uint32, shader uint32) { C.glDetachShader( C.GLuint(program), C.GLuint(shader)) }
// Link links the attached shader objects func (p *Program) Link() error { var val, val2 C.GLint C.glLinkProgram(p.i) C.glGetProgramiv(p.i, LINK_STATUS, &val) if val != TRUE { C.glGetProgramiv(p.i, INFO_LOG_LENGTH, &val) buf := make([]C.GLchar, val+1) C.glGetProgramInfoLog(p.i, C.GLsizei(val), nil, &buf[0]) return errors.New(C.GoString((*C.char)(&buf[0]))) } p.attr = make(map[string]C.GLuint) C.glGetProgramiv(p.i, ACTIVE_ATTRIBUTES, &val) C.glGetProgramiv(p.i, ACTIVE_ATTRIBUTE_MAX_LENGTH, &val2) buf := make([]C.char, val2) for i := C.GLuint(0); i < C.GLuint(val); i++ { C.glGetActiveAttrib(p.i, i, C.GLsizei(val2), nil, nil, nil, (*C.GLchar)(&buf[0])) p.attr[C.GoString(&buf[0])] = C.GLuint(C.glGetAttribLocation(p.i, (*C.GLchar)(&buf[0]))) } p.uni = make(map[string]C.GLint) C.glGetProgramiv(p.i, ACTIVE_UNIFORMS, &val) C.glGetProgramiv(p.i, ACTIVE_UNIFORM_MAX_LENGTH, &val2) buf = make([]C.char, val2) for i := C.GLuint(0); i < C.GLuint(val); i++ { C.glGetActiveUniform(p.i, i, C.GLsizei(val2), nil, nil, nil, (*C.GLchar)(&buf[0])) p.uni[C.GoString(&buf[0])] = C.glGetUniformLocation(p.i, (*C.GLchar)(&buf[0])) } return nil }
func (program *Program) GetAttrib(name string) VertexAttrib { cname := (*C.GLchar)(C.CString(name)) defer C.free(unsafe.Pointer(cname)) iloc := C.glGetAttribLocation(program.id, cname) if iloc < 0 { panic(fmt.Errorf("not an active uniform: %s", name)) } loc := C.GLuint(iloc) datatype := C.GLenum(0) C.glGetActiveAttrib(program.id, C.GLuint(loc), 0, nil, nil, &datatype, nil) switch datatype { case C.GL_FLOAT: return FloatAttrib{vattrib{loc}} case C.GL_FLOAT_VEC2: return Vec2Attrib{FloatAttrib{vattrib{loc}}} case C.GL_FLOAT_VEC3: return Vec3Attrib{FloatAttrib{vattrib{loc}}} case C.GL_FLOAT_VEC4: return Vec4Attrib{FloatAttrib{vattrib{loc}}} default: panic(fmt.Errorf("unsupported attribute type: %#x", datatype)) } }
func (program Program) BindFragDataLocation(colorNumber int, name string) { cname := glString(name) defer freeString(cname) C.glBindFragDataLocation(C.GLuint(program), C.GLuint(colorNumber), cname) }
func (program *Program) GetAttrib(name string) VertexAttrib { cname := (*C.GLchar)(C.CString(name)) defer C.free(unsafe.Pointer(cname)) iloc := C.glGetAttribLocation(program.id, cname) if iloc < 0 { panic(fmt.Errorf("not an active attribute: %s", name)) } loc := C.GLuint(iloc) datatype := C.GLenum(0) length := C.GLsizei(0) size := C.GLint(0) aname := [32]byte{} C.glGetActiveAttrib(program.id, C.GLuint(loc), C.GLsizei(len(aname)), &length, &size, &datatype, (*C.GLchar)(unsafe.Pointer(&aname[0]))) switch datatype { case C.GL_FLOAT: return FloatAttrib{vattrib{loc}} case C.GL_FLOAT_VEC2: return Vec2Attrib{FloatAttrib{vattrib{loc}}} case C.GL_FLOAT_VEC3: return Vec3Attrib{FloatAttrib{vattrib{loc}}} case C.GL_FLOAT_VEC4: return Vec4Attrib{FloatAttrib{vattrib{loc}}} default: panic(fmt.Errorf("unsupported attribute type: %#x", datatype)) } }
func (program Program) GetAttachedShaders() []Object { var len C.GLint C.glGetProgramiv(C.GLuint(program), C.GLenum(ACTIVE_UNIFORM_MAX_LENGTH), &len) objects := make([]Object, len) C.glGetAttachedShaders(C.GLuint(program), C.GLsizei(len), nil, *((**C.GLuint)(unsafe.Pointer(&objects)))) return objects }
func (program Program) BindAttribLocation(index AttribLocation, name string) { cname := glString(name) defer freeString(cname) C.glBindAttribLocation(C.GLuint(program), C.GLuint(index), cname) }
// void glSamplerParameteri(GLuint sampler,GLenum pname,GLint param) func (sampler SamplerObject) Parameters(parameters *SamplerParameters) { C.glSamplerParameteri(C.GLuint(sampler), C.GL_TEXTURE_WRAP_R, parameters.WrapR) C.glSamplerParameteri(C.GLuint(sampler), C.GL_TEXTURE_WRAP_S, parameters.WrapS) C.glSamplerParameteri(C.GLuint(sampler), C.GL_TEXTURE_WRAP_T, parameters.WrapT) C.glSamplerParameteri(C.GLuint(sampler), C.GL_TEXTURE_MIN_FILTER, parameters.MinFilter) C.glSamplerParameteri(C.GLuint(sampler), C.GL_TEXTURE_MAG_FILTER, parameters.MagFilter) }
func BindAttribLocation( program uint32, index uint32, name string) { s := glString(name) C.glBindAttribLocation( C.GLuint(program), C.GLuint(index), s) }
func GetActiveUniform(program, index uint, bufsize int) (size int32, type_ uint32, name string) { cs := CString(name) defer C.free(unsafe.Pointer(cs)) C.glGetActiveUniform(C.GLuint(program), C.GLuint(index), C.GLsizei(bufsize), nil, (*C.GLint)(&size), (*C.GLenum)(&type_), cs) name = GoString(cs) return }
func (program Program) GetActiveUniform(index UniformLocation) (string, GLenum, int) { var written C.GLsizei var size C.GLint var tp C.GLenum //Allocate a buffer of 64 characters to write variable names to var buffer *C.GLchar = (*C.GLchar)(C.malloc(64)) defer freeString(buffer) C.glGetActiveUniform(C.GLuint(program), C.GLuint(index), C.GLsizei(128), &written, &size, &tp, buffer) return C.GoStringN((*C.char)(buffer), C.int(written)), GLenum(tp), int(size) }
func (shader Shader) GetSource() string { var len C.GLint C.glGetShaderiv(C.GLuint(shader), C.GLenum(SHADER_SOURCE_LENGTH), &len) log := C.malloc(C.size_t(len + 1)) C.glGetShaderSource(C.GLuint(shader), C.GLsizei(len), nil, (*C.GLchar)(log)) defer C.free(log) return C.GoString((*C.char)(log)) }
func (shader Shader) GetInfoLog() string { var length C.GLint C.glGetShaderiv(C.GLuint(shader), C.GLenum(INFO_LOG_LENGTH), &length) // length is buffer size including null character if length > 1 { log := C.malloc(C.size_t(length)) defer C.free(log) C.glGetShaderInfoLog(C.GLuint(shader), C.GLsizei(length), nil, (*C.GLchar)(log)) return C.GoString((*C.char)(log)) } return "" }
func GetActiveUniform( program uint32, index uint32, bufsize Sizei, length *Sizei, size *int32, type_ *Enum, name *string) { s := glString(*name) C.glGetActiveUniform( C.GLuint(program), C.GLuint(index), C.GLsizei(bufsize), (*C.GLsizei)(length), (*C.GLint)(size), (*C.GLenum)(type_), s) name = goString(s) }
func (shader Shader) Compile() { C.glCompileShader(C.GLuint(shader)) status := C.GLint(0) C.glGetShaderiv(C.GLuint(shader), C.GL_COMPILE_STATUS, &status) if status != C.GL_TRUE { loglen := C.GLint(0) C.glGetShaderiv(C.GLuint(shader), C.GL_INFO_LOG_LENGTH, &loglen) log := (*C.GLchar)(C.malloc(C.size_t(loglen))) defer C.free(unsafe.Pointer(log)) C.glGetShaderInfoLog(C.GLuint(shader), C.GLsizei(loglen), nil, log) panic(fmt.Errorf("Failed to compile %s: %s", shader.Type(), C.GoString((*C.char)(log)))) } }
func GetShaderiv( shader uint32, pname Enum, params *int32) { C.glGetShaderiv( C.GLuint(shader), C.GLenum(pname), (*C.GLint)(params)) }
func BindRenderbuffer( target Enum, renderbuffer uint32) { C.glBindRenderbuffer( C.GLenum(target), C.GLuint(renderbuffer)) }
func (program Program) GetFragDataLocation(name string) int { cname := glString(name) defer freeString(cname) return int(C.glGetFragDataLocation(C.GLuint(program), cname)) }
// GetInfoLog returns the information log for a program object. // This method makes two OpenGL calls: one to get the info log size, and one to get the info log. func (p Program) GetInfoLog() string { sz := p.Get(ProgramInfoLogLength) cstr := (*C.char)(C.malloc(C.size_t(sz + 1))) defer C.free(unsafe.Pointer(cstr)) C.glGetProgramInfoLog(C.GLuint(p), C.GLsizei(sz), nil, (*C.GLchar)(cstr)) return C.GoString(cstr) }
// GetInfoLog returns the information log for a shader object. // This method makes two OpenGL calls: one to get the info log size, and one to get the info log. func (s Shader) GetInfoLog() string { sz := s.Get(ShaderInfoLogLength) cstr := (*C.char)(C.malloc(C.size_t(sz + 1))) defer C.free(unsafe.Pointer(cstr)) C.glGetShaderInfoLog(C.GLuint(s), C.GLsizei(sz), nil, (*C.GLchar)(cstr)) return C.GoString(cstr) }
// drawLoop is the primary drawing loop. // // After Cocoa has created an NSWindow and called prepareOpenGL, // it starts drawLoop on a locked goroutine to handle OpenGL calls. // // The screen is drawn every time a paint.Event is received, which can be // triggered either by the user or by Cocoa via drawgl (for example, when // the window is resized). func drawLoop(w *windowImpl, vba uintptr) { runtime.LockOSThread() C.makeCurrentContext(C.uintptr_t(w.ctx)) // Starting in OS X 10.11 (El Capitan), the vertex array is // occasionally getting unbound when the context changes threads. // // Avoid this by binding it again. C.glBindVertexArray(C.GLuint(vba)) if errno := C.glGetError(); errno != 0 { panic(fmt.Sprintf("gldriver: glBindVertexArray failed: %d", errno)) } workAvailable := w.worker.WorkAvailable() // TODO(crawshaw): exit this goroutine on Release. for { select { case <-workAvailable: w.worker.DoWork() case <-w.publish: loop: for { select { case <-workAvailable: w.worker.DoWork() default: break loop } } C.flushContext(C.uintptr_t(w.ctx)) w.publishDone <- screen.PublishResult{} } } }
func StencilFunc( func_ Enum, ref int32, mask uint32) { C.glStencilFunc( C.GLenum(func_), C.GLint(ref), C.GLuint(mask)) }
func GetVertexAttribiv( index uint32, pname Enum, params *int32) { C.glGetVertexAttribiv( C.GLuint(index), C.GLenum(pname), (*C.GLint)(params)) }
func BindTexture( target Enum, texture uint32) { C.glBindTexture( C.GLenum(target), C.GLuint(texture)) }
func GetUniformiv( program uint32, location int32, params *int32) { C.glGetUniformiv( C.GLuint(program), C.GLint(location), (*C.GLint)(params)) }
func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { defer func() { errstr := errDrain() log.Printf("gl.StencilFuncSeparate(%v, %v, %v, %v) %v", face, fn, ref, mask, errstr) }() C.glStencilFuncSeparate(face.c(), fn.c(), C.GLint(ref), C.GLuint(mask)) }
func GetVertexAttribPointerv( index uint32, pname Enum, pointer *Void) { C.glGetVertexAttribPointerv( C.GLuint(index), C.GLenum(pname), (*unsafe.Pointer)(*pointer)) }
func StencilMask(mask uint32) { defer func() { errstr := errDrain() log.Printf("gl.StencilMask(%v) %v", mask, errstr) }() C.glStencilMask(C.GLuint(mask)) }
func VertexAttrib2f( indx uint32, x float32, y float32) { C.glVertexAttrib2f( C.GLuint(indx), C.GLfloat(x), C.GLfloat(y)) }
func StencilMaskSeparate(face Enum, mask uint32) { defer func() { errstr := errDrain() log.Printf("gl.StencilMaskSeparate(%v, %v) %v", face, mask, errstr) }() C.glStencilMaskSeparate(face.c(), C.GLuint(mask)) }