• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Razakhel / RaZ / 19909051101

03 Dec 2025 09:04PM UTC coverage: 74.363% (-0.06%) from 74.418%
19909051101

push

github

Razakhel
[Extern/ImGui] Updated ImGui to 1.92.5 & ImPlot to commit 285df9 (0.17+)

- Removed the fonts/ & freetype/ folders which are technically unused for now

- Inserted ImGui's new cursor pos callback

0 of 3 new or added lines in 1 file covered. (0.0%)

5 existing lines in 4 files now uncovered.

8525 of 11464 relevant lines covered (74.36%)

1724.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.93
/src/RaZ/Render/Window.cpp
1
#include "RaZ/Data/Image.hpp"
2
#include "RaZ/Render/Renderer.hpp"
3
#include "RaZ/Render/RenderSystem.hpp"
4
#include "RaZ/Render/Window.hpp"
5
#include "RaZ/Utils/Logger.hpp"
6

7
// GLEW is needed for V-sync management
8
#include "GL/glew.h"
9
#if defined(RAZ_PLATFORM_WINDOWS)
10
#include "GL/wglew.h"
11
#elif defined(RAZ_PLATFORM_LINUX)
12
#include "GL/glxew.h"
13
#endif
14

15
#include "GLFW/glfw3.h"
16

17
#if !defined(RAZ_NO_OVERLAY)
18
// Needed to set ImGui's callbacks
19
#include "imgui_impl_glfw.h"
20
#endif
21

22
#include "tracy/Tracy.hpp"
23
#include "tracy/TracyOpenGL.hpp"
24

25
#if defined(RAZ_PLATFORM_EMSCRIPTEN)
26
#include <emscripten/html5.h>
27
#endif
28

29
namespace Raz {
30

31
Window::Window(RenderSystem& renderSystem,
11✔
32
               unsigned int width, unsigned int height,
33
               const std::string& title,
34
               WindowSetting settings,
35
               uint8_t antiAliasingSampleCount) : m_renderSystem{ &renderSystem } {
11✔
36
  ZoneScopedN("Window::Window");
37

38
  Logger::debug("[Window] Initializing...");
11✔
39

40
  glfwSetErrorCallback([] (int errorCode, const char* description) {
11✔
41
    Logger::error("[GLFW] {} (error code {})", description, errorCode);
11✔
42
  });
11✔
43

44
  if (!glfwInit())
11✔
45
    throw std::runtime_error("Error: Failed to initialize GLFW");
×
46

47
#if !defined(USE_OPENGL_ES)
48
  glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
11✔
49
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
11✔
50
#else
51
  glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
52
#endif
53

54
#if defined(RAZ_CONFIG_DEBUG)
55
  glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
11✔
56
#endif
57

58
#if defined(RAZ_PLATFORM_MAC) // Setting the OpenGL forward compatibility is required on macOS
59
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, true);
60
#endif
61

62
  glfwWindowHint(GLFW_FOCUSED, static_cast<int>(settings & WindowSetting::FOCUSED));
11✔
63
  glfwWindowHint(GLFW_RESIZABLE, static_cast<int>(settings & WindowSetting::RESIZABLE));
11✔
64
  glfwWindowHint(GLFW_VISIBLE, static_cast<int>(settings & WindowSetting::VISIBLE));
11✔
65
  glfwWindowHint(GLFW_DECORATED, static_cast<int>(settings & WindowSetting::DECORATED));
11✔
66
  glfwWindowHint(GLFW_AUTO_ICONIFY, static_cast<int>(settings & WindowSetting::AUTO_MINIMIZE));
11✔
67
  glfwWindowHint(GLFW_FLOATING, static_cast<int>(settings & WindowSetting::ALWAYS_ON_TOP));
11✔
68
  glfwWindowHint(GLFW_MAXIMIZED, static_cast<int>(settings & WindowSetting::MAXIMIZED));
11✔
69
#if !defined(RAZ_PLATFORM_EMSCRIPTEN)
70
  glfwWindowHint(GLFW_CENTER_CURSOR, static_cast<int>(settings & WindowSetting::CENTER_CURSOR));
11✔
71
  glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, static_cast<int>(settings & WindowSetting::TRANSPARENT_FB));
11✔
72
  glfwWindowHint(GLFW_FOCUS_ON_SHOW, static_cast<int>(settings & WindowSetting::AUTOFOCUS));
11✔
73
#endif
74

75
  glfwWindowHint(GLFW_SAMPLES, antiAliasingSampleCount);
11✔
76

