Brenta Engine 1.2
Loading...
Searching...
No Matches
glfw.cpp
1// SPDX-License-Identifier: MIT
2// Author: Giovanni Santini
3// Mail: giovanni.santini@proton.me
4// Github: @San7o
5
6#include <brenta/drivers/glfw.hpp>
7#include <brenta/renderer/opengl/framebuffer.hpp>
8#include <brenta/logger.hpp>
9#include <brenta/input.hpp>
10
11#include <array>
12
13using namespace brenta;
14
15std::expected<void, std::string>
16GlfwDriver::initialize(const Window::Config &conf)
17{
18 if (glfwInit() == GLFW_FALSE)
19 return std::unexpected("Glfw: failed to initialize driver");
20
21 this->set_context_version(3, 3);
22 this->use_core_profile();
23
24 if (conf.msaa)
25 {
26 glfwWindowHint(GLFW_SAMPLES, 4);
27 INFO("Glfw: enabled MSAA");
28 }
29 else
30 {
31 INFO("Glfw: disabled MSAA");
32 }
33
34 if (!conf.vsync)
35 {
36 glfwSwapInterval(0);
37 INFO("Glfw: disabled VSync");
38 }
39 else
40 {
41 INFO("Glfw: enabled VSync");
42 }
43
44 if (conf.debug)
45 {
46 glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
47 INFO("Glfw: enabled OPENGL_DEBUG_CONTEXT");
48 }
49
50#ifdef __APPLE__
51 this->set_hints_apple();
52#endif
53
54 this->create_window(conf.width, conf.height, conf.title);
55 this->make_context_current();
56 this->set_mouse_capture(conf.capture_mouse);
57 this->set_size_callback((void*)framebuffer_size_callback);
58 this->set_key_callback((void*)glfw_key_callback);
59 this->set_mouse_callback((void*)mouse_callback);
60
61 INFO("Glfw: driver initialized")
62 return {};
63}
64
65std::expected<void, std::string> GlfwDriver::terminate()
66{
67 if (!this->window)
68 {
69 ERROR("Glfw: tried to terminate driver, but it was never initialized");
70 return std::unexpected("Uninitialized");
71 }
72 glfwDestroyWindow(this->window);
73 glfwTerminate();
74 INFO("Glfw: driver terminated");
75 return {};
76}
77
78bool GlfwDriver::should_close()
79{
80 return glfwWindowShouldClose(this->window);
81}
82
83bool GlfwDriver::is_key_pressed(Key key)
84{
85 int glfw_key = this->key_to_glfw(key);
86 return glfwGetKey(this->window, glfw_key) == GLFW_PRESS;
87}
88
89void GlfwDriver::set_dimensions(int width, int height)
90{
91 this->width = width;
92 this->height = height;
93 Window::framebuffer->width = width;
94 Window::framebuffer->height = height;
95 return;
96}
97
98Time GlfwDriver::get_time()
99{
100 return this->time;
101}
102
103Window::WindowHandle GlfwDriver::get_window()
104{
105 return this->window;
106}
107
108Window::ProcHandle GlfwDriver::get_proc_address()
109{
110 return (void*)glfwGetProcAddress;
111}
112
113int GlfwDriver::get_width()
114{
115 return this->width;
116}
117
118int GlfwDriver::get_height()
119{
120 return this->height;
121}
122
123void GlfwDriver::update_dimensions()
124{
125 glfwGetWindowSize(this->window, &this->width, &this->height);
126 return;
127}
128
129void GlfwDriver::mouse_callback([[maybe_unused]] GLFWwindow *window,
130 double xpos,
131 double ypos)
132{
133 Input::mouse_callback(xpos, ypos);
134 return;
135}
136
137
138void GlfwDriver::set_mouse_callback(void* callback)
139{
140 glfwSetCursorPosCallback(this->window, (GLFWcursorposfun) callback);
141 DEBUG("Glfw: set mouse callback");
142 return;
143}
144
145void GlfwDriver::set_size_callback(void* callback)
146{
147 glfwSetFramebufferSizeCallback(this->window, (GLFWframebuffersizefun) callback);
148 DEBUG("Glfw: set framebuffer size callback");
149 return;
150}
151
152void GlfwDriver::set_mouse_capture(bool is_captured)
153{
154 if (is_captured)
155 {
156 glfwSetInputMode(this->window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
157 INFO("Glfw: mouse capture enabled");
158 }
159 else
160 {
161 glfwSetInputMode(this->window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
162 INFO("Glfw: mouse capture disabled");
163 }
164 return;
165}
166
167void GlfwDriver::close()
168{
169 glfwSetWindowShouldClose(this->window, GLFW_TRUE);
170 return;
171}
172
173void GlfwDriver::swap_buffers()
174{
175 this->time.update(glfwGetTime());
176 glfwSwapBuffers(this->window);
177 return;
178}
179
180void GlfwDriver::poll_events()
181{
182 glfwPollEvents();
183 return;
184}
185
186void GlfwDriver::set_context_version(int major, int minor)
187{
188 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major);
189 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor);
190
191 INFO("Glfw: set context to OpenGL version: {}.{}", major, minor);
192 return;
193}
194
195void GlfwDriver::glfw_key_callback([[maybe_unused]] GLFWwindow *window,
196 int glfw_key,
197 [[maybe_unused]] int scancode,
198 int glfw_action,
199 int glfw_mods)
200{
201 auto key = GlfwDriver::glfw_to_key(glfw_key);
202
203 KeyAction action;
204 switch(glfw_action)
205 {
206 case GLFW_RELEASE: action = KeyAction::Release; break;
207 case GLFW_PRESS: action = KeyAction::Press; break;
208 case GLFW_REPEAT: action = KeyAction::Repeat; break;
209 case GLFW_KEY_UNKNOWN:
210 default:
211 action = KeyAction::Unknown;
212 break;
213 }
214
215 KeyMods mods= {};
216 if (glfw_mods & GLFW_MOD_SHIFT)
217 mods.set_shift();
218 if (glfw_mods & GLFW_MOD_CONTROL)
219 mods.set_control();
220 if (glfw_mods & GLFW_MOD_ALT)
221 mods.set_alt();
222 if (glfw_mods & GLFW_MOD_SUPER)
223 mods.set_super();
224 if (glfw_mods & GLFW_MOD_CAPS_LOCK)
225 mods.set_caps_lock();
226 if (glfw_mods & GLFW_MOD_NUM_LOCK)
227 mods.set_num_lock();
228
229 Input::key_callback(key, action, mods);
230 return;
231}
232
233void GlfwDriver::set_key_callback(void* callback)
234{
235 glfwSetKeyCallback(this->window, (GLFWkeyfun) callback);
236 DEBUG("Glfw: set key callback");
237 return;
238}
239
240void GlfwDriver::set_mouse_pos_callback(void* callback)
241{
242 glfwSetCursorPosCallback(this->window, (GLFWcursorposfun) callback);
243 DEBUG("Glfw: set mouse pos");
244 return;
245}
246
247void GlfwDriver::create_window(int width, int height, const std::string &title)
248{
249 this->window = glfwCreateWindow(width, height, title.c_str(),
250 NULL, NULL);
251 if (this->window == NULL)
252 {
253 ERROR("Glfw: failed to create window");
254 Window::instance().terminate();
255 }
256 this->width = width;
257 this->height = height;
258 return;
259}
260
261void GlfwDriver::make_context_current()
262{
263 glfwMakeContextCurrent(this->window);
264 return;
265}
266
267void GlfwDriver::framebuffer_size_callback([[maybe_unused]] GLFWwindow *window,
268 [[maybe_unused]] int width,
269 [[maybe_unused]] int height)
270{
271 if (Gl::instance().is_initialized())
272 glViewport(0, 0, width, height);
273
274 Window::get_driver()->set_dimensions(width, height);
275
276 DEBUG("Glfw: size changed {}x{}", width, height);
277 return;
278}
279
280int GlfwDriver::key_to_glfw(Key key)
281{
282 static const auto key_map = []() {
283 std::array<int, static_cast<size_t>(Key::Menu) + 1> map;
284
285 map.fill(GLFW_KEY_UNKNOWN);
286
287 map[static_cast<size_t>(Key::Space)] = GLFW_KEY_SPACE;
288 map[static_cast<size_t>(Key::Apostrophe)] = GLFW_KEY_APOSTROPHE;
289 map[static_cast<size_t>(Key::Comma)] = GLFW_KEY_COMMA;
290 map[static_cast<size_t>(Key::Minus)] = GLFW_KEY_MINUS;
291 map[static_cast<size_t>(Key::Period)] = GLFW_KEY_PERIOD;
292 map[static_cast<size_t>(Key::Slash)] = GLFW_KEY_SLASH;
293 map[static_cast<size_t>(Key::D0)] = GLFW_KEY_0;
294 map[static_cast<size_t>(Key::D1)] = GLFW_KEY_1;
295 map[static_cast<size_t>(Key::D2)] = GLFW_KEY_2;
296 map[static_cast<size_t>(Key::D3)] = GLFW_KEY_3;
297 map[static_cast<size_t>(Key::D4)] = GLFW_KEY_4;
298 map[static_cast<size_t>(Key::D5)] = GLFW_KEY_5;
299 map[static_cast<size_t>(Key::D6)] = GLFW_KEY_6;
300 map[static_cast<size_t>(Key::D7)] = GLFW_KEY_7;
301 map[static_cast<size_t>(Key::D8)] = GLFW_KEY_8;
302 map[static_cast<size_t>(Key::D9)] = GLFW_KEY_9;
303 map[static_cast<size_t>(Key::Semicolon)] = GLFW_KEY_SEMICOLON;
304 map[static_cast<size_t>(Key::Equal)] = GLFW_KEY_EQUAL;
305 map[static_cast<size_t>(Key::A)] = GLFW_KEY_A;
306 map[static_cast<size_t>(Key::B)] = GLFW_KEY_B;
307 map[static_cast<size_t>(Key::C)] = GLFW_KEY_C;
308 map[static_cast<size_t>(Key::D)] = GLFW_KEY_D;
309 map[static_cast<size_t>(Key::E)] = GLFW_KEY_E;
310 map[static_cast<size_t>(Key::F)] = GLFW_KEY_F;
311 map[static_cast<size_t>(Key::G)] = GLFW_KEY_G;
312 map[static_cast<size_t>(Key::H)] = GLFW_KEY_H;
313 map[static_cast<size_t>(Key::I)] = GLFW_KEY_I;
314 map[static_cast<size_t>(Key::J)] = GLFW_KEY_J;
315 map[static_cast<size_t>(Key::K)] = GLFW_KEY_K;
316 map[static_cast<size_t>(Key::L)] = GLFW_KEY_L;
317 map[static_cast<size_t>(Key::M)] = GLFW_KEY_M;
318 map[static_cast<size_t>(Key::N)] = GLFW_KEY_N;
319 map[static_cast<size_t>(Key::O)] = GLFW_KEY_O;
320 map[static_cast<size_t>(Key::P)] = GLFW_KEY_P;
321 map[static_cast<size_t>(Key::Q)] = GLFW_KEY_Q;
322 map[static_cast<size_t>(Key::R)] = GLFW_KEY_R;
323 map[static_cast<size_t>(Key::S)] = GLFW_KEY_S;
324 map[static_cast<size_t>(Key::T)] = GLFW_KEY_T;
325 map[static_cast<size_t>(Key::U)] = GLFW_KEY_U;
326 map[static_cast<size_t>(Key::V)] = GLFW_KEY_V;
327 map[static_cast<size_t>(Key::W)] = GLFW_KEY_W;
328 map[static_cast<size_t>(Key::X)] = GLFW_KEY_X;
329 map[static_cast<size_t>(Key::Y)] = GLFW_KEY_Y;
330 map[static_cast<size_t>(Key::Z)] = GLFW_KEY_Z;
331 map[static_cast<size_t>(Key::LeftBracket)] = GLFW_KEY_LEFT_BRACKET;
332 map[static_cast<size_t>(Key::Backslash)] = GLFW_KEY_BACKSLASH;
333 map[static_cast<size_t>(Key::RightBracket)] = GLFW_KEY_RIGHT_BRACKET;
334 map[static_cast<size_t>(Key::GraveAccent)] = GLFW_KEY_GRAVE_ACCENT;
335 map[static_cast<size_t>(Key::World1)] = GLFW_KEY_WORLD_1;
336 map[static_cast<size_t>(Key::World2)] = GLFW_KEY_WORLD_2;
337
338 // Function keys
339 map[static_cast<size_t>(Key::Escape)] = GLFW_KEY_ESCAPE;
340 map[static_cast<size_t>(Key::Enter)] = GLFW_KEY_ENTER;
341 map[static_cast<size_t>(Key::Tab)] = GLFW_KEY_TAB;
342 map[static_cast<size_t>(Key::Backspace)] = GLFW_KEY_BACKSPACE;
343 map[static_cast<size_t>(Key::Insert)] = GLFW_KEY_INSERT;
344 map[static_cast<size_t>(Key::Delete)] = GLFW_KEY_DELETE;
345 map[static_cast<size_t>(Key::Right)] = GLFW_KEY_RIGHT;
346 map[static_cast<size_t>(Key::Left)] = GLFW_KEY_LEFT;
347 map[static_cast<size_t>(Key::Down)] = GLFW_KEY_DOWN;
348 map[static_cast<size_t>(Key::Up)] = GLFW_KEY_UP;
349 map[static_cast<size_t>(Key::PageUp)] = GLFW_KEY_PAGE_UP;
350 map[static_cast<size_t>(Key::PageDown)] = GLFW_KEY_PAGE_DOWN;
351 map[static_cast<size_t>(Key::Home)] = GLFW_KEY_HOME;
352 map[static_cast<size_t>(Key::End)] = GLFW_KEY_END;
353 map[static_cast<size_t>(Key::CapsLock)] = GLFW_KEY_CAPS_LOCK;
354 map[static_cast<size_t>(Key::ScrollLock)] = GLFW_KEY_SCROLL_LOCK;
355 map[static_cast<size_t>(Key::NumLock)] = GLFW_KEY_NUM_LOCK;
356 map[static_cast<size_t>(Key::PrintScreen)] = GLFW_KEY_PRINT_SCREEN;
357 map[static_cast<size_t>(Key::Pause)] = GLFW_KEY_PAUSE;
358 map[static_cast<size_t>(Key::F1)] = GLFW_KEY_F1;
359 map[static_cast<size_t>(Key::F2)] = GLFW_KEY_F2;
360 map[static_cast<size_t>(Key::F3)] = GLFW_KEY_F3;
361 map[static_cast<size_t>(Key::F4)] = GLFW_KEY_F4;
362 map[static_cast<size_t>(Key::F5)] = GLFW_KEY_F5;
363 map[static_cast<size_t>(Key::F6)] = GLFW_KEY_F6;
364 map[static_cast<size_t>(Key::F7)] = GLFW_KEY_F7;
365 map[static_cast<size_t>(Key::F8)] = GLFW_KEY_F8;
366 map[static_cast<size_t>(Key::F9)] = GLFW_KEY_F9;
367 map[static_cast<size_t>(Key::F10)] = GLFW_KEY_F10;
368 map[static_cast<size_t>(Key::F11)] = GLFW_KEY_F11;
369 map[static_cast<size_t>(Key::F12)] = GLFW_KEY_F12;
370 map[static_cast<size_t>(Key::F13)] = GLFW_KEY_F13;
371 map[static_cast<size_t>(Key::F14)] = GLFW_KEY_F14;
372 map[static_cast<size_t>(Key::F15)] = GLFW_KEY_F15;
373 map[static_cast<size_t>(Key::F16)] = GLFW_KEY_F16;
374 map[static_cast<size_t>(Key::F17)] = GLFW_KEY_F17;
375 map[static_cast<size_t>(Key::F18)] = GLFW_KEY_F18;
376 map[static_cast<size_t>(Key::F19)] = GLFW_KEY_F19;
377 map[static_cast<size_t>(Key::F20)] = GLFW_KEY_F20;
378 map[static_cast<size_t>(Key::F21)] = GLFW_KEY_F21;
379 map[static_cast<size_t>(Key::F22)] = GLFW_KEY_F22;
380 map[static_cast<size_t>(Key::F23)] = GLFW_KEY_F23;
381 map[static_cast<size_t>(Key::F24)] = GLFW_KEY_F24;
382 map[static_cast<size_t>(Key::F25)] = GLFW_KEY_F25;
383
384 // Keypad
385 map[static_cast<size_t>(Key::KP0)] = GLFW_KEY_KP_0;
386 map[static_cast<size_t>(Key::KP1)] = GLFW_KEY_KP_1;
387 map[static_cast<size_t>(Key::KP2)] = GLFW_KEY_KP_2;
388 map[static_cast<size_t>(Key::KP3)] = GLFW_KEY_KP_3;
389 map[static_cast<size_t>(Key::KP4)] = GLFW_KEY_KP_4;
390 map[static_cast<size_t>(Key::KP5)] = GLFW_KEY_KP_5;
391 map[static_cast<size_t>(Key::KP6)] = GLFW_KEY_KP_6;
392 map[static_cast<size_t>(Key::KP7)] = GLFW_KEY_KP_7;
393 map[static_cast<size_t>(Key::KP8)] = GLFW_KEY_KP_8;
394 map[static_cast<size_t>(Key::KP9)] = GLFW_KEY_KP_9;
395 map[static_cast<size_t>(Key::KPDecimal)] = GLFW_KEY_KP_DECIMAL;
396 map[static_cast<size_t>(Key::KPDivide)] = GLFW_KEY_KP_DIVIDE;
397 map[static_cast<size_t>(Key::KPMultiply)] = GLFW_KEY_KP_MULTIPLY;
398 map[static_cast<size_t>(Key::KPSubtract)] = GLFW_KEY_KP_SUBTRACT;
399 map[static_cast<size_t>(Key::KPAdd)] = GLFW_KEY_KP_ADD;
400 map[static_cast<size_t>(Key::KPEnter)] = GLFW_KEY_KP_ENTER;
401 map[static_cast<size_t>(Key::KPEqual)] = GLFW_KEY_KP_EQUAL;
402
403 // Modifiers
404 map[static_cast<size_t>(Key::LeftShift)] = GLFW_KEY_LEFT_SHIFT;
405 map[static_cast<size_t>(Key::LeftControl)] = GLFW_KEY_LEFT_CONTROL;
406 map[static_cast<size_t>(Key::LeftAlt)] = GLFW_KEY_LEFT_ALT;
407 map[static_cast<size_t>(Key::LeftSuper)] = GLFW_KEY_LEFT_SUPER;
408 map[static_cast<size_t>(Key::RightShift)] = GLFW_KEY_RIGHT_SHIFT;
409 map[static_cast<size_t>(Key::RightControl)] = GLFW_KEY_RIGHT_CONTROL;
410 map[static_cast<size_t>(Key::RightAlt)] = GLFW_KEY_RIGHT_ALT;
411 map[static_cast<size_t>(Key::RightSuper)] = GLFW_KEY_RIGHT_SUPER;
412 map[static_cast<size_t>(Key::Menu)] = GLFW_KEY_MENU;
413
414 return map;
415 }();
416
417 auto index = static_cast<size_t>(key);
418 return (index < key_map.size()) ? key_map[index] : GLFW_KEY_UNKNOWN;
419}
420
421Key GlfwDriver::glfw_to_key(int glfw_key)
422{
423 static const auto reverse_map = []() {
424 std::array<Key, GLFW_KEY_LAST + 1> map;
425 map.fill(Key::Unknown);
426
427 // Alphanumeric
428 map[GLFW_KEY_SPACE] = Key::Space;
429 map[GLFW_KEY_APOSTROPHE] = Key::Apostrophe;
430 map[GLFW_KEY_COMMA] = Key::Comma;
431 map[GLFW_KEY_MINUS] = Key::Minus;
432 map[GLFW_KEY_PERIOD] = Key::Period;
433 map[GLFW_KEY_SLASH] = Key::Slash;
434 map[GLFW_KEY_0] = Key::D0;
435 map[GLFW_KEY_1] = Key::D1;
436 map[GLFW_KEY_2] = Key::D2;
437 map[GLFW_KEY_3] = Key::D3;
438 map[GLFW_KEY_4] = Key::D4;
439 map[GLFW_KEY_5] = Key::D5;
440 map[GLFW_KEY_6] = Key::D6;
441 map[GLFW_KEY_7] = Key::D7;
442 map[GLFW_KEY_8] = Key::D8;
443 map[GLFW_KEY_9] = Key::D9;
444 map[GLFW_KEY_SEMICOLON] = Key::Semicolon;
445 map[GLFW_KEY_EQUAL] = Key::Equal;
446 map[GLFW_KEY_A] = Key::A;
447 map[GLFW_KEY_B] = Key::B;
448 map[GLFW_KEY_C] = Key::C;
449 map[GLFW_KEY_D] = Key::D;
450 map[GLFW_KEY_E] = Key::E;
451 map[GLFW_KEY_F] = Key::F;
452 map[GLFW_KEY_G] = Key::G;
453 map[GLFW_KEY_H] = Key::H;
454 map[GLFW_KEY_I] = Key::I;
455 map[GLFW_KEY_J] = Key::J;
456 map[GLFW_KEY_K] = Key::K;
457 map[GLFW_KEY_L] = Key::L;
458 map[GLFW_KEY_M] = Key::M;
459 map[GLFW_KEY_N] = Key::N;
460 map[GLFW_KEY_O] = Key::O;
461 map[GLFW_KEY_P] = Key::P;
462 map[GLFW_KEY_Q] = Key::Q;
463 map[GLFW_KEY_R] = Key::R;
464 map[GLFW_KEY_S] = Key::S;
465 map[GLFW_KEY_T] = Key::T;
466 map[GLFW_KEY_U] = Key::U;
467 map[GLFW_KEY_V] = Key::V;
468 map[GLFW_KEY_W] = Key::W;
469 map[GLFW_KEY_X] = Key::X;
470 map[GLFW_KEY_Y] = Key::Y;
471 map[GLFW_KEY_Z] = Key::Z;
472 map[GLFW_KEY_LEFT_BRACKET] = Key::LeftBracket;
473 map[GLFW_KEY_BACKSLASH] = Key::Backslash;
474 map[GLFW_KEY_RIGHT_BRACKET] = Key::RightBracket;
475 map[GLFW_KEY_GRAVE_ACCENT] = Key::GraveAccent;
476 map[GLFW_KEY_WORLD_1] = Key::World1;
477 map[GLFW_KEY_WORLD_2] = Key::World2;
478
479 // Function keys
480 map[GLFW_KEY_ESCAPE] = Key::Escape;
481 map[GLFW_KEY_ENTER] = Key::Enter;
482 map[GLFW_KEY_TAB] = Key::Tab;
483 map[GLFW_KEY_BACKSPACE] = Key::Backspace;
484 map[GLFW_KEY_INSERT] = Key::Insert;
485 map[GLFW_KEY_DELETE] = Key::Delete;
486 map[GLFW_KEY_RIGHT] = Key::Right;
487 map[GLFW_KEY_LEFT] = Key::Left;
488 map[GLFW_KEY_DOWN] = Key::Down;
489 map[GLFW_KEY_UP] = Key::Up;
490 map[GLFW_KEY_PAGE_UP] = Key::PageUp;
491 map[GLFW_KEY_PAGE_DOWN] = Key::PageDown;
492 map[GLFW_KEY_HOME] = Key::Home;
493 map[GLFW_KEY_END] = Key::End;
494 map[GLFW_KEY_CAPS_LOCK] = Key::CapsLock;
495 map[GLFW_KEY_SCROLL_LOCK] = Key::ScrollLock;
496 map[GLFW_KEY_NUM_LOCK] = Key::NumLock;
497 map[GLFW_KEY_PRINT_SCREEN] = Key::PrintScreen;
498 map[GLFW_KEY_PAUSE] = Key::Pause;
499 map[GLFW_KEY_F1] = Key::F1;
500 map[GLFW_KEY_F2] = Key::F2;
501 map[GLFW_KEY_F3] = Key::F3;
502 map[GLFW_KEY_F4] = Key::F4;
503 map[GLFW_KEY_F5] = Key::F5;
504 map[GLFW_KEY_F6] = Key::F6;
505 map[GLFW_KEY_F7] = Key::F7;
506 map[GLFW_KEY_F8] = Key::F8;
507 map[GLFW_KEY_F9] = Key::F9;
508 map[GLFW_KEY_F10] = Key::F10;
509 map[GLFW_KEY_F11] = Key::F11;
510 map[GLFW_KEY_F12] = Key::F12;
511 map[GLFW_KEY_F13] = Key::F13;
512 map[GLFW_KEY_F14] = Key::F14;
513 map[GLFW_KEY_F15] = Key::F15;
514 map[GLFW_KEY_F16] = Key::F16;
515 map[GLFW_KEY_F17] = Key::F17;
516 map[GLFW_KEY_F18] = Key::F18;
517 map[GLFW_KEY_F19] = Key::F19;
518 map[GLFW_KEY_F20] = Key::F20;
519 map[GLFW_KEY_F21] = Key::F21;
520 map[GLFW_KEY_F22] = Key::F22;
521 map[GLFW_KEY_F23] = Key::F23;
522 map[GLFW_KEY_F24] = Key::F24;
523 map[GLFW_KEY_F25] = Key::F25;
524
525 // Keypad
526 map[GLFW_KEY_KP_0] = Key::KP0;
527 map[GLFW_KEY_KP_1] = Key::KP1;
528 map[GLFW_KEY_KP_2] = Key::KP2;
529 map[GLFW_KEY_KP_3] = Key::KP3;
530 map[GLFW_KEY_KP_4] = Key::KP4;
531 map[GLFW_KEY_KP_5] = Key::KP5;
532 map[GLFW_KEY_KP_6] = Key::KP6;
533 map[GLFW_KEY_KP_7] = Key::KP7;
534 map[GLFW_KEY_KP_8] = Key::KP8;
535 map[GLFW_KEY_KP_9] = Key::KP9;
536 map[GLFW_KEY_KP_DECIMAL] = Key::KPDecimal;
537 map[GLFW_KEY_KP_DIVIDE] = Key::KPDivide;
538 map[GLFW_KEY_KP_MULTIPLY] = Key::KPMultiply;
539 map[GLFW_KEY_KP_SUBTRACT] = Key::KPSubtract;
540 map[GLFW_KEY_KP_ADD] = Key::KPAdd;
541 map[GLFW_KEY_KP_ENTER] = Key::KPEnter;
542 map[GLFW_KEY_KP_EQUAL] = Key::KPEqual;
543
544 // Modifiers
545 map[GLFW_KEY_LEFT_SHIFT] = Key::LeftShift;
546 map[GLFW_KEY_LEFT_CONTROL] = Key::LeftControl;
547 map[GLFW_KEY_LEFT_ALT] = Key::LeftAlt;
548 map[GLFW_KEY_LEFT_SUPER] = Key::LeftSuper;
549 map[GLFW_KEY_RIGHT_SHIFT] = Key::RightShift;
550 map[GLFW_KEY_RIGHT_CONTROL] = Key::RightControl;
551 map[GLFW_KEY_RIGHT_ALT] = Key::RightAlt;
552 map[GLFW_KEY_RIGHT_SUPER] = Key::RightSuper;
553 map[GLFW_KEY_MENU] = Key::Menu;
554
555 return map;
556 }();
557
558 if (glfw_key >= 0 && glfw_key <= GLFW_KEY_LAST) {
559 return reverse_map[static_cast<size_t>(glfw_key)];
560 }
561 return Key::Unknown;
562}
563
564void GlfwDriver::use_core_profile()
565{
566 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
567 INFO("Glfw: set OpenGL profile to core");
568 return;
569}
570
571void GlfwDriver::set_hints_apple()
572{
573 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
574 return;
575}