diff --git a/app/android.go b/app/android.go index 76a69c1..9e18c1a 100644 --- a/app/android.go +++ b/app/android.go @@ -268,6 +268,10 @@ func main(f func(App)) { var mainUserFn func(App) func mainUI(vm, jniEnv, ctx uintptr) error { + var worker gl.Worker + glctx, worker = gl.NewContext() + workAvailable := worker.WorkAvailable() + donec := make(chan struct{}) go func() { mainUserFn(theApp) @@ -326,8 +330,8 @@ func mainUI(vm, jniEnv, ctx uintptr) error { } C.surface = nil theApp.sendLifecycle(lifecycle.StageAlive) - case <-gl.WorkAvailable: - gl.DoWork() + case <-workAvailable: + worker.DoWork() case <-theApp.publish: // TODO: compare a generation number to redrawGen for stale paints? if C.surface != nil { diff --git a/app/app.go b/app/app.go index 38c6d99..44cca84 100644 --- a/app/app.go +++ b/app/app.go @@ -67,6 +67,8 @@ var theApp = &app{ publishResult: make(chan PublishResult), } +var glctx gl.Context // TODO: move into theApp + func init() { theApp.eventsIn = pump(theApp.eventsOut) } @@ -76,8 +78,9 @@ func (a *app) sendLifecycle(to lifecycle.Stage) { return } a.eventsIn <- lifecycle.Event{ - From: a.lifecycleStage, - To: to, + From: a.lifecycleStage, + To: to, + DrawContext: glctx, } a.lifecycleStage = to } @@ -108,7 +111,7 @@ func (a *app) Publish() PublishResult { // // This enforces that the final receive (for this paint cycle) on // gl.WorkAvailable happens before the send on endPaint. - gl.Flush() + glctx.Flush() a.publish <- struct{}{} return <-a.publishResult } @@ -196,7 +199,7 @@ func pump(dst chan interface{}) (src chan interface{}) { func (a *app) registerGLViewportFilter() { a.RegisterFilter(func(e interface{}) interface{} { if e, ok := e.(size.Event); ok { - gl.Viewport(0, 0, e.WidthPx, e.HeightPx) + glctx.Viewport(0, 0, e.WidthPx, e.HeightPx) } return e }) diff --git a/app/darwin_amd64.go b/app/darwin_amd64.go index 77a3527..9351c82 100644 --- a/app/darwin_amd64.go +++ b/app/darwin_amd64.go @@ -78,17 +78,20 @@ func main(f func(App)) { func loop(ctx C.GLintptr) { runtime.LockOSThread() C.makeCurrentContext(ctx) + var worker gl.Worker + glctx, worker = gl.NewContext() + workAvailable := worker.WorkAvailable() for { select { - case <-gl.WorkAvailable: - gl.DoWork() + case <-workAvailable: + worker.DoWork() case <-draw: loop1: for { select { - case <-gl.WorkAvailable: - gl.DoWork() + case <-workAvailable: + worker.DoWork() case <-theApp.publish: C.CGLFlushDrawable(C.CGLGetCurrentContext()) theApp.publishResult <- PublishResult{} diff --git a/app/darwin_armx.go b/app/darwin_armx.go index 2d34771..01f43ee 100644 --- a/app/darwin_armx.go +++ b/app/darwin_armx.go @@ -119,8 +119,6 @@ func updateConfig(width, height, orientation int32) { } } -var startedgl = false - // touchIDs is the current active touches. The position in the array // is the ID, the value is the UITouch* pointer value. // @@ -168,11 +166,19 @@ func sendTouch(cTouch, cTouchType uintptr, x, y float32) { } } +var ( + worker gl.Worker + workAvailable <-chan struct{} +) + //export drawgl func drawgl(ctx uintptr) { - if !startedgl { - startedgl = true + if glctx == nil { C.setContext(unsafe.Pointer(ctx)) + + glctx, worker = gl.NewContext() + workAvailable = worker.WorkAvailable() + // TODO(crawshaw): not just on process start. theApp.sendLifecycle(lifecycle.StageFocused) } @@ -183,8 +189,8 @@ func drawgl(ctx uintptr) { for { select { - case <-gl.WorkAvailable: - gl.DoWork() + case <-workAvailable: + worker.DoWork() case <-theApp.publish: theApp.publishResult <- PublishResult{} return diff --git a/app/x11.go b/app/x11.go index e366c58..841c743 100644 --- a/app/x11.go +++ b/app/x11.go @@ -41,6 +41,11 @@ func init() { func main(f func(App)) { runtime.LockOSThread() + + var worker gl.Worker + glctx, worker = gl.NewContext() + workAvailable := worker.WorkAvailable() + C.createWindow() // TODO: send lifecycle events when e.g. the X11 window is iconified or moved off-screen. @@ -65,8 +70,8 @@ func main(f func(App)) { select { case <-donec: return - case <-gl.WorkAvailable: - gl.DoWork() + case <-workAvailable: + worker.DoWork() case <-theApp.publish: C.swapBuffers() tc = ticker.C diff --git a/event/lifecycle/lifecycle.go b/event/lifecycle/lifecycle.go index 9376fe5..b25ca68 100644 --- a/event/lifecycle/lifecycle.go +++ b/event/lifecycle/lifecycle.go @@ -45,6 +45,13 @@ const ( // Event is a lifecycle change from an old stage to a new stage. type Event struct { From, To Stage + + // DrawContext is the state used for painting, if any is valid. + // + // For OpenGL apps, a non-nil DrawContext is a gl.Context. + // + // TODO: make this an App method if we move away from an event channel? + DrawContext interface{} } // Crosses returns whether the transition from From to To crosses the stage s: diff --git a/example/audio/main.go b/example/audio/main.go index ba75ff6..e632bcb 100644 --- a/example/audio/main.go +++ b/example/audio/main.go @@ -72,6 +72,7 @@ var ( func main() { app.Main(func(a app.App) { + var glctx gl.Context visible := false for e := range a.Events() { switch e := a.Filter(e).(type) { @@ -79,7 +80,8 @@ func main() { switch e.Crosses(lifecycle.StageVisible) { case lifecycle.CrossOn: visible = true - onStart() + glctx, _ = e.DrawContext.(gl.Context) + onStart(glctx) case lifecycle.CrossOff: visible = false onStop() @@ -87,7 +89,7 @@ func main() { case size.Event: sz = e case paint.Event: - onPaint() + onPaint(glctx) a.Publish() if visible { // Keep animating. @@ -98,8 +100,8 @@ func main() { }) } -func onStart() { - images = glutil.NewImages() +func onStart(glctx gl.Context) { + images = glutil.NewImages(glctx) eng = glsprite.Engine(images) loadScene() @@ -119,9 +121,9 @@ func onStop() { player.Close() } -func onPaint() { - gl.ClearColor(1, 1, 1, 1) - gl.Clear(gl.COLOR_BUFFER_BIT) +func onPaint(glctx gl.Context) { + glctx.ClearColor(1, 1, 1, 1) + glctx.Clear(gl.COLOR_BUFFER_BIT) now := clock.Time(time.Since(startTime) * 60 / time.Second) eng.Render(scene, now, sz) } diff --git a/example/basic/main.go b/example/basic/main.go index 9756b89..bcd90e1 100644 --- a/example/basic/main.go +++ b/example/basic/main.go @@ -59,6 +59,7 @@ var ( func main() { app.Main(func(a app.App) { + var glctx gl.Context visible, sz := false, size.Event{} for e := range a.Events() { switch e := a.Filter(e).(type) { @@ -66,17 +67,18 @@ func main() { switch e.Crosses(lifecycle.StageVisible) { case lifecycle.CrossOn: visible = true - onStart() + glctx, _ = e.DrawContext.(gl.Context) + onStart(glctx) case lifecycle.CrossOff: visible = false - onStop() + onStart(glctx) } case size.Event: sz = e touchX = float32(sz.WidthPx / 2) touchY = float32(sz.HeightPx / 2) case paint.Event: - onPaint(sz) + onPaint(glctx, sz) a.Publish() if visible { // Drive the animation by preparing to paint the next frame @@ -95,52 +97,52 @@ func main() { }) } -func onStart() { +func onStart(glctx gl.Context) { var err error - program, err = glutil.CreateProgram(vertexShader, fragmentShader) + program, err = glutil.CreateProgram(glctx, vertexShader, fragmentShader) if err != nil { log.Printf("error creating GL program: %v", err) return } - buf = gl.CreateBuffer() - gl.BindBuffer(gl.ARRAY_BUFFER, buf) - gl.BufferData(gl.ARRAY_BUFFER, triangleData, gl.STATIC_DRAW) + buf = glctx.CreateBuffer() + glctx.BindBuffer(gl.ARRAY_BUFFER, buf) + glctx.BufferData(gl.ARRAY_BUFFER, triangleData, gl.STATIC_DRAW) - position = gl.GetAttribLocation(program, "position") - color = gl.GetUniformLocation(program, "color") - offset = gl.GetUniformLocation(program, "offset") + position = glctx.GetAttribLocation(program, "position") + color = glctx.GetUniformLocation(program, "color") + offset = glctx.GetUniformLocation(program, "offset") - images = glutil.NewImages() + images = glutil.NewImages(glctx) fps = debug.NewFPS(images) } -func onStop() { - gl.DeleteProgram(program) - gl.DeleteBuffer(buf) +func onStop(glctx gl.Context) { + glctx.DeleteProgram(program) + glctx.DeleteBuffer(buf) fps.Release() images.Release() } -func onPaint(sz size.Event) { - gl.ClearColor(1, 0, 0, 1) - gl.Clear(gl.COLOR_BUFFER_BIT) +func onPaint(glctx gl.Context, sz size.Event) { + glctx.ClearColor(1, 0, 0, 1) + glctx.Clear(gl.COLOR_BUFFER_BIT) - gl.UseProgram(program) + glctx.UseProgram(program) green += 0.01 if green > 1 { green = 0 } - gl.Uniform4f(color, 0, green, 0, 1) + glctx.Uniform4f(color, 0, green, 0, 1) - gl.Uniform2f(offset, touchX/float32(sz.WidthPx), touchY/float32(sz.HeightPx)) + glctx.Uniform2f(offset, touchX/float32(sz.WidthPx), touchY/float32(sz.HeightPx)) - gl.BindBuffer(gl.ARRAY_BUFFER, buf) - gl.EnableVertexAttribArray(position) - gl.VertexAttribPointer(position, coordsPerVertex, gl.FLOAT, false, 0, 0) - gl.DrawArrays(gl.TRIANGLES, 0, vertexCount) - gl.DisableVertexAttribArray(position) + glctx.BindBuffer(gl.ARRAY_BUFFER, buf) + glctx.EnableVertexAttribArray(position) + glctx.VertexAttribPointer(position, coordsPerVertex, gl.FLOAT, false, 0, 0) + glctx.DrawArrays(gl.TRIANGLES, 0, vertexCount) + glctx.DisableVertexAttribArray(position) fps.Draw(sz) } diff --git a/example/network/main.go b/example/network/main.go index aee316c..6e29a2d 100644 --- a/example/network/main.go +++ b/example/network/main.go @@ -43,9 +43,11 @@ import ( "net/http" "golang.org/x/mobile/app" + "golang.org/x/mobile/event/lifecycle" "golang.org/x/mobile/event/paint" "golang.org/x/mobile/event/size" "golang.org/x/mobile/exp/app/debug" + "golang.org/x/mobile/exp/gl/glutil" "golang.org/x/mobile/gl" ) @@ -54,6 +56,7 @@ func main() { go checkNetwork() app.Main(func(a app.App) { + var glctx gl.Context det, sz := determined, size.Event{} for { select { @@ -63,10 +66,17 @@ func main() { case e := <-a.Events(): switch e := a.Filter(e).(type) { + case lifecycle.Event: + glctx, _ = e.DrawContext.(gl.Context) + if glctx != nil { + glctx = e.DrawContext.(gl.Context) + images = glutil.NewImages(glctx) + fps = debug.NewFPS(images) + } case size.Event: sz = e case paint.Event: - onDraw(sz) + onDraw(glctx, sz) a.Publish() } } @@ -75,6 +85,8 @@ func main() { } var ( + images *glutil.Images + fps *debug.FPS determined = make(chan struct{}) ok = false ) @@ -89,18 +101,18 @@ func checkNetwork() { ok = true } -func onDraw(sz size.Event) { +func onDraw(glctx gl.Context, sz size.Event) { select { case <-determined: if ok { - gl.ClearColor(0, 1, 0, 1) + glctx.ClearColor(0, 1, 0, 1) } else { - gl.ClearColor(1, 0, 0, 1) + glctx.ClearColor(1, 0, 0, 1) } default: - gl.ClearColor(0, 0, 0, 1) + glctx.ClearColor(0, 0, 0, 1) } - gl.Clear(gl.COLOR_BUFFER_BIT) + glctx.Clear(gl.COLOR_BUFFER_BIT) - debug.DrawFPS(sz) + fps.Draw(sz) } diff --git a/exp/gl/glutil/glimage.go b/exp/gl/glutil/glimage.go index 0405adc..497fd89 100644 --- a/exp/gl/glutil/glimage.go +++ b/exp/gl/glutil/glimage.go @@ -20,6 +20,7 @@ import ( // Images maintains the shared state used by a set of *Image objects. type Images struct { + glctx gl.Context quadXY gl.Buffer quadUV gl.Buffer program gl.Program @@ -29,35 +30,33 @@ type Images struct { inUV gl.Attrib textureSample gl.Uniform - // TODO(crawshaw): store *gl.Context - mu sync.Mutex activeImages int } // NewImages creates an *Images. -// TODO(crawshaw): take *gl.Context parameter -func NewImages() *Images { - program, err := CreateProgram(vertexShader, fragmentShader) +func NewImages(glctx gl.Context) *Images { + program, err := CreateProgram(glctx, vertexShader, fragmentShader) if err != nil { panic(err) } p := &Images{ - quadXY: gl.CreateBuffer(), - quadUV: gl.CreateBuffer(), + glctx: glctx, + quadXY: glctx.CreateBuffer(), + quadUV: glctx.CreateBuffer(), program: program, - pos: gl.GetAttribLocation(program, "pos"), - mvp: gl.GetUniformLocation(program, "mvp"), - uvp: gl.GetUniformLocation(program, "uvp"), - inUV: gl.GetAttribLocation(program, "inUV"), - textureSample: gl.GetUniformLocation(program, "textureSample"), + pos: glctx.GetAttribLocation(program, "pos"), + mvp: glctx.GetUniformLocation(program, "mvp"), + uvp: glctx.GetUniformLocation(program, "uvp"), + inUV: glctx.GetAttribLocation(program, "inUV"), + textureSample: glctx.GetUniformLocation(program, "textureSample"), } - gl.BindBuffer(gl.ARRAY_BUFFER, p.quadXY) - gl.BufferData(gl.ARRAY_BUFFER, quadXYCoords, gl.STATIC_DRAW) - gl.BindBuffer(gl.ARRAY_BUFFER, p.quadUV) - gl.BufferData(gl.ARRAY_BUFFER, quadUVCoords, gl.STATIC_DRAW) + glctx.BindBuffer(gl.ARRAY_BUFFER, p.quadXY) + glctx.BufferData(gl.ARRAY_BUFFER, quadXYCoords, gl.STATIC_DRAW) + glctx.BindBuffer(gl.ARRAY_BUFFER, p.quadUV) + glctx.BufferData(gl.ARRAY_BUFFER, quadUVCoords, gl.STATIC_DRAW) return p } @@ -76,9 +75,9 @@ func (p *Images) Release() { panic("glutil.Images.Release called, but active *Image objects remain") } - gl.DeleteProgram(p.program) - gl.DeleteBuffer(p.quadXY) - gl.DeleteBuffer(p.quadUV) + p.glctx.DeleteProgram(p.program) + p.glctx.DeleteBuffer(p.quadXY) + p.glctx.DeleteBuffer(p.quadUV) p.program = gl.Program{} } @@ -122,14 +121,14 @@ func (p *Images) NewImage(w, h int) *Image { p.activeImages++ p.mu.Unlock() - img.gltex = gl.CreateTexture() + img.gltex = p.glctx.CreateTexture() - gl.BindTexture(gl.TEXTURE_2D, img.gltex) - gl.TexImage2D(gl.TEXTURE_2D, 0, img.width, img.height, gl.RGBA, gl.UNSIGNED_BYTE, nil) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) - gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) + p.glctx.BindTexture(gl.TEXTURE_2D, img.gltex) + p.glctx.TexImage2D(gl.TEXTURE_2D, 0, img.width, img.height, gl.RGBA, gl.UNSIGNED_BYTE, nil) + p.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR) + p.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR) + p.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE) + p.glctx.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE) runtime.SetFinalizer(img, (*Image).Release) return img @@ -145,8 +144,8 @@ func roundToPower2(x int) int { // Upload copies the host image data to the GL device. func (img *Image) Upload() { - gl.BindTexture(gl.TEXTURE_2D, img.gltex) - gl.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, img.width, img.height, gl.RGBA, gl.UNSIGNED_BYTE, img.RGBA.Pix) + img.images.glctx.BindTexture(gl.TEXTURE_2D, img.gltex) + img.images.glctx.TexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, img.width, img.height, gl.RGBA, gl.UNSIGNED_BYTE, img.RGBA.Pix) } // Release invalidates the Image and removes any underlying data structures. @@ -156,7 +155,7 @@ func (img *Image) Release() { return } - gl.DeleteTexture(img.gltex) + img.images.glctx.DeleteTexture(img.gltex) img.gltex = gl.Texture{} img.images.mu.Lock() @@ -168,9 +167,10 @@ func (img *Image) Release() { // three of its corners, in the current GL framebuffer. func (img *Image) Draw(sz size.Event, topLeft, topRight, bottomLeft geom.Point, srcBounds image.Rectangle) { glimage := img.images + glctx := img.images.glctx // TODO(crawshaw): Adjust viewport for the top bar on android? - gl.UseProgram(glimage.program) + glctx.UseProgram(glimage.program) { // We are drawing a parallelogram PQRS, defined by three of its // corners, onto the entire GL framebuffer ABCD. The two quads may @@ -226,7 +226,7 @@ func (img *Image) Draw(sz size.Event, topLeft, topRight, bottomLeft geom.Point, // which gives: // a00 = (2*qx2 - 2*px2) / 2 = qx2 - px2 // and similarly for the other elements of a. - writeAffine(glimage.mvp, &f32.Affine{{ + writeAffine(glctx, glimage.mvp, &f32.Affine{{ qx2 - px2, px2 - sx2, qx2 + sx2, @@ -261,7 +261,7 @@ func (img *Image) Draw(sz size.Event, topLeft, topRight, bottomLeft geom.Point, // a10 + 0 + a12 = qy = py // 0 + a01 + a02 = sx = px // 0 + a11 + a12 = sy - writeAffine(glimage.uvp, &f32.Affine{{ + writeAffine(glctx, glimage.uvp, &f32.Affine{{ qx - px, 0, px, @@ -272,22 +272,22 @@ func (img *Image) Draw(sz size.Event, topLeft, topRight, bottomLeft geom.Point, }}) } - gl.ActiveTexture(gl.TEXTURE0) - gl.BindTexture(gl.TEXTURE_2D, img.gltex) - gl.Uniform1i(glimage.textureSample, 0) + glctx.ActiveTexture(gl.TEXTURE0) + glctx.BindTexture(gl.TEXTURE_2D, img.gltex) + glctx.Uniform1i(glimage.textureSample, 0) - gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadXY) - gl.EnableVertexAttribArray(glimage.pos) - gl.VertexAttribPointer(glimage.pos, 2, gl.FLOAT, false, 0, 0) + glctx.BindBuffer(gl.ARRAY_BUFFER, glimage.quadXY) + glctx.EnableVertexAttribArray(glimage.pos) + glctx.VertexAttribPointer(glimage.pos, 2, gl.FLOAT, false, 0, 0) - gl.BindBuffer(gl.ARRAY_BUFFER, glimage.quadUV) - gl.EnableVertexAttribArray(glimage.inUV) - gl.VertexAttribPointer(glimage.inUV, 2, gl.FLOAT, false, 0, 0) + glctx.BindBuffer(gl.ARRAY_BUFFER, glimage.quadUV) + glctx.EnableVertexAttribArray(glimage.inUV) + glctx.VertexAttribPointer(glimage.inUV, 2, gl.FLOAT, false, 0, 0) - gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) + glctx.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) - gl.DisableVertexAttribArray(glimage.pos) - gl.DisableVertexAttribArray(glimage.inUV) + glctx.DisableVertexAttribArray(glimage.pos) + glctx.DisableVertexAttribArray(glimage.inUV) } var quadXYCoords = f32.Bytes(binary.LittleEndian, diff --git a/exp/gl/glutil/glutil.go b/exp/gl/glutil/glutil.go index 2ac6c87..d742913 100644 --- a/exp/gl/glutil/glutil.go +++ b/exp/gl/glutil/glutil.go @@ -14,53 +14,53 @@ import ( ) // CreateProgram creates, compiles, and links a gl.Program. -func CreateProgram(vertexSrc, fragmentSrc string) (gl.Program, error) { - program := gl.CreateProgram() +func CreateProgram(glctx gl.Context, vertexSrc, fragmentSrc string) (gl.Program, error) { + program := glctx.CreateProgram() if program.Value == 0 { return gl.Program{}, fmt.Errorf("glutil: no programs available") } - vertexShader, err := loadShader(gl.VERTEX_SHADER, vertexSrc) + vertexShader, err := loadShader(glctx, gl.VERTEX_SHADER, vertexSrc) if err != nil { return gl.Program{}, err } - fragmentShader, err := loadShader(gl.FRAGMENT_SHADER, fragmentSrc) + fragmentShader, err := loadShader(glctx, gl.FRAGMENT_SHADER, fragmentSrc) if err != nil { - gl.DeleteShader(vertexShader) + glctx.DeleteShader(vertexShader) return gl.Program{}, err } - gl.AttachShader(program, vertexShader) - gl.AttachShader(program, fragmentShader) - gl.LinkProgram(program) + glctx.AttachShader(program, vertexShader) + glctx.AttachShader(program, fragmentShader) + glctx.LinkProgram(program) // Flag shaders for deletion when program is unlinked. - gl.DeleteShader(vertexShader) - gl.DeleteShader(fragmentShader) + glctx.DeleteShader(vertexShader) + glctx.DeleteShader(fragmentShader) - if gl.GetProgrami(program, gl.LINK_STATUS) == 0 { - defer gl.DeleteProgram(program) - return gl.Program{}, fmt.Errorf("glutil: %s", gl.GetProgramInfoLog(program)) + if glctx.GetProgrami(program, gl.LINK_STATUS) == 0 { + defer glctx.DeleteProgram(program) + return gl.Program{}, fmt.Errorf("glutil: %s", glctx.GetProgramInfoLog(program)) } return program, nil } -func loadShader(shaderType gl.Enum, src string) (gl.Shader, error) { - shader := gl.CreateShader(shaderType) +func loadShader(glctx gl.Context, shaderType gl.Enum, src string) (gl.Shader, error) { + shader := glctx.CreateShader(shaderType) if shader.Value == 0 { 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)) + glctx.ShaderSource(shader, src) + glctx.CompileShader(shader) + if glctx.GetShaderi(shader, gl.COMPILE_STATUS) == 0 { + defer glctx.DeleteShader(shader) + return gl.Shader{}, fmt.Errorf("shader compile: %s", glctx.GetShaderInfoLog(shader)) } return shader, nil } // writeAffine writes the contents of an Affine to a 3x3 matrix GL uniform. -func writeAffine(u gl.Uniform, a *f32.Affine) { +func writeAffine(glctx gl.Context, u gl.Uniform, a *f32.Affine) { var m [9]float32 m[0*3+0] = a[0][0] m[0*3+1] = a[1][0] @@ -71,5 +71,5 @@ func writeAffine(u gl.Uniform, a *f32.Affine) { m[2*3+0] = a[0][2] m[2*3+1] = a[1][2] m[2*3+2] = 1 - gl.UniformMatrix3fv(u, m[:]) + glctx.UniformMatrix3fv(u, m[:]) } diff --git a/gl/doc.go b/gl/doc.go index 1309f43..1ea6efb 100644 --- a/gl/doc.go +++ b/gl/doc.go @@ -14,9 +14,7 @@ https://www.khronos.org/opengles/sdk/docs/man/ One notable departure from the C API is the introduction of types to represent common uses of GLint: Texture, Surface, Buffer, etc. -Calls are not safe for concurrent use. However calls can be made from -any goroutine, the gl package removes the notion of thread-local -context. +Debug Logging A tracing version of the OpenGL bindings is behind the `gldebug` build tag. It acts as a simplified version of apitrace. Build your Go binary diff --git a/gl/gendebug.go b/gl/gendebug.go index 67fa42d..9dc7c5c 100644 --- a/gl/gendebug.go +++ b/gl/gendebug.go @@ -84,14 +84,14 @@ func main() { for _, d := range f.Decls { // Before: - // func StencilMask(mask uint32) { + // func (ctx *context) StencilMask(mask uint32) { // C.glStencilMask(C.GLuint(mask)) // } // // After: - // func StencilMask(mask uint32) { + // func (ctx *context) StencilMask(mask uint32) { // defer func() { - // errstr := errDrain() + // errstr := ctx.errDrain() // log.Printf("gl.StencilMask(%v) %v", mask, errstr) // }() // C.glStencilMask(C.GLuint(mask)) @@ -100,7 +100,7 @@ func main() { if !ok { continue } - if fn.Recv != nil { + if fn.Recv == nil || fn.Recv.List[0].Names[0].Name != "ctx" { continue } @@ -112,7 +112,7 @@ func main() { ) // Print function signature. - fmt.Fprintf(buf, "func %s(", fn.Name.Name) + fmt.Fprintf(buf, "func (ctx *context) %s(", fn.Name.Name) for i, p := range fn.Type.Params.List { if i > 0 { fmt.Fprint(buf, ", ") @@ -162,7 +162,7 @@ func main() { if !skip { // Insert a defer block for tracing. fmt.Fprintf(buf, "defer func() {\n") - fmt.Fprintf(buf, "\terrstr := errDrain()\n") + fmt.Fprintf(buf, "\terrstr := ctx.errDrain()\n") switch fn.Name.Name { case "GetUniformLocation", "GetAttribLocation": fmt.Fprintf(buf, "\tr0.name = name\n") @@ -243,10 +243,10 @@ import ( "unsafe" ) -func errDrain() string { +func (ctx *context) errDrain() string { var errs []Enum for { - e := GetError() + e := ctx.GetError() if e == 0 { break } diff --git a/gl/gl.go b/gl/gl.go index e10c1ae..45f0103 100644 --- a/gl/gl.go +++ b/gl/gl.go @@ -10,7 +10,7 @@ package gl // TODO(crawshaw): build on more host platforms (makes it easier to gobind). // TODO(crawshaw): expand to cover OpenGL ES 3. // TODO(crawshaw): should functions on specific types become methods? E.g. -// func (t Texture) Bind(target Enum) +// func (t Texture) Bind(target Enum) // this seems natural in Go, but moves us slightly // further away from the underlying OpenGL spec. @@ -22,11 +22,8 @@ import ( "unsafe" ) -// ActiveTexture sets the active texture unit. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glActiveTexture.xhtml -func ActiveTexture(texture Enum) { - enqueue(call{ +func (ctx *context) ActiveTexture(texture Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnActiveTexture, a0: texture.c(), @@ -34,11 +31,8 @@ func ActiveTexture(texture Enum) { }) } -// AttachShader attaches a shader to a program. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glAttachShader.xhtml -func AttachShader(p Program, s Shader) { - enqueue(call{ +func (ctx *context) AttachShader(p Program, s Shader) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnAttachShader, a0: p.c(), @@ -47,12 +41,8 @@ func AttachShader(p Program, s Shader) { }) } -// BindAttribLocation binds a vertex attribute index with a named -// variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBindAttribLocation.xhtml -func BindAttribLocation(p Program, a Attrib, name string) { - enqueue(call{ +func (ctx *context) BindAttribLocation(p Program, a Attrib, name string) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindAttribLocation, a0: p.c(), @@ -62,11 +52,8 @@ func BindAttribLocation(p Program, a Attrib, name string) { }) } -// BindBuffer binds a buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBindBuffer.xhtml -func BindBuffer(target Enum, b Buffer) { - enqueue(call{ +func (ctx *context) BindBuffer(target Enum, b Buffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindBuffer, a0: target.c(), @@ -75,11 +62,8 @@ func BindBuffer(target Enum, b Buffer) { }) } -// BindFramebuffer binds a framebuffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBindFramebuffer.xhtml -func BindFramebuffer(target Enum, fb Framebuffer) { - enqueue(call{ +func (ctx *context) BindFramebuffer(target Enum, fb Framebuffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindFramebuffer, a0: target.c(), @@ -88,11 +72,8 @@ func BindFramebuffer(target Enum, fb Framebuffer) { }) } -// BindRenderbuffer binds a render buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBindRenderbuffer.xhtml -func BindRenderbuffer(target Enum, rb Renderbuffer) { - enqueue(call{ +func (ctx *context) BindRenderbuffer(target Enum, rb Renderbuffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindRenderbuffer, a0: target.c(), @@ -101,11 +82,8 @@ func BindRenderbuffer(target Enum, rb Renderbuffer) { }) } -// BindTexture binds a texture. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBindTexture.xhtml -func BindTexture(target Enum, t Texture) { - enqueue(call{ +func (ctx *context) BindTexture(target Enum, t Texture) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindTexture, a0: target.c(), @@ -114,11 +92,8 @@ func BindTexture(target Enum, t Texture) { }) } -// BlendColor sets the blend color. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendColor.xhtml -func BlendColor(red, green, blue, alpha float32) { - enqueue(call{ +func (ctx *context) BlendColor(red, green, blue, alpha float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendColor, a0: C.uintptr_t(math.Float32bits(red)), @@ -129,11 +104,8 @@ func BlendColor(red, green, blue, alpha float32) { }) } -// BlendEquation sets both RGB and alpha blend equations. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendEquation.xhtml -func BlendEquation(mode Enum) { - enqueue(call{ +func (ctx *context) BlendEquation(mode Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendEquation, a0: mode.c(), @@ -141,11 +113,8 @@ func BlendEquation(mode Enum) { }) } -// BlendEquationSeparate sets RGB and alpha blend equations separately. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendEquationSeparate.xhtml -func BlendEquationSeparate(modeRGB, modeAlpha Enum) { - enqueue(call{ +func (ctx *context) BlendEquationSeparate(modeRGB, modeAlpha Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendEquationSeparate, a0: modeRGB.c(), @@ -154,11 +123,8 @@ func BlendEquationSeparate(modeRGB, modeAlpha Enum) { }) } -// BlendFunc sets the pixel blending factors. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendFunc.xhtml -func BlendFunc(sfactor, dfactor Enum) { - enqueue(call{ +func (ctx *context) BlendFunc(sfactor, dfactor Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendFunc, a0: sfactor.c(), @@ -167,11 +133,8 @@ func BlendFunc(sfactor, dfactor Enum) { }) } -// BlendFunc sets the pixel RGB and alpha blending factors separately. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendFuncSeparate.xhtml -func BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) { - enqueue(call{ +func (ctx *context) BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendFuncSeparate, a0: sfactorRGB.c(), @@ -182,11 +145,8 @@ func BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) }) } -// BufferData creates a new data store for the bound buffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBufferData.xhtml -func BufferData(target Enum, src []byte, usage Enum) { - enqueue(call{ +func (ctx *context) BufferData(target Enum, src []byte, usage Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBufferData, a0: target.c(), @@ -198,11 +158,8 @@ func BufferData(target Enum, src []byte, usage Enum) { }) } -// BufferInit creates a new uninitialized data store for the bound buffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBufferData.xhtml -func BufferInit(target Enum, size int, usage Enum) { - enqueue(call{ +func (ctx *context) BufferInit(target Enum, size int, usage Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBufferData, a0: target.c(), @@ -213,11 +170,8 @@ func BufferInit(target Enum, size int, usage Enum) { }) } -// BufferSubData sets some of data in the bound buffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glBufferSubData.xhtml -func BufferSubData(target Enum, offset int, data []byte) { - enqueue(call{ +func (ctx *context) BufferSubData(target Enum, offset int, data []byte) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBufferSubData, a0: target.c(), @@ -229,12 +183,8 @@ func BufferSubData(target Enum, offset int, data []byte) { }) } -// CheckFramebufferStatus reports the completeness status of the -// active framebuffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCheckFramebufferStatus.xhtml -func CheckFramebufferStatus(target Enum) Enum { - return Enum(enqueue(call{ +func (ctx *context) CheckFramebufferStatus(target Enum) Enum { + return Enum(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCheckFramebufferStatus, a0: target.c(), @@ -243,14 +193,8 @@ func CheckFramebufferStatus(target Enum) Enum { })) } -// Clear clears the window. -// -// The behavior of Clear is influenced by the pixel ownership test, -// the scissor test, dithering, and the buffer writemasks. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glClear.xhtml -func Clear(mask Enum) { - enqueue(call{ +func (ctx *context) Clear(mask Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClear, a0: C.uintptr_t(mask), @@ -258,11 +202,8 @@ func Clear(mask Enum) { }) } -// ClearColor specifies the RGBA values used to clear color buffers. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glClearColor.xhtml -func ClearColor(red, green, blue, alpha float32) { - enqueue(call{ +func (ctx *context) ClearColor(red, green, blue, alpha float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClearColor, a0: C.uintptr_t(math.Float32bits(red)), @@ -273,11 +214,8 @@ func ClearColor(red, green, blue, alpha float32) { }) } -// ClearDepthf sets the depth value used to clear the depth buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glClearDepthf.xhtml -func ClearDepthf(d float32) { - enqueue(call{ +func (ctx *context) ClearDepthf(d float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClearDepthf, a0: C.uintptr_t(math.Float32bits(d)), @@ -285,11 +223,8 @@ func ClearDepthf(d float32) { }) } -// ClearStencil sets the index used to clear the stencil buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glClearStencil.xhtml -func ClearStencil(s int) { - enqueue(call{ +func (ctx *context) ClearStencil(s int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClearStencil, a0: C.uintptr_t(s), @@ -297,12 +232,8 @@ func ClearStencil(s int) { }) } -// ColorMask specifies whether color components in the framebuffer -// can be written. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glColorMask.xhtml -func ColorMask(red, green, blue, alpha bool) { - enqueue(call{ +func (ctx *context) ColorMask(red, green, blue, alpha bool) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnColorMask, a0: glBoolean(red), @@ -313,11 +244,8 @@ func ColorMask(red, green, blue, alpha bool) { }) } -// CompileShader compiles the source code of s. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCompileShader.xhtml -func CompileShader(s Shader) { - enqueue(call{ +func (ctx *context) CompileShader(s Shader) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCompileShader, a0: s.c(), @@ -325,11 +253,8 @@ func CompileShader(s Shader) { }) } -// CompressedTexImage2D writes a compressed 2D texture. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCompressedTexImage2D.xhtml -func CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) { - enqueue(call{ +func (ctx *context) CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCompressedTexImage2D, a0: target.c(), @@ -345,11 +270,8 @@ func CompressedTexImage2D(target Enum, level int, internalformat Enum, width, he }) } -// CompressedTexSubImage2D writes a subregion of a compressed 2D texture. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCompressedTexSubImage2D.xhtml -func CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) { - enqueue(call{ +func (ctx *context) CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCompressedTexSubImage2D, a0: target.c(), @@ -366,11 +288,8 @@ func CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height }) } -// CopyTexImage2D writes a 2D texture from the current framebuffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCopyTexImage2D.xhtml -func CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) { - enqueue(call{ +func (ctx *context) CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCopyTexImage2D, a0: target.c(), @@ -385,12 +304,8 @@ func CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, he }) } -// CopyTexSubImage2D writes a 2D texture subregion from the -// current framebuffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCopyTexSubImage2D.xhtml -func CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { - enqueue(call{ +func (ctx *context) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCopyTexSubImage2D, a0: target.c(), @@ -405,11 +320,8 @@ func CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height }) } -// CreateBuffer creates a buffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGenBuffers.xhtml -func CreateBuffer() Buffer { - return Buffer{Value: uint32(enqueue(call{ +func (ctx *context) CreateBuffer() Buffer { + return Buffer{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenBuffer, }, @@ -417,11 +329,8 @@ func CreateBuffer() Buffer { }))} } -// CreateFramebuffer creates a framebuffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGenFramebuffers.xhtml -func CreateFramebuffer() Framebuffer { - return Framebuffer{Value: uint32(enqueue(call{ +func (ctx *context) CreateFramebuffer() Framebuffer { + return Framebuffer{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenFramebuffer, }, @@ -429,11 +338,8 @@ func CreateFramebuffer() Framebuffer { }))} } -// CreateProgram creates a new empty program object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCreateProgram.xhtml -func CreateProgram() Program { - return Program{Value: uint32(enqueue(call{ +func (ctx *context) CreateProgram() Program { + return Program{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCreateProgram, }, @@ -441,11 +347,8 @@ func CreateProgram() Program { }))} } -// CreateRenderbuffer create a renderbuffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGenRenderbuffers.xhtml -func CreateRenderbuffer() Renderbuffer { - return Renderbuffer{Value: uint32(enqueue(call{ +func (ctx *context) CreateRenderbuffer() Renderbuffer { + return Renderbuffer{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenRenderbuffer, }, @@ -453,11 +356,8 @@ func CreateRenderbuffer() Renderbuffer { }))} } -// CreateShader creates a new empty shader object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCreateShader.xhtml -func CreateShader(ty Enum) Shader { - return Shader{Value: uint32(enqueue(call{ +func (ctx *context) CreateShader(ty Enum) Shader { + return Shader{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCreateShader, a0: C.uintptr_t(ty), @@ -466,11 +366,8 @@ func CreateShader(ty Enum) Shader { }))} } -// CreateTexture creates a texture object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGenTextures.xhtml -func CreateTexture() Texture { - return Texture{Value: uint32(enqueue(call{ +func (ctx *context) CreateTexture() Texture { + return Texture{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenTexture, }, @@ -478,13 +375,8 @@ func CreateTexture() Texture { }))} } -// CullFace specifies which polygons are candidates for culling. -// -// Valid modes: FRONT, BACK, FRONT_AND_BACK. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glCullFace.xhtml -func CullFace(mode Enum) { - enqueue(call{ +func (ctx *context) CullFace(mode Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCullFace, a0: mode.c(), @@ -492,11 +384,8 @@ func CullFace(mode Enum) { }) } -// DeleteBuffer deletes the given buffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteBuffers.xhtml -func DeleteBuffer(v Buffer) { - enqueue(call{ +func (ctx *context) DeleteBuffer(v Buffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteBuffer, a0: C.uintptr_t(v.Value), @@ -504,11 +393,8 @@ func DeleteBuffer(v Buffer) { }) } -// DeleteFramebuffer deletes the given framebuffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteFramebuffers.xhtml -func DeleteFramebuffer(v Framebuffer) { - enqueue(call{ +func (ctx *context) DeleteFramebuffer(v Framebuffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteFramebuffer, a0: C.uintptr_t(v.Value), @@ -516,11 +402,8 @@ func DeleteFramebuffer(v Framebuffer) { }) } -// DeleteProgram deletes the given program object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteProgram.xhtml -func DeleteProgram(p Program) { - enqueue(call{ +func (ctx *context) DeleteProgram(p Program) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteProgram, a0: p.c(), @@ -528,11 +411,8 @@ func DeleteProgram(p Program) { }) } -// DeleteRenderbuffer deletes the given render buffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteRenderbuffers.xhtml -func DeleteRenderbuffer(v Renderbuffer) { - enqueue(call{ +func (ctx *context) DeleteRenderbuffer(v Renderbuffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteRenderbuffer, a0: v.c(), @@ -540,11 +420,8 @@ func DeleteRenderbuffer(v Renderbuffer) { }) } -// DeleteShader deletes shader s. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteShader.xhtml -func DeleteShader(s Shader) { - enqueue(call{ +func (ctx *context) DeleteShader(s Shader) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteShader, a0: s.c(), @@ -552,11 +429,8 @@ func DeleteShader(s Shader) { }) } -// DeleteTexture deletes the given texture object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteTextures.xhtml -func DeleteTexture(v Texture) { - enqueue(call{ +func (ctx *context) DeleteTexture(v Texture) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteTexture, a0: v.c(), @@ -564,21 +438,8 @@ func DeleteTexture(v Texture) { }) } -// DepthFunc sets the function used for depth buffer comparisons. -// -// Valid fn values: -// NEVER -// LESS -// EQUAL -// LEQUAL -// GREATER -// NOTEQUAL -// GEQUAL -// ALWAYS -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDepthFunc.xhtml -func DepthFunc(fn Enum) { - enqueue(call{ +func (ctx *context) DepthFunc(fn Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDepthFunc, a0: fn.c(), @@ -586,11 +447,8 @@ func DepthFunc(fn Enum) { }) } -// DepthMask sets the depth buffer enabled for writing. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDepthMask.xhtml -func DepthMask(flag bool) { - enqueue(call{ +func (ctx *context) DepthMask(flag bool) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDepthMask, a0: glBoolean(flag), @@ -598,12 +456,8 @@ func DepthMask(flag bool) { }) } -// DepthRangef sets the mapping from normalized device coordinates to -// window coordinates. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDepthRangef.xhtml -func DepthRangef(n, f float32) { - enqueue(call{ +func (ctx *context) DepthRangef(n, f float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDepthRangef, a0: C.uintptr_t(math.Float32bits(n)), @@ -612,11 +466,8 @@ func DepthRangef(n, f float32) { }) } -// DetachShader detaches the shader s from the program p. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDetachShader.xhtml -func DetachShader(p Program, s Shader) { - enqueue(call{ +func (ctx *context) DetachShader(p Program, s Shader) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDetachShader, a0: p.c(), @@ -625,11 +476,8 @@ func DetachShader(p Program, s Shader) { }) } -// Disable disables various GL capabilities. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDisable.xhtml -func Disable(cap Enum) { - enqueue(call{ +func (ctx *context) Disable(cap Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDisable, a0: cap.c(), @@ -637,11 +485,8 @@ func Disable(cap Enum) { }) } -// DisableVertexAttribArray disables a vertex attribute array. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDisableVertexAttribArray.xhtml -func DisableVertexAttribArray(a Attrib) { - enqueue(call{ +func (ctx *context) DisableVertexAttribArray(a Attrib) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDisableVertexAttribArray, a0: a.c(), @@ -649,11 +494,8 @@ func DisableVertexAttribArray(a Attrib) { }) } -// DrawArrays renders geometric primitives from the bound data. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDrawArrays.xhtml -func DrawArrays(mode Enum, first, count int) { - enqueue(call{ +func (ctx *context) DrawArrays(mode Enum, first, count int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDrawArrays, a0: mode.c(), @@ -663,11 +505,8 @@ func DrawArrays(mode Enum, first, count int) { }) } -// DrawElements renders primitives from a bound buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glDrawElements.xhtml -func DrawElements(mode Enum, count int, ty Enum, offset int) { - enqueue(call{ +func (ctx *context) DrawElements(mode Enum, count int, ty Enum, offset int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDrawElements, a0: mode.c(), @@ -678,13 +517,8 @@ func DrawElements(mode Enum, count int, ty Enum, offset int) { }) } -// TODO(crawshaw): consider DrawElements8 / DrawElements16 / DrawElements32 - -// Enable enables various GL capabilities. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glEnable.xhtml -func Enable(cap Enum) { - enqueue(call{ +func (ctx *context) Enable(cap Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnEnable, a0: cap.c(), @@ -692,11 +526,8 @@ func Enable(cap Enum) { }) } -// EnableVertexAttribArray enables a vertex attribute array. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glEnableVertexAttribArray.xhtml -func EnableVertexAttribArray(a Attrib) { - enqueue(call{ +func (ctx *context) EnableVertexAttribArray(a Attrib) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnEnableVertexAttribArray, a0: a.c(), @@ -704,12 +535,8 @@ func EnableVertexAttribArray(a Attrib) { }) } -// Finish blocks until the effects of all previously called GL -// commands are complete. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glFinish.xhtml -func Finish() { - enqueue(call{ +func (ctx *context) Finish() { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFinish, }, @@ -717,14 +544,8 @@ func Finish() { }) } -// Flush empties all buffers. It does not block. -// -// An OpenGL implementation may buffer network communication, -// the command stream, or data inside the graphics accelerator. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glFlush.xhtml -func Flush() { - enqueue(call{ +func (ctx *context) Flush() { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFlush, }, @@ -732,11 +553,8 @@ func Flush() { }) } -// FramebufferRenderbuffer attaches rb to the current frame buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glFramebufferRenderbuffer.xhtml -func FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) { - enqueue(call{ +func (ctx *context) FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFramebufferRenderbuffer, a0: target.c(), @@ -747,11 +565,8 @@ func FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) }) } -// FramebufferTexture2D attaches the t to the current frame buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glFramebufferTexture2D.xhtml -func FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { - enqueue(call{ +func (ctx *context) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFramebufferTexture2D, a0: target.c(), @@ -763,13 +578,8 @@ func FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level i }) } -// FrontFace defines which polygons are front-facing. -// -// Valid modes: CW, CCW. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glFrontFace.xhtml -func FrontFace(mode Enum) { - enqueue(call{ +func (ctx *context) FrontFace(mode Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFrontFace, a0: mode.c(), @@ -777,11 +587,8 @@ func FrontFace(mode Enum) { }) } -// GenerateMipmap generates mipmaps for the current texture. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGenerateMipmap.xhtml -func GenerateMipmap(target Enum) { - enqueue(call{ +func (ctx *context) GenerateMipmap(target Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenerateMipmap, a0: target.c(), @@ -789,20 +596,14 @@ func GenerateMipmap(target Enum) { }) } -// GetActiveAttrib returns details about an active attribute variable. -// A value of 0 for index selects the first active attribute variable. -// Permissible values for index range from 0 to the number of active -// attribute variables minus 1. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetActiveAttrib.xhtml -func GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) { - bufSize := GetProgrami(p, ACTIVE_ATTRIBUTE_MAX_LENGTH) +func (ctx *context) GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) { + bufSize := ctx.GetProgrami(p, ACTIVE_ATTRIBUTE_MAX_LENGTH) buf := C.malloc(C.size_t(bufSize)) defer C.free(buf) var cSize C.GLint var cType C.GLenum - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetActiveAttrib, a0: p.c(), @@ -819,20 +620,14 @@ func GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) { return C.GoString((*C.char)(buf)), int(cSize), Enum(cType) } -// GetActiveUniform returns details about an active uniform variable. -// A value of 0 for index selects the first active uniform variable. -// Permissible values for index range from 0 to the number of active -// uniform variables minus 1. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetActiveUniform.xhtml -func GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) { - bufSize := GetProgrami(p, ACTIVE_UNIFORM_MAX_LENGTH) +func (ctx *context) GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) { + bufSize := ctx.GetProgrami(p, ACTIVE_UNIFORM_MAX_LENGTH) buf := C.malloc(C.size_t(bufSize)) defer C.free(buf) var cSize C.GLint var cType C.GLenum - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetActiveUniform, a0: p.c(), @@ -849,18 +644,15 @@ func GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) return C.GoString((*C.char)(buf)), int(cSize), Enum(cType) } -// GetAttachedShaders returns the shader objects attached to program p. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetAttachedShaders.xhtml -func GetAttachedShaders(p Program) []Shader { - shadersLen := GetProgrami(p, ATTACHED_SHADERS) +func (ctx *context) GetAttachedShaders(p Program) []Shader { + shadersLen := ctx.GetProgrami(p, ATTACHED_SHADERS) if shadersLen == 0 { return nil } var n C.GLsizei buf := make([]C.GLuint, shadersLen) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetAttachedShaders, a0: p.c(), @@ -879,11 +671,8 @@ func GetAttachedShaders(p Program) []Shader { return shaders } -// GetAttribLocation returns the location of an attribute variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetAttribLocation.xhtml -func GetAttribLocation(p Program, name string) Attrib { - return Attrib{Value: uint(enqueue(call{ +func (ctx *context) GetAttribLocation(p Program, name string) Attrib { + return Attrib{Value: uint(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetAttribLocation, a0: p.c(), @@ -893,15 +682,10 @@ func GetAttribLocation(p Program, name string) Attrib { }))} } -// GetBooleanv returns the boolean values of parameter pname. -// -// Many boolean parameters can be queried more easily using IsEnabled. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml -func GetBooleanv(dst []bool, pname Enum) { +func (ctx *context) GetBooleanv(dst []bool, pname Enum) { buf := make([]C.GLboolean, len(dst)) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetBooleanv, a0: pname.c(), @@ -915,11 +699,8 @@ func GetBooleanv(dst []bool, pname Enum) { } } -// GetFloatv returns the float values of parameter pname. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml -func GetFloatv(dst []float32, pname Enum) { - enqueue(call{ +func (ctx *context) GetFloatv(dst []float32, pname Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetFloatv, a0: pname.c(), @@ -929,15 +710,10 @@ func GetFloatv(dst []float32, pname Enum) { }) } -// GetIntegerv returns the int values of parameter pname. -// -// Single values may be queried more easily using GetInteger. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml -func GetIntegerv(dst []int32, pname Enum) { +func (ctx *context) GetIntegerv(dst []int32, pname Enum) { buf := make([]C.GLint, len(dst)) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetIntegerv, a0: pname.c(), @@ -951,20 +727,14 @@ func GetIntegerv(dst []int32, pname Enum) { } } -// GetInteger returns the int value of parameter pname. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml -func GetInteger(pname Enum) int { +func (ctx *context) GetInteger(pname Enum) int { var v [1]int32 - GetIntegerv(v[:], pname) + ctx.GetIntegerv(v[:], pname) return int(v[0]) } -// GetBufferParameteri returns a parameter for the active buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetBufferParameter.xhtml -func GetBufferParameteri(target, value Enum) int { - return int(enqueue(call{ +func (ctx *context) GetBufferParameteri(target, value Enum) int { + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetBufferParameteri, a0: target.c(), @@ -974,11 +744,8 @@ func GetBufferParameteri(target, value Enum) int { })) } -// GetError returns the next error. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetError.xhtml -func GetError() Enum { - return Enum(enqueue(call{ +func (ctx *context) GetError() Enum { + return Enum(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetError, }, @@ -986,12 +753,8 @@ func GetError() Enum { })) } -// GetFramebufferAttachmentParameteri returns attachment parameters -// for the active framebuffer object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetFramebufferAttachmentParameteriv.xhtml -func GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { - return int(enqueue(call{ +func (ctx *context) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetFramebufferAttachmentParameteriv, a0: target.c(), @@ -1002,11 +765,8 @@ func GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int { })) } -// 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 { - return int(enqueue(call{ +func (ctx *context) GetProgrami(p Program, pname Enum) int { + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetProgramiv, a0: p.c(), @@ -1016,15 +776,12 @@ func GetProgrami(p Program, pname Enum) int { })) } -// GetProgramInfoLog returns the information log for a program. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetProgramInfoLog.xhtml -func GetProgramInfoLog(p Program) string { - infoLen := GetProgrami(p, INFO_LOG_LENGTH) +func (ctx *context) GetProgramInfoLog(p Program) string { + infoLen := ctx.GetProgrami(p, INFO_LOG_LENGTH) buf := C.malloc(C.size_t(infoLen)) defer C.free(buf) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetProgramInfoLog, a0: p.c(), @@ -1038,11 +795,8 @@ func GetProgramInfoLog(p Program) string { return C.GoString((*C.char)(buf)) } -// GetRenderbufferParameteri returns a parameter value for a render buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetRenderbufferParameteriv.xhtml -func GetRenderbufferParameteri(target, pname Enum) int { - return int(enqueue(call{ +func (ctx *context) GetRenderbufferParameteri(target, pname Enum) int { + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetRenderbufferParameteriv, a0: target.c(), @@ -1052,11 +806,8 @@ func GetRenderbufferParameteri(target, pname Enum) int { })) } -// GetShaderi returns a parameter value for a shader. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderiv.xhtml -func GetShaderi(s Shader, pname Enum) int { - return int(enqueue(call{ +func (ctx *context) GetShaderi(s Shader, pname Enum) int { + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderiv, a0: s.c(), @@ -1066,15 +817,12 @@ func GetShaderi(s Shader, pname Enum) int { })) } -// GetShaderInfoLog returns the information log for a shader. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderInfoLog.xhtml -func GetShaderInfoLog(s Shader) string { - infoLen := GetShaderi(s, INFO_LOG_LENGTH) +func (ctx *context) GetShaderInfoLog(s Shader) string { + infoLen := ctx.GetShaderi(s, INFO_LOG_LENGTH) buf := C.malloc(C.size_t(infoLen)) defer C.free(buf) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderInfoLog, a0: s.c(), @@ -1088,15 +836,11 @@ func GetShaderInfoLog(s Shader) string { return C.GoString((*C.char)(buf)) } -// GetShaderPrecisionFormat returns range and precision limits for -// shader types. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderPrecisionFormat.xhtml -func GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) { +func (ctx *context) GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) { var cRange [2]C.GLint var cPrecision C.GLint - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderPrecisionFormat, a0: shadertype.c(), @@ -1110,18 +854,15 @@ func GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHi return int(cRange[0]), int(cRange[1]), int(cPrecision) } -// GetShaderSource returns source code of shader s. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderSource.xhtml -func GetShaderSource(s Shader) string { - sourceLen := GetShaderi(s, SHADER_SOURCE_LENGTH) +func (ctx *context) GetShaderSource(s Shader) string { + sourceLen := ctx.GetShaderi(s, SHADER_SOURCE_LENGTH) if sourceLen == 0 { return "" } buf := C.malloc(C.size_t(sourceLen)) defer C.free(buf) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderSource, a0: s.c(), @@ -1135,18 +876,8 @@ func GetShaderSource(s Shader) string { return C.GoString((*C.char)(buf)) } -// GetString reports current GL state. -// -// Valid name values: -// EXTENSIONS -// RENDERER -// SHADING_LANGUAGE_VERSION -// VENDOR -// VERSION -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetString.xhtml -func GetString(pname Enum) string { - ret := enqueue(call{ +func (ctx *context) GetString(pname Enum) string { + ret := ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetString, a0: pname.c(), @@ -1156,11 +887,8 @@ func GetString(pname Enum) string { return C.GoString((*C.char)((unsafe.Pointer(uintptr(ret))))) } -// GetTexParameterfv returns the float values of a texture parameter. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetTexParameter.xhtml -func GetTexParameterfv(dst []float32, target, pname Enum) { - enqueue(call{ +func (ctx *context) GetTexParameterfv(dst []float32, target, pname Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetTexParameterfv, a0: target.c(), @@ -1171,11 +899,8 @@ func GetTexParameterfv(dst []float32, target, pname Enum) { }) } -// GetTexParameteriv returns the int values of a texture parameter. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetTexParameter.xhtml -func GetTexParameteriv(dst []int32, target, pname Enum) { - enqueue(call{ +func (ctx *context) GetTexParameteriv(dst []int32, target, pname Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetTexParameteriv, a0: target.c(), @@ -1186,11 +911,8 @@ func GetTexParameteriv(dst []int32, target, pname Enum) { }) } -// GetUniformfv returns the float values of a uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniform.xhtml -func GetUniformfv(dst []float32, src Uniform, p Program) { - enqueue(call{ +func (ctx *context) GetUniformfv(dst []float32, src Uniform, p Program) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetUniformfv, a0: p.c(), @@ -1201,11 +923,8 @@ func GetUniformfv(dst []float32, src Uniform, p Program) { }) } -// GetUniformiv returns the float values of a uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniform.xhtml -func GetUniformiv(dst []int32, src Uniform, p Program) { - enqueue(call{ +func (ctx *context) GetUniformiv(dst []int32, src Uniform, p Program) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetUniformiv, a0: p.c(), @@ -1216,11 +935,8 @@ func GetUniformiv(dst []int32, src Uniform, p Program) { }) } -// GetUniformLocation returns the location of a uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniformLocation.xhtml -func GetUniformLocation(p Program, name string) Uniform { - return Uniform{Value: int32(enqueue(call{ +func (ctx *context) GetUniformLocation(p Program, name string) Uniform { + return Uniform{Value: int32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetUniformLocation, a0: p.c(), @@ -1230,20 +946,14 @@ func GetUniformLocation(p Program, name string) Uniform { }))} } -// GetVertexAttribf reads the float value of a vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml -func GetVertexAttribf(src Attrib, pname Enum) float32 { +func (ctx *context) GetVertexAttribf(src Attrib, pname Enum) float32 { var params [1]float32 - GetVertexAttribfv(params[:], src, pname) + ctx.GetVertexAttribfv(params[:], src, pname) return params[0] } -// GetVertexAttribfv reads float values of a vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml -func GetVertexAttribfv(dst []float32, src Attrib, pname Enum) { - enqueue(call{ +func (ctx *context) GetVertexAttribfv(dst []float32, src Attrib, pname Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetVertexAttribfv, a0: src.c(), @@ -1254,20 +964,14 @@ func GetVertexAttribfv(dst []float32, src Attrib, pname Enum) { }) } -// GetVertexAttribi reads the int value of a vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml -func GetVertexAttribi(src Attrib, pname Enum) int32 { +func (ctx *context) GetVertexAttribi(src Attrib, pname Enum) int32 { var params [1]int32 - GetVertexAttribiv(params[:], src, pname) + ctx.GetVertexAttribiv(params[:], src, pname) return params[0] } -// GetVertexAttribiv reads int values of a vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml -func GetVertexAttribiv(dst []int32, src Attrib, pname Enum) { - enqueue(call{ +func (ctx *context) GetVertexAttribiv(dst []int32, src Attrib, pname Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetVertexAttribiv, a0: src.c(), @@ -1278,13 +982,8 @@ func GetVertexAttribiv(dst []int32, src Attrib, pname Enum) { }) } -// TODO(crawshaw): glGetVertexAttribPointerv - -// Hint sets implementation-specific modes. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glHint.xhtml -func Hint(target, mode Enum) { - enqueue(call{ +func (ctx *context) Hint(target, mode Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnHint, a0: target.c(), @@ -1293,11 +992,8 @@ func Hint(target, mode Enum) { }) } -// IsBuffer reports if b is a valid buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsBuffer.xhtml -func IsBuffer(b Buffer) bool { - return 0 != enqueue(call{ +func (ctx *context) IsBuffer(b Buffer) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsBuffer, a0: b.c(), @@ -1306,11 +1002,8 @@ func IsBuffer(b Buffer) bool { }) } -// IsEnabled reports if cap is an enabled capability. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsEnabled.xhtml -func IsEnabled(cap Enum) bool { - return 0 != enqueue(call{ +func (ctx *context) IsEnabled(cap Enum) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsEnabled, a0: cap.c(), @@ -1319,11 +1012,8 @@ func IsEnabled(cap Enum) bool { }) } -// IsFramebuffer reports if fb is a valid frame buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsFramebuffer.xhtml -func IsFramebuffer(fb Framebuffer) bool { - return 0 != enqueue(call{ +func (ctx *context) IsFramebuffer(fb Framebuffer) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsFramebuffer, a0: fb.c(), @@ -1332,11 +1022,8 @@ func IsFramebuffer(fb Framebuffer) bool { }) } -// IsProgram reports if p is a valid program object. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsProgram.xhtml -func IsProgram(p Program) bool { - return 0 != enqueue(call{ +func (ctx *context) IsProgram(p Program) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsProgram, a0: p.c(), @@ -1345,11 +1032,8 @@ func IsProgram(p Program) bool { }) } -// IsRenderbuffer reports if rb is a valid render buffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsRenderbuffer.xhtml -func IsRenderbuffer(rb Renderbuffer) bool { - return 0 != enqueue(call{ +func (ctx *context) IsRenderbuffer(rb Renderbuffer) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsRenderbuffer, a0: rb.c(), @@ -1358,11 +1042,8 @@ func IsRenderbuffer(rb Renderbuffer) bool { }) } -// IsShader reports if s is valid shader. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsShader.xhtml -func IsShader(s Shader) bool { - return 0 != enqueue(call{ +func (ctx *context) IsShader(s Shader) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsShader, a0: s.c(), @@ -1371,11 +1052,8 @@ func IsShader(s Shader) bool { }) } -// IsTexture reports if t is a valid texture. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glIsTexture.xhtml -func IsTexture(t Texture) bool { - return 0 != enqueue(call{ +func (ctx *context) IsTexture(t Texture) bool { + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsTexture, a0: t.c(), @@ -1384,11 +1062,8 @@ func IsTexture(t Texture) bool { }) } -// LineWidth specifies the width of lines. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glLineWidth.xhtml -func LineWidth(width float32) { - enqueue(call{ +func (ctx *context) LineWidth(width float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnLineWidth, a0: C.uintptr_t(math.Float32bits(width)), @@ -1396,11 +1071,8 @@ func LineWidth(width float32) { }) } -// LinkProgram links the specified program. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glLinkProgram.xhtml -func LinkProgram(p Program) { - enqueue(call{ +func (ctx *context) LinkProgram(p Program) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnLinkProgram, a0: p.c(), @@ -1408,11 +1080,8 @@ func LinkProgram(p Program) { }) } -// PixelStorei sets pixel storage parameters. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glPixelStorei.xhtml -func PixelStorei(pname Enum, param int32) { - enqueue(call{ +func (ctx *context) PixelStorei(pname Enum, param int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnPixelStorei, a0: pname.c(), @@ -1421,11 +1090,8 @@ func PixelStorei(pname Enum, param int32) { }) } -// PolygonOffset sets the scaling factors for depth offsets. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glPolygonOffset.xhtml -func PolygonOffset(factor, units float32) { - enqueue(call{ +func (ctx *context) PolygonOffset(factor, units float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnPolygonOffset, a0: C.uintptr_t(math.Float32bits(factor)), @@ -1434,13 +1100,8 @@ func PolygonOffset(factor, units float32) { }) } -// ReadPixels returns pixel data from a buffer. -// -// In GLES 3, the source buffer is controlled with ReadBuffer. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glReadPixels.xhtml -func ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) { - enqueue(call{ +func (ctx *context) ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnReadPixels, // TODO(crawshaw): support PIXEL_PACK_BUFFER in GLES3, uses offset. @@ -1456,23 +1117,16 @@ func ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) { }) } -// ReleaseShaderCompiler frees resources allocated by the shader compiler. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glReleaseShaderCompiler.xhtml -func ReleaseShaderCompiler() { - enqueue(call{ +func (ctx *context) ReleaseShaderCompiler() { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnReleaseShaderCompiler, }, }) } -// RenderbufferStorage establishes the data storage, format, and -// dimensions of a renderbuffer object's image. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glRenderbufferStorage.xhtml -func RenderbufferStorage(target, internalFormat Enum, width, height int) { - enqueue(call{ +func (ctx *context) RenderbufferStorage(target, internalFormat Enum, width, height int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnRenderbufferStorage, a0: target.c(), @@ -1483,11 +1137,8 @@ func RenderbufferStorage(target, internalFormat Enum, width, height int) { }) } -// SampleCoverage sets multisample coverage parameters. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glSampleCoverage.xhtml -func SampleCoverage(value float32, invert bool) { - enqueue(call{ +func (ctx *context) SampleCoverage(value float32, invert bool) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnSampleCoverage, a0: C.uintptr_t(math.Float32bits(value)), @@ -1496,11 +1147,8 @@ func SampleCoverage(value float32, invert bool) { }) } -// Scissor defines the scissor box rectangle, in window coordinates. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glScissor.xhtml -func Scissor(x, y, width, height int32) { - enqueue(call{ +func (ctx *context) Scissor(x, y, width, height int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnScissor, a0: C.uintptr_t(x), @@ -1511,12 +1159,7 @@ func Scissor(x, y, width, height int32) { }) } -// TODO(crawshaw): ShaderBinary - -// ShaderSource sets the source code of s to the given source code. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glShaderSource.xhtml -func ShaderSource(s Shader, src string) { +func (ctx *context) ShaderSource(s Shader, src string) { // We are passing a char**. Make sure both the string and its // containing 1-element array are off the stack. Both are freed // in work.c. @@ -1524,7 +1167,7 @@ func ShaderSource(s Shader, src string) { cstrp := (**C.char)(C.malloc(C.size_t(unsafe.Sizeof(cstr)))) *cstrp = cstr - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnShaderSource, a0: s.c(), @@ -1534,11 +1177,8 @@ func ShaderSource(s Shader, src string) { }) } -// StencilFunc sets the front and back stencil test reference value. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilFunc.xhtml -func StencilFunc(fn Enum, ref int, mask uint32) { - enqueue(call{ +func (ctx *context) StencilFunc(fn Enum, ref int, mask uint32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilFunc, a0: fn.c(), @@ -1548,11 +1188,8 @@ func StencilFunc(fn Enum, ref int, mask uint32) { }) } -// StencilFunc sets the front or back stencil test reference value. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilFuncSeparate.xhtml -func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { - enqueue(call{ +func (ctx *context) StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilFuncSeparate, a0: face.c(), @@ -1563,11 +1200,8 @@ func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { }) } -// StencilMask controls the writing of bits in the stencil planes. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilMask.xhtml -func StencilMask(mask uint32) { - enqueue(call{ +func (ctx *context) StencilMask(mask uint32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilMask, a0: C.uintptr_t(mask), @@ -1575,11 +1209,8 @@ func StencilMask(mask uint32) { }) } -// StencilMaskSeparate controls the writing of bits in the stencil planes. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilMaskSeparate.xhtml -func StencilMaskSeparate(face Enum, mask uint32) { - enqueue(call{ +func (ctx *context) StencilMaskSeparate(face Enum, mask uint32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilMaskSeparate, a0: face.c(), @@ -1588,11 +1219,8 @@ func StencilMaskSeparate(face Enum, mask uint32) { }) } -// StencilOp sets front and back stencil test actions. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilOp.xhtml -func StencilOp(fail, zfail, zpass Enum) { - enqueue(call{ +func (ctx *context) StencilOp(fail, zfail, zpass Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilOp, a0: fail.c(), @@ -1602,11 +1230,8 @@ func StencilOp(fail, zfail, zpass Enum) { }) } -// StencilOpSeparate sets front or back stencil tests. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilOpSeparate.xhtml -func StencilOpSeparate(face, sfail, dpfail, dppass Enum) { - enqueue(call{ +func (ctx *context) StencilOpSeparate(face, sfail, dpfail, dppass Enum) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilOpSeparate, a0: face.c(), @@ -1617,10 +1242,7 @@ func StencilOpSeparate(face, sfail, dpfail, dppass Enum) { }) } -// TexImage2D writes a 2D texture image. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glTexImage2D.xhtml -func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) { +func (ctx *context) TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) { // It is common to pass TexImage2D a nil data, indicating that a // bound GL buffer is being used as the source. In that case, it // is not necessary to block. @@ -1629,7 +1251,7 @@ func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, blocking, a7 = true, C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))) } - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexImage2D, // TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER. @@ -1646,11 +1268,8 @@ func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, }) } -// TexSubImage2D writes a subregion of a 2D texture image. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glTexSubImage2D.xhtml -func TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) { - enqueue(call{ +func (ctx *context) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexSubImage2D, // TODO(crawshaw): GLES3 offset for PIXEL_UNPACK_BUFFER and PIXEL_PACK_BUFFER. @@ -1668,11 +1287,8 @@ func TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty E }) } -// TexParameterf sets a float texture parameter. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml -func TexParameterf(target, pname Enum, param float32) { - enqueue(call{ +func (ctx *context) TexParameterf(target, pname Enum, param float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameterf, a0: target.c(), @@ -1682,11 +1298,8 @@ func TexParameterf(target, pname Enum, param float32) { }) } -// TexParameterfv sets a float texture parameter array. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml -func TexParameterfv(target, pname Enum, params []float32) { - enqueue(call{ +func (ctx *context) TexParameterfv(target, pname Enum, params []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameterfv, a0: target.c(), @@ -1697,11 +1310,8 @@ func TexParameterfv(target, pname Enum, params []float32) { }) } -// TexParameteri sets an integer texture parameter. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml -func TexParameteri(target, pname Enum, param int) { - enqueue(call{ +func (ctx *context) TexParameteri(target, pname Enum, param int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameteri, a0: target.c(), @@ -1711,11 +1321,8 @@ func TexParameteri(target, pname Enum, param int) { }) } -// TexParameteriv sets an integer texture parameter array. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml -func TexParameteriv(target, pname Enum, params []int32) { - enqueue(call{ +func (ctx *context) TexParameteriv(target, pname Enum, params []int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameteriv, a0: target.c(), @@ -1726,11 +1333,8 @@ func TexParameteriv(target, pname Enum, params []int32) { }) } -// Uniform1f writes a float uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform1f(dst Uniform, v float32) { - enqueue(call{ +func (ctx *context) Uniform1f(dst Uniform, v float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1f, a0: dst.c(), @@ -1739,11 +1343,8 @@ func Uniform1f(dst Uniform, v float32) { }) } -// Uniform1fv writes a [len(src)]float uniform array. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform1fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) Uniform1fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1fv, a0: dst.c(), @@ -1754,15 +1355,8 @@ func Uniform1fv(dst Uniform, src []float32) { }) } -// Uniform1i writes an int uniform variable. -// -// Uniform1i and Uniform1iv are the only two functions that may be used -// to load uniform variables defined as sampler types. Loading samplers -// with any other function will result in a INVALID_OPERATION error. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform1i(dst Uniform, v int) { - enqueue(call{ +func (ctx *context) Uniform1i(dst Uniform, v int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1i, a0: dst.c(), @@ -1771,15 +1365,8 @@ func Uniform1i(dst Uniform, v int) { }) } -// Uniform1iv writes a int uniform array of len(src) elements. -// -// Uniform1i and Uniform1iv are the only two functions that may be used -// to load uniform variables defined as sampler types. Loading samplers -// with any other function will result in a INVALID_OPERATION error. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform1iv(dst Uniform, src []int32) { - enqueue(call{ +func (ctx *context) Uniform1iv(dst Uniform, src []int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1iv, a0: dst.c(), @@ -1790,11 +1377,8 @@ func Uniform1iv(dst Uniform, src []int32) { }) } -// Uniform2f writes a vec2 uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform2f(dst Uniform, v0, v1 float32) { - enqueue(call{ +func (ctx *context) Uniform2f(dst Uniform, v0, v1 float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2f, a0: dst.c(), @@ -1804,11 +1388,8 @@ func Uniform2f(dst Uniform, v0, v1 float32) { }) } -// Uniform2fv writes a vec2 uniform array of len(src)/2 elements. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform2fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) Uniform2fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2fv, a0: dst.c(), @@ -1819,11 +1400,8 @@ func Uniform2fv(dst Uniform, src []float32) { }) } -// Uniform2i writes an ivec2 uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform2i(dst Uniform, v0, v1 int) { - enqueue(call{ +func (ctx *context) Uniform2i(dst Uniform, v0, v1 int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2i, a0: dst.c(), @@ -1833,11 +1411,8 @@ func Uniform2i(dst Uniform, v0, v1 int) { }) } -// Uniform2iv writes an ivec2 uniform array of len(src)/2 elements. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform2iv(dst Uniform, src []int32) { - enqueue(call{ +func (ctx *context) Uniform2iv(dst Uniform, src []int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2iv, a0: dst.c(), @@ -1848,11 +1423,8 @@ func Uniform2iv(dst Uniform, src []int32) { }) } -// Uniform3f writes a vec3 uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform3f(dst Uniform, v0, v1, v2 float32) { - enqueue(call{ +func (ctx *context) Uniform3f(dst Uniform, v0, v1, v2 float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3f, a0: dst.c(), @@ -1863,11 +1435,8 @@ func Uniform3f(dst Uniform, v0, v1, v2 float32) { }) } -// Uniform3fv writes a vec3 uniform array of len(src)/3 elements. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform3fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) Uniform3fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3fv, a0: dst.c(), @@ -1878,11 +1447,8 @@ func Uniform3fv(dst Uniform, src []float32) { }) } -// Uniform3i writes an ivec3 uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform3i(dst Uniform, v0, v1, v2 int32) { - enqueue(call{ +func (ctx *context) Uniform3i(dst Uniform, v0, v1, v2 int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3i, a0: dst.c(), @@ -1893,11 +1459,8 @@ func Uniform3i(dst Uniform, v0, v1, v2 int32) { }) } -// Uniform3iv writes an ivec3 uniform array of len(src)/3 elements. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform3iv(dst Uniform, src []int32) { - enqueue(call{ +func (ctx *context) Uniform3iv(dst Uniform, src []int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3iv, a0: dst.c(), @@ -1908,11 +1471,8 @@ func Uniform3iv(dst Uniform, src []int32) { }) } -// Uniform4f writes a vec4 uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { - enqueue(call{ +func (ctx *context) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4f, a0: dst.c(), @@ -1924,11 +1484,8 @@ func Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { }) } -// Uniform4fv writes a vec4 uniform array of len(src)/4 elements. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform4fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) Uniform4fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4fv, a0: dst.c(), @@ -1939,11 +1496,8 @@ func Uniform4fv(dst Uniform, src []float32) { }) } -// Uniform4i writes an ivec4 uniform variable. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform4i(dst Uniform, v0, v1, v2, v3 int32) { - enqueue(call{ +func (ctx *context) Uniform4i(dst Uniform, v0, v1, v2, v3 int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4i, a0: dst.c(), @@ -1955,11 +1509,8 @@ func Uniform4i(dst Uniform, v0, v1, v2, v3 int32) { }) } -// Uniform4i writes an ivec4 uniform array of len(src)/4 elements. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func Uniform4iv(dst Uniform, src []int32) { - enqueue(call{ +func (ctx *context) Uniform4iv(dst Uniform, src []int32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4iv, a0: dst.c(), @@ -1970,14 +1521,8 @@ func Uniform4iv(dst Uniform, src []int32) { }) } -// UniformMatrix2fv writes 2x2 matrices. Each matrix uses four -// float32 values, so the number of matrices written is len(src)/4. -// -// Each matrix must be supplied in column major order. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func UniformMatrix2fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) UniformMatrix2fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniformMatrix2fv, // OpenGL ES 2 does not support transpose. @@ -1989,14 +1534,8 @@ func UniformMatrix2fv(dst Uniform, src []float32) { }) } -// UniformMatrix3fv writes 3x3 matrices. Each matrix uses nine -// float32 values, so the number of matrices written is len(src)/9. -// -// Each matrix must be supplied in column major order. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func UniformMatrix3fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) UniformMatrix3fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniformMatrix3fv, a0: dst.c(), @@ -2007,14 +1546,8 @@ func UniformMatrix3fv(dst Uniform, src []float32) { }) } -// UniformMatrix4fv writes 4x4 matrices. Each matrix uses 16 -// float32 values, so the number of matrices written is len(src)/16. -// -// Each matrix must be supplied in column major order. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml -func UniformMatrix4fv(dst Uniform, src []float32) { - enqueue(call{ +func (ctx *context) UniformMatrix4fv(dst Uniform, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniformMatrix4fv, a0: dst.c(), @@ -2025,11 +1558,8 @@ func UniformMatrix4fv(dst Uniform, src []float32) { }) } -// UseProgram sets the active program. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glUseProgram.xhtml -func UseProgram(p Program) { - enqueue(call{ +func (ctx *context) UseProgram(p Program) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUseProgram, a0: p.c(), @@ -2037,14 +1567,8 @@ func UseProgram(p Program) { }) } -// ValidateProgram checks to see whether the executables contained in -// program can execute given the current OpenGL state. -// -// Typically only used for debugging. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glValidateProgram.xhtml -func ValidateProgram(p Program) { - enqueue(call{ +func (ctx *context) ValidateProgram(p Program) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnValidateProgram, a0: p.c(), @@ -2052,11 +1576,8 @@ func ValidateProgram(p Program) { }) } -// VertexAttrib1f writes a float vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib1f(dst Attrib, x float32) { - enqueue(call{ +func (ctx *context) VertexAttrib1f(dst Attrib, x float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib1f, a0: dst.c(), @@ -2065,11 +1586,8 @@ func VertexAttrib1f(dst Attrib, x float32) { }) } -// VertexAttrib1fv writes a float vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib1fv(dst Attrib, src []float32) { - enqueue(call{ +func (ctx *context) VertexAttrib1fv(dst Attrib, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib1fv, a0: dst.c(), @@ -2079,11 +1597,8 @@ func VertexAttrib1fv(dst Attrib, src []float32) { }) } -// VertexAttrib2f writes a vec2 vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib2f(dst Attrib, x, y float32) { - enqueue(call{ +func (ctx *context) VertexAttrib2f(dst Attrib, x, y float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib2f, a0: dst.c(), @@ -2093,11 +1608,8 @@ func VertexAttrib2f(dst Attrib, x, y float32) { }) } -// VertexAttrib2fv writes a vec2 vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib2fv(dst Attrib, src []float32) { - enqueue(call{ +func (ctx *context) VertexAttrib2fv(dst Attrib, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib2fv, a0: dst.c(), @@ -2107,11 +1619,8 @@ func VertexAttrib2fv(dst Attrib, src []float32) { }) } -// VertexAttrib3f writes a vec3 vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib3f(dst Attrib, x, y, z float32) { - enqueue(call{ +func (ctx *context) VertexAttrib3f(dst Attrib, x, y, z float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib3f, a0: dst.c(), @@ -2122,11 +1631,8 @@ func VertexAttrib3f(dst Attrib, x, y, z float32) { }) } -// VertexAttrib3fv writes a vec3 vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib3fv(dst Attrib, src []float32) { - enqueue(call{ +func (ctx *context) VertexAttrib3fv(dst Attrib, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib3fv, a0: dst.c(), @@ -2136,11 +1642,8 @@ func VertexAttrib3fv(dst Attrib, src []float32) { }) } -// VertexAttrib4f writes a vec4 vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib4f(dst Attrib, x, y, z, w float32) { - enqueue(call{ +func (ctx *context) VertexAttrib4f(dst Attrib, x, y, z, w float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib4f, a0: dst.c(), @@ -2152,11 +1655,8 @@ func VertexAttrib4f(dst Attrib, x, y, z, w float32) { }) } -// VertexAttrib4fv writes a vec4 vertex attribute. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml -func VertexAttrib4fv(dst Attrib, src []float32) { - enqueue(call{ +func (ctx *context) VertexAttrib4fv(dst Attrib, src []float32) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib4fv, a0: dst.c(), @@ -2166,19 +1666,8 @@ func VertexAttrib4fv(dst Attrib, src []float32) { }) } -// VertexAttribPointer uses a bound buffer to define vertex attribute data. -// -// Direct use of VertexAttribPointer to load data into OpenGL is not -// supported via the Go bindings. Instead, use BindBuffer with an -// ARRAY_BUFFER and then fill it using BufferData. -// -// The size argument specifies the number of components per attribute, -// between 1-4. The stride argument specifies the byte offset between -// consecutive vertex attributes. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttribPointer.xhtml -func VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) { - enqueue(call{ +func (ctx *context) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttribPointer, a0: dst.c(), @@ -2191,12 +1680,8 @@ func VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, }) } -// Viewport sets the viewport, an affine transformation that -// normalizes device coordinates to window coordinates. -// -// http://www.khronos.org/opengles/sdk/docs/man3/html/glViewport.xhtml -func Viewport(x, y, width, height int) { - enqueue(call{ +func (ctx *context) Viewport(x, y, width, height int) { + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnViewport, a0: C.uintptr_t(x), diff --git a/gl/gldebug.go b/gl/gldebug.go index 552c6ab..a0d152e 100644 --- a/gl/gldebug.go +++ b/gl/gldebug.go @@ -20,10 +20,10 @@ import ( "unsafe" ) -func errDrain() string { +func (ctx *context) errDrain() string { var errs []Enum for { - e := GetError() + e := ctx.GetError() if e == 0 { break } @@ -630,12 +630,12 @@ func (v Enum) String() string { } } -func ActiveTexture(texture Enum) { +func (ctx *context) ActiveTexture(texture Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ActiveTexture(%v) %v", texture, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnActiveTexture, a0: texture.c(), @@ -643,12 +643,12 @@ func ActiveTexture(texture Enum) { }) } -func AttachShader(p Program, s Shader) { +func (ctx *context) AttachShader(p Program, s Shader) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.AttachShader(%v, %v) %v", p, s, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnAttachShader, a0: p.c(), @@ -657,12 +657,12 @@ func AttachShader(p Program, s Shader) { }) } -func BindAttribLocation(p Program, a Attrib, name string) { +func (ctx *context) BindAttribLocation(p Program, a Attrib, name string) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BindAttribLocation(%v, %v, %v) %v", p, a, name, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindAttribLocation, a0: p.c(), @@ -672,12 +672,12 @@ func BindAttribLocation(p Program, a Attrib, name string) { }) } -func BindBuffer(target Enum, b Buffer) { +func (ctx *context) BindBuffer(target Enum, b Buffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BindBuffer(%v, %v) %v", target, b, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindBuffer, a0: target.c(), @@ -686,12 +686,12 @@ func BindBuffer(target Enum, b Buffer) { }) } -func BindFramebuffer(target Enum, fb Framebuffer) { +func (ctx *context) BindFramebuffer(target Enum, fb Framebuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BindFramebuffer(%v, %v) %v", target, fb, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindFramebuffer, a0: target.c(), @@ -700,12 +700,12 @@ func BindFramebuffer(target Enum, fb Framebuffer) { }) } -func BindRenderbuffer(target Enum, rb Renderbuffer) { +func (ctx *context) BindRenderbuffer(target Enum, rb Renderbuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BindRenderbuffer(%v, %v) %v", target, rb, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindRenderbuffer, a0: target.c(), @@ -714,12 +714,12 @@ func BindRenderbuffer(target Enum, rb Renderbuffer) { }) } -func BindTexture(target Enum, t Texture) { +func (ctx *context) BindTexture(target Enum, t Texture) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BindTexture(%v, %v) %v", target, t, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBindTexture, a0: target.c(), @@ -728,12 +728,12 @@ func BindTexture(target Enum, t Texture) { }) } -func BlendColor(red, green, blue, alpha float32) { +func (ctx *context) BlendColor(red, green, blue, alpha float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BlendColor(%v, %v, %v, %v) %v", red, green, blue, alpha, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendColor, a0: C.uintptr_t(math.Float32bits(red)), @@ -744,12 +744,12 @@ func BlendColor(red, green, blue, alpha float32) { }) } -func BlendEquation(mode Enum) { +func (ctx *context) BlendEquation(mode Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BlendEquation(%v) %v", mode, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendEquation, a0: mode.c(), @@ -757,12 +757,12 @@ func BlendEquation(mode Enum) { }) } -func BlendEquationSeparate(modeRGB, modeAlpha Enum) { +func (ctx *context) BlendEquationSeparate(modeRGB, modeAlpha Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BlendEquationSeparate(%v, %v) %v", modeRGB, modeAlpha, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendEquationSeparate, a0: modeRGB.c(), @@ -771,12 +771,12 @@ func BlendEquationSeparate(modeRGB, modeAlpha Enum) { }) } -func BlendFunc(sfactor, dfactor Enum) { +func (ctx *context) BlendFunc(sfactor, dfactor Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BlendFunc(%v, %v) %v", sfactor, dfactor, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendFunc, a0: sfactor.c(), @@ -785,12 +785,12 @@ func BlendFunc(sfactor, dfactor Enum) { }) } -func BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) { +func (ctx *context) BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BlendFuncSeparate(%v, %v, %v, %v) %v", sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBlendFuncSeparate, a0: sfactorRGB.c(), @@ -801,12 +801,12 @@ func BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) }) } -func BufferData(target Enum, src []byte, usage Enum) { +func (ctx *context) BufferData(target Enum, src []byte, usage Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BufferData(%v, len(%d), %v) %v", target, len(src), usage, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBufferData, a0: target.c(), @@ -818,12 +818,12 @@ func BufferData(target Enum, src []byte, usage Enum) { }) } -func BufferInit(target Enum, size int, usage Enum) { +func (ctx *context) BufferInit(target Enum, size int, usage Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BufferInit(%v, %v, %v) %v", target, size, usage, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBufferData, a0: target.c(), @@ -834,12 +834,12 @@ func BufferInit(target Enum, size int, usage Enum) { }) } -func BufferSubData(target Enum, offset int, data []byte) { +func (ctx *context) BufferSubData(target Enum, offset int, data []byte) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.BufferSubData(%v, %v, len(%d)) %v", target, offset, len(data), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnBufferSubData, a0: target.c(), @@ -851,12 +851,12 @@ func BufferSubData(target Enum, offset int, data []byte) { }) } -func CheckFramebufferStatus(target Enum) (r0 Enum) { +func (ctx *context) CheckFramebufferStatus(target Enum) (r0 Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CheckFramebufferStatus(%v) %v%v", target, r0, errstr) }() - return Enum(enqueue(call{ + return Enum(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCheckFramebufferStatus, a0: target.c(), @@ -865,12 +865,12 @@ func CheckFramebufferStatus(target Enum) (r0 Enum) { })) } -func Clear(mask Enum) { +func (ctx *context) Clear(mask Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Clear(%v) %v", mask, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClear, a0: C.uintptr_t(mask), @@ -878,12 +878,12 @@ func Clear(mask Enum) { }) } -func ClearColor(red, green, blue, alpha float32) { +func (ctx *context) ClearColor(red, green, blue, alpha float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ClearColor(%v, %v, %v, %v) %v", red, green, blue, alpha, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClearColor, a0: C.uintptr_t(math.Float32bits(red)), @@ -894,12 +894,12 @@ func ClearColor(red, green, blue, alpha float32) { }) } -func ClearDepthf(d float32) { +func (ctx *context) ClearDepthf(d float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ClearDepthf(%v) %v", d, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClearDepthf, a0: C.uintptr_t(math.Float32bits(d)), @@ -907,12 +907,12 @@ func ClearDepthf(d float32) { }) } -func ClearStencil(s int) { +func (ctx *context) ClearStencil(s int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ClearStencil(%v) %v", s, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnClearStencil, a0: C.uintptr_t(s), @@ -920,12 +920,12 @@ func ClearStencil(s int) { }) } -func ColorMask(red, green, blue, alpha bool) { +func (ctx *context) ColorMask(red, green, blue, alpha bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ColorMask(%v, %v, %v, %v) %v", red, green, blue, alpha, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnColorMask, a0: glBoolean(red), @@ -936,12 +936,12 @@ func ColorMask(red, green, blue, alpha bool) { }) } -func CompileShader(s Shader) { +func (ctx *context) CompileShader(s Shader) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CompileShader(%v) %v", s, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCompileShader, a0: s.c(), @@ -949,12 +949,12 @@ func CompileShader(s Shader) { }) } -func CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) { +func (ctx *context) CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CompressedTexImage2D(%v, %v, %v, %v, %v, %v, len(%d)) %v", target, level, internalformat, width, height, border, len(data), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCompressedTexImage2D, a0: target.c(), @@ -970,12 +970,12 @@ func CompressedTexImage2D(target Enum, level int, internalformat Enum, width, he }) } -func CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) { +func (ctx *context) CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CompressedTexSubImage2D(%v, %v, %v, %v, %v, %v, %v, len(%d)) %v", target, level, xoffset, yoffset, width, height, format, len(data), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCompressedTexSubImage2D, a0: target.c(), @@ -992,12 +992,12 @@ func CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height }) } -func CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) { +func (ctx *context) CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CopyTexImage2D(%v, %v, %v, %v, %v, %v, %v, %v) %v", target, level, internalformat, x, y, width, height, border, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCopyTexImage2D, a0: target.c(), @@ -1012,12 +1012,12 @@ func CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, he }) } -func CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { +func (ctx *context) CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CopyTexSubImage2D(%v, %v, %v, %v, %v, %v, %v, %v) %v", target, level, xoffset, yoffset, x, y, width, height, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCopyTexSubImage2D, a0: target.c(), @@ -1032,12 +1032,12 @@ func CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height }) } -func CreateBuffer() (r0 Buffer) { +func (ctx *context) CreateBuffer() (r0 Buffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CreateBuffer() %v%v", r0, errstr) }() - return Buffer{Value: uint32(enqueue(call{ + return Buffer{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenBuffer, }, @@ -1045,12 +1045,12 @@ func CreateBuffer() (r0 Buffer) { }))} } -func CreateFramebuffer() (r0 Framebuffer) { +func (ctx *context) CreateFramebuffer() (r0 Framebuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CreateFramebuffer() %v%v", r0, errstr) }() - return Framebuffer{Value: uint32(enqueue(call{ + return Framebuffer{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenFramebuffer, }, @@ -1058,12 +1058,12 @@ func CreateFramebuffer() (r0 Framebuffer) { }))} } -func CreateProgram() (r0 Program) { +func (ctx *context) CreateProgram() (r0 Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CreateProgram() %v%v", r0, errstr) }() - return Program{Value: uint32(enqueue(call{ + return Program{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCreateProgram, }, @@ -1071,12 +1071,12 @@ func CreateProgram() (r0 Program) { }))} } -func CreateRenderbuffer() (r0 Renderbuffer) { +func (ctx *context) CreateRenderbuffer() (r0 Renderbuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CreateRenderbuffer() %v%v", r0, errstr) }() - return Renderbuffer{Value: uint32(enqueue(call{ + return Renderbuffer{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenRenderbuffer, }, @@ -1084,12 +1084,12 @@ func CreateRenderbuffer() (r0 Renderbuffer) { }))} } -func CreateShader(ty Enum) (r0 Shader) { +func (ctx *context) CreateShader(ty Enum) (r0 Shader) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CreateShader(%v) %v%v", ty, r0, errstr) }() - return Shader{Value: uint32(enqueue(call{ + return Shader{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCreateShader, a0: C.uintptr_t(ty), @@ -1098,12 +1098,12 @@ func CreateShader(ty Enum) (r0 Shader) { }))} } -func CreateTexture() (r0 Texture) { +func (ctx *context) CreateTexture() (r0 Texture) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CreateTexture() %v%v", r0, errstr) }() - return Texture{Value: uint32(enqueue(call{ + return Texture{Value: uint32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenTexture, }, @@ -1111,12 +1111,12 @@ func CreateTexture() (r0 Texture) { }))} } -func CullFace(mode Enum) { +func (ctx *context) CullFace(mode Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.CullFace(%v) %v", mode, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnCullFace, a0: mode.c(), @@ -1124,12 +1124,12 @@ func CullFace(mode Enum) { }) } -func DeleteBuffer(v Buffer) { +func (ctx *context) DeleteBuffer(v Buffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DeleteBuffer(%v) %v", v, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteBuffer, a0: C.uintptr_t(v.Value), @@ -1137,12 +1137,12 @@ func DeleteBuffer(v Buffer) { }) } -func DeleteFramebuffer(v Framebuffer) { +func (ctx *context) DeleteFramebuffer(v Framebuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DeleteFramebuffer(%v) %v", v, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteFramebuffer, a0: C.uintptr_t(v.Value), @@ -1150,12 +1150,12 @@ func DeleteFramebuffer(v Framebuffer) { }) } -func DeleteProgram(p Program) { +func (ctx *context) DeleteProgram(p Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DeleteProgram(%v) %v", p, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteProgram, a0: p.c(), @@ -1163,12 +1163,12 @@ func DeleteProgram(p Program) { }) } -func DeleteRenderbuffer(v Renderbuffer) { +func (ctx *context) DeleteRenderbuffer(v Renderbuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DeleteRenderbuffer(%v) %v", v, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteRenderbuffer, a0: v.c(), @@ -1176,12 +1176,12 @@ func DeleteRenderbuffer(v Renderbuffer) { }) } -func DeleteShader(s Shader) { +func (ctx *context) DeleteShader(s Shader) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DeleteShader(%v) %v", s, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteShader, a0: s.c(), @@ -1189,12 +1189,12 @@ func DeleteShader(s Shader) { }) } -func DeleteTexture(v Texture) { +func (ctx *context) DeleteTexture(v Texture) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DeleteTexture(%v) %v", v, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDeleteTexture, a0: v.c(), @@ -1202,12 +1202,12 @@ func DeleteTexture(v Texture) { }) } -func DepthFunc(fn Enum) { +func (ctx *context) DepthFunc(fn Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DepthFunc(%v) %v", fn, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDepthFunc, a0: fn.c(), @@ -1215,12 +1215,12 @@ func DepthFunc(fn Enum) { }) } -func DepthMask(flag bool) { +func (ctx *context) DepthMask(flag bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DepthMask(%v) %v", flag, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDepthMask, a0: glBoolean(flag), @@ -1228,12 +1228,12 @@ func DepthMask(flag bool) { }) } -func DepthRangef(n, f float32) { +func (ctx *context) DepthRangef(n, f float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DepthRangef(%v, %v) %v", n, f, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDepthRangef, a0: C.uintptr_t(math.Float32bits(n)), @@ -1242,12 +1242,12 @@ func DepthRangef(n, f float32) { }) } -func DetachShader(p Program, s Shader) { +func (ctx *context) DetachShader(p Program, s Shader) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DetachShader(%v, %v) %v", p, s, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDetachShader, a0: p.c(), @@ -1256,12 +1256,12 @@ func DetachShader(p Program, s Shader) { }) } -func Disable(cap Enum) { +func (ctx *context) Disable(cap Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Disable(%v) %v", cap, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDisable, a0: cap.c(), @@ -1269,12 +1269,12 @@ func Disable(cap Enum) { }) } -func DisableVertexAttribArray(a Attrib) { +func (ctx *context) DisableVertexAttribArray(a Attrib) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DisableVertexAttribArray(%v) %v", a, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDisableVertexAttribArray, a0: a.c(), @@ -1282,12 +1282,12 @@ func DisableVertexAttribArray(a Attrib) { }) } -func DrawArrays(mode Enum, first, count int) { +func (ctx *context) DrawArrays(mode Enum, first, count int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DrawArrays(%v, %v, %v) %v", mode, first, count, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDrawArrays, a0: mode.c(), @@ -1297,12 +1297,12 @@ func DrawArrays(mode Enum, first, count int) { }) } -func DrawElements(mode Enum, count int, ty Enum, offset int) { +func (ctx *context) DrawElements(mode Enum, count int, ty Enum, offset int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.DrawElements(%v, %v, %v, %v) %v", mode, count, ty, offset, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnDrawElements, a0: mode.c(), @@ -1313,12 +1313,12 @@ func DrawElements(mode Enum, count int, ty Enum, offset int) { }) } -func Enable(cap Enum) { +func (ctx *context) Enable(cap Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Enable(%v) %v", cap, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnEnable, a0: cap.c(), @@ -1326,12 +1326,12 @@ func Enable(cap Enum) { }) } -func EnableVertexAttribArray(a Attrib) { +func (ctx *context) EnableVertexAttribArray(a Attrib) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.EnableVertexAttribArray(%v) %v", a, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnEnableVertexAttribArray, a0: a.c(), @@ -1339,12 +1339,12 @@ func EnableVertexAttribArray(a Attrib) { }) } -func Finish() { +func (ctx *context) Finish() { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Finish() %v", errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFinish, }, @@ -1352,12 +1352,12 @@ func Finish() { }) } -func Flush() { +func (ctx *context) Flush() { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Flush() %v", errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFlush, }, @@ -1365,12 +1365,12 @@ func Flush() { }) } -func FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) { +func (ctx *context) FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.FramebufferRenderbuffer(%v, %v, %v, %v) %v", target, attachment, rbTarget, rb, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFramebufferRenderbuffer, a0: target.c(), @@ -1381,12 +1381,12 @@ func FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) }) } -func FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { +func (ctx *context) FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.FramebufferTexture2D(%v, %v, %v, %v, %v) %v", target, attachment, texTarget, t, level, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFramebufferTexture2D, a0: target.c(), @@ -1398,12 +1398,12 @@ func FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level i }) } -func FrontFace(mode Enum) { +func (ctx *context) FrontFace(mode Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.FrontFace(%v) %v", mode, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnFrontFace, a0: mode.c(), @@ -1411,12 +1411,12 @@ func FrontFace(mode Enum) { }) } -func GenerateMipmap(target Enum) { +func (ctx *context) GenerateMipmap(target Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GenerateMipmap(%v) %v", target, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGenerateMipmap, a0: target.c(), @@ -1424,17 +1424,17 @@ func GenerateMipmap(target Enum) { }) } -func GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) { +func (ctx *context) GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetActiveAttrib(%v, %v) (%v, %v, %v) %v", p, index, name, size, ty, errstr) }() - bufSize := GetProgrami(p, ACTIVE_ATTRIBUTE_MAX_LENGTH) + bufSize := ctx.GetProgrami(p, ACTIVE_ATTRIBUTE_MAX_LENGTH) buf := C.malloc(C.size_t(bufSize)) defer C.free(buf) var cSize C.GLint var cType C.GLenum - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetActiveAttrib, a0: p.c(), @@ -1450,17 +1450,17 @@ func GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) { return C.GoString((*C.char)(buf)), int(cSize), Enum(cType) } -func GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) { +func (ctx *context) GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetActiveUniform(%v, %v) (%v, %v, %v) %v", p, index, name, size, ty, errstr) }() - bufSize := GetProgrami(p, ACTIVE_UNIFORM_MAX_LENGTH) + bufSize := ctx.GetProgrami(p, ACTIVE_UNIFORM_MAX_LENGTH) buf := C.malloc(C.size_t(bufSize)) defer C.free(buf) var cSize C.GLint var cType C.GLenum - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetActiveUniform, a0: p.c(), @@ -1476,18 +1476,18 @@ func GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) return C.GoString((*C.char)(buf)), int(cSize), Enum(cType) } -func GetAttachedShaders(p Program) (r0 []Shader) { +func (ctx *context) GetAttachedShaders(p Program) (r0 []Shader) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetAttachedShaders(%v) %v%v", p, r0, errstr) }() - shadersLen := GetProgrami(p, ATTACHED_SHADERS) + shadersLen := ctx.GetProgrami(p, ATTACHED_SHADERS) if shadersLen == 0 { return nil } var n C.GLsizei buf := make([]C.GLuint, shadersLen) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetAttachedShaders, a0: p.c(), @@ -1505,13 +1505,13 @@ func GetAttachedShaders(p Program) (r0 []Shader) { return shaders } -func GetAttribLocation(p Program, name string) (r0 Attrib) { +func (ctx *context) GetAttribLocation(p Program, name string) (r0 Attrib) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() r0.name = name log.Printf("gl.GetAttribLocation(%v, %v) %v%v", p, name, r0, errstr) }() - return Attrib{Value: uint(enqueue(call{ + return Attrib{Value: uint(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetAttribLocation, a0: p.c(), @@ -1521,13 +1521,13 @@ func GetAttribLocation(p Program, name string) (r0 Attrib) { }))} } -func GetBooleanv(dst []bool, pname Enum) { +func (ctx *context) GetBooleanv(dst []bool, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetBooleanv(%v, %v) %v", dst, pname, errstr) }() buf := make([]C.GLboolean, len(dst)) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetBooleanv, a0: pname.c(), @@ -1540,12 +1540,12 @@ func GetBooleanv(dst []bool, pname Enum) { } } -func GetFloatv(dst []float32, pname Enum) { +func (ctx *context) GetFloatv(dst []float32, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetFloatv(len(%d), %v) %v", len(dst), pname, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetFloatv, a0: pname.c(), @@ -1555,13 +1555,13 @@ func GetFloatv(dst []float32, pname Enum) { }) } -func GetIntegerv(dst []int32, pname Enum) { +func (ctx *context) GetIntegerv(dst []int32, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetIntegerv(%v, %v) %v", dst, pname, errstr) }() buf := make([]C.GLint, len(dst)) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetIntegerv, a0: pname.c(), @@ -1574,22 +1574,22 @@ func GetIntegerv(dst []int32, pname Enum) { } } -func GetInteger(pname Enum) (r0 int) { +func (ctx *context) GetInteger(pname Enum) (r0 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetInteger(%v) %v%v", pname, r0, errstr) }() var v [1]int32 - GetIntegerv(v[:], pname) + ctx.GetIntegerv(v[:], pname) return int(v[0]) } -func GetBufferParameteri(target, value Enum) (r0 int) { +func (ctx *context) GetBufferParameteri(target, value Enum) (r0 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetBufferParameteri(%v, %v) %v%v", target, value, r0, errstr) }() - return int(enqueue(call{ + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetBufferParameteri, a0: target.c(), @@ -1599,8 +1599,8 @@ func GetBufferParameteri(target, value Enum) (r0 int) { })) } -func GetError() (r0 Enum) { - return Enum(enqueue(call{ +func (ctx *context) GetError() (r0 Enum) { + return Enum(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetError, }, @@ -1608,12 +1608,12 @@ func GetError() (r0 Enum) { })) } -func GetFramebufferAttachmentParameteri(target, attachment, pname Enum) (r0 int) { +func (ctx *context) GetFramebufferAttachmentParameteri(target, attachment, pname Enum) (r0 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetFramebufferAttachmentParameteri(%v, %v, %v) %v%v", target, attachment, pname, r0, errstr) }() - return int(enqueue(call{ + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetFramebufferAttachmentParameteriv, a0: target.c(), @@ -1624,12 +1624,12 @@ func GetFramebufferAttachmentParameteri(target, attachment, pname Enum) (r0 int) })) } -func GetProgrami(p Program, pname Enum) (r0 int) { +func (ctx *context) GetProgrami(p Program, pname Enum) (r0 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetProgrami(%v, %v) %v%v", p, pname, r0, errstr) }() - return int(enqueue(call{ + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetProgramiv, a0: p.c(), @@ -1639,15 +1639,15 @@ func GetProgrami(p Program, pname Enum) (r0 int) { })) } -func GetProgramInfoLog(p Program) (r0 string) { +func (ctx *context) GetProgramInfoLog(p Program) (r0 string) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetProgramInfoLog(%v) %v%v", p, r0, errstr) }() - infoLen := GetProgrami(p, INFO_LOG_LENGTH) + infoLen := ctx.GetProgrami(p, INFO_LOG_LENGTH) buf := C.malloc(C.size_t(infoLen)) defer C.free(buf) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetProgramInfoLog, a0: p.c(), @@ -1660,12 +1660,12 @@ func GetProgramInfoLog(p Program) (r0 string) { return C.GoString((*C.char)(buf)) } -func GetRenderbufferParameteri(target, pname Enum) (r0 int) { +func (ctx *context) GetRenderbufferParameteri(target, pname Enum) (r0 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetRenderbufferParameteri(%v, %v) %v%v", target, pname, r0, errstr) }() - return int(enqueue(call{ + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetRenderbufferParameteriv, a0: target.c(), @@ -1675,12 +1675,12 @@ func GetRenderbufferParameteri(target, pname Enum) (r0 int) { })) } -func GetShaderi(s Shader, pname Enum) (r0 int) { +func (ctx *context) GetShaderi(s Shader, pname Enum) (r0 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetShaderi(%v, %v) %v%v", s, pname, r0, errstr) }() - return int(enqueue(call{ + return int(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderiv, a0: s.c(), @@ -1690,15 +1690,15 @@ func GetShaderi(s Shader, pname Enum) (r0 int) { })) } -func GetShaderInfoLog(s Shader) (r0 string) { +func (ctx *context) GetShaderInfoLog(s Shader) (r0 string) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetShaderInfoLog(%v) %v%v", s, r0, errstr) }() - infoLen := GetShaderi(s, INFO_LOG_LENGTH) + infoLen := ctx.GetShaderi(s, INFO_LOG_LENGTH) buf := C.malloc(C.size_t(infoLen)) defer C.free(buf) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderInfoLog, a0: s.c(), @@ -1711,14 +1711,14 @@ func GetShaderInfoLog(s Shader) (r0 string) { return C.GoString((*C.char)(buf)) } -func GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) { +func (ctx *context) GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetShaderPrecisionFormat(%v, %v) (%v, %v, %v) %v", shadertype, precisiontype, rangeLow, rangeHigh, precision, errstr) }() var cRange [2]C.GLint var cPrecision C.GLint - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderPrecisionFormat, a0: shadertype.c(), @@ -1731,18 +1731,18 @@ func GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHi return int(cRange[0]), int(cRange[1]), int(cPrecision) } -func GetShaderSource(s Shader) (r0 string) { +func (ctx *context) GetShaderSource(s Shader) (r0 string) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetShaderSource(%v) %v%v", s, r0, errstr) }() - sourceLen := GetShaderi(s, SHADER_SOURCE_LENGTH) + sourceLen := ctx.GetShaderi(s, SHADER_SOURCE_LENGTH) if sourceLen == 0 { return "" } buf := C.malloc(C.size_t(sourceLen)) defer C.free(buf) - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetShaderSource, a0: s.c(), @@ -1755,12 +1755,12 @@ func GetShaderSource(s Shader) (r0 string) { return C.GoString((*C.char)(buf)) } -func GetString(pname Enum) (r0 string) { +func (ctx *context) GetString(pname Enum) (r0 string) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetString(%v) %v%v", pname, r0, errstr) }() - ret := enqueue(call{ + ret := ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetString, a0: pname.c(), @@ -1770,12 +1770,12 @@ func GetString(pname Enum) (r0 string) { return C.GoString((*C.char)((unsafe.Pointer(uintptr(ret))))) } -func GetTexParameterfv(dst []float32, target, pname Enum) { +func (ctx *context) GetTexParameterfv(dst []float32, target, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetTexParameterfv(len(%d), %v, %v) %v", len(dst), target, pname, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetTexParameterfv, a0: target.c(), @@ -1786,12 +1786,12 @@ func GetTexParameterfv(dst []float32, target, pname Enum) { }) } -func GetTexParameteriv(dst []int32, target, pname Enum) { +func (ctx *context) GetTexParameteriv(dst []int32, target, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetTexParameteriv(%v, %v, %v) %v", dst, target, pname, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetTexParameteriv, a0: target.c(), @@ -1802,12 +1802,12 @@ func GetTexParameteriv(dst []int32, target, pname Enum) { }) } -func GetUniformfv(dst []float32, src Uniform, p Program) { +func (ctx *context) GetUniformfv(dst []float32, src Uniform, p Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetUniformfv(len(%d), %v, %v) %v", len(dst), src, p, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetUniformfv, a0: p.c(), @@ -1818,12 +1818,12 @@ func GetUniformfv(dst []float32, src Uniform, p Program) { }) } -func GetUniformiv(dst []int32, src Uniform, p Program) { +func (ctx *context) GetUniformiv(dst []int32, src Uniform, p Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetUniformiv(%v, %v, %v) %v", dst, src, p, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetUniformiv, a0: p.c(), @@ -1834,13 +1834,13 @@ func GetUniformiv(dst []int32, src Uniform, p Program) { }) } -func GetUniformLocation(p Program, name string) (r0 Uniform) { +func (ctx *context) GetUniformLocation(p Program, name string) (r0 Uniform) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() r0.name = name log.Printf("gl.GetUniformLocation(%v, %v) %v%v", p, name, r0, errstr) }() - return Uniform{Value: int32(enqueue(call{ + return Uniform{Value: int32(ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetUniformLocation, a0: p.c(), @@ -1850,22 +1850,22 @@ func GetUniformLocation(p Program, name string) (r0 Uniform) { }))} } -func GetVertexAttribf(src Attrib, pname Enum) (r0 float32) { +func (ctx *context) GetVertexAttribf(src Attrib, pname Enum) (r0 float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetVertexAttribf(%v, %v) %v%v", src, pname, r0, errstr) }() var params [1]float32 - GetVertexAttribfv(params[:], src, pname) + ctx.GetVertexAttribfv(params[:], src, pname) return params[0] } -func GetVertexAttribfv(dst []float32, src Attrib, pname Enum) { +func (ctx *context) GetVertexAttribfv(dst []float32, src Attrib, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetVertexAttribfv(len(%d), %v, %v) %v", len(dst), src, pname, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetVertexAttribfv, a0: src.c(), @@ -1876,22 +1876,22 @@ func GetVertexAttribfv(dst []float32, src Attrib, pname Enum) { }) } -func GetVertexAttribi(src Attrib, pname Enum) (r0 int32) { +func (ctx *context) GetVertexAttribi(src Attrib, pname Enum) (r0 int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetVertexAttribi(%v, %v) %v%v", src, pname, r0, errstr) }() var params [1]int32 - GetVertexAttribiv(params[:], src, pname) + ctx.GetVertexAttribiv(params[:], src, pname) return params[0] } -func GetVertexAttribiv(dst []int32, src Attrib, pname Enum) { +func (ctx *context) GetVertexAttribiv(dst []int32, src Attrib, pname Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.GetVertexAttribiv(%v, %v, %v) %v", dst, src, pname, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnGetVertexAttribiv, a0: src.c(), @@ -1902,12 +1902,12 @@ func GetVertexAttribiv(dst []int32, src Attrib, pname Enum) { }) } -func Hint(target, mode Enum) { +func (ctx *context) Hint(target, mode Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Hint(%v, %v) %v", target, mode, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnHint, a0: target.c(), @@ -1916,12 +1916,12 @@ func Hint(target, mode Enum) { }) } -func IsBuffer(b Buffer) (r0 bool) { +func (ctx *context) IsBuffer(b Buffer) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsBuffer(%v) %v%v", b, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsBuffer, a0: b.c(), @@ -1930,12 +1930,12 @@ func IsBuffer(b Buffer) (r0 bool) { }) } -func IsEnabled(cap Enum) (r0 bool) { +func (ctx *context) IsEnabled(cap Enum) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsEnabled(%v) %v%v", cap, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsEnabled, a0: cap.c(), @@ -1944,12 +1944,12 @@ func IsEnabled(cap Enum) (r0 bool) { }) } -func IsFramebuffer(fb Framebuffer) (r0 bool) { +func (ctx *context) IsFramebuffer(fb Framebuffer) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsFramebuffer(%v) %v%v", fb, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsFramebuffer, a0: fb.c(), @@ -1958,12 +1958,12 @@ func IsFramebuffer(fb Framebuffer) (r0 bool) { }) } -func IsProgram(p Program) (r0 bool) { +func (ctx *context) IsProgram(p Program) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsProgram(%v) %v%v", p, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsProgram, a0: p.c(), @@ -1972,12 +1972,12 @@ func IsProgram(p Program) (r0 bool) { }) } -func IsRenderbuffer(rb Renderbuffer) (r0 bool) { +func (ctx *context) IsRenderbuffer(rb Renderbuffer) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsRenderbuffer(%v) %v%v", rb, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsRenderbuffer, a0: rb.c(), @@ -1986,12 +1986,12 @@ func IsRenderbuffer(rb Renderbuffer) (r0 bool) { }) } -func IsShader(s Shader) (r0 bool) { +func (ctx *context) IsShader(s Shader) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsShader(%v) %v%v", s, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsShader, a0: s.c(), @@ -2000,12 +2000,12 @@ func IsShader(s Shader) (r0 bool) { }) } -func IsTexture(t Texture) (r0 bool) { +func (ctx *context) IsTexture(t Texture) (r0 bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.IsTexture(%v) %v%v", t, r0, errstr) }() - return 0 != enqueue(call{ + return 0 != ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnIsTexture, a0: t.c(), @@ -2014,12 +2014,12 @@ func IsTexture(t Texture) (r0 bool) { }) } -func LineWidth(width float32) { +func (ctx *context) LineWidth(width float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.LineWidth(%v) %v", width, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnLineWidth, a0: C.uintptr_t(math.Float32bits(width)), @@ -2027,12 +2027,12 @@ func LineWidth(width float32) { }) } -func LinkProgram(p Program) { +func (ctx *context) LinkProgram(p Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.LinkProgram(%v) %v", p, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnLinkProgram, a0: p.c(), @@ -2040,12 +2040,12 @@ func LinkProgram(p Program) { }) } -func PixelStorei(pname Enum, param int32) { +func (ctx *context) PixelStorei(pname Enum, param int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.PixelStorei(%v, %v) %v", pname, param, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnPixelStorei, a0: pname.c(), @@ -2054,12 +2054,12 @@ func PixelStorei(pname Enum, param int32) { }) } -func PolygonOffset(factor, units float32) { +func (ctx *context) PolygonOffset(factor, units float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.PolygonOffset(%v, %v) %v", factor, units, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnPolygonOffset, a0: C.uintptr_t(math.Float32bits(factor)), @@ -2068,12 +2068,12 @@ func PolygonOffset(factor, units float32) { }) } -func ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) { +func (ctx *context) ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ReadPixels(len(%d), %v, %v, %v, %v, %v, %v) %v", len(dst), x, y, width, height, format, ty, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnReadPixels, @@ -2089,24 +2089,24 @@ func ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) { }) } -func ReleaseShaderCompiler() { +func (ctx *context) ReleaseShaderCompiler() { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ReleaseShaderCompiler() %v", errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnReleaseShaderCompiler, }, }) } -func RenderbufferStorage(target, internalFormat Enum, width, height int) { +func (ctx *context) RenderbufferStorage(target, internalFormat Enum, width, height int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.RenderbufferStorage(%v, %v, %v, %v) %v", target, internalFormat, width, height, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnRenderbufferStorage, a0: target.c(), @@ -2117,12 +2117,12 @@ func RenderbufferStorage(target, internalFormat Enum, width, height int) { }) } -func SampleCoverage(value float32, invert bool) { +func (ctx *context) SampleCoverage(value float32, invert bool) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.SampleCoverage(%v, %v) %v", value, invert, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnSampleCoverage, a0: C.uintptr_t(math.Float32bits(value)), @@ -2131,12 +2131,12 @@ func SampleCoverage(value float32, invert bool) { }) } -func Scissor(x, y, width, height int32) { +func (ctx *context) Scissor(x, y, width, height int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Scissor(%v, %v, %v, %v) %v", x, y, width, height, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnScissor, a0: C.uintptr_t(x), @@ -2147,15 +2147,15 @@ func Scissor(x, y, width, height int32) { }) } -func ShaderSource(s Shader, src string) { +func (ctx *context) ShaderSource(s Shader, src string) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ShaderSource(%v, %v) %v", s, src, errstr) }() cstr := C.CString(src) cstrp := (**C.char)(C.malloc(C.size_t(unsafe.Sizeof(cstr)))) *cstrp = cstr - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnShaderSource, a0: s.c(), @@ -2165,12 +2165,12 @@ func ShaderSource(s Shader, src string) { }) } -func StencilFunc(fn Enum, ref int, mask uint32) { +func (ctx *context) StencilFunc(fn Enum, ref int, mask uint32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.StencilFunc(%v, %v, %v) %v", fn, ref, mask, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilFunc, a0: fn.c(), @@ -2180,12 +2180,12 @@ func StencilFunc(fn Enum, ref int, mask uint32) { }) } -func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { +func (ctx *context) StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.StencilFuncSeparate(%v, %v, %v, %v) %v", face, fn, ref, mask, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilFuncSeparate, a0: face.c(), @@ -2196,12 +2196,12 @@ func StencilFuncSeparate(face, fn Enum, ref int, mask uint32) { }) } -func StencilMask(mask uint32) { +func (ctx *context) StencilMask(mask uint32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.StencilMask(%v) %v", mask, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilMask, a0: C.uintptr_t(mask), @@ -2209,12 +2209,12 @@ func StencilMask(mask uint32) { }) } -func StencilMaskSeparate(face Enum, mask uint32) { +func (ctx *context) StencilMaskSeparate(face Enum, mask uint32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.StencilMaskSeparate(%v, %v) %v", face, mask, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilMaskSeparate, a0: face.c(), @@ -2223,12 +2223,12 @@ func StencilMaskSeparate(face Enum, mask uint32) { }) } -func StencilOp(fail, zfail, zpass Enum) { +func (ctx *context) StencilOp(fail, zfail, zpass Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.StencilOp(%v, %v, %v) %v", fail, zfail, zpass, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilOp, a0: fail.c(), @@ -2238,12 +2238,12 @@ func StencilOp(fail, zfail, zpass Enum) { }) } -func StencilOpSeparate(face, sfail, dpfail, dppass Enum) { +func (ctx *context) StencilOpSeparate(face, sfail, dpfail, dppass Enum) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.StencilOpSeparate(%v, %v, %v, %v) %v", face, sfail, dpfail, dppass, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnStencilOpSeparate, a0: face.c(), @@ -2254,16 +2254,16 @@ func StencilOpSeparate(face, sfail, dpfail, dppass Enum) { }) } -func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) { +func (ctx *context) TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.TexImage2D(%v, %v, %v, %v, %v, %v, len(%d)) %v", target, level, width, height, format, ty, len(data), errstr) }() blocking, a7 := false, C.uintptr_t(0) if len(data) > 0 { blocking, a7 = true, C.uintptr_t(uintptr(unsafe.Pointer(&data[0]))) } - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexImage2D, @@ -2280,12 +2280,12 @@ func TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, }) } -func TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) { +func (ctx *context) TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.TexSubImage2D(%v, %v, %v, %v, %v, %v, %v, %v, len(%d)) %v", target, level, x, y, width, height, format, ty, len(data), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexSubImage2D, @@ -2303,12 +2303,12 @@ func TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty E }) } -func TexParameterf(target, pname Enum, param float32) { +func (ctx *context) TexParameterf(target, pname Enum, param float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.TexParameterf(%v, %v, %v) %v", target, pname, param, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameterf, a0: target.c(), @@ -2318,12 +2318,12 @@ func TexParameterf(target, pname Enum, param float32) { }) } -func TexParameterfv(target, pname Enum, params []float32) { +func (ctx *context) TexParameterfv(target, pname Enum, params []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.TexParameterfv(%v, %v, len(%d)) %v", target, pname, len(params), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameterfv, a0: target.c(), @@ -2334,12 +2334,12 @@ func TexParameterfv(target, pname Enum, params []float32) { }) } -func TexParameteri(target, pname Enum, param int) { +func (ctx *context) TexParameteri(target, pname Enum, param int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.TexParameteri(%v, %v, %v) %v", target, pname, param, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameteri, a0: target.c(), @@ -2349,12 +2349,12 @@ func TexParameteri(target, pname Enum, param int) { }) } -func TexParameteriv(target, pname Enum, params []int32) { +func (ctx *context) TexParameteriv(target, pname Enum, params []int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.TexParameteriv(%v, %v, %v) %v", target, pname, params, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnTexParameteriv, a0: target.c(), @@ -2365,12 +2365,12 @@ func TexParameteriv(target, pname Enum, params []int32) { }) } -func Uniform1f(dst Uniform, v float32) { +func (ctx *context) Uniform1f(dst Uniform, v float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform1f(%v, %v) %v", dst, v, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1f, a0: dst.c(), @@ -2379,12 +2379,12 @@ func Uniform1f(dst Uniform, v float32) { }) } -func Uniform1fv(dst Uniform, src []float32) { +func (ctx *context) Uniform1fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform1fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1fv, a0: dst.c(), @@ -2395,12 +2395,12 @@ func Uniform1fv(dst Uniform, src []float32) { }) } -func Uniform1i(dst Uniform, v int) { +func (ctx *context) Uniform1i(dst Uniform, v int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform1i(%v, %v) %v", dst, v, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1i, a0: dst.c(), @@ -2409,12 +2409,12 @@ func Uniform1i(dst Uniform, v int) { }) } -func Uniform1iv(dst Uniform, src []int32) { +func (ctx *context) Uniform1iv(dst Uniform, src []int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform1iv(%v, %v) %v", dst, src, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform1iv, a0: dst.c(), @@ -2425,12 +2425,12 @@ func Uniform1iv(dst Uniform, src []int32) { }) } -func Uniform2f(dst Uniform, v0, v1 float32) { +func (ctx *context) Uniform2f(dst Uniform, v0, v1 float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform2f(%v, %v, %v) %v", dst, v0, v1, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2f, a0: dst.c(), @@ -2440,12 +2440,12 @@ func Uniform2f(dst Uniform, v0, v1 float32) { }) } -func Uniform2fv(dst Uniform, src []float32) { +func (ctx *context) Uniform2fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform2fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2fv, a0: dst.c(), @@ -2456,12 +2456,12 @@ func Uniform2fv(dst Uniform, src []float32) { }) } -func Uniform2i(dst Uniform, v0, v1 int) { +func (ctx *context) Uniform2i(dst Uniform, v0, v1 int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform2i(%v, %v, %v) %v", dst, v0, v1, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2i, a0: dst.c(), @@ -2471,12 +2471,12 @@ func Uniform2i(dst Uniform, v0, v1 int) { }) } -func Uniform2iv(dst Uniform, src []int32) { +func (ctx *context) Uniform2iv(dst Uniform, src []int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform2iv(%v, %v) %v", dst, src, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform2iv, a0: dst.c(), @@ -2487,12 +2487,12 @@ func Uniform2iv(dst Uniform, src []int32) { }) } -func Uniform3f(dst Uniform, v0, v1, v2 float32) { +func (ctx *context) Uniform3f(dst Uniform, v0, v1, v2 float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform3f(%v, %v, %v, %v) %v", dst, v0, v1, v2, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3f, a0: dst.c(), @@ -2503,12 +2503,12 @@ func Uniform3f(dst Uniform, v0, v1, v2 float32) { }) } -func Uniform3fv(dst Uniform, src []float32) { +func (ctx *context) Uniform3fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform3fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3fv, a0: dst.c(), @@ -2519,12 +2519,12 @@ func Uniform3fv(dst Uniform, src []float32) { }) } -func Uniform3i(dst Uniform, v0, v1, v2 int32) { +func (ctx *context) Uniform3i(dst Uniform, v0, v1, v2 int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform3i(%v, %v, %v, %v) %v", dst, v0, v1, v2, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3i, a0: dst.c(), @@ -2535,12 +2535,12 @@ func Uniform3i(dst Uniform, v0, v1, v2 int32) { }) } -func Uniform3iv(dst Uniform, src []int32) { +func (ctx *context) Uniform3iv(dst Uniform, src []int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform3iv(%v, %v) %v", dst, src, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform3iv, a0: dst.c(), @@ -2551,12 +2551,12 @@ func Uniform3iv(dst Uniform, src []int32) { }) } -func Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { +func (ctx *context) Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform4f(%v, %v, %v, %v, %v) %v", dst, v0, v1, v2, v3, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4f, a0: dst.c(), @@ -2568,12 +2568,12 @@ func Uniform4f(dst Uniform, v0, v1, v2, v3 float32) { }) } -func Uniform4fv(dst Uniform, src []float32) { +func (ctx *context) Uniform4fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform4fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4fv, a0: dst.c(), @@ -2584,12 +2584,12 @@ func Uniform4fv(dst Uniform, src []float32) { }) } -func Uniform4i(dst Uniform, v0, v1, v2, v3 int32) { +func (ctx *context) Uniform4i(dst Uniform, v0, v1, v2, v3 int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform4i(%v, %v, %v, %v, %v) %v", dst, v0, v1, v2, v3, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4i, a0: dst.c(), @@ -2601,12 +2601,12 @@ func Uniform4i(dst Uniform, v0, v1, v2, v3 int32) { }) } -func Uniform4iv(dst Uniform, src []int32) { +func (ctx *context) Uniform4iv(dst Uniform, src []int32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Uniform4iv(%v, %v) %v", dst, src, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniform4iv, a0: dst.c(), @@ -2617,12 +2617,12 @@ func Uniform4iv(dst Uniform, src []int32) { }) } -func UniformMatrix2fv(dst Uniform, src []float32) { +func (ctx *context) UniformMatrix2fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.UniformMatrix2fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniformMatrix2fv, @@ -2634,12 +2634,12 @@ func UniformMatrix2fv(dst Uniform, src []float32) { }) } -func UniformMatrix3fv(dst Uniform, src []float32) { +func (ctx *context) UniformMatrix3fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.UniformMatrix3fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniformMatrix3fv, a0: dst.c(), @@ -2650,12 +2650,12 @@ func UniformMatrix3fv(dst Uniform, src []float32) { }) } -func UniformMatrix4fv(dst Uniform, src []float32) { +func (ctx *context) UniformMatrix4fv(dst Uniform, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.UniformMatrix4fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUniformMatrix4fv, a0: dst.c(), @@ -2666,12 +2666,12 @@ func UniformMatrix4fv(dst Uniform, src []float32) { }) } -func UseProgram(p Program) { +func (ctx *context) UseProgram(p Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.UseProgram(%v) %v", p, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnUseProgram, a0: p.c(), @@ -2679,12 +2679,12 @@ func UseProgram(p Program) { }) } -func ValidateProgram(p Program) { +func (ctx *context) ValidateProgram(p Program) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.ValidateProgram(%v) %v", p, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnValidateProgram, a0: p.c(), @@ -2692,12 +2692,12 @@ func ValidateProgram(p Program) { }) } -func VertexAttrib1f(dst Attrib, x float32) { +func (ctx *context) VertexAttrib1f(dst Attrib, x float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib1f(%v, %v) %v", dst, x, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib1f, a0: dst.c(), @@ -2706,12 +2706,12 @@ func VertexAttrib1f(dst Attrib, x float32) { }) } -func VertexAttrib1fv(dst Attrib, src []float32) { +func (ctx *context) VertexAttrib1fv(dst Attrib, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib1fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib1fv, a0: dst.c(), @@ -2721,12 +2721,12 @@ func VertexAttrib1fv(dst Attrib, src []float32) { }) } -func VertexAttrib2f(dst Attrib, x, y float32) { +func (ctx *context) VertexAttrib2f(dst Attrib, x, y float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib2f(%v, %v, %v) %v", dst, x, y, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib2f, a0: dst.c(), @@ -2736,12 +2736,12 @@ func VertexAttrib2f(dst Attrib, x, y float32) { }) } -func VertexAttrib2fv(dst Attrib, src []float32) { +func (ctx *context) VertexAttrib2fv(dst Attrib, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib2fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib2fv, a0: dst.c(), @@ -2751,12 +2751,12 @@ func VertexAttrib2fv(dst Attrib, src []float32) { }) } -func VertexAttrib3f(dst Attrib, x, y, z float32) { +func (ctx *context) VertexAttrib3f(dst Attrib, x, y, z float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib3f(%v, %v, %v, %v) %v", dst, x, y, z, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib3f, a0: dst.c(), @@ -2767,12 +2767,12 @@ func VertexAttrib3f(dst Attrib, x, y, z float32) { }) } -func VertexAttrib3fv(dst Attrib, src []float32) { +func (ctx *context) VertexAttrib3fv(dst Attrib, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib3fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib3fv, a0: dst.c(), @@ -2782,12 +2782,12 @@ func VertexAttrib3fv(dst Attrib, src []float32) { }) } -func VertexAttrib4f(dst Attrib, x, y, z, w float32) { +func (ctx *context) VertexAttrib4f(dst Attrib, x, y, z, w float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib4f(%v, %v, %v, %v, %v) %v", dst, x, y, z, w, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib4f, a0: dst.c(), @@ -2799,12 +2799,12 @@ func VertexAttrib4f(dst Attrib, x, y, z, w float32) { }) } -func VertexAttrib4fv(dst Attrib, src []float32) { +func (ctx *context) VertexAttrib4fv(dst Attrib, src []float32) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttrib4fv(%v, len(%d)) %v", dst, len(src), errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttrib4fv, a0: dst.c(), @@ -2814,12 +2814,12 @@ func VertexAttrib4fv(dst Attrib, src []float32) { }) } -func VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) { +func (ctx *context) VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.VertexAttribPointer(%v, %v, %v, %v, %v, %v) %v", dst, size, ty, normalized, stride, offset, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnVertexAttribPointer, a0: dst.c(), @@ -2832,12 +2832,12 @@ func VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, }) } -func Viewport(x, y, width, height int) { +func (ctx *context) Viewport(x, y, width, height int) { defer func() { - errstr := errDrain() + errstr := ctx.errDrain() log.Printf("gl.Viewport(%v, %v, %v, %v) %v", x, y, width, height, errstr) }() - enqueue(call{ + ctx.enqueue(call{ args: C.struct_fnargs{ fn: C.glfnViewport, a0: C.uintptr_t(x), diff --git a/gl/interface.go b/gl/interface.go new file mode 100644 index 0000000..4178a3a --- /dev/null +++ b/gl/interface.go @@ -0,0 +1,856 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package gl + +// Context is an OpenGL context. +// +// Calls are not safe for concurrent use. However calls can be made from +// any goroutine, the gl package removes the notion of thread-local +// context. +// +// Contexts are independent. Two contexts can be used concurrently. +type Context interface { + // ActiveTexture sets the active texture unit. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glActiveTexture.xhtml + ActiveTexture(texture Enum) + + // AttachShader attaches a shader to a program. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glAttachShader.xhtml + AttachShader(p Program, s Shader) + + // BindAttribLocation binds a vertex attribute index with a named + // variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBindAttribLocation.xhtml + BindAttribLocation(p Program, a Attrib, name string) + + // BindBuffer binds a buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBindBuffer.xhtml + BindBuffer(target Enum, b Buffer) + + // BindFramebuffer binds a framebuffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBindFramebuffer.xhtml + BindFramebuffer(target Enum, fb Framebuffer) + + // BindRenderbuffer binds a render buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBindRenderbuffer.xhtml + BindRenderbuffer(target Enum, rb Renderbuffer) + + // BindTexture binds a texture. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBindTexture.xhtml + BindTexture(target Enum, t Texture) + + // BlendColor sets the blend color. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendColor.xhtml + BlendColor(red, green, blue, alpha float32) + + // BlendEquation sets both RGB and alpha blend equations. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendEquation.xhtml + BlendEquation(mode Enum) + + // BlendEquationSeparate sets RGB and alpha blend equations separately. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendEquationSeparate.xhtml + BlendEquationSeparate(modeRGB, modeAlpha Enum) + + // BlendFunc sets the pixel blending factors. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendFunc.xhtml + BlendFunc(sfactor, dfactor Enum) + + // BlendFunc sets the pixel RGB and alpha blending factors separately. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBlendFuncSeparate.xhtml + BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha Enum) + + // BufferData creates a new data store for the bound buffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBufferData.xhtml + BufferData(target Enum, src []byte, usage Enum) + + // BufferInit creates a new uninitialized data store for the bound buffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBufferData.xhtml + BufferInit(target Enum, size int, usage Enum) + + // BufferSubData sets some of data in the bound buffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glBufferSubData.xhtml + BufferSubData(target Enum, offset int, data []byte) + + // CheckFramebufferStatus reports the completeness status of the + // active framebuffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCheckFramebufferStatus.xhtml + CheckFramebufferStatus(target Enum) Enum + + // Clear clears the window. + // + // The behavior of Clear is influenced by the pixel ownership test, + // the scissor test, dithering, and the buffer writemasks. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glClear.xhtml + Clear(mask Enum) + + // ClearColor specifies the RGBA values used to clear color buffers. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glClearColor.xhtml + ClearColor(red, green, blue, alpha float32) + + // ClearDepthf sets the depth value used to clear the depth buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glClearDepthf.xhtml + ClearDepthf(d float32) + + // ClearStencil sets the index used to clear the stencil buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glClearStencil.xhtml + ClearStencil(s int) + + // ColorMask specifies whether color components in the framebuffer + // can be written. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glColorMask.xhtml + ColorMask(red, green, blue, alpha bool) + + // CompileShader compiles the source code of s. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCompileShader.xhtml + CompileShader(s Shader) + + // CompressedTexImage2D writes a compressed 2D texture. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCompressedTexImage2D.xhtml + CompressedTexImage2D(target Enum, level int, internalformat Enum, width, height, border int, data []byte) + + // CompressedTexSubImage2D writes a subregion of a compressed 2D texture. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCompressedTexSubImage2D.xhtml + CompressedTexSubImage2D(target Enum, level, xoffset, yoffset, width, height int, format Enum, data []byte) + + // CopyTexImage2D writes a 2D texture from the current framebuffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCopyTexImage2D.xhtml + CopyTexImage2D(target Enum, level int, internalformat Enum, x, y, width, height, border int) + + // CopyTexSubImage2D writes a 2D texture subregion from the + // current framebuffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCopyTexSubImage2D.xhtml + CopyTexSubImage2D(target Enum, level, xoffset, yoffset, x, y, width, height int) + + // CreateBuffer creates a buffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGenBuffers.xhtml + CreateBuffer() Buffer + + // CreateFramebuffer creates a framebuffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGenFramebuffers.xhtml + CreateFramebuffer() Framebuffer + + // CreateProgram creates a new empty program object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCreateProgram.xhtml + CreateProgram() Program + + // CreateRenderbuffer create a renderbuffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGenRenderbuffers.xhtml + CreateRenderbuffer() Renderbuffer + + // CreateShader creates a new empty shader object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCreateShader.xhtml + CreateShader(ty Enum) Shader + + // CreateTexture creates a texture object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGenTextures.xhtml + CreateTexture() Texture + + // CullFace specifies which polygons are candidates for culling. + // + // Valid modes: FRONT, BACK, FRONT_AND_BACK. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glCullFace.xhtml + CullFace(mode Enum) + + // DeleteBuffer deletes the given buffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteBuffers.xhtml + DeleteBuffer(v Buffer) + + // DeleteFramebuffer deletes the given framebuffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteFramebuffers.xhtml + DeleteFramebuffer(v Framebuffer) + + // DeleteProgram deletes the given program object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteProgram.xhtml + DeleteProgram(p Program) + + // DeleteRenderbuffer deletes the given render buffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteRenderbuffers.xhtml + DeleteRenderbuffer(v Renderbuffer) + + // DeleteShader deletes shader s. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteShader.xhtml + DeleteShader(s Shader) + + // DeleteTexture deletes the given texture object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDeleteTextures.xhtml + DeleteTexture(v Texture) + + // DepthFunc sets the function used for depth buffer comparisons. + // + // Valid fn values: + // NEVER + // LESS + // EQUAL + // LEQUAL + // GREATER + // NOTEQUAL + // GEQUAL + // ALWAYS + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDepthFunc.xhtml + DepthFunc(fn Enum) + + // DepthMask sets the depth buffer enabled for writing. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDepthMask.xhtml + DepthMask(flag bool) + + // DepthRangef sets the mapping from normalized device coordinates to + // window coordinates. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDepthRangef.xhtml + DepthRangef(n, f float32) + + // DetachShader detaches the shader s from the program p. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDetachShader.xhtml + DetachShader(p Program, s Shader) + + // Disable disables various GL capabilities. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDisable.xhtml + Disable(cap Enum) + + // DisableVertexAttribArray disables a vertex attribute array. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDisableVertexAttribArray.xhtml + DisableVertexAttribArray(a Attrib) + + // DrawArrays renders geometric primitives from the bound data. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDrawArrays.xhtml + DrawArrays(mode Enum, first, count int) + + // DrawElements renders primitives from a bound buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glDrawElements.xhtml + DrawElements(mode Enum, count int, ty Enum, offset int) + + // TODO(crawshaw): consider DrawElements8 / DrawElements16 / DrawElements32 + + // Enable enables various GL capabilities. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glEnable.xhtml + Enable(cap Enum) + + // EnableVertexAttribArray enables a vertex attribute array. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glEnableVertexAttribArray.xhtml + EnableVertexAttribArray(a Attrib) + + // Finish blocks until the effects of all previously called GL + // commands are complete. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glFinish.xhtml + Finish() + + // Flush empties all buffers. It does not block. + // + // An OpenGL implementation may buffer network communication, + // the command stream, or data inside the graphics accelerator. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glFlush.xhtml + Flush() + + // FramebufferRenderbuffer attaches rb to the current frame buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glFramebufferRenderbuffer.xhtml + FramebufferRenderbuffer(target, attachment, rbTarget Enum, rb Renderbuffer) + + // FramebufferTexture2D attaches the t to the current frame buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glFramebufferTexture2D.xhtml + FramebufferTexture2D(target, attachment, texTarget Enum, t Texture, level int) + + // FrontFace defines which polygons are front-facing. + // + // Valid modes: CW, CCW. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glFrontFace.xhtml + FrontFace(mode Enum) + + // GenerateMipmap generates mipmaps for the current texture. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGenerateMipmap.xhtml + GenerateMipmap(target Enum) + + // GetActiveAttrib returns details about an active attribute variable. + // A value of 0 for index selects the first active attribute variable. + // Permissible values for index range from 0 to the number of active + // attribute variables minus 1. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetActiveAttrib.xhtml + GetActiveAttrib(p Program, index uint32) (name string, size int, ty Enum) + + // GetActiveUniform returns details about an active uniform variable. + // A value of 0 for index selects the first active uniform variable. + // Permissible values for index range from 0 to the number of active + // uniform variables minus 1. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetActiveUniform.xhtml + GetActiveUniform(p Program, index uint32) (name string, size int, ty Enum) + + // GetAttachedShaders returns the shader objects attached to program p. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetAttachedShaders.xhtml + GetAttachedShaders(p Program) []Shader + + // GetAttribLocation returns the location of an attribute variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetAttribLocation.xhtml + GetAttribLocation(p Program, name string) Attrib + + // GetBooleanv returns the boolean values of parameter pname. + // + // Many boolean parameters can be queried more easily using IsEnabled. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml + GetBooleanv(dst []bool, pname Enum) + + // GetFloatv returns the float values of parameter pname. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml + GetFloatv(dst []float32, pname Enum) + + // GetIntegerv returns the int values of parameter pname. + // + // Single values may be queried more easily using GetInteger. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml + GetIntegerv(dst []int32, pname Enum) + + // GetInteger returns the int value of parameter pname. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGet.xhtml + GetInteger(pname Enum) int + + // GetBufferParameteri returns a parameter for the active buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetBufferParameter.xhtml + GetBufferParameteri(target, value Enum) int + + // GetError returns the next error. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetError.xhtml + GetError() Enum + + // GetFramebufferAttachmentParameteri returns attachment parameters + // for the active framebuffer object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetFramebufferAttachmentParameteriv.xhtml + GetFramebufferAttachmentParameteri(target, attachment, pname Enum) int + + // GetProgrami returns a parameter value for a program. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetProgramiv.xhtml + GetProgrami(p Program, pname Enum) int + + // GetProgramInfoLog returns the information log for a program. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetProgramInfoLog.xhtml + GetProgramInfoLog(p Program) string + + // GetRenderbufferParameteri returns a parameter value for a render buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetRenderbufferParameteriv.xhtml + GetRenderbufferParameteri(target, pname Enum) int + + // GetShaderi returns a parameter value for a shader. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderiv.xhtml + GetShaderi(s Shader, pname Enum) int + + // GetShaderInfoLog returns the information log for a shader. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderInfoLog.xhtml + GetShaderInfoLog(s Shader) string + + // GetShaderPrecisionFormat returns range and precision limits for + // shader types. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderPrecisionFormat.xhtml + GetShaderPrecisionFormat(shadertype, precisiontype Enum) (rangeLow, rangeHigh, precision int) + + // GetShaderSource returns source code of shader s. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetShaderSource.xhtml + GetShaderSource(s Shader) string + + // GetString reports current GL state. + // + // Valid name values: + // EXTENSIONS + // RENDERER + // SHADING_LANGUAGE_VERSION + // VENDOR + // VERSION + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetString.xhtml + GetString(pname Enum) string + + // GetTexParameterfv returns the float values of a texture parameter. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetTexParameter.xhtml + GetTexParameterfv(dst []float32, target, pname Enum) + + // GetTexParameteriv returns the int values of a texture parameter. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetTexParameter.xhtml + GetTexParameteriv(dst []int32, target, pname Enum) + + // GetUniformfv returns the float values of a uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniform.xhtml + GetUniformfv(dst []float32, src Uniform, p Program) + + // GetUniformiv returns the float values of a uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniform.xhtml + GetUniformiv(dst []int32, src Uniform, p Program) + + // GetUniformLocation returns the location of a uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetUniformLocation.xhtml + GetUniformLocation(p Program, name string) Uniform + + // GetVertexAttribf reads the float value of a vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml + GetVertexAttribf(src Attrib, pname Enum) float32 + + // GetVertexAttribfv reads float values of a vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml + GetVertexAttribfv(dst []float32, src Attrib, pname Enum) + + // GetVertexAttribi reads the int value of a vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml + GetVertexAttribi(src Attrib, pname Enum) int32 + + // GetVertexAttribiv reads int values of a vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glGetVertexAttrib.xhtml + GetVertexAttribiv(dst []int32, src Attrib, pname Enum) + + // TODO(crawshaw): glGetVertexAttribPointerv + + // Hint sets implementation-specific modes. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glHint.xhtml + Hint(target, mode Enum) + + // IsBuffer reports if b is a valid buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsBuffer.xhtml + IsBuffer(b Buffer) bool + + // IsEnabled reports if cap is an enabled capability. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsEnabled.xhtml + IsEnabled(cap Enum) bool + + // IsFramebuffer reports if fb is a valid frame buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsFramebuffer.xhtml + IsFramebuffer(fb Framebuffer) bool + + // IsProgram reports if p is a valid program object. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsProgram.xhtml + IsProgram(p Program) bool + + // IsRenderbuffer reports if rb is a valid render buffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsRenderbuffer.xhtml + IsRenderbuffer(rb Renderbuffer) bool + + // IsShader reports if s is valid shader. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsShader.xhtml + IsShader(s Shader) bool + + // IsTexture reports if t is a valid texture. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glIsTexture.xhtml + IsTexture(t Texture) bool + + // LineWidth specifies the width of lines. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glLineWidth.xhtml + LineWidth(width float32) + + // LinkProgram links the specified program. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glLinkProgram.xhtml + LinkProgram(p Program) + + // PixelStorei sets pixel storage parameters. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glPixelStorei.xhtml + PixelStorei(pname Enum, param int32) + + // PolygonOffset sets the scaling factors for depth offsets. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glPolygonOffset.xhtml + PolygonOffset(factor, units float32) + + // ReadPixels returns pixel data from a buffer. + // + // In GLES 3, the source buffer is controlled with ReadBuffer. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glReadPixels.xhtml + ReadPixels(dst []byte, x, y, width, height int, format, ty Enum) + + // ReleaseShaderCompiler frees resources allocated by the shader compiler. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glReleaseShaderCompiler.xhtml + ReleaseShaderCompiler() + + // RenderbufferStorage establishes the data storage, format, and + // dimensions of a renderbuffer object's image. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glRenderbufferStorage.xhtml + RenderbufferStorage(target, internalFormat Enum, width, height int) + + // SampleCoverage sets multisample coverage parameters. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glSampleCoverage.xhtml + SampleCoverage(value float32, invert bool) + + // Scissor defines the scissor box rectangle, in window coordinates. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glScissor.xhtml + Scissor(x, y, width, height int32) + + // TODO(crawshaw): ShaderBinary + + // ShaderSource sets the source code of s to the given source code. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glShaderSource.xhtml + ShaderSource(s Shader, src string) + + // StencilFunc sets the front and back stencil test reference value. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilFunc.xhtml + StencilFunc(fn Enum, ref int, mask uint32) + + // StencilFunc sets the front or back stencil test reference value. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilFuncSeparate.xhtml + StencilFuncSeparate(face, fn Enum, ref int, mask uint32) + + // StencilMask controls the writing of bits in the stencil planes. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilMask.xhtml + StencilMask(mask uint32) + + // StencilMaskSeparate controls the writing of bits in the stencil planes. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilMaskSeparate.xhtml + StencilMaskSeparate(face Enum, mask uint32) + + // StencilOp sets front and back stencil test actions. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilOp.xhtml + StencilOp(fail, zfail, zpass Enum) + + // StencilOpSeparate sets front or back stencil tests. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glStencilOpSeparate.xhtml + StencilOpSeparate(face, sfail, dpfail, dppass Enum) + + // TexImage2D writes a 2D texture image. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glTexImage2D.xhtml + TexImage2D(target Enum, level int, width, height int, format Enum, ty Enum, data []byte) + + // TexSubImage2D writes a subregion of a 2D texture image. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glTexSubImage2D.xhtml + TexSubImage2D(target Enum, level int, x, y, width, height int, format, ty Enum, data []byte) + + // TexParameterf sets a float texture parameter. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml + TexParameterf(target, pname Enum, param float32) + + // TexParameterfv sets a float texture parameter array. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml + TexParameterfv(target, pname Enum, params []float32) + + // TexParameteri sets an integer texture parameter. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml + TexParameteri(target, pname Enum, param int) + + // TexParameteriv sets an integer texture parameter array. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glTexParameter.xhtml + TexParameteriv(target, pname Enum, params []int32) + + // Uniform1f writes a float uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform1f(dst Uniform, v float32) + + // Uniform1fv writes a [len(src)]float uniform array. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform1fv(dst Uniform, src []float32) + + // Uniform1i writes an int uniform variable. + // + // Uniform1i and Uniform1iv are the only two functions that may be used + // to load uniform variables defined as sampler types. Loading samplers + // with any other function will result in a INVALID_OPERATION error. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform1i(dst Uniform, v int) + + // Uniform1iv writes a int uniform array of len(src) elements. + // + // Uniform1i and Uniform1iv are the only two functions that may be used + // to load uniform variables defined as sampler types. Loading samplers + // with any other function will result in a INVALID_OPERATION error. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform1iv(dst Uniform, src []int32) + + // Uniform2f writes a vec2 uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform2f(dst Uniform, v0, v1 float32) + + // Uniform2fv writes a vec2 uniform array of len(src)/2 elements. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform2fv(dst Uniform, src []float32) + + // Uniform2i writes an ivec2 uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform2i(dst Uniform, v0, v1 int) + + // Uniform2iv writes an ivec2 uniform array of len(src)/2 elements. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform2iv(dst Uniform, src []int32) + + // Uniform3f writes a vec3 uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform3f(dst Uniform, v0, v1, v2 float32) + + // Uniform3fv writes a vec3 uniform array of len(src)/3 elements. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform3fv(dst Uniform, src []float32) + + // Uniform3i writes an ivec3 uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform3i(dst Uniform, v0, v1, v2 int32) + + // Uniform3iv writes an ivec3 uniform array of len(src)/3 elements. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform3iv(dst Uniform, src []int32) + + // Uniform4f writes a vec4 uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform4f(dst Uniform, v0, v1, v2, v3 float32) + + // Uniform4fv writes a vec4 uniform array of len(src)/4 elements. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform4fv(dst Uniform, src []float32) + + // Uniform4i writes an ivec4 uniform variable. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform4i(dst Uniform, v0, v1, v2, v3 int32) + + // Uniform4i writes an ivec4 uniform array of len(src)/4 elements. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + Uniform4iv(dst Uniform, src []int32) + + // UniformMatrix2fv writes 2x2 matrices. Each matrix uses four + // float32 values, so the number of matrices written is len(src)/4. + // + // Each matrix must be supplied in column major order. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + UniformMatrix2fv(dst Uniform, src []float32) + + // UniformMatrix3fv writes 3x3 matrices. Each matrix uses nine + // float32 values, so the number of matrices written is len(src)/9. + // + // Each matrix must be supplied in column major order. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + UniformMatrix3fv(dst Uniform, src []float32) + + // UniformMatrix4fv writes 4x4 matrices. Each matrix uses 16 + // float32 values, so the number of matrices written is len(src)/16. + // + // Each matrix must be supplied in column major order. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUniform.xhtml + UniformMatrix4fv(dst Uniform, src []float32) + + // UseProgram sets the active program. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glUseProgram.xhtml + UseProgram(p Program) + + // ValidateProgram checks to see whether the executables contained in + // program can execute given the current OpenGL state. + // + // Typically only used for debugging. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glValidateProgram.xhtml + ValidateProgram(p Program) + + // VertexAttrib1f writes a float vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib1f(dst Attrib, x float32) + + // VertexAttrib1fv writes a float vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib1fv(dst Attrib, src []float32) + + // VertexAttrib2f writes a vec2 vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib2f(dst Attrib, x, y float32) + + // VertexAttrib2fv writes a vec2 vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib2fv(dst Attrib, src []float32) + + // VertexAttrib3f writes a vec3 vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib3f(dst Attrib, x, y, z float32) + + // VertexAttrib3fv writes a vec3 vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib3fv(dst Attrib, src []float32) + + // VertexAttrib4f writes a vec4 vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib4f(dst Attrib, x, y, z, w float32) + + // VertexAttrib4fv writes a vec4 vertex attribute. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttrib.xhtml + VertexAttrib4fv(dst Attrib, src []float32) + + // VertexAttribPointer uses a bound buffer to define vertex attribute data. + // + // Direct use of VertexAttribPointer to load data into OpenGL is not + // supported via the Go bindings. Instead, use BindBuffer with an + // ARRAY_BUFFER and then fill it using BufferData. + // + // The size argument specifies the number of components per attribute, + // between 1-4. The stride argument specifies the byte offset between + // consecutive vertex attributes. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glVertexAttribPointer.xhtml + VertexAttribPointer(dst Attrib, size int, ty Enum, normalized bool, stride, offset int) + + // Viewport sets the viewport, an affine transformation that + // normalizes device coordinates to window coordinates. + // + // http://www.khronos.org/opengles/sdk/docs/man3/html/glViewport.xhtml + Viewport(x, y, width, height int) +} + +// Worker is used by display driver code to execute OpenGL calls. +// +// Typically display driver code creates a gl.Context for an application, +// and along with it establishes a locked OS thread to execute the cgo +// calls: +// +// go func() { +// runtime.LockOSThread() +// // ... platform-specific cgo call to bind a C OpenGL context +// // into thread-local storage. +// +// glctx, worker := gl.NewContext() +// workAvailable := glctx.WorkAvailable() +// go userAppCode(glctx) +// for { +// select { +// case <-workAvailable: +// glctx.DoWork() +// case <-drawEvent: +// // ... platform-specific cgo call to draw screen +// } +// } +// }() +type Worker interface { + // WorkAvailable returns a channel that communicates when DoWork + // should be called. + // + // This is an internal implementation detail and should only be + // used by the package responsible for managing the screen (e.g. + // golang.org/x/mobile/app). + WorkAvailable() <-chan struct{} + + // DoWork performs any pending OpenGL calls. + // + // This is an internal implementation detail and should only be used by the + // golang.org/x/mobile/app package. + DoWork() +} diff --git a/gl/work.c b/gl/work.c index eb5802b..bcc1b4c 100644 --- a/gl/work.c +++ b/gl/work.c @@ -8,7 +8,8 @@ #include "_cgo_export.h" #include "work.h" -void processFn(struct fnargs* args) { +uintptr_t processFn(struct fnargs* args) { + uintptr_t ret = 0; switch (args->fn) { case glfnUNDEFINED: abort(); // bad glfn @@ -475,4 +476,5 @@ void processFn(struct fnargs* args) { glViewport((GLint)args->a0, (GLint)args->a1, (GLint)args->a2, (GLint)args->a3); break; } + return ret; } diff --git a/gl/work.go b/gl/work.go index 7df0492..3c4b34a 100644 --- a/gl/work.go +++ b/gl/work.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// +build darwin linux +// +build darwin linux cgo package gl @@ -20,71 +20,81 @@ package gl #include #include "work.h" -struct fnargs cargs[10]; -uintptr_t ret; - -void process(int count) { +// TODO: return uintptr_t instead of taking ret. +void process(struct fnargs* cargs, int count, uintptr_t* ret) { int i; for (i = 0; i < count; i++) { - processFn(&cargs[i]); + *ret = processFn(&cargs[i]); } } */ import "C" -// work is a queue of calls to execute. -var work = make(chan call, 10) +const workbufLen = 10 -// retvalue is sent a return value when blocking calls complete. -// It is safe to use a global unbuffered channel here as calls -// cannot currently be made concurrently. +type context struct { + cptr uintptr + + workAvailable chan struct{} + + // work is a queue of calls to execute. + work chan call + + // retvalue is sent a return value when blocking calls complete. + // It is safe to use a global unbuffered channel here as calls + // cannot currently be made concurrently. + // + // TODO: the comment above about concurrent calls isn't actually true: package + // app calls package gl, but it has to do so in a separate goroutine, which + // means that its gl calls (which may be blocking) can race with other gl calls + // in the main program. We should make it safe to issue blocking gl calls + // concurrently, or get the gl calls out of package app, or both. + retvalue chan C.uintptr_t + + cargs [workbufLen]C.struct_fnargs + ret C.uintptr_t +} + +func (ctx *context) WorkAvailable() <-chan struct{} { return ctx.workAvailable } + +// NewContext creates a cgo OpenGL context. // -// TODO: the comment above about concurrent calls isn't actually true: package -// app calls package gl, but it has to do so in a separate goroutine, which -// means that its gl calls (which may be blocking) can race with other gl calls -// in the main program. We should make it safe to issue blocking gl calls -// concurrently, or get the gl calls out of package app, or both. -var retvalue = make(chan C.uintptr_t) +// See the Worker interface for more details on how it is used. +func NewContext() (Context, Worker) { + glctx := &context{ + workAvailable: make(chan struct{}, 1), + work: make(chan call, workbufLen), + retvalue: make(chan C.uintptr_t), + } + return glctx, glctx +} type call struct { args C.struct_fnargs blocking bool } -func enqueue(c call) C.uintptr_t { - work <- c +func (ctx *context) enqueue(c call) C.uintptr_t { + ctx.work <- c select { - case workAvailable <- struct{}{}: + case ctx.workAvailable <- struct{}{}: default: } if c.blocking { - return <-retvalue + return <-ctx.retvalue } return 0 } -var ( - workAvailable = make(chan struct{}, 1) - // WorkAvailable communicates when DoWork should be called. - // - // This is an internal implementation detail and should only be used by the - // golang.org/x/mobile/app package. - WorkAvailable <-chan struct{} = workAvailable -) - -// DoWork performs any pending OpenGL calls. -// -// This is an internal implementation detail and should only be used by the -// golang.org/x/mobile/app package. -func DoWork() { - queue := make([]call, 0, len(work)) +func (ctx *context) DoWork() { + queue := make([]call, 0, len(ctx.work)) for { // Wait until at least one piece of work is ready. // Accumulate work until a piece is marked as blocking. select { - case w := <-work: + case w := <-ctx.work: queue = append(queue, w) default: return @@ -93,7 +103,7 @@ func DoWork() { enqueue: for len(queue) < cap(queue) && !blocking { select { - case w := <-work: + case w := <-ctx.work: queue = append(queue, w) blocking = queue[len(queue)-1].blocking default: @@ -103,14 +113,14 @@ func DoWork() { // Process the queued GL functions. for i, q := range queue { - C.cargs[i] = q.args + ctx.cargs[i] = q.args } - C.process(C.int(len(queue))) + C.process(&ctx.cargs[0], C.int(len(queue)), &ctx.ret) // Cleanup and signal. queue = queue[:0] if blocking { - retvalue <- C.ret + ctx.retvalue <- ctx.ret } } } diff --git a/gl/work.h b/gl/work.h index dc7d0f0..bfd3a6e 100644 --- a/gl/work.h +++ b/gl/work.h @@ -176,4 +176,4 @@ struct fnargs { extern uintptr_t ret; -extern void processFn(struct fnargs* args); +extern uintptr_t processFn(struct fnargs* args);