Skip to content

Instantly share code, notes, and snippets.

@mbertschler
Created August 13, 2015 15:38
Show Gist options
  • Save mbertschler/426362db4a2cd70e316b to your computer and use it in GitHub Desktop.
Save mbertschler/426362db4a2cd70e316b to your computer and use it in GitHub Desktop.
Multithreaded GLFW App with multiple Windows Render Problems
package main
import (
"fmt"
"runtime"
"time"
"github.com/go-gl/gl/v2.1/gl"
"github.com/go-gl/glfw/v3.1/glfw"
)
func main() {
runtime.LockOSThread()
if err := glfw.Init(); err != nil {
panic(err)
}
glfw.WindowHint(glfw.ContextVersionMajor, 2)
glfw.WindowHint(glfw.ContextVersionMinor, 1)
glfw.WindowHint(glfw.Samples, 4)
if err := gl.Init(); err != nil {
panic(err)
}
// do stuff outside of main goroutine
go doStuff()
// run the mainthread loop
Main()
}
// outside the mainthread goroutine
func doStuff() {
Window1 := NewWindow("Window 1", 400, 300)
Window1.Render()
Window2 := NewWindow("Window 2", 300, 200)
Window2.Render()
time.Sleep(time.Second)
Window3 := NewWindow("Window 3", 200, 100)
Window3.Render()
}
// ================== main thread ====================
// adapted from: https://github.com/golang/go/wiki/LockOSThread
func Main() {
// original code:
// for f := range mainfunc {
// f()
// }
// select loop to catch events:
for {
select {
case f := <-mainfunc:
f()
//comment out these two lines:
default:
glfw.WaitEvents()
}
}
}
// buffered channel to make it possible to put a func
// in the chan and then run it with PostEmptyEvent()
var mainfunc = make(chan func(), 1)
func do(f func()) {
done := make(chan bool, 1)
mainfunc <- func() {
f()
done <- true
}
// added to break WaitEvents in Main():
glfw.PostEmptyEvent()
<-done
}
// ================= Window functions =================
type Window struct {
win *glfw.Window
}
func NewWindow(title string, width, height int) *Window {
var win *glfw.Window
var err error
do(func() {
win, err = glfw.CreateWindow(width, height, title, nil, nil)
if err != nil {
panic(err)
}
win.MakeContextCurrent()
win.SetScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) {
fmt.Printf("Scroll: x: %.1f y: %.1f\n", xoff, yoff)
})
gl.ClearColor(0.2, 0.2, 0.2, 1.0)
})
return &Window{win}
}
func (w *Window) Render() {
do(func() {
w.win.MakeContextCurrent()
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
w.win.SwapBuffers()
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment