// 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 initGL() { // Using attribute arrays in OpenGL 3.3 requires the use of a VBA. // But VBAs don't exist in ES 2. So we bind a default one. var id C.GLuint C.glGenVertexArrays(1, &id) C.glBindVertexArray(id) }
// createContext creates an OpenGL context, binds it as the current context // stored in thread-local storage, and locks the current goroutine to an os // thread. func createContext() *contextGL { // The OpenGL active context is stored in TLS. runtime.LockOSThread() c := new(contextGL) C.CGCreate(&c.ctx) // Using attribute arrays in OpenGL 3.3 requires the use of a VBA. // But VBAs don't exist in ES 2. So we bind a default one. var id C.GLuint C.glGenVertexArrays(1, &id) C.glBindVertexArray(id) return c }
// createContext creates an OpenGL context, binds it as the current context // stored in thread-local storage, and locks the current goroutine to an os // thread. func createContext() (*contextGL, error) { // The OpenGL active context is stored in TLS. runtime.LockOSThread() c := new(contextGL) if cglErr := C.CGCreate(&c.ctx); cglErr != C.kCGLNoError { return nil, fmt.Errorf("CGL: %v", C.GoString(C.CGLErrorString(cglErr))) } // Using attribute arrays in OpenGL 3.3 requires the use of a VBA. // But VBAs don't exist in ES 2. So we bind a default one. var id C.GLuint C.glGenVertexArrays(1, &id) C.glBindVertexArray(id) return c, nil }
func BindVertexArray(array VertexArray) { C.glBindVertexArray(C.GLuint(array)) }
func (array VertexArray) Bind() { C.glBindVertexArray(C.GLuint(array)) }
func (array VertexArray) Unbind() { C.glBindVertexArray(C.GLuint(0)) }