mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 10:48:53 +01:00
Add internal/ui module
This commit is contained in:
parent
5f4aa33edf
commit
96f5315c49
@ -15,30 +15,60 @@
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
"image"
|
"image"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsKeyPressed returns a boolean indicating whether key is pressed.
|
// IsKeyPressed returns a boolean indicating whether key is pressed.
|
||||||
func IsKeyPressed(key Key) bool {
|
func IsKeyPressed(key Key) bool {
|
||||||
return currentUI.input.isKeyPressed(key)
|
return ui.Current().Input().IsKeyPressed(ui.Key(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// CursorPosition returns a position of a mouse cursor.
|
// CursorPosition returns a position of a mouse cursor.
|
||||||
func CursorPosition() (x, y int) {
|
func CursorPosition() (x, y int) {
|
||||||
return currentUI.input.cursorPosition()
|
return ui.Current().Input().CursorPosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed.
|
// IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed.
|
||||||
func IsMouseButtonPressed(mouseButton MouseButton) bool {
|
func IsMouseButtonPressed(mouseButton MouseButton) bool {
|
||||||
return currentUI.input.isMouseButtonPressed(mouseButton)
|
return ui.Current().Input().IsMouseButtonPressed(ui.MouseButton(mouseButton))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewImage returns an empty image.
|
// NewImage returns an empty image.
|
||||||
func NewImage(width, height int, filter Filter) (*Image, error) {
|
func NewImage(width, height int, filter Filter) (*Image, error) {
|
||||||
return currentUI.newImage(width, height, filter)
|
var innerImage *innerImage
|
||||||
|
var err error
|
||||||
|
ui.Current().Use(func(c *opengl.Context) {
|
||||||
|
var texture *graphics.Texture
|
||||||
|
texture, err = graphics.NewTexture(c, width, height, glFilter(c, filter))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
innerImage, err = newInnerImage(c, texture)
|
||||||
|
innerImage.Clear(c)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Image{ui: ui.Current(), inner: innerImage}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewImageFromImage creates a new image with the given image (img).
|
// NewImageFromImage creates a new image with the given image (img).
|
||||||
func NewImageFromImage(img image.Image, filter Filter) (*Image, error) {
|
func NewImageFromImage(img image.Image, filter Filter) (*Image, error) {
|
||||||
return currentUI.newImageFromImage(img, filter)
|
var innerImage *innerImage
|
||||||
|
var err error
|
||||||
|
ui.Current().Use(func(c *opengl.Context) {
|
||||||
|
var texture *graphics.Texture
|
||||||
|
texture, err = graphics.NewTextureFromImage(c, img, glFilter(c, filter))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
innerImage, err = newInnerImage(c, texture)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Image{ui: ui.Current(), inner: innerImage}, nil
|
||||||
}
|
}
|
||||||
|
@ -34,13 +34,12 @@ func newGraphicsContext(c *opengl.Context, screenWidth, screenHeight, screenScal
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
gc := &graphicsContext{
|
return &graphicsContext{
|
||||||
glContext: c,
|
glContext: c,
|
||||||
defaultR: &innerImage{f, nil},
|
defaultR: &innerImage{f, nil},
|
||||||
screen: screen,
|
screen: screen,
|
||||||
screenScale: screenScale,
|
screenScale: screenScale,
|
||||||
}
|
}, nil
|
||||||
return gc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type graphicsContext struct {
|
type graphicsContext struct {
|
||||||
|
19
image.go
19
image.go
@ -18,6 +18,7 @@ import (
|
|||||||
"github.com/hajimehoshi/ebiten/internal"
|
"github.com/hajimehoshi/ebiten/internal"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
"github.com/hajimehoshi/ebiten/internal/graphics"
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
)
|
)
|
||||||
@ -102,7 +103,7 @@ func (t *textureQuads) Texture(i int) (u0, v0, u1, v1 float32) {
|
|||||||
// The pixel format is alpha-premultiplied.
|
// The pixel format is alpha-premultiplied.
|
||||||
// Image implements image.Image.
|
// Image implements image.Image.
|
||||||
type Image struct {
|
type Image struct {
|
||||||
ui *ui
|
ui *ui.UI
|
||||||
inner *innerImage
|
inner *innerImage
|
||||||
pixels []uint8
|
pixels []uint8
|
||||||
}
|
}
|
||||||
@ -115,8 +116,8 @@ func (i *Image) Size() (width, height int) {
|
|||||||
// Clear resets the pixels of the image into 0.
|
// Clear resets the pixels of the image into 0.
|
||||||
func (i *Image) Clear() (err error) {
|
func (i *Image) Clear() (err error) {
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
i.ui.use(func() {
|
i.ui.Use(func(c *opengl.Context) {
|
||||||
err = i.inner.Clear(i.ui.glContext)
|
err = i.inner.Clear(c)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -124,8 +125,8 @@ func (i *Image) Clear() (err error) {
|
|||||||
// Fill fills the image with a solid color.
|
// Fill fills the image with a solid color.
|
||||||
func (i *Image) Fill(clr color.Color) (err error) {
|
func (i *Image) Fill(clr color.Color) (err error) {
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
i.ui.use(func() {
|
i.ui.Use(func(c *opengl.Context) {
|
||||||
err = i.inner.Fill(i.ui.glContext, clr)
|
err = i.inner.Fill(c, clr)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -147,8 +148,8 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) {
|
|||||||
|
|
||||||
func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) {
|
func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) {
|
||||||
i.pixels = nil
|
i.pixels = nil
|
||||||
i.ui.use(func() {
|
i.ui.Use(func(c *opengl.Context) {
|
||||||
err = i.inner.drawImage(i.ui.glContext, image, option)
|
err = i.inner.drawImage(c, image, option)
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -169,9 +170,9 @@ func (i *Image) ColorModel() color.Model {
|
|||||||
// This method loads pixels from GPU to VRAM if necessary.
|
// This method loads pixels from GPU to VRAM if necessary.
|
||||||
func (i *Image) At(x, y int) color.Color {
|
func (i *Image) At(x, y int) color.Color {
|
||||||
if i.pixels == nil {
|
if i.pixels == nil {
|
||||||
i.ui.use(func() {
|
i.ui.Use(func(c *opengl.Context) {
|
||||||
var err error
|
var err error
|
||||||
i.pixels, err = i.inner.texture.Pixels(i.ui.glContext)
|
i.pixels, err = i.inner.texture.Pixels(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2014 Hajime Hoshi
|
// Copyright 2015 Hajime Hoshi
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -12,13 +12,33 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package ebiten
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
glfw "github.com/go-gl/glfw3"
|
glfw "github.com/go-gl/glfw3"
|
||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Key int
|
||||||
|
|
||||||
|
const (
|
||||||
|
KeyUp Key = iota
|
||||||
|
KeyDown
|
||||||
|
KeyLeft
|
||||||
|
KeyRight
|
||||||
|
KeySpace
|
||||||
|
KeyMax
|
||||||
|
)
|
||||||
|
|
||||||
|
type MouseButton int
|
||||||
|
|
||||||
|
const (
|
||||||
|
MouseButtonLeft MouseButton = iota
|
||||||
|
MouseButtonRight
|
||||||
|
MouseButtonMiddle
|
||||||
|
MouseButtonMax
|
||||||
|
)
|
||||||
|
|
||||||
type input struct {
|
type input struct {
|
||||||
keyPressed [KeyMax]bool
|
keyPressed [KeyMax]bool
|
||||||
mouseButtonPressed [MouseButtonMax]bool
|
mouseButtonPressed [MouseButtonMax]bool
|
||||||
@ -26,15 +46,15 @@ type input struct {
|
|||||||
cursorY int
|
cursorY int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *input) isKeyPressed(key Key) bool {
|
func (i *input) IsKeyPressed(key Key) bool {
|
||||||
return i.keyPressed[key]
|
return i.keyPressed[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *input) isMouseButtonPressed(button MouseButton) bool {
|
func (i *input) IsMouseButtonPressed(button MouseButton) bool {
|
||||||
return i.mouseButtonPressed[button]
|
return i.mouseButtonPressed[button]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *input) cursorPosition() (x, y int) {
|
func (i *input) CursorPosition() (x, y int) {
|
||||||
return i.cursorX, i.cursorY
|
return i.cursorX, i.cursorY
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2014 Hajime Hoshi
|
// Copyright 2015 Hajime Hoshi
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
// you may not use this file except in compliance with the License.
|
// you may not use this file except in compliance with the License.
|
||||||
@ -12,18 +12,20 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
package ebiten
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
glfw "github.com/go-gl/glfw3"
|
glfw "github.com/go-gl/glfw3"
|
||||||
"github.com/hajimehoshi/ebiten/internal/graphics"
|
|
||||||
"github.com/hajimehoshi/ebiten/internal/opengl"
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
"image"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var currentUI *ui
|
var currentUI *UI
|
||||||
|
|
||||||
|
func Current() *UI {
|
||||||
|
return currentUI
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
@ -42,28 +44,32 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
u := &ui{
|
u := &UI{
|
||||||
window: window,
|
window: window,
|
||||||
funcs: make(chan func()),
|
funcs: make(chan func()),
|
||||||
}
|
}
|
||||||
u.run()
|
go func() {
|
||||||
u.use(func() {
|
runtime.LockOSThread()
|
||||||
|
u.window.MakeContextCurrent()
|
||||||
u.glContext = opengl.NewContext()
|
u.glContext = opengl.NewContext()
|
||||||
glfw.SwapInterval(1)
|
glfw.SwapInterval(1)
|
||||||
})
|
for f := range u.funcs {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}()
|
||||||
currentUI = u
|
currentUI = u
|
||||||
}
|
}
|
||||||
|
|
||||||
type ui struct {
|
type UI struct {
|
||||||
window *glfw.Window
|
window *glfw.Window
|
||||||
scale int
|
scale int
|
||||||
glContext *opengl.Context
|
realScale int
|
||||||
graphicsContext *graphicsContext
|
glContext *opengl.Context
|
||||||
input input
|
input input
|
||||||
funcs chan func()
|
funcs chan func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func startUI(width, height, scale int, title string) (*ui, error) {
|
func New(width, height, scale int, title string) (*UI, error) {
|
||||||
monitor, err := glfw.GetPrimaryMonitor()
|
monitor, err := glfw.GetPrimaryMonitor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -103,101 +109,41 @@ func startUI(width, height, scale int, title string) (*ui, error) {
|
|||||||
|
|
||||||
// For retina displays, recalculate the scale with the framebuffer size.
|
// For retina displays, recalculate the scale with the framebuffer size.
|
||||||
windowWidth, _ := window.GetFramebufferSize()
|
windowWidth, _ := window.GetFramebufferSize()
|
||||||
realScale := windowWidth / width
|
ui.realScale = windowWidth / width
|
||||||
ui.use(func() {
|
|
||||||
ui.graphicsContext, err = newGraphicsContext(ui.glContext, width, height, realScale)
|
|
||||||
})
|
|
||||||
return ui, err
|
return ui, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) doEvents() {
|
func (u *UI) RealScale() int {
|
||||||
glfw.PollEvents()
|
return u.realScale
|
||||||
u.update()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) terminate() {
|
func (u *UI) DoEvents() {
|
||||||
|
glfw.PollEvents()
|
||||||
|
u.input.update(u.window, u.scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *UI) Terminate() {
|
||||||
glfw.Terminate()
|
glfw.Terminate()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) isClosed() bool {
|
func (u *UI) IsClosed() bool {
|
||||||
return u.window.ShouldClose()
|
return u.window.ShouldClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) draw(f func(*Image) error) (err error) {
|
func (u *UI) SwapBuffers() {
|
||||||
u.use(func() {
|
u.window.SwapBuffers()
|
||||||
err = u.graphicsContext.preUpdate()
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = f(&Image{ui: u, inner: u.graphicsContext.screen})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
u.use(func() {
|
|
||||||
err = u.graphicsContext.postUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
u.window.SwapBuffers()
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) newImageFromImage(img image.Image, filter Filter) (*Image, error) {
|
func (u *UI) Input() *input {
|
||||||
var innerImage *innerImage
|
return &u.input
|
||||||
var err error
|
|
||||||
u.use(func() {
|
|
||||||
var texture *graphics.Texture
|
|
||||||
texture, err = graphics.NewTextureFromImage(u.glContext, img, glFilter(u.glContext, filter))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
innerImage, err = newInnerImage(u.glContext, texture)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Image{ui: u, inner: innerImage}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) newImage(width, height int, filter Filter) (*Image, error) {
|
func (u *UI) Use(f func(*opengl.Context)) {
|
||||||
var innerImage *innerImage
|
|
||||||
var err error
|
|
||||||
u.use(func() {
|
|
||||||
var texture *graphics.Texture
|
|
||||||
texture, err = graphics.NewTexture(u.glContext, width, height, glFilter(u.glContext, filter))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
innerImage, err = newInnerImage(u.glContext, texture)
|
|
||||||
innerImage.Clear(u.glContext)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Image{ui: u, inner: innerImage}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ui) run() {
|
|
||||||
go func() {
|
|
||||||
runtime.LockOSThread()
|
|
||||||
u.window.MakeContextCurrent()
|
|
||||||
for f := range u.funcs {
|
|
||||||
f()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *ui) use(f func()) {
|
|
||||||
ch := make(chan struct{})
|
ch := make(chan struct{})
|
||||||
u.funcs <- func() {
|
u.funcs <- func() {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
f()
|
f(u.glContext)
|
||||||
}
|
}
|
||||||
<-ch
|
<-ch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *ui) update() {
|
|
||||||
u.input.update(u.window, u.scale)
|
|
||||||
}
|
|
26
keys.go
26
keys.go
@ -14,19 +14,25 @@
|
|||||||
|
|
||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
|
)
|
||||||
|
|
||||||
// A Key represents a keyboard key.
|
// A Key represents a keyboard key.
|
||||||
type Key int
|
type Key int
|
||||||
|
|
||||||
// TODO: Add more keys.
|
// TODO: Add more keys.
|
||||||
|
|
||||||
|
// TODO: Generate this automatically.
|
||||||
|
|
||||||
// Keys
|
// Keys
|
||||||
const (
|
const (
|
||||||
KeyUp Key = iota
|
KeyUp = Key(ui.KeyUp)
|
||||||
KeyDown
|
KeyDown = Key(ui.KeyDown)
|
||||||
KeyLeft
|
KeyLeft = Key(ui.KeyLeft)
|
||||||
KeyRight
|
KeyRight = Key(ui.KeyRight)
|
||||||
KeySpace
|
KeySpace = Key(ui.KeySpace)
|
||||||
KeyMax
|
KeyMax = Key(ui.KeyMax)
|
||||||
)
|
)
|
||||||
|
|
||||||
// A MouseButton represents a mouse button.
|
// A MouseButton represents a mouse button.
|
||||||
@ -34,8 +40,8 @@ type MouseButton int
|
|||||||
|
|
||||||
// MouseButtons
|
// MouseButtons
|
||||||
const (
|
const (
|
||||||
MouseButtonLeft MouseButton = iota
|
MouseButtonLeft = MouseButton(ui.MouseButtonLeft)
|
||||||
MouseButtonRight
|
MouseButtonRight = MouseButton(ui.MouseButtonRight)
|
||||||
MouseButtonMiddle
|
MouseButtonMiddle = MouseButton(ui.MouseButtonMiddle)
|
||||||
MouseButtonMax
|
MouseButtonMax = MouseButton(ui.MouseButtonMax)
|
||||||
)
|
)
|
||||||
|
36
run.go
36
run.go
@ -15,6 +15,8 @@
|
|||||||
package ebiten
|
package ebiten
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/opengl"
|
||||||
|
"github.com/hajimehoshi/ebiten/internal/ui"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,20 +30,44 @@ import (
|
|||||||
// but this is not strictly guaranteed.
|
// but this is not strictly guaranteed.
|
||||||
// If you need to care about time, you need to check current time every time f is called.
|
// If you need to care about time, you need to check current time every time f is called.
|
||||||
func Run(f func(*Image) error, width, height, scale int, title string) error {
|
func Run(f func(*Image) error, width, height, scale int, title string) error {
|
||||||
ui, err := startUI(width, height, scale, title)
|
ui, err := ui.New(width, height, scale, title)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer ui.Terminate()
|
||||||
|
|
||||||
|
var graphicsContext *graphicsContext
|
||||||
|
ui.Use(func(c *opengl.Context) {
|
||||||
|
graphicsContext, err = newGraphicsContext(c, width, height, ui.RealScale())
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer ui.terminate()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// To avoid busy loop when the window is inactive, wait 1/120 [sec] at least.
|
// To avoid busy loop when the window is inactive, wait 1/120 [sec] at least.
|
||||||
ch := time.After(1 * time.Second / 120)
|
ch := time.After(1 * time.Second / 120)
|
||||||
ui.doEvents()
|
ui.DoEvents()
|
||||||
if ui.isClosed() {
|
if ui.IsClosed() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if err := ui.draw(f); err != nil {
|
ui.Use(func(*opengl.Context) {
|
||||||
|
err = graphicsContext.preUpdate()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := f(&Image{ui: ui, inner: graphicsContext.screen}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ui.Use(func(*opengl.Context) {
|
||||||
|
err = graphicsContext.postUpdate()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ui.SwapBuffers()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
<-ch
|
<-ch
|
||||||
|
Loading…
Reference in New Issue
Block a user