glfw.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  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. "runtime"
  7. "bytes"
  8. "github.com/g3n/engine/core"
  9. "github.com/g3n/engine/gls"
  10. "github.com/g3n/engine/gui/assets"
  11. "github.com/go-gl/glfw/v3.2/glfw"
  12. "image"
  13. _ "image/png"
  14. "os"
  15. )
  16. // Keycodes
  17. const (
  18. KeyUnknown = Key(glfw.KeyUnknown)
  19. KeySpace = Key(glfw.KeySpace)
  20. KeyApostrophe = Key(glfw.KeyApostrophe)
  21. KeyComma = Key(glfw.KeyComma)
  22. KeyMinus = Key(glfw.KeyMinus)
  23. KeyPeriod = Key(glfw.KeyPeriod)
  24. KeySlash = Key(glfw.KeySlash)
  25. Key0 = Key(glfw.Key0)
  26. Key1 = Key(glfw.Key1)
  27. Key2 = Key(glfw.Key2)
  28. Key3 = Key(glfw.Key3)
  29. Key4 = Key(glfw.Key4)
  30. Key5 = Key(glfw.Key5)
  31. Key6 = Key(glfw.Key6)
  32. Key7 = Key(glfw.Key7)
  33. Key8 = Key(glfw.Key8)
  34. Key9 = Key(glfw.Key9)
  35. KeySemicolon = Key(glfw.KeySemicolon)
  36. KeyEqual = Key(glfw.KeyEqual)
  37. KeyA = Key(glfw.KeyA)
  38. KeyB = Key(glfw.KeyB)
  39. KeyC = Key(glfw.KeyC)
  40. KeyD = Key(glfw.KeyD)
  41. KeyE = Key(glfw.KeyE)
  42. KeyF = Key(glfw.KeyF)
  43. KeyG = Key(glfw.KeyG)
  44. KeyH = Key(glfw.KeyH)
  45. KeyI = Key(glfw.KeyI)
  46. KeyJ = Key(glfw.KeyJ)
  47. KeyK = Key(glfw.KeyK)
  48. KeyL = Key(glfw.KeyL)
  49. KeyM = Key(glfw.KeyM)
  50. KeyN = Key(glfw.KeyN)
  51. KeyO = Key(glfw.KeyO)
  52. KeyP = Key(glfw.KeyP)
  53. KeyQ = Key(glfw.KeyQ)
  54. KeyR = Key(glfw.KeyR)
  55. KeyS = Key(glfw.KeyS)
  56. KeyT = Key(glfw.KeyT)
  57. KeyU = Key(glfw.KeyU)
  58. KeyV = Key(glfw.KeyV)
  59. KeyW = Key(glfw.KeyW)
  60. KeyX = Key(glfw.KeyX)
  61. KeyY = Key(glfw.KeyY)
  62. KeyZ = Key(glfw.KeyZ)
  63. KeyLeftBracket = Key(glfw.KeyLeftBracket)
  64. KeyBackslash = Key(glfw.KeyBackslash)
  65. KeyRightBracket = Key(glfw.KeyRightBracket)
  66. KeyGraveAccent = Key(glfw.KeyGraveAccent)
  67. KeyWorld1 = Key(glfw.KeyWorld1)
  68. KeyWorld2 = Key(glfw.KeyWorld2)
  69. KeyEscape = Key(glfw.KeyEscape)
  70. KeyEnter = Key(glfw.KeyEnter)
  71. KeyTab = Key(glfw.KeyTab)
  72. KeyBackspace = Key(glfw.KeyBackspace)
  73. KeyInsert = Key(glfw.KeyInsert)
  74. KeyDelete = Key(glfw.KeyDelete)
  75. KeyRight = Key(glfw.KeyRight)
  76. KeyLeft = Key(glfw.KeyLeft)
  77. KeyDown = Key(glfw.KeyDown)
  78. KeyUp = Key(glfw.KeyUp)
  79. KeyPageUp = Key(glfw.KeyPageUp)
  80. KeyPageDown = Key(glfw.KeyPageDown)
  81. KeyHome = Key(glfw.KeyHome)
  82. KeyEnd = Key(glfw.KeyEnd)
  83. KeyCapsLock = Key(glfw.KeyCapsLock)
  84. KeyScrollLock = Key(glfw.KeyScrollLock)
  85. KeyNumLock = Key(glfw.KeyNumLock)
  86. KeyPrintScreen = Key(glfw.KeyPrintScreen)
  87. KeyPause = Key(glfw.KeyPause)
  88. KeyF1 = Key(glfw.KeyF1)
  89. KeyF2 = Key(glfw.KeyF2)
  90. KeyF3 = Key(glfw.KeyF3)
  91. KeyF4 = Key(glfw.KeyF4)
  92. KeyF5 = Key(glfw.KeyF5)
  93. KeyF6 = Key(glfw.KeyF6)
  94. KeyF7 = Key(glfw.KeyF7)
  95. KeyF8 = Key(glfw.KeyF8)
  96. KeyF9 = Key(glfw.KeyF9)
  97. KeyF10 = Key(glfw.KeyF10)
  98. KeyF11 = Key(glfw.KeyF11)
  99. KeyF12 = Key(glfw.KeyF12)
  100. KeyF13 = Key(glfw.KeyF13)
  101. KeyF14 = Key(glfw.KeyF14)
  102. KeyF15 = Key(glfw.KeyF15)
  103. KeyF16 = Key(glfw.KeyF16)
  104. KeyF17 = Key(glfw.KeyF17)
  105. KeyF18 = Key(glfw.KeyF18)
  106. KeyF19 = Key(glfw.KeyF19)
  107. KeyF20 = Key(glfw.KeyF20)
  108. KeyF21 = Key(glfw.KeyF21)
  109. KeyF22 = Key(glfw.KeyF22)
  110. KeyF23 = Key(glfw.KeyF23)
  111. KeyF24 = Key(glfw.KeyF24)
  112. KeyF25 = Key(glfw.KeyF25)
  113. KeyKP0 = Key(glfw.KeyKP0)
  114. KeyKP1 = Key(glfw.KeyKP1)
  115. KeyKP2 = Key(glfw.KeyKP2)
  116. KeyKP3 = Key(glfw.KeyKP3)
  117. KeyKP4 = Key(glfw.KeyKP4)
  118. KeyKP5 = Key(glfw.KeyKP5)
  119. KeyKP6 = Key(glfw.KeyKP6)
  120. KeyKP7 = Key(glfw.KeyKP7)
  121. KeyKP8 = Key(glfw.KeyKP8)
  122. KeyKP9 = Key(glfw.KeyKP9)
  123. KeyKPDecimal = Key(glfw.KeyKPDecimal)
  124. KeyKPDivide = Key(glfw.KeyKPDivide)
  125. KeyKPMultiply = Key(glfw.KeyKPMultiply)
  126. KeyKPSubtract = Key(glfw.KeyKPSubtract)
  127. KeyKPAdd = Key(glfw.KeyKPAdd)
  128. KeyKPEnter = Key(glfw.KeyKPEnter)
  129. KeyKPEqual = Key(glfw.KeyKPEqual)
  130. KeyLeftShift = Key(glfw.KeyLeftShift)
  131. KeyLeftControl = Key(glfw.KeyLeftControl)
  132. KeyLeftAlt = Key(glfw.KeyLeftAlt)
  133. KeyLeftSuper = Key(glfw.KeyLeftSuper)
  134. KeyRightShift = Key(glfw.KeyRightShift)
  135. KeyRightControl = Key(glfw.KeyRightControl)
  136. KeyRightAlt = Key(glfw.KeyRightAlt)
  137. KeyRightSuper = Key(glfw.KeyRightSuper)
  138. KeyMenu = Key(glfw.KeyMenu)
  139. KeyLast = Key(glfw.KeyLast)
  140. )
  141. // Modifier keys
  142. const (
  143. ModShift = ModifierKey(glfw.ModShift)
  144. ModControl = ModifierKey(glfw.ModControl)
  145. ModAlt = ModifierKey(glfw.ModAlt)
  146. ModSuper = ModifierKey(glfw.ModSuper)
  147. )
  148. // Mouse buttons
  149. const (
  150. MouseButton1 = MouseButton(glfw.MouseButton1)
  151. MouseButton2 = MouseButton(glfw.MouseButton2)
  152. MouseButton3 = MouseButton(glfw.MouseButton3)
  153. MouseButton4 = MouseButton(glfw.MouseButton4)
  154. MouseButton5 = MouseButton(glfw.MouseButton5)
  155. MouseButton6 = MouseButton(glfw.MouseButton6)
  156. MouseButton7 = MouseButton(glfw.MouseButton7)
  157. MouseButton8 = MouseButton(glfw.MouseButton8)
  158. MouseButtonLast = MouseButton(glfw.MouseButtonLast)
  159. MouseButtonLeft = MouseButton(glfw.MouseButtonLeft)
  160. MouseButtonRight = MouseButton(glfw.MouseButtonRight)
  161. MouseButtonMiddle = MouseButton(glfw.MouseButtonMiddle)
  162. )
  163. // Standard cursors for g3n. The diagonal cursors are not standard for GLFW.
  164. const (
  165. ArrowCursor = StandardCursor(glfw.ArrowCursor)
  166. IBeamCursor = StandardCursor(glfw.IBeamCursor)
  167. CrosshairCursor = StandardCursor(glfw.CrosshairCursor)
  168. HandCursor = StandardCursor(glfw.HandCursor)
  169. HResizeCursor = StandardCursor(glfw.HResizeCursor)
  170. VResizeCursor = StandardCursor(glfw.VResizeCursor)
  171. DiagResize1Cursor = StandardCursor(VResizeCursor + 1)
  172. DiagResize2Cursor = StandardCursor(VResizeCursor + 2)
  173. )
  174. // Actions
  175. const (
  176. // Release indicates that key or mouse button was released
  177. Release = Action(glfw.Release)
  178. // Press indicates that key or mouse button was pressed
  179. Press = Action(glfw.Press)
  180. // Repeat indicates that key was held down until it repeated
  181. Repeat = Action(glfw.Repeat)
  182. )
  183. // Input modes
  184. const (
  185. CursorInputMode = InputMode(glfw.CursorMode) // See Cursor mode values
  186. StickyKeysInputMode = InputMode(glfw.StickyKeysMode) // Value can be either 1 or 0
  187. StickyMouseButtonsInputMode = InputMode(glfw.StickyMouseButtonsMode) // Value can be either 1 or 0
  188. )
  189. // Cursor mode values
  190. const (
  191. CursorNormal = CursorMode(glfw.CursorNormal)
  192. CursorHidden = CursorMode(glfw.CursorHidden)
  193. CursorDisabled = CursorMode(glfw.CursorDisabled)
  194. )
  195. // glfwManager contains data shared by all windows
  196. type glfwManager struct {
  197. arrowCursor *glfw.Cursor // Preallocated standard arrow cursor
  198. ibeamCursor *glfw.Cursor // Preallocated standard ibeam cursor
  199. crosshairCursor *glfw.Cursor // Preallocated standard cross hair cursor
  200. handCursor *glfw.Cursor // Preallocated standard hand cursor
  201. hresizeCursor *glfw.Cursor // Preallocated standard horizontal resize cursor
  202. vresizeCursor *glfw.Cursor // Preallocated standard vertical resize cursor
  203. // Non GLFW standard cursors (but g3n standard)
  204. diag1Cursor *glfw.Cursor // Preallocated diagonal resize cursor (/)
  205. diag2Cursor *glfw.Cursor // Preallocated diagonal resize cursor (\)
  206. // User-created custom cursors
  207. customCursors map[int]*glfw.Cursor
  208. lastCursorKey int
  209. }
  210. // glfwWindow describes one glfw window
  211. type glfwWindow struct {
  212. core.Dispatcher // Embedded event dispatcher
  213. gls *gls.GLS // Associated OpenGL State
  214. win *glfw.Window // Pointer to native glfw window
  215. mgr *glfwManager // Pointer to window manager
  216. fullScreen bool
  217. lastX int
  218. lastY int
  219. lastWidth int
  220. lastHeight int
  221. scaleX float64
  222. scaleY float64
  223. // Events
  224. keyEv KeyEvent
  225. charEv CharEvent
  226. mouseEv MouseEvent
  227. posEv PosEvent
  228. sizeEv SizeEvent
  229. cursorEv CursorEvent
  230. scrollEv ScrollEvent
  231. }
  232. // glfw manager singleton
  233. var manager *glfwManager
  234. // Manager returns the glfw window manager
  235. func Manager() (IWindowManager, error) {
  236. if manager != nil {
  237. return manager, nil
  238. }
  239. // Initialize glfw
  240. err := glfw.Init()
  241. if err != nil {
  242. return nil, err
  243. }
  244. // Sets window hints
  245. glfw.WindowHint(glfw.ContextVersionMajor, 3)
  246. glfw.WindowHint(glfw.ContextVersionMinor, 3)
  247. glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
  248. glfw.WindowHint(glfw.Samples, 8)
  249. // Sets OpenGL forward compatible context only for OSX because it is required for OSX.
  250. // When this is set, glLineWidth(width) only accepts width=1.0 and generates an error
  251. // for any other values although the spec says it should ignore unsupported widths
  252. // and generate an error only when width <= 0.
  253. if runtime.GOOS == "darwin" {
  254. glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
  255. }
  256. manager = new(glfwManager)
  257. // Preallocate GLFW standard cursors
  258. manager.arrowCursor = glfw.CreateStandardCursor(glfw.ArrowCursor)
  259. manager.ibeamCursor = glfw.CreateStandardCursor(glfw.IBeamCursor)
  260. manager.crosshairCursor = glfw.CreateStandardCursor(glfw.CrosshairCursor)
  261. manager.handCursor = glfw.CreateStandardCursor(glfw.HandCursor)
  262. manager.hresizeCursor = glfw.CreateStandardCursor(glfw.HResizeCursor)
  263. manager.vresizeCursor = glfw.CreateStandardCursor(glfw.VResizeCursor)
  264. // Preallocate g3n cursors (diagonal cursors)
  265. cursorDiag1Png := assets.MustAsset("cursors/diag1.png")
  266. cursorDiag2Png := assets.MustAsset("cursors/diag2.png")
  267. diag1Img, _, err := image.Decode(bytes.NewReader(cursorDiag1Png))
  268. diag2Img, _, err := image.Decode(bytes.NewReader(cursorDiag2Png))
  269. if err != nil {
  270. return nil, err
  271. }
  272. manager.diag1Cursor = glfw.CreateCursor(diag1Img, 8, 8)
  273. manager.diag2Cursor = glfw.CreateCursor(diag2Img, 8, 8)
  274. // Create map for custom cursors
  275. manager.customCursors = make(map[int]*glfw.Cursor)
  276. return manager, nil
  277. }
  278. // ScreenResolution returns the screen resolution
  279. func (m *glfwManager) ScreenResolution(p interface{}) (width, height int) {
  280. mon := glfw.GetPrimaryMonitor()
  281. vmode := mon.GetVideoMode()
  282. return vmode.Width, vmode.Height
  283. }
  284. // PollEvents process events in the event queue
  285. func (m *glfwManager) PollEvents() {
  286. glfw.PollEvents()
  287. }
  288. // SetSwapInterval sets the number of screen updates to wait from the time SwapBuffer()
  289. // is called before swapping the buffers and returning.
  290. func (m *glfwManager) SetSwapInterval(interval int) {
  291. glfw.SwapInterval(interval)
  292. }
  293. // Terminate destroys any remaining window, cursors and other related objects.
  294. func (m *glfwManager) Terminate() {
  295. glfw.Terminate()
  296. manager = nil
  297. }
  298. // CreateCursor creates a new custom cursor and returns an int handle.
  299. func (m *glfwManager) CreateCursor(imgFile string, xhot, yhot int) (int, error) {
  300. // Open image file
  301. file, err := os.Open(imgFile)
  302. if err != nil {
  303. return 0, err
  304. }
  305. defer file.Close()
  306. // Decodes image
  307. img, _, err := image.Decode(file)
  308. if err != nil {
  309. return 0, err
  310. }
  311. cursor := glfw.CreateCursor(img, xhot, yhot)
  312. if err != nil {
  313. return 0, err
  314. }
  315. m.lastCursorKey += 1
  316. m.customCursors[m.lastCursorKey] = cursor
  317. return m.lastCursorKey, nil
  318. }
  319. // DisposeCursor deletes the existing custom cursor with the provided int handle.
  320. func (m *glfwManager) DisposeCursor(key int) {
  321. delete(m.customCursors, key)
  322. }
  323. // DisposeAllCursors deletes all existing custom cursors.
  324. func (m *glfwManager) DisposeAllCursors() {
  325. m.customCursors = make(map[int]*glfw.Cursor)
  326. m.lastCursorKey = 0
  327. }
  328. // CreateWindow creates and returns a new window with the specified width and height in screen coordinates
  329. func (m *glfwManager) CreateWindow(width, height int, title string, fullscreen bool) (IWindow, error) {
  330. // Creates window and sets it as the current context.
  331. // The window is created always as not full screen because if it is
  332. // created as full screen it not possible to revert it to windowed mode.
  333. // At the end of this function, the window will be set to full screen if requested.
  334. win, err := glfw.CreateWindow(width, height, title, nil, nil)
  335. if err != nil {
  336. return nil, err
  337. }
  338. win.MakeContextCurrent()
  339. // Create wrapper window with dispacher
  340. w := new(glfwWindow)
  341. w.win = win
  342. w.mgr = m
  343. w.Dispatcher.Initialize()
  344. fbw, fbh := w.FramebufferSize()
  345. w.scaleX = float64(fbw) / float64(width)
  346. w.scaleY = float64(fbh) / float64(height)
  347. // Set key callback to dispatch event
  348. win.SetKeyCallback(func(x *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
  349. w.keyEv.W = w
  350. w.keyEv.Keycode = Key(key)
  351. w.keyEv.Scancode = scancode
  352. w.keyEv.Action = Action(action)
  353. w.keyEv.Mods = ModifierKey(mods)
  354. if action == glfw.Press {
  355. w.Dispatch(OnKeyDown, &w.keyEv)
  356. return
  357. }
  358. if action == glfw.Release {
  359. w.Dispatch(OnKeyUp, &w.keyEv)
  360. return
  361. }
  362. if action == glfw.Repeat {
  363. w.Dispatch(OnKeyRepeat, &w.keyEv)
  364. return
  365. }
  366. })
  367. // Set char callback
  368. win.SetCharModsCallback(func(x *glfw.Window, char rune, mods glfw.ModifierKey) {
  369. w.charEv.W = w
  370. w.charEv.Char = char
  371. w.charEv.Mods = ModifierKey(mods)
  372. w.Dispatch(OnChar, &w.charEv)
  373. })
  374. // Set mouse button callback to dispatch event
  375. win.SetMouseButtonCallback(func(x *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
  376. xpos, ypos := x.GetCursorPos()
  377. w.mouseEv.W = w
  378. w.mouseEv.Button = MouseButton(button)
  379. w.mouseEv.Action = Action(action)
  380. w.mouseEv.Mods = ModifierKey(mods)
  381. w.mouseEv.Xpos = float32(xpos * w.scaleX)
  382. w.mouseEv.Ypos = float32(ypos * w.scaleY)
  383. if action == glfw.Press {
  384. w.Dispatch(OnMouseDown, &w.mouseEv)
  385. return
  386. }
  387. if action == glfw.Release {
  388. w.Dispatch(OnMouseUp, &w.mouseEv)
  389. return
  390. }
  391. })
  392. // Set window size callback to dispatch event
  393. win.SetSizeCallback(func(x *glfw.Window, width int, height int) {
  394. fbw, fbh := x.GetFramebufferSize()
  395. w.sizeEv.W = w
  396. w.sizeEv.Width = width
  397. w.sizeEv.Height = height
  398. w.scaleX = float64(fbw) / float64(width)
  399. w.scaleY = float64(fbh) / float64(height)
  400. w.Dispatch(OnWindowSize, &w.sizeEv)
  401. })
  402. // Set window position event callback to dispatch event
  403. win.SetPosCallback(func(x *glfw.Window, xpos int, ypos int) {
  404. w.posEv.W = w
  405. w.posEv.Xpos = xpos
  406. w.posEv.Ypos = ypos
  407. w.Dispatch(OnWindowPos, &w.posEv)
  408. })
  409. // Set window cursor position event callback to dispatch event
  410. win.SetCursorPosCallback(func(x *glfw.Window, xpos float64, ypos float64) {
  411. w.cursorEv.W = w
  412. w.cursorEv.Xpos = float32(xpos * w.scaleX)
  413. w.cursorEv.Ypos = float32(ypos * w.scaleY)
  414. w.Dispatch(OnCursor, &w.cursorEv)
  415. })
  416. // Set mouse wheel scroll event callback to dispatch event
  417. win.SetScrollCallback(func(x *glfw.Window, xoff float64, yoff float64) {
  418. w.scrollEv.W = w
  419. w.scrollEv.Xoffset = float32(xoff)
  420. w.scrollEv.Yoffset = float32(yoff)
  421. w.Dispatch(OnScroll, &w.scrollEv)
  422. })
  423. // Sets full screen if requested
  424. if fullscreen {
  425. w.SetFullScreen(true)
  426. }
  427. // Create OpenGL state
  428. gl, err := gls.New()
  429. if err != nil {
  430. return nil, err
  431. }
  432. w.gls = gl
  433. return w, nil
  434. }
  435. // Gls returns the associated OpenGL state
  436. func (w *glfwWindow) Gls() *gls.GLS {
  437. return w.gls
  438. }
  439. // Manager returns the window manager and satisfies the IWindow interface
  440. func (w *glfwWindow) Manager() IWindowManager {
  441. return w.mgr
  442. }
  443. // MakeContextCurrent makes the OpenGL context of this window current on the calling thread
  444. func (w *glfwWindow) MakeContextCurrent() {
  445. w.win.MakeContextCurrent()
  446. }
  447. // FullScreen returns this window full screen state for the primary monitor
  448. func (w *glfwWindow) FullScreen() bool {
  449. return w.fullScreen
  450. }
  451. // SetFullScreen sets this window full screen state for the primary monitor
  452. func (w *glfwWindow) SetFullScreen(full bool) {
  453. // If already in the desired state, nothing to do
  454. if w.fullScreen == full {
  455. return
  456. }
  457. // Sets this window full screen for the primary monitor
  458. if full {
  459. // Get primary monitor
  460. mon := glfw.GetPrimaryMonitor()
  461. vmode := mon.GetVideoMode()
  462. width := vmode.Width
  463. height := vmode.Height
  464. // Saves current position and size of the window
  465. w.lastX, w.lastY = w.win.GetPos()
  466. w.lastWidth, w.lastHeight = w.win.GetSize()
  467. // Sets monitor for full screen
  468. w.win.SetMonitor(mon, 0, 0, width, height, vmode.RefreshRate)
  469. w.fullScreen = true
  470. } else {
  471. // Restore window to previous position and size
  472. w.win.SetMonitor(nil, w.lastX, w.lastY, w.lastWidth, w.lastHeight, glfw.DontCare)
  473. w.fullScreen = false
  474. }
  475. }
  476. // Destroy destroys this window and its context
  477. func (w *glfwWindow) Destroy() {
  478. w.win.Destroy()
  479. w.win = nil
  480. }
  481. // SwapBuffers swaps the front and back buffers of this window.
  482. // If the swap interval is greater than zero,
  483. // the GPU driver waits the specified number of screen updates before swapping the buffers.
  484. func (w *glfwWindow) SwapBuffers() {
  485. w.win.SwapBuffers()
  486. }
  487. // FramebufferSize returns framebuffer size of this window
  488. func (w *glfwWindow) FramebufferSize() (width int, height int) {
  489. return w.win.GetFramebufferSize()
  490. }
  491. // Scale returns this window's DPI scale factor (FramebufferSize / Size)
  492. func (w *glfwWindow) Scale() (x float64, y float64) {
  493. return w.scaleX, w.scaleY
  494. }
  495. // Size returns this window's size in screen coordinates
  496. func (w *glfwWindow) Size() (width int, height int) {
  497. return w.win.GetSize()
  498. }
  499. // SetSize sets the size, in screen coordinates, of the client area of this window
  500. func (w *glfwWindow) SetSize(width int, height int) {
  501. w.win.SetSize(width, height)
  502. }
  503. // Pos returns the position, in screen coordinates, of the upper-left corner of the client area of this window
  504. func (w *glfwWindow) Pos() (xpos, ypos int) {
  505. return w.win.GetPos()
  506. }
  507. // SetPos sets the position, in screen coordinates, of the upper-left corner of the client area of this window.
  508. // If the window is a full screen window, this function does nothing.
  509. func (w *glfwWindow) SetPos(xpos, ypos int) {
  510. w.win.SetPos(xpos, ypos)
  511. }
  512. // SetTitle sets this window title, encoded as UTF-8
  513. func (w *glfwWindow) SetTitle(title string) {
  514. w.win.SetTitle(title)
  515. }
  516. // ShouldClose returns the current state of this window should close flag
  517. func (w *glfwWindow) ShouldClose() bool {
  518. return w.win.ShouldClose()
  519. }
  520. // SetShouldClose sets the state of this windows should close flag
  521. func (w *glfwWindow) SetShouldClose(v bool) {
  522. w.win.SetShouldClose(v)
  523. }
  524. // SetStandardCursor sets the window's cursor to a standard one
  525. func (w *glfwWindow) SetStandardCursor(cursor StandardCursor) {
  526. switch cursor {
  527. case ArrowCursor:
  528. w.win.SetCursor(w.mgr.arrowCursor)
  529. case IBeamCursor:
  530. w.win.SetCursor(w.mgr.ibeamCursor)
  531. case CrosshairCursor:
  532. w.win.SetCursor(w.mgr.crosshairCursor)
  533. case HandCursor:
  534. w.win.SetCursor(w.mgr.handCursor)
  535. case HResizeCursor:
  536. w.win.SetCursor(w.mgr.hresizeCursor)
  537. case VResizeCursor:
  538. w.win.SetCursor(w.mgr.vresizeCursor)
  539. // Non-GLFW cursors (but standard cursors for g3n)
  540. case DiagResize1Cursor:
  541. w.win.SetCursor(w.mgr.diag1Cursor)
  542. case DiagResize2Cursor:
  543. w.win.SetCursor(w.mgr.diag2Cursor)
  544. default:
  545. panic("Invalid cursor")
  546. }
  547. }
  548. // SetStandardCursor sets this window's cursor to a custom, user-created one
  549. func (w *glfwWindow) SetCustomCursor(key int) {
  550. w.win.SetCursor(w.mgr.customCursors[key])
  551. }
  552. // SetInputMode changes specified input to specified state
  553. // Reference: http://www.glfw.org/docs/latest/group__input.html#gaa92336e173da9c8834558b54ee80563b
  554. func (w *glfwWindow) SetInputMode(mode InputMode, state int) {
  555. w.win.SetInputMode(glfw.InputMode(mode), state)
  556. }
  557. // SetCursorPos sets cursor position in window coordinates
  558. // Reference: http://www.glfw.org/docs/latest/group__input.html#ga04b03af936d906ca123c8f4ee08b39e7
  559. func (w *glfwWindow) SetCursorPos(xpos, ypos float64) {
  560. w.win.SetCursorPos(xpos, ypos)
  561. }