func run(title string, width, height int, fullscreen bool) { document := js.Global.Get("document") canvas = document.Call("createElement", "canvas") target := document.Call("getElementById", title) if target == nil { target = document.Get("body") } target.Call("appendChild", canvas) attrs := webgl.DefaultAttributes() attrs.Alpha = false attrs.Depth = false attrs.PremultipliedAlpha = false attrs.PreserveDrawingBuffer = false attrs.Antialias = false var err error gl, err = webgl.NewContext(canvas, attrs) if err != nil { log.Fatal(err) } js.Global.Set("onunload", func() { responder.Close() }) canvas.Get("style").Set("display", "block") winWidth := js.Global.Get("innerWidth").Int() winHeight := js.Global.Get("innerHeight").Int() if fullscreen { canvas.Set("width", winWidth) canvas.Set("height", winHeight) } else { canvas.Set("width", width) canvas.Set("height", height) canvas.Get("style").Set("marginLeft", toPx((winWidth-width)/2)) canvas.Get("style").Set("marginTop", toPx((winHeight-height)/2)) } canvas.Call("addEventListener", "mousemove", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") x := float32((ev.Get("clientX").Int() - rect.Get("left").Int())) y := float32((ev.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, MOVE) }, false) canvas.Call("addEventListener", "mousedown", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") x := float32((ev.Get("clientX").Int() - rect.Get("left").Int())) y := float32((ev.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, PRESS) }, false) canvas.Call("addEventListener", "mouseup", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") x := float32((ev.Get("clientX").Int() - rect.Get("left").Int())) y := float32((ev.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, RELEASE) }, false) canvas.Call("addEventListener", "touchstart", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, PRESS) } }, false) canvas.Call("addEventListener", "touchcancel", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, RELEASE) } }, false) canvas.Call("addEventListener", "touchend", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, PRESS) } }, false) canvas.Call("addEventListener", "touchmove", func(ev *js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, MOVE) } }, false) js.Global.Call("addEventListener", "keypress", func(ev *js.Object) { responder.Type(rune(ev.Get("charCode").Int())) }, false) js.Global.Call("addEventListener", "keydown", func(ev *js.Object) { responder.Key(Key(ev.Get("keyCode").Int()), 0, PRESS) }, false) js.Global.Call("addEventListener", "keyup", func(ev *js.Object) { responder.Key(Key(ev.Get("keyCode").Int()), 0, RELEASE) }, false) gl.Viewport(0, 0, width, height) responder.Preload() Files.Load(func() { responder.Setup() RequestAnimationFrame(animate) }) }
func run(title string, width, height int, fullscreen bool) { defer runtime.UnlockOSThread() runtime.GOMAXPROCS(runtime.NumCPU()) fatalErr(glfw.Init()) monitor := glfw.GetPrimaryMonitor() mode := monitor.GetVideoMode() // ideally we want a "windowless full screen" // but using normal full screen and disabling minimizing on OS X (which is broken) // is the best we can do for now... if fullscreen { if runtime.GOOS == "darwin" { glfw.WindowHint(glfw.AutoIconify, glfw.False) } glfw.WindowHint(glfw.Decorated, glfw.False) } else { monitor = nil } glfw.WindowHint(glfw.ContextVersionMajor, 2) glfw.WindowHint(glfw.ContextVersionMinor, 1) var err error window, err = glfw.CreateWindow(width, height, title, monitor, nil) fatalErr(err) window.MakeContextCurrent() if !fullscreen { window.SetPos((mode.Width-width)/2, (mode.Height-height)/2) } width, height = window.GetFramebufferSize() glfw.SwapInterval(1) gl = webgl.NewContext() gl.Viewport(0, 0, width, height) window.SetFramebufferSizeCallback(func(window *glfw.Window, w, h int) { width, height = window.GetFramebufferSize() gl.Viewport(0, 0, width, height) responder.Resize(w, h) }) window.SetCursorPosCallback(func(window *glfw.Window, x, y float64) { responder.Mouse(float32(x), float32(y), MouseMove, MOVE) }) window.SetMouseButtonCallback(func(window *glfw.Window, b glfw.MouseButton, a glfw.Action, m glfw.ModifierKey) { x, y := window.GetCursorPos() if a == glfw.Press { responder.Mouse(float32(x), float32(y), MouseKey(b), PRESS) } else { responder.Mouse(float32(x), float32(y), MouseKey(b), RELEASE) } }) window.SetScrollCallback(func(window *glfw.Window, xoff, yoff float64) { responder.Scroll(float32(yoff)) }) window.SetKeyCallback(func(window *glfw.Window, k glfw.Key, s int, a glfw.Action, m glfw.ModifierKey) { if a == glfw.Press { responder.Key(Key(k), Modifier(m), PRESS) } else if a == glfw.Release { responder.Key(Key(k), Modifier(m), RELEASE) } }) window.SetCharCallback(func(window *glfw.Window, char rune) { responder.Type(char) }) setupAudio() responder.Preload() Files.Load(func() {}) responder.Setup() shouldClose := window.ShouldClose() for !shouldClose { responder.Update(Time.Delta()) gl.Clear(gl.COLOR_BUFFER_BIT) responder.Render() window.SwapBuffers() glfw.PollEvents() Time.Tick() shouldClose = window.ShouldClose() } window.Destroy() glfw.Terminate() responder.Close() }
func run(title string, width, height int, fullscreen bool) { runtime.LockOSThread() defer runtime.UnlockOSThread() fatalErr(glfw.Init()) monitor, err := glfw.GetPrimaryMonitor() fatalErr(err) mode, err := monitor.GetVideoMode() fatalErr(err) if fullscreen { width = mode.Width height = mode.Height fatalErr(glfw.WindowHint(glfw.Decorated, 0)) } else { monitor = nil } fatalErr(glfw.WindowHint(glfw.ContextVersionMajor, 2)) fatalErr(glfw.WindowHint(glfw.ContextVersionMinor, 1)) window, err = glfw.CreateWindow(width, height, title, monitor, nil) fatalErr(err) window.MakeContextCurrent() if !fullscreen { fatalErr(window.SetPosition((mode.Width-width)/2, (mode.Height-height)/2)) } width, height, err = window.GetFramebufferSize() fatalErr(err) fatalErr(glfw.SwapInterval(1)) gl = webgl.NewContext() gl.Viewport(0, 0, width, height) window.SetFramebufferSizeCallback(func(window *glfw.Window, w, h int) { width, height, err = window.GetFramebufferSize() fatalErr(err) gl.Viewport(0, 0, width, height) responder.Resize(w, h) }) window.SetCursorPositionCallback(func(window *glfw.Window, x, y float64) { responder.Mouse(float32(x), float32(y), MOVE) }) window.SetMouseButtonCallback(func(window *glfw.Window, b glfw.MouseButton, a glfw.Action, m glfw.ModifierKey) { x, y, err := window.GetCursorPosition() fatalErr(err) if a == glfw.Press { responder.Mouse(float32(x), float32(y), PRESS) } else { responder.Mouse(float32(x), float32(y), RELEASE) } }) window.SetScrollCallback(func(window *glfw.Window, xoff, yoff float64) { responder.Scroll(float32(yoff)) }) window.SetKeyCallback(func(window *glfw.Window, k glfw.Key, s int, a glfw.Action, m glfw.ModifierKey) { if a == glfw.Press { responder.Key(Key(k), Modifier(m), PRESS) } else if a == glfw.Release { responder.Key(Key(k), Modifier(m), RELEASE) } }) window.SetCharacterCallback(func(window *glfw.Window, char rune) { responder.Type(char) }) responder.Preload() Files.Load(func() {}) responder.Setup() shouldClose, err := window.ShouldClose() fatalErr(err) for !shouldClose { responder.Update(Time.Delta()) gl.Clear(gl.COLOR_BUFFER_BIT) responder.Render() fatalErr(window.SwapBuffers()) fatalErr(glfw.PollEvents()) Time.Tick() shouldClose, err = window.ShouldClose() fatalErr(err) } fatalErr(window.Destroy()) fatalErr(glfw.Terminate()) responder.Close() }