add context
This commit is contained in:
parent
6253156e24
commit
9d4111282e
58
graphics.go
58
graphics.go
|
@ -1,58 +0,0 @@
|
||||||
package pixel
|
|
||||||
|
|
||||||
import "github.com/faiface/pixel/pixelgl"
|
|
||||||
|
|
||||||
// Warning: technical stuff below.
|
|
||||||
|
|
||||||
// VertexFormat is an internal format of the OpenGL vertex data.
|
|
||||||
//
|
|
||||||
// You can actually change this and all of the Pixel's functions will use the new format.
|
|
||||||
// Only change when you're implementing an OpenGL effect or something similar.
|
|
||||||
var VertexFormat = DefaultVertexFormat()
|
|
||||||
|
|
||||||
// DefaultVertexFormat returns the default vertex format used by Pixel.
|
|
||||||
func DefaultVertexFormat() pixelgl.VertexFormat {
|
|
||||||
return pixelgl.VertexFormat{
|
|
||||||
{Purpose: pixelgl.Position, Size: 2},
|
|
||||||
{Purpose: pixelgl.Color, Size: 4},
|
|
||||||
{Purpose: pixelgl.TexCoord, Size: 2},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConvertVertexData converts data in the oldFormat to the newFormat. Vertex attributes in the new format
|
|
||||||
// will be copied from the corresponding vertex attributes in the old format. If a vertex attribute in the new format
|
|
||||||
// has no corresponding attribute in the old format, it will be filled with zeros.
|
|
||||||
func ConvertVertexData(oldFormat, newFormat pixelgl.VertexFormat, data []float64) []float64 {
|
|
||||||
// calculate the mapping between old and new format
|
|
||||||
// if i is a start of a vertex attribute in the new format, then mapping[i] returns
|
|
||||||
// the index where the same attribute starts in the old format
|
|
||||||
mapping := make(map[int]int)
|
|
||||||
i := 0
|
|
||||||
for _, newAttr := range newFormat {
|
|
||||||
j := 0
|
|
||||||
for _, oldAttr := range oldFormat {
|
|
||||||
if newAttr == oldAttr {
|
|
||||||
mapping[i] = j
|
|
||||||
break
|
|
||||||
}
|
|
||||||
j += oldAttr.Size
|
|
||||||
}
|
|
||||||
i += newAttr.Size
|
|
||||||
}
|
|
||||||
|
|
||||||
oldData, newData := data, []float64{}
|
|
||||||
|
|
||||||
for i := 0; i < len(oldData); i += oldFormat.Size() {
|
|
||||||
j := 0
|
|
||||||
for _, attr := range newFormat {
|
|
||||||
if oldIndex, ok := mapping[j]; ok { // the attribute was found in the old format
|
|
||||||
newData = append(newData, oldData[i+oldIndex:i+oldIndex+attr.Size]...)
|
|
||||||
} else { // the attribute wasn't found in the old format, so fill with zeros
|
|
||||||
newData = append(newData, make([]float64, attr.Size)...)
|
|
||||||
}
|
|
||||||
j += attr.Size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newData
|
|
||||||
}
|
|
|
@ -12,10 +12,10 @@ package pixelgl
|
||||||
// The recommended way to implement a Doer is to wrap another Doer (vertex array wraps texture and so on), let's call
|
// The recommended way to implement a Doer is to wrap another Doer (vertex array wraps texture and so on), let's call
|
||||||
// it parent. Then the Do method will look like this:
|
// it parent. Then the Do method will look like this:
|
||||||
//
|
//
|
||||||
// func (o *MyObject) Do(sub func()) {
|
// func (o *MyObject) Do(sub func(Context)) {
|
||||||
// o.parent.Do(func() {
|
// o.parent.Do(func(ctx Context) {
|
||||||
// // enter the object's state
|
// // enter the object's state
|
||||||
// sub()
|
// sub(ctx)
|
||||||
// // leave the object's state
|
// // leave the object's state
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
|
@ -23,6 +23,45 @@ package pixelgl
|
||||||
// It might seem difficult to grasp this kind of recursion at first, but it's really simple. What it's basically saying
|
// It might seem difficult to grasp this kind of recursion at first, but it's really simple. What it's basically saying
|
||||||
// is: "Hey parent, enter your state, then let me enter mine, then I'll do whatever I'm supposed to do in the middle.
|
// is: "Hey parent, enter your state, then let me enter mine, then I'll do whatever I'm supposed to do in the middle.
|
||||||
// After that I'll leave my state and please leave your state too parent."
|
// After that I'll leave my state and please leave your state too parent."
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
type Doer interface {
|
type Doer interface {
|
||||||
Do(sub func())
|
Do(sub func(Context))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Context takes state from one object to another. OpenGL is a state machine, so we have to approach it like that.
|
||||||
|
// However, global variables are evil, so we have Context, that transfers important OpenGL state from one object to another.
|
||||||
|
//
|
||||||
|
// This type does *not* represent an OpenGL context in the OpenGL terminology.
|
||||||
|
type Context struct {
|
||||||
|
vertexFormat VertexFormat
|
||||||
|
shader *Shader
|
||||||
|
}
|
||||||
|
|
||||||
|
// VertexFormat returns the current vertex format.
|
||||||
|
func (c Context) VertexFormat() VertexFormat {
|
||||||
|
return c.vertexFormat
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shader returns the current shader.
|
||||||
|
func (c Context) Shader() *Shader {
|
||||||
|
return c.shader
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithVertexFormat returns a copy of this context with the specified vertex format.
|
||||||
|
func (c Context) WithVertexFormat(vf VertexFormat) Context {
|
||||||
|
return Context{
|
||||||
|
vertexFormat: vf,
|
||||||
|
shader: c.shader,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithShader returns a copy of this context with the specified shader.
|
||||||
|
func (c Context) WithShader(s *Shader) Context {
|
||||||
|
return Context{
|
||||||
|
vertexFormat: c.vertexFormat,
|
||||||
|
shader: s,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func NewShader(parent Doer, vertexShader, fragmentShader string) (*Shader, error
|
||||||
}
|
}
|
||||||
|
|
||||||
var err, glerr error
|
var err, glerr error
|
||||||
parent.Do(func() {
|
parent.Do(func(ctx Context) {
|
||||||
err, glerr = DoErrGLErr(func() error {
|
err, glerr = DoErrGLErr(func() error {
|
||||||
var vshader, fshader uint32
|
var vshader, fshader uint32
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ func NewShader(parent Doer, vertexShader, fragmentShader string) (*Shader, error
|
||||||
|
|
||||||
// Delete deletes a shader program. Don't use a shader after deletion.
|
// Delete deletes a shader program. Don't use a shader after deletion.
|
||||||
func (s *Shader) Delete() {
|
func (s *Shader) Delete() {
|
||||||
s.parent.Do(func() {
|
s.parent.Do(func(ctx Context) {
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.DeleteProgram(s.program)
|
gl.DeleteProgram(s.program)
|
||||||
})
|
})
|
||||||
|
@ -113,12 +113,12 @@ func (s *Shader) Delete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do stars using a shader, executes sub, and stops using it.
|
// Do stars using a shader, executes sub, and stops using it.
|
||||||
func (s *Shader) Do(sub func()) {
|
func (s *Shader) Do(sub func(Context)) {
|
||||||
s.parent.Do(func() {
|
s.parent.Do(func(ctx Context) {
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.UseProgram(s.program)
|
gl.UseProgram(s.program)
|
||||||
})
|
})
|
||||||
sub()
|
sub(ctx.WithShader(s))
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.UseProgram(0)
|
gl.UseProgram(0)
|
||||||
})
|
})
|
||||||
|
|
|
@ -17,7 +17,7 @@ func NewTexture(parent Doer, width, height int, pixels []uint8) (*Texture, error
|
||||||
texture := &Texture{parent: parent}
|
texture := &Texture{parent: parent}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
parent.Do(func() {
|
parent.Do(func(ctx Context) {
|
||||||
err = DoGLErr(func() {
|
err = DoGLErr(func() {
|
||||||
gl.GenTextures(1, &texture.tex)
|
gl.GenTextures(1, &texture.tex)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, texture.tex)
|
gl.BindTexture(gl.TEXTURE_2D, texture.tex)
|
||||||
|
@ -48,7 +48,7 @@ func NewTexture(parent Doer, width, height int, pixels []uint8) (*Texture, error
|
||||||
|
|
||||||
// Delete deletes a texture. Don't use a texture after deletion.
|
// Delete deletes a texture. Don't use a texture after deletion.
|
||||||
func (t *Texture) Delete() {
|
func (t *Texture) Delete() {
|
||||||
t.parent.Do(func() {
|
t.parent.Do(func(ctx Context) {
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.DeleteTextures(1, &t.tex)
|
gl.DeleteTextures(1, &t.tex)
|
||||||
})
|
})
|
||||||
|
@ -56,12 +56,12 @@ func (t *Texture) Delete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do bind a texture, executes sub, and unbinds the texture.
|
// Do bind a texture, executes sub, and unbinds the texture.
|
||||||
func (t *Texture) Do(sub func()) {
|
func (t *Texture) Do(sub func(Context)) {
|
||||||
t.parent.Do(func() {
|
t.parent.Do(func(ctx Context) {
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.BindTexture(gl.TEXTURE_2D, t.tex)
|
gl.BindTexture(gl.TEXTURE_2D, t.tex)
|
||||||
})
|
})
|
||||||
sub()
|
sub(ctx)
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.BindTexture(gl.TEXTURE_2D, 0)
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
})
|
})
|
||||||
|
|
|
@ -125,7 +125,7 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
parent.Do(func() {
|
parent.Do(func(ctx Context) {
|
||||||
err = DoGLErr(func() {
|
err = DoGLErr(func() {
|
||||||
gl.GenVertexArrays(1, &va.vao)
|
gl.GenVertexArrays(1, &va.vao)
|
||||||
gl.BindVertexArray(va.vao)
|
gl.BindVertexArray(va.vao)
|
||||||
|
@ -161,7 +161,7 @@ func NewVertexArray(parent Doer, format VertexFormat, mode VertexDrawMode, usage
|
||||||
|
|
||||||
// Delete deletes a vertex array and it's associated vertex buffer. Don't use a vertex array after deletion.
|
// Delete deletes a vertex array and it's associated vertex buffer. Don't use a vertex array after deletion.
|
||||||
func (va *VertexArray) Delete() {
|
func (va *VertexArray) Delete() {
|
||||||
va.parent.Do(func() {
|
va.parent.Do(func(ctx Context) {
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.DeleteVertexArrays(1, &va.vao)
|
gl.DeleteVertexArrays(1, &va.vao)
|
||||||
gl.DeleteBuffers(1, &va.vbo)
|
gl.DeleteBuffers(1, &va.vbo)
|
||||||
|
@ -193,7 +193,7 @@ func (va *VertexArray) DrawMode() VertexDrawMode {
|
||||||
|
|
||||||
// Draw draws a vertex array.
|
// Draw draws a vertex array.
|
||||||
func (va *VertexArray) Draw() {
|
func (va *VertexArray) Draw() {
|
||||||
va.Do(func() {})
|
va.Do(func(Context) {})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Data returns a copy of data inside a vertex array (actually it's vertex buffer).
|
// Data returns a copy of data inside a vertex array (actually it's vertex buffer).
|
||||||
|
@ -233,13 +233,13 @@ func (va *VertexArray) SetVertexAttribute(vertex int, attr VertexAttribute, data
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do binds a vertex arrray and it's associated vertex buffer, executes sub, and unbinds the vertex array and it's vertex buffer.
|
// 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()) {
|
func (va *VertexArray) Do(sub func(Context)) {
|
||||||
va.parent.Do(func() {
|
va.parent.Do(func(ctx Context) {
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.BindVertexArray(va.vao)
|
gl.BindVertexArray(va.vao)
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
gl.BindBuffer(gl.ARRAY_BUFFER, va.vbo)
|
||||||
})
|
})
|
||||||
sub()
|
sub(ctx)
|
||||||
DoNoBlock(func() {
|
DoNoBlock(func() {
|
||||||
gl.DrawArrays(uint32(va.mode), 0, int32(va.count))
|
gl.DrawArrays(uint32(va.mode), 0, int32(va.count))
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
|
|
34
window.go
34
window.go
|
@ -108,7 +108,7 @@ func NewWindow(config WindowConfig) (*Window, error) {
|
||||||
|
|
||||||
// Delete destroys a window. The window can't be used any further.
|
// Delete destroys a window. The window can't be used any further.
|
||||||
func (w *Window) Delete() {
|
func (w *Window) Delete() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.Destroy()
|
w.window.Destroy()
|
||||||
})
|
})
|
||||||
|
@ -117,14 +117,14 @@ func (w *Window) Delete() {
|
||||||
|
|
||||||
// Clear clears the window with a color.
|
// Clear clears the window with a color.
|
||||||
func (w *Window) Clear(c color.Color) {
|
func (w *Window) Clear(c color.Color) {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Clear(colorToRGBA(c))
|
pixelgl.Clear(colorToRGBA(c))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update swaps buffers and polls events.
|
// Update swaps buffers and polls events.
|
||||||
func (w *Window) Update() {
|
func (w *Window) Update() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
if w.config.VSync {
|
if w.config.VSync {
|
||||||
glfw.SwapInterval(1)
|
glfw.SwapInterval(1)
|
||||||
|
@ -137,7 +137,7 @@ func (w *Window) Update() {
|
||||||
|
|
||||||
// SetTitle changes the title of a window.
|
// SetTitle changes the title of a window.
|
||||||
func (w *Window) SetTitle(title string) {
|
func (w *Window) SetTitle(title string) {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.SetTitle(title)
|
w.window.SetTitle(title)
|
||||||
})
|
})
|
||||||
|
@ -147,7 +147,7 @@ func (w *Window) SetTitle(title string) {
|
||||||
// SetSize resizes a window to the specified size in pixels.
|
// SetSize resizes a window to the specified size in pixels.
|
||||||
// In case of a fullscreen window, it changes the resolution of that window.
|
// In case of a fullscreen window, it changes the resolution of that window.
|
||||||
func (w *Window) SetSize(width, height float64) {
|
func (w *Window) SetSize(width, height float64) {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.SetSize(int(width), int(height))
|
w.window.SetSize(int(width), int(height))
|
||||||
})
|
})
|
||||||
|
@ -156,7 +156,7 @@ func (w *Window) SetSize(width, height float64) {
|
||||||
|
|
||||||
// Size returns the size of the client area of a window (the part you can draw on).
|
// Size returns the size of the client area of a window (the part you can draw on).
|
||||||
func (w *Window) Size() (width, height float64) {
|
func (w *Window) Size() (width, height float64) {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
wi, hi := w.window.GetSize()
|
wi, hi := w.window.GetSize()
|
||||||
width = float64(wi)
|
width = float64(wi)
|
||||||
|
@ -168,7 +168,7 @@ func (w *Window) Size() (width, height float64) {
|
||||||
|
|
||||||
// Show makes a window visible if it was hidden.
|
// Show makes a window visible if it was hidden.
|
||||||
func (w *Window) Show() {
|
func (w *Window) Show() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.Show()
|
w.window.Show()
|
||||||
})
|
})
|
||||||
|
@ -177,7 +177,7 @@ func (w *Window) Show() {
|
||||||
|
|
||||||
// Hide hides a window if it was visible.
|
// Hide hides a window if it was visible.
|
||||||
func (w *Window) Hide() {
|
func (w *Window) Hide() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.Hide()
|
w.window.Hide()
|
||||||
})
|
})
|
||||||
|
@ -191,7 +191,7 @@ func (w *Window) Hide() {
|
||||||
func (w *Window) SetFullscreen(monitor *Monitor) {
|
func (w *Window) SetFullscreen(monitor *Monitor) {
|
||||||
if w.Monitor() != monitor {
|
if w.Monitor() != monitor {
|
||||||
if monitor == nil {
|
if monitor == nil {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.SetMonitor(
|
w.window.SetMonitor(
|
||||||
nil,
|
nil,
|
||||||
|
@ -204,7 +204,7 @@ func (w *Window) SetFullscreen(monitor *Monitor) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.restore.xpos, w.restore.ypos = w.window.GetPos()
|
w.restore.xpos, w.restore.ypos = w.window.GetPos()
|
||||||
w.restore.width, w.restore.height = w.window.GetSize()
|
w.restore.width, w.restore.height = w.window.GetSize()
|
||||||
|
@ -233,7 +233,7 @@ func (w *Window) IsFullscreen() bool {
|
||||||
// Monitor returns a monitor a fullscreen window is on. If the window is not fullscreen, this function returns nil.
|
// Monitor returns a monitor a fullscreen window is on. If the window is not fullscreen, this function returns nil.
|
||||||
func (w *Window) Monitor() *Monitor {
|
func (w *Window) Monitor() *Monitor {
|
||||||
var monitor *glfw.Monitor
|
var monitor *glfw.Monitor
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
monitor = pixelgl.DoVal(func() interface{} {
|
monitor = pixelgl.DoVal(func() interface{} {
|
||||||
return w.window.GetMonitor()
|
return w.window.GetMonitor()
|
||||||
}).(*glfw.Monitor)
|
}).(*glfw.Monitor)
|
||||||
|
@ -248,7 +248,7 @@ func (w *Window) Monitor() *Monitor {
|
||||||
|
|
||||||
// Focus brings a window to the front and sets input focus.
|
// Focus brings a window to the front and sets input focus.
|
||||||
func (w *Window) Focus() {
|
func (w *Window) Focus() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.Focus()
|
w.window.Focus()
|
||||||
})
|
})
|
||||||
|
@ -258,7 +258,7 @@ func (w *Window) Focus() {
|
||||||
// Focused returns true if a window has input focus.
|
// Focused returns true if a window has input focus.
|
||||||
func (w *Window) Focused() bool {
|
func (w *Window) Focused() bool {
|
||||||
var focused bool
|
var focused bool
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
focused = pixelgl.DoVal(func() interface{} {
|
focused = pixelgl.DoVal(func() interface{} {
|
||||||
return w.window.GetAttrib(glfw.Focused) == glfw.True
|
return w.window.GetAttrib(glfw.Focused) == glfw.True
|
||||||
}).(bool)
|
}).(bool)
|
||||||
|
@ -268,7 +268,7 @@ func (w *Window) Focused() bool {
|
||||||
|
|
||||||
// Maximize puts a windowed window to a maximized state.
|
// Maximize puts a windowed window to a maximized state.
|
||||||
func (w *Window) Maximize() {
|
func (w *Window) Maximize() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.Maximize()
|
w.window.Maximize()
|
||||||
})
|
})
|
||||||
|
@ -277,7 +277,7 @@ func (w *Window) Maximize() {
|
||||||
|
|
||||||
// Restore restores a windowed window from a maximized state.
|
// Restore restores a windowed window from a maximized state.
|
||||||
func (w *Window) Restore() {
|
func (w *Window) Restore() {
|
||||||
w.Do(func() {
|
w.Do(func(pixelgl.Context) {
|
||||||
pixelgl.Do(func() {
|
pixelgl.Do(func() {
|
||||||
w.window.Restore()
|
w.window.Restore()
|
||||||
})
|
})
|
||||||
|
@ -290,7 +290,7 @@ var currentWindow struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do makes the context of this window current, if it's not already, and executes sub.
|
// Do makes the context of this window current, if it's not already, and executes sub.
|
||||||
func (w *Window) Do(sub func()) {
|
func (w *Window) Do(sub func(pixelgl.Context)) {
|
||||||
currentWindow.Lock()
|
currentWindow.Lock()
|
||||||
defer currentWindow.Unlock()
|
defer currentWindow.Unlock()
|
||||||
|
|
||||||
|
@ -302,5 +302,5 @@ func (w *Window) Do(sub func()) {
|
||||||
currentWindow.handler = w
|
currentWindow.handler = w
|
||||||
}
|
}
|
||||||
|
|
||||||
sub()
|
sub(pixelgl.Context{})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue