This repository has been archived by the owner on Sep 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
window.go
129 lines (112 loc) · 3.14 KB
/
window.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package app
import (
"fmt"
"image"
"runtime"
"unsafe"
"github.com/go-gl/gl/v4.6-core/gl"
"github.com/go-gl/glfw/v3.3/glfw"
"github.com/mokiat/lacking/app"
"github.com/mokiat/lacking/log"
)
var (
appLogger = log.Path("/lacking-gl/app")
glLogger = appLogger.Path("/opengl")
)
// Run starts a new application and opens a single window.
//
// The specified configuration is used to determine how the
// window is initialized.
//
// The specified controller will be used to send notifications
// on window state changes.
func Run(cfg *Config, controller app.Controller) error {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
if err := glfw.Init(); err != nil {
return fmt.Errorf("failed to initialize glfw: %w", err)
}
defer glfw.Terminate()
var (
windowWidth = cfg.width
windowHeight = cfg.height
monitor *glfw.Monitor
)
if cfg.fullscreen {
monitor = glfw.GetPrimaryMonitor()
videoMode := monitor.GetVideoMode()
windowWidth = videoMode.Width
windowHeight = videoMode.Height
}
glfw.WindowHint(glfw.ContextVersionMajor, 4)
glfw.WindowHint(glfw.ContextVersionMinor, 6)
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
glfw.WindowHint(glfw.SRGBCapable, glfw.True)
if cfg.maximized {
glfw.WindowHint(glfw.Maximized, glfw.True)
}
window, err := glfw.CreateWindow(windowWidth, windowHeight, cfg.title, monitor, nil)
if err != nil {
return fmt.Errorf("failed to create glfw window: %w", err)
}
defer window.Destroy()
if cfg.minWidth != nil || cfg.maxWidth != nil || cfg.minHeight != nil || cfg.maxHeight != nil {
minWidth := glfw.DontCare
if cfg.minWidth != nil {
minWidth = *cfg.minWidth
}
minHeight := glfw.DontCare
if cfg.minHeight != nil {
minHeight = *cfg.minHeight
}
maxWidth := glfw.DontCare
if cfg.maxWidth != nil {
maxWidth = *cfg.maxWidth
}
maxHeight := glfw.DontCare
if cfg.maxHeight != nil {
maxHeight = *cfg.maxHeight
}
window.SetSizeLimits(minWidth, minHeight, maxWidth, maxHeight)
}
if cfg.icon != "" {
img, err := openImage(cfg.locator, cfg.icon)
if err != nil {
return fmt.Errorf("failed to open icon %q: %w", cfg.icon, err)
}
window.SetIcon([]image.Image{img})
}
window.MakeContextCurrent()
defer glfw.DetachCurrentContext()
glfw.SwapInterval(cfg.swapInterval)
if err := gl.Init(); err != nil {
return fmt.Errorf("failed to initialize opengl: %w", err)
}
if glLogger.DebugEnabled() {
gl.Enable(gl.DEBUG_OUTPUT)
gl.DebugMessageCallback(func(source uint32, gltype uint32, id uint32, severity uint32, length int32, message string, userParam unsafe.Pointer) {
switch severity {
case gl.DEBUG_SEVERITY_LOW:
glLogger.Debug(message)
case gl.DEBUG_SEVERITY_MEDIUM:
glLogger.Warn(message)
case gl.DEBUG_SEVERITY_HIGH:
glLogger.Error(message)
default:
glLogger.Debug(message)
}
}, gl.PtrOffset(0))
}
l := newLoop(cfg.locator, cfg.title, window, controller)
if cfg.cursor != nil {
cursor := l.CreateCursor(*cfg.cursor)
defer cursor.Destroy()
l.UseCursor(cursor)
defer l.UseCursor(nil)
}
if !cfg.cursorVisible {
l.SetCursorVisible(false)
}
return l.Run()
}