77
#if !defined(RAZ_PLATFORM_EMSCRIPTEN)
78
  static constexpr std::array<std::pair<int, int>, 8> glVersions = {{
79
    { 4, 6 },
80
    { 4, 5 },
81
    { 4, 4 },
82
    { 4, 3 },
83
    { 4, 2 },
84
    { 4, 1 },
85
    { 4, 0 },
86
    { 3, 3 }
87
  }};
88

89
  for (auto [major, minor] : glVersions) {
22✔
90
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, major);
22✔
91
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, minor);
22✔
92

93
    m_windowHandle = glfwCreateWindow(static_cast<int>(width), static_cast<int>(height), title.c_str(), nullptr, glfwGetCurrentContext());
22✔
94

95
    if (m_windowHandle)
22✔
96
      break;
11✔
97

98
    if (glfwGetError(nullptr) == GLFW_VERSION_UNAVAILABLE) {
11✔
99
      Logger::error("[Window] OpenGL {}.{} unsupported; attempting to fallback to a lower version", major, minor);
11✔
100
      continue;
11✔
101
    }
102

103
    close();
×
104
    throw std::runtime_error("Error: Failed to create GLFW Window");
×
105
  }
106
#else
107
  m_windowHandle = glfwCreateWindow(static_cast<int>(width), static_cast<int>(height), title.c_str(), nullptr, glfwGetCurrentContext());
108
#endif
109

110
  glfwSetWindowUserPointer(m_windowHandle, this);
11✔
111
  glfwGetWindowSize(m_windowHandle, &m_width, &m_height);
11✔
112
  glfwGetWindowPos(m_windowHandle, &m_posX, &m_posY);
11✔
113

114
  if (glfwGetCurrentContext() == nullptr)
11✔
115
    glfwMakeContextCurrent(m_windowHandle);
2✔
116

117
  Renderer::initialize();
11✔
118
  setClearColor(0.15f, 0.15f, 0.15f);
11✔
119

120
  glfwSetFramebufferSizeCallback(m_windowHandle, [] (GLFWwindow* windowHandle, int newWidth, int newHeight) {
11✔
121
    const auto* window = static_cast<const Window*>(glfwGetWindowUserPointer(windowHandle));
1✔
122
    window->m_renderSystem->resizeViewport(static_cast<unsigned int>(newWidth), static_cast<unsigned int>(newHeight));
1✔
123
  });
1✔
124

125
#if !defined(RAZ_NO_OVERLAY)
126
  Overlay::initialize(m_windowHandle);
11✔
127
#endif
128

129
  ++s_refCounter;
11✔
130

131
  Logger::debug("[Window] Initialized");
11✔
132
}
11✔
133

134
void Window::setClearColor(const Color& color, float alpha) const {
15✔
135
  Renderer::clearColor(color.red(), color.green(), color.blue(), alpha);
15✔
136
}
15✔
137

138
void Window::setTitle(const std::string& title) const {
1✔
139
  glfwSetWindowTitle(m_windowHandle, title.c_str());
1✔
140
}
1✔
141

142
void Window::setIcon(const Image& img) const {
1✔
143
  if (img.isEmpty()) {
1✔
144
    Logger::error("[Window] Empty image given as window icon");
×
145
    return;
×
146
  }
147

148
  if (img.getColorspace() != ImageColorspace::RGBA) {
1✔
149
    Logger::error("[Window] The window icon can only be created from an image having an RGBA colorspace");
×
150
    return;
×
151
  }
152

153
  if (img.getDataType() != ImageDataType::BYTE) {
1✔
154
    Logger::error("[Window] The window icon can only be created from an image having byte data");
×
155
    return;
×
156
  }
157

158
  const GLFWimage icon = { static_cast<int>(img.getWidth()),
1✔
159
                           static_cast<int>(img.getHeight()),
2✔
160
                           const_cast<unsigned char*>(static_cast<const uint8_t*>(img.getDataPtr())) };
1✔
161
  glfwSetWindowIcon(m_windowHandle, 1, &icon);
1✔
162
}
163

164
void Window::resize(unsigned int width, unsigned int height) {
1✔
165
  glfwSetWindowSize(m_windowHandle, static_cast<int>(width), static_cast<int>(height));
1✔
166
  glfwGetWindowSize(m_windowHandle, &m_width, &m_height);
1✔
167
}
1✔
168

