From 32ee3d9f57b37723ee97c3b798be6968f98df1b1 Mon Sep 17 00:00:00 2001 From: hachem Date: Tue, 22 Sep 2026 06:45:33 +0200 Subject: fix: windows support --- src/core/application.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++----- src/core/application.h | 3 +++ src/core/log.h | 9 +++------ src/core/window.cpp | 8 ++++++-- src/core/window.h | 2 +- 5 files changed, 58 insertions(+), 14 deletions(-) (limited to 'src/core') diff --git a/src/core/application.cpp b/src/core/application.cpp index e406511..ecaaa56 100644 --- a/src/core/application.cpp +++ b/src/core/application.cpp @@ -4,10 +4,13 @@ #include "settings_manager.h" #include "platform/opengl/opengl_device.h" -#include "platform/vulkan/vulkan_device.h" +#ifndef DONUT_NO_VULKAN + #include "platform/vulkan/vulkan_device.h" +#endif #include #include +#include #include #include #include @@ -27,6 +30,7 @@ namespace Donut } Application::Application(const std::string& name, int width, int height) + : m_title(name), m_init_w(width), m_init_h(height) { s_instance = this; @@ -38,11 +42,30 @@ namespace Donut ? RendererAPI::API::Vulkan : RendererAPI::API::OpenGL); } +#ifdef DONUT_NO_VULKAN + if (RendererAPI::get_api() == RendererAPI::API::Vulkan) + { + DONUT_WARN("built without the Vulkan backend, falling back to OpenGL"); + RendererAPI::set_api(RendererAPI::API::OpenGL); + } +#else + if (RendererAPI::get_api() == RendererAPI::API::Vulkan && !RHI::vulkan_runtime_available()) + { + DONUT_WARN("no Vulkan runtime on this machine (vulkan-1.dll), falling back to OpenGL"); + RendererAPI::set_api(RendererAPI::API::OpenGL); + } if (RendererAPI::get_api() == RendererAPI::API::Vulkan) RHI::vulkan_prepare_glfw(); +#endif m_window = create_scope(name, width, height); m_window->set_event_callback([this](Event& event) { on_event(event); }); + if (!m_window->get_native_window()) + { + DONUT_ERROR("no window, no app (GLFW said why above)"); + m_running = false; + return; + } on_init(); } @@ -58,15 +81,31 @@ namespace Donut int w = 0, h = 0; glfwGetFramebufferSize((GLFWwindow*)m_window->get_native_window(), &w, &h); +#ifndef DONUT_NO_VULKAN if (RendererAPI::get_api() == RendererAPI::API::Vulkan) m_device = RHI::create_vulkan_device(); else +#endif m_device = RHI::create_opengl_device(); RHI::NativeWindow native{ m_window->get_native_window(), w, h }; if (!m_device->init(native)) { + m_device->shutdown(); + m_device.reset(); +#ifndef DONUT_NO_VULKAN + if (RendererAPI::get_api() == RendererAPI::API::Vulkan) + { + DONUT_WARN("Vulkan device init failed (see above), falling back to OpenGL"); + RendererAPI::set_api(RendererAPI::API::OpenGL); + m_window.reset(); + m_window = create_scope(m_title, m_init_w, m_init_h); + m_window->set_event_callback([this](Event& event) { on_event(event); }); + if (m_window->get_native_window()) { on_init(); return; } + } +#endif DONUT_ERROR("RHI device initialization failed"); + m_running = false; return; } @@ -76,7 +115,8 @@ namespace Donut m_ui = create_scope(); m_device->init_imgui(); - m_ui->init(); + const float dpi = ImGui_ImplGlfw_GetContentScaleForWindow((GLFWwindow*)m_window->get_native_window()); + m_ui->init(dpi); g_prev_scroll = glfwSetScrollCallback((GLFWwindow*)m_window->get_native_window(), donut_scroll_callback); @@ -93,8 +133,8 @@ namespace Donut { double frame_start = glfwGetTime(); glfwPollEvents(); - if (!m_minimized && m_device) - render_frame(); + if (m_minimized) { glfwWaitEventsTimeout(0.1); continue; } + if (m_device) render_frame(); if (!SettingsManager::get_v_sync_enabled()) { @@ -165,7 +205,7 @@ namespace Donut { ExportConfig cfg; cfg.width = 1280; cfg.height = 720; - int written = export_frame(cfg); + [[maybe_unused]] const int written = export_frame(cfg); DONUT_INFO("autoexport wrote {} file(s)", written); close(); } diff --git a/src/core/application.h b/src/core/application.h index 5a4957b..1fc65b9 100644 --- a/src/core/application.h +++ b/src/core/application.h @@ -62,6 +62,9 @@ namespace Donut bool m_running = true; bool m_minimized = false; + std::string m_title; + int m_init_w = 1280, m_init_h = 720; + static Application* s_instance; }; } diff --git a/src/core/log.h b/src/core/log.h index 4237d1c..cc99aa1 100644 --- a/src/core/log.h +++ b/src/core/log.h @@ -144,13 +144,10 @@ namespace Donut #if defined(DONUT_DEBUG) #define DONUT_TRACE(format, ...) ::Donut::Logger::trace(format __VA_OPT__(,) __VA_ARGS__) #define DONUT_INFO(format, ...) ::Donut::Logger::info(format __VA_OPT__(,) __VA_ARGS__) - #define DONUT_WARN(format, ...) ::Donut::Logger::warn(format __VA_OPT__(,) __VA_ARGS__) - #define DONUT_ERROR(format, ...) ::Donut::Logger::error(format __VA_OPT__(,) __VA_ARGS__) - #define DONUT_FATAL(format, ...) ::Donut::Logger::fatal(format __VA_OPT__(,) __VA_ARGS__) #else #define DONUT_TRACE(format, ...) {} #define DONUT_INFO(format, ...) {} - #define DONUT_WARN(format, ...) {} - #define DONUT_ERROR(format, ...) {} - #define DONUT_FATAL(format, ...) {} #endif +#define DONUT_WARN(format, ...) ::Donut::Logger::warn(format __VA_OPT__(,) __VA_ARGS__) +#define DONUT_ERROR(format, ...) ::Donut::Logger::error(format __VA_OPT__(,) __VA_ARGS__) +#define DONUT_FATAL(format, ...) ::Donut::Logger::fatal(format __VA_OPT__(,) __VA_ARGS__) diff --git a/src/core/window.cpp b/src/core/window.cpp index d3c1ff5..090fc47 100644 --- a/src/core/window.cpp +++ b/src/core/window.cpp @@ -24,6 +24,8 @@ namespace Donut { DONUT_INFO("Initializing window: ", m_title, " (", m_width, "x", m_height, ")"); + glfwSetErrorCallback(glfw_error_callback); + if (!s_glfw_initialized) { int success = glfwInit(); @@ -43,19 +45,21 @@ namespace Donut } else { -#ifdef __APPLE__ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); +#ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); #endif } + glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE); m_window = glfwCreateWindow(m_width, m_height, m_title.c_str(), nullptr, nullptr); if (!m_window) { DONUT_ERROR("Could not create GLFW window!"); glfwTerminate(); + s_glfw_initialized = false; return; } @@ -65,7 +69,6 @@ namespace Donut glfwMakeContextCurrent(m_window); glfwSetWindowUserPointer(m_window, this); - glfwSetErrorCallback(glfw_error_callback); glfwSetWindowCloseCallback(m_window, glfw_window_close_callback); glfwSetWindowSizeCallback(m_window, glfw_window_size_callback); glfwSetWindowFocusCallback(m_window, glfw_window_focus_callback); @@ -82,6 +85,7 @@ namespace Donut auto Window::shutdown() -> void { DONUT_INFO("Shutting down window: ", m_title); + if (!m_window) return; glfwDestroyWindow(m_window); s_glfw_window_count--; diff --git a/src/core/window.h b/src/core/window.h index b8b59c5..b97874d 100644 --- a/src/core/window.h +++ b/src/core/window.h @@ -53,7 +53,7 @@ namespace Donut static auto glfw_cursor_pos_callback(GLFWwindow* window, double x_pos, double y_pos) -> void; private: - GLFWwindow* m_window; + GLFWwindow* m_window = nullptr; EventHandler m_event_handler; std::string m_title; -- cgit v1.3