cae  0.0.0
Cross-API graphics engine
Loading...
Searching...
No Matches
glfw.cpp
Go to the documentation of this file.
1#include "GLFW/GLFW.hpp"
2
3#include "Utils/Image.hpp"
4#include "Utils/Logger.hpp"
5
6#include <GLFW/glfw3native.h>
7
8#include <unordered_map>
9
10static cae::KeyCode translateKey(const int key)
11{
12 switch (key)
13 {
14 case GLFW_KEY_A:
15 return cae::KeyCode::A;
16 case GLFW_KEY_B:
17 return cae::KeyCode::B;
18 case GLFW_KEY_C:
19 return cae::KeyCode::C;
20 case GLFW_KEY_D:
21 return cae::KeyCode::D;
22 case GLFW_KEY_E:
23 return cae::KeyCode::E;
24 case GLFW_KEY_F:
25 return cae::KeyCode::F;
26 case GLFW_KEY_G:
27 return cae::KeyCode::G;
28 case GLFW_KEY_H:
29 return cae::KeyCode::H;
30 case GLFW_KEY_I:
31 return cae::KeyCode::I;
32 case GLFW_KEY_J:
33 return cae::KeyCode::J;
34 case GLFW_KEY_K:
35 return cae::KeyCode::K;
36 case GLFW_KEY_L:
37 return cae::KeyCode::L;
38 case GLFW_KEY_M:
39 return cae::KeyCode::M;
40 case GLFW_KEY_N:
41 return cae::KeyCode::N;
42 case GLFW_KEY_O:
43 return cae::KeyCode::O;
44 case GLFW_KEY_P:
45 return cae::KeyCode::P;
46 case GLFW_KEY_Q:
47 return cae::KeyCode::Q;
48 case GLFW_KEY_R:
49 return cae::KeyCode::R;
50 case GLFW_KEY_S:
51 return cae::KeyCode::S;
52 case GLFW_KEY_T:
53 return cae::KeyCode::T;
54 case GLFW_KEY_U:
55 return cae::KeyCode::U;
56 case GLFW_KEY_V:
57 return cae::KeyCode::V;
58 case GLFW_KEY_W:
59 return cae::KeyCode::W;
60 case GLFW_KEY_X:
61 return cae::KeyCode::X;
62 case GLFW_KEY_Y:
63 return cae::KeyCode::Y;
64 case GLFW_KEY_Z:
65 return cae::KeyCode::Z;
66
67 case GLFW_KEY_0:
68 return cae::KeyCode::Num0;
69 case GLFW_KEY_1:
70 return cae::KeyCode::Num1;
71 case GLFW_KEY_2:
72 return cae::KeyCode::Num2;
73 case GLFW_KEY_3:
74 return cae::KeyCode::Num3;
75 case GLFW_KEY_4:
76 return cae::KeyCode::Num4;
77 case GLFW_KEY_5:
78 return cae::KeyCode::Num5;
79 case GLFW_KEY_6:
80 return cae::KeyCode::Num6;
81 case GLFW_KEY_7:
82 return cae::KeyCode::Num7;
83 case GLFW_KEY_8:
84 return cae::KeyCode::Num8;
85 case GLFW_KEY_9:
86 return cae::KeyCode::Num9;
87
88 case GLFW_KEY_LEFT_SHIFT:
90 case GLFW_KEY_RIGHT_SHIFT:
92 case GLFW_KEY_LEFT_CONTROL:
94 case GLFW_KEY_RIGHT_CONTROL:
96 case GLFW_KEY_LEFT_ALT:
97 return cae::KeyCode::LAlt;
98 case GLFW_KEY_RIGHT_ALT:
99 return cae::KeyCode::RAlt;
100 case GLFW_KEY_LEFT_SUPER:
102 case GLFW_KEY_RIGHT_SUPER:
104 case GLFW_KEY_CAPS_LOCK:
106
107 case GLFW_KEY_UP:
108 return cae::KeyCode::Up;
109 case GLFW_KEY_DOWN:
110 return cae::KeyCode::Down;
111 case GLFW_KEY_LEFT:
112 return cae::KeyCode::Left;
113 case GLFW_KEY_RIGHT:
114 return cae::KeyCode::Right;
115 case GLFW_KEY_HOME:
116 return cae::KeyCode::Home;
117 case GLFW_KEY_END:
118 return cae::KeyCode::End;
119 case GLFW_KEY_PAGE_UP:
121 case GLFW_KEY_PAGE_DOWN:
123
124 case GLFW_KEY_ENTER:
125 return cae::KeyCode::Enter;
126 case GLFW_KEY_BACKSPACE:
128 case GLFW_KEY_TAB:
129 return cae::KeyCode::Tab;
130 case GLFW_KEY_SPACE:
131 return cae::KeyCode::Space;
132 case GLFW_KEY_DELETE:
134 case GLFW_KEY_INSERT:
136
137 case GLFW_KEY_F1:
138 return cae::KeyCode::F1;
139 case GLFW_KEY_F2:
140 return cae::KeyCode::F2;
141 case GLFW_KEY_F3:
142 return cae::KeyCode::F3;
143 case GLFW_KEY_F4:
144 return cae::KeyCode::F4;
145 case GLFW_KEY_F5:
146 return cae::KeyCode::F5;
147 case GLFW_KEY_F6:
148 return cae::KeyCode::F6;
149 case GLFW_KEY_F7:
150 return cae::KeyCode::F7;
151 case GLFW_KEY_F8:
152 return cae::KeyCode::F8;
153 case GLFW_KEY_F9:
154 return cae::KeyCode::F9;
155 case GLFW_KEY_F10:
156 return cae::KeyCode::F10;
157 case GLFW_KEY_F11:
158 return cae::KeyCode::F11;
159 case GLFW_KEY_F12:
160 return cae::KeyCode::F12;
161
162 case GLFW_KEY_ESCAPE:
164 case GLFW_KEY_PRINT_SCREEN:
166 case GLFW_KEY_PAUSE:
167 return cae::KeyCode::Pause;
168 case GLFW_KEY_MENU:
169 return cae::KeyCode::Menu;
170
171 default:
172 return cae::KeyCode::Count;
173 }
174}
175
176void cae::GLFW::keyCallback(GLFWwindow *window, const int key, int, const int action, int)
177{
178 auto *self = static_cast<GLFW *>(glfwGetWindowUserPointer(window));
179 if (self == nullptr)
180 {
181 return;
182 }
183
184 WindowEvent e{};
185 if (action == GLFW_PRESS)
186 {
188 }
189 else if (action == GLFW_RELEASE)
190 {
191 e.type = WindowEventType::KeyUp;
192 }
193 else
194 {
195 return;
196 }
197
198 e.key.key = translateKey(key);
199 self->m_eventQueue.push(e);
200}
201
202void cae::GLFW::mouseButtonCallback(GLFWwindow *window, int button, const int action, int)
203{
204 auto *self = static_cast<GLFW *>(glfwGetWindowUserPointer(window));
205 if (self == nullptr)
206 {
207 return;
208 }
209
210 WindowEvent e{};
212
213 e.mouseButton.button = static_cast<MouseButton>(button);
214 self->m_eventQueue.push(e);
215}
216
217void cae::GLFW::cursorPosCallback(GLFWwindow *window, const double x, const double y)
218{
219 auto *self = static_cast<GLFW *>(glfwGetWindowUserPointer(window));
220 if (self == nullptr)
221 {
222 return;
223 }
224
225 WindowEvent e{};
227 e.mouseMove.x = static_cast<int>(x);
228 e.mouseMove.y = static_cast<int>(y);
229
230 self->m_eventQueue.push(e);
231}
232
233void cae::GLFW::scrollCallback(GLFWwindow *window, const double xoffset, const double yoffset)
234{
235 auto *self = static_cast<GLFW *>(glfwGetWindowUserPointer(window));
236 if (self == nullptr)
237 {
238 return;
239 }
240
241 WindowEvent e{};
243 e.scroll.x = static_cast<float>(xoffset);
244 e.scroll.y = static_cast<float>(yoffset);
245
246 self->m_eventQueue.push(e);
247}
248
249void cae::GLFW::frameBufferResizeCallback(GLFWwindow *window, const int width, const int height)
250{
251 auto *self = static_cast<GLFW *>(glfwGetWindowUserPointer(window));
252 if (self == nullptr)
253 {
254 return;
255 }
256
257 self->m_frameBufferResized = true;
258 self->m_frameBufferSize = {.width = static_cast<uint16_t>(width), .height = static_cast<uint16_t>(height)};
259
260 WindowEvent e{};
262 e.resize.w = self->m_frameBufferSize.width;
263 e.resize.h = self->m_frameBufferSize.height;
264
265 self->m_eventQueue.push(e);
266}
267
268bool cae::GLFW::create(const std::string &name, const WindowSize size)
269{
270 m_window = nullptr;
271 if (glfwInit() == 0)
272 {
273 utl::Logger::log("Failed to init glfw", utl::LogLevel::WARNING);
274 return false;
275 }
276#ifdef __APPLE__
277#else
278 glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
279#endif
280
281 m_window = glfwCreateWindow(size.width, size.height, name.c_str(), nullptr, nullptr);
282 if (m_window == nullptr)
283 {
284 glfwTerminate();
285 utl::Logger::log("Failed to create GLFW window", utl::LogLevel::WARNING);
286
287 return false;
288 }
289 glfwSetWindowUserPointer(m_window, this);
290
291 glfwSetFramebufferSizeCallback(m_window, frameBufferResizeCallback);
292 glfwSetKeyCallback(m_window, keyCallback);
293 glfwSetMouseButtonCallback(m_window, mouseButtonCallback);
294 glfwSetCursorPosCallback(m_window, cursorPosCallback);
295 glfwSetScrollCallback(m_window, scrollCallback);
296#ifdef __APPLE__
297 glfwMakeContextCurrent((GLFWwindow *)m_window);
298#endif
299 return true;
300}
301
303{
304 if (m_window != nullptr)
305 {
306 glfwDestroyWindow(m_window);
307 m_window = nullptr;
308 }
309 glfwTerminate();
310}
311
313{
314 int width = 0;
315 int height = 0;
316 glfwGetWindowSize(m_window, &width, &height);
317 return {.width = static_cast<uint16_t>(width), .height = static_cast<uint16_t>(height)};
318}
319
321{
322 NativeWindowHandle handle{};
323#ifdef _WIN32
324 handle.window = glfwGetWin32Window(m_window);
325 handle.display = GetModuleHandle(nullptr);
326#elifdef __linux__
327 handle.window = reinterpret_cast<void *>(glfwGetX11Window(m_window));
328 handle.display = glfwGetX11Display();
329#elifdef __APPLE__
330 handle.window = glfwGetCocoaWindow(m_window);
331 handle.display = nullptr;
332#endif
333 return handle;
334}
335
336void cae::GLFW::setIcon(const std::string &path) const
337{
338 static const utl::Image image(path);
339 if (image.pixels == nullptr)
340 {
341 utl::Logger::log("Failed to create icon.", utl::LogLevel::WARNING);
342 return;
343 }
344 static const GLFWimage appIcon{.width = image.width, .height = image.height, .pixels = image.pixels};
345 glfwSetWindowIcon(m_window, 1, &appIcon);
346}
347
349{
350 if (m_eventQueue.empty())
351 {
352 return false;
353 }
354
355 event = m_eventQueue.front();
356 m_eventQueue.pop();
357 return true;
358}
This file contains the GLFW class declaration.
This file contains image struct.
This file contains the Logger class.
Class for the GLFW plugin.
Definition GLFW.hpp:31
bool create(const std::string &name, WindowSize size) override
Create a window with the given name and size.
Definition glfw.cpp:268
void setIcon(const std::string &path) const override
Set the window icon from the given image path.
Definition glfw.cpp:336
static void cursorPosCallback(GLFWwindow *window, double x, double y)
Definition glfw.cpp:217
void close() override
Close the window.
Definition glfw.cpp:302
bool m_frameBufferResized
Definition GLFW.hpp:72
static void scrollCallback(GLFWwindow *window, double xoffset, double yoffset)
Definition glfw.cpp:233
static void frameBufferResizeCallback(GLFWwindow *window, int width, int height)
Definition glfw.cpp:249
WindowSize getWindowSize() const override
Get the current window size.
Definition glfw.cpp:312
bool pollEvent(WindowEvent &event) override
Poll window events into outEvent.
Definition glfw.cpp:348
NativeWindowHandle getNativeHandle() const override
Get the native window handle.
Definition glfw.cpp:320
static void mouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
Definition glfw.cpp:202
static void keyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
Definition glfw.cpp:176
static void log(const std::string &message, const LogLevel &logLevel)
Log a message with a specific log level.
Definition Logger.hpp:71
static cae::KeyCode translateKey(const int key)
Definition glfw.cpp:10
KeyCode
Definition Keyboard.hpp:23
MouseButton
Definition Mouse.hpp:14
Struct for native window handle.
Definition IWindow.hpp:34
Struct for window events.
Definition IWindow.hpp:63
WindowEventType type
Definition IWindow.hpp:64
Struct for window size.
Definition IWindow.hpp:23
uint16_t height
Definition IWindow.hpp:25
uint16_t width
Definition IWindow.hpp:24
Struct for image.
Definition Image.hpp:20
int height
Definition Image.hpp:34
pixel pixels
Definition Image.hpp:32
int width
Definition Image.hpp:33