169
void Window::makeFullscreen() {
×
170
  glfwGetWindowSize(m_windowHandle, &m_width, &m_height);
×
171
  glfwGetWindowPos(m_windowHandle, &m_posX, &m_posY);
×
172

173
  GLFWmonitor* monitor    = glfwGetPrimaryMonitor();
×
174
  const GLFWvidmode* mode = glfwGetVideoMode(monitor);
×
175

176
  glfwSetWindowMonitor(m_windowHandle, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
×
177
}
×
178

179
void Window::makeWindowed() {
1✔
180
  glfwSetWindowMonitor(m_windowHandle, nullptr, m_posX, m_posY, m_width, m_height, GLFW_DONT_CARE);
1✔
181
}
1✔
182

183
void Window::enableFaceCulling(bool value) const {
3✔
184
  if (value)
3✔
185
    Renderer::enable(Capability::CULL);
2✔
186
  else
187
    Renderer::disable(Capability::CULL);
1✔
188
}
3✔
189

190
bool Window::recoverVerticalSyncState() const {
×
191
  ZoneScopedN("Window::recoverVerticalSyncState");
192

193
#if defined(RAZ_PLATFORM_WINDOWS)
194
  if (wglGetExtensionsStringEXT())
195
    return static_cast<bool>(wglGetSwapIntervalEXT());
196

197
  return true;
198
#elif defined(RAZ_PLATFORM_LINUX)
199
  if (glXQueryExtensionsString(glXGetCurrentDisplay(), 0)) {
×
200
    unsigned int interval {};
×
201
    glXQueryDrawable(glXGetCurrentDisplay(), glXGetCurrentDrawable(), GLX_SWAP_INTERVAL_EXT, &interval);
×
202

203
    return static_cast<bool>(interval);
×
204
  }
205

206
  return true;
×
207
#elif defined(RAZ_PLATFORM_MAC)
208
  return true;
209
#else
210
  Logger::warn("Vertical synchronization unsupported");
211
  return false;
212
#endif
213
}
214

215
void Window::enableVerticalSync([[maybe_unused]] bool value) const {
3✔
216
  ZoneScopedN("Window::enableVerticalSync");
217

218
#if defined(RAZ_PLATFORM_WINDOWS)
219
  if (wglGetExtensionsStringEXT()) {
220
    wglSwapIntervalEXT(static_cast<int>(value));
221
    return;
222
  }
223
#elif defined(RAZ_PLATFORM_LINUX)
224
  if (glXQueryExtensionsString(glXGetCurrentDisplay(), 0)) {
3✔
225
    glXSwapIntervalEXT(glXGetCurrentDisplay(), glXGetCurrentDrawable(), value);
3✔
226
    glXSwapIntervalMESA(static_cast<unsigned int>(value));
3✔
227
    return;
3✔
228
  }
229
#elif defined(RAZ_PLATFORM_MAC)
230
  glfwSwapInterval(value);
231
#else
232
  Logger::warn("Vertical synchronization unsupported");
233
#endif
234
}
235

236
void Window::setCursorState(Cursor::State state) const {
3✔
237
  glfwSetInputMode(m_windowHandle, GLFW_CURSOR, state);
3✔
238
}
3✔
239

240
void Window::addKeyCallback(Keyboard::Key key, std::function<void(float)> actionPress,
3✔
241
                                               Input::ActionTrigger frequency,
242
                                               std::function<void()> actionRelease) {
243
  m_keyboardCallbacks.emplace_back(key, std::move(actionPress), frequency, std::move(actionRelease));
3✔
244
  updateCallbacks();
3✔
245
}
3✔
246

247
void Window::addMouseButtonCallback(Mouse::Button button, std::function<void(float)> actionPress,
3✔
248
                                                          Input::ActionTrigger frequency,
249
                                                          std::function<void()> actionRelease) {
250
  m_mouseButtonCallbacks.emplace_back(button, std::move(actionPress), frequency, std::move(actionRelease));
3✔
251
  updateCallbacks();
3✔
252
}
3✔
253

254
void Window::setMouseScrollCallback(std::function<void(double, double)> func) {
1✔
255
  m_mouseScrollCallback = std::move(func);
1✔
256
  updateCallbacks();
1✔
257
}
1✔
258

259
void Window::setMouseMoveCallback(std::function<void(double, double)> func) {
1✔
260
  m_mouseMoveCallback = { m_width * 0.5, m_height * 0.5, std::move(func) };
1✔
261
  updateCallbacks();
1✔
262
}
1✔
263

264
void Window::setCloseCallback(std::function<void()> func) {
1✔
265
  m_closeCallback = std::move(func);
1✔
266

267
  glfwSetWindowCloseCallback(m_windowHandle, [] (GLFWwindow* windowHandle) {
1✔
268
    static_cast<const Window*>(glfwGetWindowUserPointer(windowHandle))->m_closeCallback();
×
269
  });
×
270
}
1✔
271

272
void Window::updateCallbacks() const {
9✔
273
  ZoneScopedN("Window::updateCallbacks");
274

275
#if !defined(RAZ_NO_OVERLAY)
276
  // Monitor events
277
  glfwSetMonitorCallback([] (GLFWmonitor* monitorHandle, int event) {
9✔
278
    ImGui_ImplGlfw_MonitorCallback(monitorHandle, event);
×
279
  });
×
280
#endif
281

282
#if !defined(RAZ_NO_OVERLAY)
283
  // Window focus
284
  glfwSetWindowFocusCallback(m_windowHandle, [] (GLFWwindow* windowHandle, int focused) {
9✔
285
    ImGui_ImplGlfw_WindowFocusCallback(windowHandle, focused);
×
286
  });
×
287
#endif
288

289
  // Keyboard inputs
290
  glfwSetKeyCallback(m_windowHandle, [] (GLFWwindow* windowHandle, int key, int scancode, int action, int mods) {
9✔
291
#if !defined(RAZ_NO_OVERLAY)
292
    ImGui_ImplGlfw_KeyCallback(windowHandle, key, scancode, action, mods);
×
293

294
    // Key callbacks shouldn't be executed if the overlay requested keyboard focus
295
    if (ImGui::GetIO().WantCaptureKeyboard)
×
296
      return;
×
297
#endif
298

299
    Window& window = *static_cast<Window*>(glfwGetWindowUserPointer(windowHandle));
×
300

301
    for (const auto& callback : window.m_keyboardCallbacks) {
×
302
      if (key != callback.key)
×
303
        continue;
×
304

305
      auto& actions = window.m_inputActions;
×
306

307
      if (action == GLFW_PRESS) {
×
308
        actions.emplace(key, InputAction{ callback.actionPress, callback.frequency });
×
309
      } else if (action == GLFW_RELEASE) {
×
310
        actions.erase(key);
×
311

312
        if (const auto& actionRelease = callback.actionRelease)
×
313
          actionRelease();
×
314
      }
315
    }
316
  });
317

318
#if !defined(RAZ_NO_OVERLAY)
319
  // Unicode character inputs
320
  glfwSetCharCallback(m_windowHandle, [] (GLFWwindow* windowHandle, unsigned int codePoint) {
9✔
321
    ImGui_ImplGlfw_CharCallback(windowHandle, codePoint);
×
322
  });
×
323
#endif
324

325
#if !defined(RAZ_NO_OVERLAY)
326
  // Cursor enter event
327
  glfwSetCursorEnterCallback(m_windowHandle, [] (GLFWwindow* windowHandle, int entered) {
9✔
328
    ImGui_ImplGlfw_CursorEnterCallback(windowHandle, entered);
×
329
  });
×
330
#endif
331

332
  // Mouse buttons inputs
333
  glfwSetMouseButtonCallback(m_windowHandle, [] (GLFWwindow* windowHandle, int button, int action, int mods) {
9✔
334
#if !defined(RAZ_NO_OVERLAY)
335
    ImGui_ImplGlfw_MouseButtonCallback(windowHandle, button, action, mods);
×
336

337
    // Mouse buttons callbacks shouldn't be executed if the overlay requested mouse focus
338
    if (ImGui::GetIO().WantCaptureMouse)
×
339
      return;
×
340
#endif
341

342
    Window& window = *static_cast<Window*>(glfwGetWindowUserPointer(windowHandle));
×
343

344
    for (const auto& callback : window.m_mouseButtonCallbacks) {
×
345
      if (button != callback.button)
×
346
        continue;
×
347

348
      if (action == GLFW_PRESS) {
×
349
        window.m_inputActions.emplace(button, InputAction{ callback.actionPress, callback.frequency });
×
350
      } else if (action == GLFW_RELEASE) {
×
351
        window.m_inputActions.erase(button);
×
352

353
        if (const auto& actionRelease = callback.actionRelease)
×
354
          actionRelease();
×
355
      }
356
    }
357
  });
358

359
  // Mouse scroll input
360
  glfwSetScrollCallback(m_windowHandle, [] (GLFWwindow* windowHandle, double xOffset, double yOffset) {
9✔
361
#if !defined(RAZ_NO_OVERLAY)
362
    ImGui_ImplGlfw_ScrollCallback(windowHandle, xOffset, yOffset);
×
363

364
    // Scroll callback shouldn't be executed if the overlay requested mouse focus
365
    if (ImGui::GetIO().WantCaptureMouse)
×
366
      return;
×
367
#endif
368

369
    if (const auto& scrollCallback = static_cast<Window*>(glfwGetWindowUserPointer(windowHandle))->m_mouseScrollCallback)
×
370
      scrollCallback(xOffset, yOffset);
×
371
  });
372

373
  // Mouse move input
374
  glfwSetCursorPosCallback(m_windowHandle, [] (GLFWwindow* windowHandle, double xPosition, double yPosition) {
9✔
375
#if !defined(RAZ_NO_OVERLAY)
NEW
376
    ImGui_ImplGlfw_CursorPosCallback(windowHandle, xPosition, yPosition);
×
377

NEW
378
    if (ImGui::GetIO().WantCaptureMouse)
×
NEW
379
      return;
×
380
#endif
381

UNCOV
382
    auto& [xPrevPos, yPrevPos, action] = static_cast<Window*>(glfwGetWindowUserPointer(windowHandle))->m_mouseMoveCallback;
×
383

384
    if (action == nullptr)
×
385
      return;
×
386

387
    action(xPosition - xPrevPos, yPosition - yPrevPos);
×
388
    xPrevPos = xPosition;
×
389
    yPrevPos = yPosition;
×
390
  });
391
}
9✔
392

393
bool Window::run(float deltaTime) {
9✔
394
  ZoneScopedN("Window::run");
395

396
  if (glfwWindowShouldClose(m_windowHandle))
9✔
397
    return false;
×
398

399
  processInputs(deltaTime);
9✔
400

401
#if !defined(RAZ_NO_OVERLAY)
402
  if (m_isOverlayEnabled && !m_overlay.isEmpty())
9✔
403
    m_overlay.render();
4✔
404
#endif
405

406
  {
407
    ZoneScopedN("glfwSwapBuffers");
408
    TracyGpuZone("SwapBuffers")
409
    glfwSwapBuffers(m_windowHandle);
9✔
410
  }
411

412
#if defined(RAZ_PLATFORM_EMSCRIPTEN)
413
  emscripten_webgl_commit_frame();
414
#endif
415

416
  {
417
    TracyGpuZone("TracyGpuCollect")
418
    TracyGpuCollect
419
  }
420

421
  return true;
9✔
422
}
423

424
Vec2f Window::recoverMousePosition() const {
1✔
425
  double xPos {};
1✔
426
  double yPos {};
1✔
427
  glfwGetCursorPos(m_windowHandle, &xPos, &yPos);
1✔
428

429
  return Vec2f(static_cast<float>(xPos), static_cast<float>(yPos));
1✔
430
}
431

432
void Window::processInputs(float deltaTime) {
9✔
433
  ZoneScopedN("Window::processInputs");
434

435
  {
436
    ZoneScopedN("glfwPollEvents");
437
    glfwPollEvents();
9✔
438
  }
439

440
  auto actionIter = m_inputActions.cbegin();
9✔
441

442
  while (actionIter != m_inputActions.cend()) {
9✔
443
    const auto& [action, frequency] = actionIter->second;
×
444

445
    action(deltaTime);
×
446

447
    // Removing the current action if it should be executed only once, or simply increment the iterator
448
    if (frequency == Input::ONCE)
×
449
      actionIter = m_inputActions.erase(actionIter); // std::unordered_map::erase(iter) returns an iterator on the next element
×
450
    else
451
      ++actionIter;
×
452
  }
453
}
9✔
454

455
void Window::setShouldClose() const {
×
456
  glfwSetWindowShouldClose(m_windowHandle, true);
×
457
}
×
458

459
void Window::close() {
11✔
460
  ZoneScopedN("Window::close");
461

462
  if (!m_windowHandle.isValid())
11✔
463
    return;
×
464

465
  Logger::debug("[Window] Closing...");
11✔
466

467
  --s_refCounter;
11✔
468

469
  if (s_refCounter == 0) {
11✔
470
#if !defined(RAZ_NO_OVERLAY)
471
    Overlay::destroy();
2✔
472
#endif
473

474
    {
475
      ZoneScopedN("glfwTerminate");
476
      glfwTerminate();
2✔
477
    }
478
    m_windowHandle = nullptr;
2✔
479
  }
480

481
  Logger::debug("[Window] Closed");
22✔
482
}
483

484
} // namespace Raz
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc