diff --git a/pixelgl/interface.go b/pixelgl/interface.go index c079204ea91fc1cfdacb82322b2673e2f0b23885..3dd71e696ff16e740301b241c3c5d656f437400b 100644 --- a/pixelgl/interface.go +++ b/pixelgl/interface.go @@ -27,6 +27,8 @@ package pixelgl // Also notice, that the functions are passing a Context around. This context contains the most important state variables. // Usually, you just pass it as you received it. If you want to pass a changed context to your child (e.g. your a shader), // use ctx.With* methods. +// +// If possible and makes sense, Do method should be reentrant. type Doer interface { Do(sub func(Context)) } diff --git a/pixelgl/shader.go b/pixelgl/shader.go index 2b24ebd8da022380856c568d5fbe5b28e735a016..3023d8c45b1efd3d518aa42076b03c9e2ac44d39 100644 --- a/pixelgl/shader.go +++ b/pixelgl/shader.go @@ -17,6 +17,7 @@ type UniformFormat map[string]Attr // Shader is an OpenGL shader program. type Shader struct { + enabled bool parent Doer program uint32 vertexFormat VertexFormat @@ -383,6 +384,11 @@ func (s *Shader) SetUniformMat43(purpose AttrPurpose, value mgl32.Mat4x3) (ok bo // Do stars using a shader, executes sub, and stops using it. func (s *Shader) Do(sub func(Context)) { s.parent.Do(func(ctx Context) { + if s.enabled { + sub(ctx.WithShader(s)) + return + } + s.enabled = true DoNoBlock(func() { gl.UseProgram(s.program) }) @@ -390,5 +396,6 @@ func (s *Shader) Do(sub func(Context)) { DoNoBlock(func() { gl.UseProgram(0) }) + s.enabled = false }) } diff --git a/pixelgl/texture.go b/pixelgl/texture.go index ae6d8a77463c34d51ad208abbb99c097180a3cfe..c79d8cf5398e8a8ecd021f61454c0a74c592fa1f 100644 --- a/pixelgl/texture.go +++ b/pixelgl/texture.go @@ -7,8 +7,9 @@ import ( // Texture is an OpenGL texture. type Texture struct { - parent Doer - tex uint32 + enabled bool + parent Doer + tex uint32 } // NewTexture creates a new texture with the specified width and height. @@ -63,6 +64,11 @@ func (t *Texture) ID() uint32 { // Do bind a texture, executes sub, and unbinds the texture. func (t *Texture) Do(sub func(Context)) { t.parent.Do(func(ctx Context) { + if t.enabled { + sub(ctx) + return + } + t.enabled = true DoNoBlock(func() { gl.BindTexture(gl.TEXTURE_2D, t.tex) }) @@ -70,5 +76,6 @@ func (t *Texture) Do(sub func(Context)) { DoNoBlock(func() { gl.BindTexture(gl.TEXTURE_2D, 0) }) + t.enabled = false }) } diff --git a/pixelgl/vertex.go b/pixelgl/vertex.go index f112daee242cff7e686418f28334555057020a8f..25012d46a1f57c177f6717c540aa4bb4f15c3648 100644 --- a/pixelgl/vertex.go +++ b/pixelgl/vertex.go @@ -69,14 +69,15 @@ const ( // VertexArray is an OpenGL vertex array object that also holds it's own vertex buffer object. // From the user's points of view, VertexArray is an array of vertices that can be drawn. type VertexArray struct { - parent Doer - vao uint32 - vbo uint32 - format VertexFormat - stride int - count int - attrs map[Attr]int - mode VertexDrawMode + enabled bool + parent Doer + vao uint32 + vbo uint32 + format VertexFormat + stride int + count int + attrs map[Attr]int + mode VertexDrawMode } // NewVertexArray creates a new empty vertex array and wraps another Doer around it. @@ -341,6 +342,11 @@ func (va *VertexArray) SetVertexAttributeVec4(vertex int, purpose AttrPurpose, v // Do binds a vertex arrray and it's associated vertex buffer, executes sub, and unbinds the vertex array and it's vertex buffer. func (va *VertexArray) Do(sub func(Context)) { va.parent.Do(func(ctx Context) { + if va.enabled { + sub(ctx) + return + } + va.enabled = true DoNoBlock(func() { gl.BindVertexArray(va.vao) gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo) @@ -351,5 +357,6 @@ func (va *VertexArray) Do(sub func(Context)) { gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BindVertexArray(0) }) + va.enabled = false }) }