glfw.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package window
  5. import (
  6. "github.com/g3n/engine/core"
  7. "github.com/go-gl/glfw/v3.2/glfw"
  8. )
  9. type GLFW struct {
  10. core.Dispatcher
  11. win *glfw.Window
  12. keyEv KeyEvent
  13. charEv CharEvent
  14. mouseEv MouseEvent
  15. posEv PosEvent
  16. sizeEv SizeEvent
  17. cursorEv CursorEvent
  18. scrollEv ScrollEvent
  19. arrowCursor *glfw.Cursor
  20. ibeamCursor *glfw.Cursor
  21. crosshairCursor *glfw.Cursor
  22. handCursor *glfw.Cursor
  23. hresizeCursor *glfw.Cursor
  24. vresizeCursor *glfw.Cursor
  25. }
  26. // Global GLFW initialization flag
  27. // is initialized when the first window is created
  28. var initialized bool = false
  29. func newGLFW(width, height int, title string, full bool) (*GLFW, error) {
  30. // Initialize GLFW once before the first window is created
  31. if !initialized {
  32. err := glfw.Init()
  33. if err != nil {
  34. return nil, err
  35. }
  36. // Sets window hints
  37. glfw.WindowHint(glfw.ContextVersionMajor, 3)
  38. glfw.WindowHint(glfw.ContextVersionMinor, 3)
  39. glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
  40. glfw.WindowHint(glfw.Samples, 8)
  41. initialized = true
  42. }
  43. // Creates window and sets it as the current context
  44. win, err := glfw.CreateWindow(width, height, title, nil, nil)
  45. if err != nil {
  46. return nil, err
  47. }
  48. win.MakeContextCurrent()
  49. // Create wrapper window with dispacher
  50. w := new(GLFW)
  51. w.win = win
  52. w.Dispatcher.Initialize()
  53. // Set key callback to dispatch event
  54. win.SetKeyCallback(func(x *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
  55. w.keyEv.W = w
  56. w.keyEv.Keycode = Key(key)
  57. w.keyEv.Scancode = scancode
  58. w.keyEv.Action = Action(action)
  59. w.keyEv.Mods = ModifierKey(mods)
  60. if action == glfw.Press {
  61. w.Dispatch(OnKeyDown, &w.keyEv)
  62. return
  63. }
  64. if action == glfw.Release {
  65. w.Dispatch(OnKeyUp, &w.keyEv)
  66. return
  67. }
  68. })
  69. // Set char callback
  70. win.SetCharModsCallback(func(x *glfw.Window, char rune, mods glfw.ModifierKey) {
  71. w.charEv.W = w
  72. w.charEv.Char = char
  73. w.charEv.Mods = ModifierKey(mods)
  74. w.Dispatch(OnChar, &w.charEv)
  75. })
  76. // Set mouse button callback to dispatch event
  77. win.SetMouseButtonCallback(func(x *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
  78. xpos, ypos := x.GetCursorPos()
  79. w.mouseEv.W = w
  80. w.mouseEv.Button = MouseButton(button)
  81. w.mouseEv.Action = Action(action)
  82. w.mouseEv.Mods = ModifierKey(mods)
  83. w.mouseEv.Xpos = float32(xpos)
  84. w.mouseEv.Ypos = float32(ypos)
  85. if action == glfw.Press {
  86. w.Dispatch(OnMouseDown, &w.mouseEv)
  87. return
  88. }
  89. if action == glfw.Release {
  90. w.Dispatch(OnMouseUp, &w.mouseEv)
  91. return
  92. }
  93. })
  94. // Set window size callback to dispatch event
  95. win.SetSizeCallback(func(x *glfw.Window, width int, height int) {
  96. w.sizeEv.W = w
  97. w.sizeEv.Width = width
  98. w.sizeEv.Height = height
  99. w.Dispatch(OnWindowSize, &w.sizeEv)
  100. })
  101. // Set window position event callback to dispatch event
  102. win.SetPosCallback(func(x *glfw.Window, xpos int, ypos int) {
  103. w.posEv.W = w
  104. w.posEv.Xpos = xpos
  105. w.posEv.Ypos = ypos
  106. w.Dispatch(OnWindowPos, &w.posEv)
  107. })
  108. // Set window cursor position event callback to dispatch event
  109. win.SetCursorPosCallback(func(x *glfw.Window, xpos float64, ypos float64) {
  110. w.cursorEv.W = w
  111. w.cursorEv.Xpos = float32(xpos)
  112. w.cursorEv.Ypos = float32(ypos)
  113. w.Dispatch(OnCursor, &w.cursorEv)
  114. })
  115. // Set mouse wheel scroll event callback to dispatch event
  116. win.SetScrollCallback(func(x *glfw.Window, xoff float64, yoff float64) {
  117. w.scrollEv.W = w
  118. w.scrollEv.Xoffset = float32(xoff)
  119. w.scrollEv.Yoffset = float32(yoff)
  120. w.Dispatch(OnScroll, &w.scrollEv)
  121. })
  122. // Preallocate standard cursors
  123. w.arrowCursor = glfw.CreateStandardCursor(int(glfw.ArrowCursor))
  124. w.ibeamCursor = glfw.CreateStandardCursor(int(glfw.IBeamCursor))
  125. w.crosshairCursor = glfw.CreateStandardCursor(int(glfw.CrosshairCursor))
  126. w.handCursor = glfw.CreateStandardCursor(int(glfw.HandCursor))
  127. w.hresizeCursor = glfw.CreateStandardCursor(int(glfw.HResizeCursor))
  128. w.vresizeCursor = glfw.CreateStandardCursor(int(glfw.VResizeCursor))
  129. return w, nil
  130. }
  131. func (w *GLFW) SwapInterval(interval int) {
  132. glfw.SwapInterval(interval)
  133. }
  134. func (w *GLFW) MakeContextCurrent() {
  135. w.win.MakeContextCurrent()
  136. }
  137. func (w *GLFW) GetSize() (width int, height int) {
  138. return w.win.GetSize()
  139. }
  140. func (w *GLFW) SetSize(width int, height int) {
  141. w.win.SetSize(width, height)
  142. }
  143. func (w *GLFW) GetPos() (xpos, ypos int) {
  144. return w.win.GetPos()
  145. }
  146. func (w *GLFW) SetPos(xpos, ypos int) {
  147. w.win.SetPos(xpos, ypos)
  148. }
  149. func (w *GLFW) SetTitle(title string) {
  150. w.win.SetTitle(title)
  151. }
  152. func (w *GLFW) SetStandardCursor(cursor StandardCursor) {
  153. switch cursor {
  154. case ArrowCursor:
  155. w.win.SetCursor(w.arrowCursor)
  156. case IBeamCursor:
  157. w.win.SetCursor(w.ibeamCursor)
  158. case CrosshairCursor:
  159. w.win.SetCursor(w.crosshairCursor)
  160. case HandCursor:
  161. w.win.SetCursor(w.handCursor)
  162. case HResizeCursor:
  163. w.win.SetCursor(w.hresizeCursor)
  164. case VResizeCursor:
  165. w.win.SetCursor(w.vresizeCursor)
  166. default:
  167. panic("Invalid cursor")
  168. }
  169. }
  170. func (w *GLFW) ShouldClose() bool {
  171. return w.win.ShouldClose()
  172. }
  173. func (w *GLFW) SetShouldClose(v bool) {
  174. w.win.SetShouldClose(v)
  175. }
  176. func (w *GLFW) SwapBuffers() {
  177. w.win.SwapBuffers()
  178. }
  179. func (w *GLFW) PollEvents() {
  180. glfw.PollEvents()
  181. }
  182. func (w *GLFW) GetTime() float64 {
  183. return glfw.GetTime()
  184. }