From eb316e5126b16815ec7caeea0d5a32bd81ca0cd3 Mon Sep 17 00:00:00 2001
From: faiface <faiface@ksp.sk>
Date: Wed, 23 Nov 2016 23:12:23 +0100
Subject: [PATCH] add window creation

---
 init.go           | 35 +++++++++++++++++++
 pixelgl/thread.go |  8 +++--
 window.go         | 86 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 127 insertions(+), 2 deletions(-)
 create mode 100644 init.go
 create mode 100644 window.go

diff --git a/init.go b/init.go
new file mode 100644
index 0000000..ff33fb4
--- /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 a8a4e7b..f24cc2c 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 0000000..25ef5b4
--- /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
+}
-- 
GitLab