diff --git a/init.go b/init.go new file mode 100644 index 0000000000000000000000000000000000000000..ff33fb4c60d5e8cb37df6de772a8c2240c4dc60f --- /dev/null +++ b/init.go @@ -0,0 +1,35 @@ +package pixel + +import ( + "github.com/faiface/pixel/pixelgl" + "github.com/go-gl/glfw/v3.2/glfw" + "github.com/pkg/errors" +) + +// Init initializes Pixel library. Call this function before using any of Pixel's functionality. +// +// If the initialization fails, an error is returned. +func Init() error { + err := pixelgl.DoErr(func() error { + return glfw.Init() + }) + if err != nil { + return errors.Wrap(err, "initializing GLFW failed") + } + return nil +} + +// MustInit initializes Pixel library and panics when the initialization fails. +func MustInit() { + err := Init() + if err != nil { + panic(err) + } +} + +// Quit terminates Pixel library. Call this function when you're done with Pixel. +func Quit() { + pixelgl.Do(func() { + glfw.Terminate() + }) +} diff --git a/pixelgl/thread.go b/pixelgl/thread.go index a8a4e7b46daa1f34e0cbf74725acd167ae25a6c2..f24cc2c7a4a91fd2ee64dc6933173d826862bea3 100644 --- a/pixelgl/thread.go +++ b/pixelgl/thread.go @@ -17,7 +17,6 @@ func init() { go func() { runtime.LockOSThread() for f := range callQueue { - getLastGLErr() // swallow unchecked errors f() } }() @@ -28,7 +27,9 @@ func init() { // It must be called under the presence of an active OpenGL context, e.g., always after calling window.MakeContextCurrent(). // Also, always call this function when switching contexts. func Init() { - err := gl.Init() + err := DoErr(func() error { + return gl.Init() + }) if err != nil { panic(err) } @@ -75,6 +76,7 @@ func DoVal(f func() interface{}) interface{} { func DoGLErr(f func()) (gl error) { glerr := make(chan error) callQueue <- func() { + getLastGLErr() // swallow f() glerr <- getLastGLErr() } @@ -86,6 +88,7 @@ func DoErrGLErr(f func() error) (_, gl error) { err := make(chan error) glerr := make(chan error) callQueue <- func() { + getLastGLErr() // swallow err <- f() glerr <- getLastGLErr() } @@ -97,6 +100,7 @@ func DoValGLErr(f func() interface{}) (_ interface{}, gl error) { val := make(chan interface{}) glerr := make(chan error) callQueue <- func() { + getLastGLErr() // swallow val <- f() glerr <- getLastGLErr() } diff --git a/window.go b/window.go new file mode 100644 index 0000000000000000000000000000000000000000..25ef5b447df3c11d35564f737181a9b94c1fda4e --- /dev/null +++ b/window.go @@ -0,0 +1,86 @@ +package pixel + +import ( + "github.com/faiface/pixel/pixelgl" + "github.com/go-gl/glfw/v3.2/glfw" + "github.com/pkg/errors" +) + +type WindowConfig struct { + Title string + Width float64 + Height float64 + Resizable bool + Hidden bool + Undecorated bool + Unfocused bool + Maximized bool + VSync bool + MSAASamples int +} + +type Window struct { + window *glfw.Window + config WindowConfig +} + +func NewWindow(config WindowConfig) (*Window, error) { + bool2int := map[bool]int{ + true: glfw.True, + false: glfw.False, + } + + w := &Window{config: config} + + err := pixelgl.DoErr(func() error { + glfw.WindowHint(glfw.ContextVersionMajor, 3) + glfw.WindowHint(glfw.ContextVersionMinor, 3) + glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) + glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) + + glfw.WindowHint(glfw.Resizable, bool2int[config.Resizable]) + glfw.WindowHint(glfw.Visible, bool2int[!config.Hidden]) + glfw.WindowHint(glfw.Decorated, bool2int[!config.Undecorated]) + glfw.WindowHint(glfw.Focused, bool2int[!config.Unfocused]) + glfw.WindowHint(glfw.Maximized, bool2int[config.Maximized]) + glfw.WindowHint(glfw.Samples, config.MSAASamples) + + var err error + w.window, err = glfw.CreateWindow(int(config.Width), int(config.Height), config.Title, nil, nil) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, errors.Wrap(err, "creating window failed") + } + + return w, nil +} + +func (w *Window) Update() { + pixelgl.Do(func() { + w.Begin() + if w.config.VSync { + glfw.SwapInterval(1) + } + w.window.SwapBuffers() + glfw.PollEvents() + w.End() + }) +} + +var currentWindow *Window = nil + +func (w *Window) Begin() { + if currentWindow != w { + w.window.MakeContextCurrent() + pixelgl.Init() + currentWindow = w + } +} + +func (w *Window) End() { + // nothing really +}