diff --git a/core/os/os.h b/core/os/os.h index 91e0ce937944..22197d3517a4 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -111,9 +111,6 @@ class OS { virtual void initialize() = 0; virtual void initialize_joypads() = 0; - void set_current_rendering_driver_name(const String &p_driver_name) { _current_rendering_driver_name = p_driver_name; } - void set_current_rendering_method(const String &p_name) { _current_rendering_method = p_name; } - void set_display_driver_id(int p_display_driver_id) { _display_driver_id = p_display_driver_id; } virtual void set_main_loop(MainLoop *p_main_loop) = 0; @@ -131,6 +128,9 @@ class OS { static OS *get_singleton(); + void set_current_rendering_driver_name(const String &p_driver_name) { _current_rendering_driver_name = p_driver_name; } + void set_current_rendering_method(const String &p_name) { _current_rendering_method = p_name; } + String get_current_rendering_driver_name() const { return _current_rendering_driver_name; } String get_current_rendering_method() const { return _current_rendering_method; } diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index d78fca5e16cd..95aed56bb18f 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2790,6 +2790,10 @@ If [code]true[/code], the forward renderer will fall back to Direct3D 12 if Vulkan is not supported. [b]Note:[/b] This setting is implemented only on Windows. + + If [code]true[/code], the forward renderer will fall back to OpenGL 3 if both Direct3D 12, Metal and Vulkan are not supported. + [b]Note:[/b] This setting is implemented only on Windows, Android, macOS, iOS, and Linux/X11. + If [code]true[/code], the forward renderer will fall back to Vulkan if Direct3D 12 is not supported. [b]Note:[/b] This setting is implemented only on Windows. diff --git a/drivers/d3d12/SCsub b/drivers/d3d12/SCsub index 55ba1dc579c5..f1264f040d3d 100644 --- a/drivers/d3d12/SCsub +++ b/drivers/d3d12/SCsub @@ -138,7 +138,6 @@ if env.msvc: ] else: extra_defines += [ - ("__REQUIRED_RPCNDR_H_VERSION__", 475), "HAVE_STRUCT_TIMESPEC", ] diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 61b1498755f6..fb7fbdc02d79 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -36,6 +36,11 @@ #include "core/templates/self_list.h" #include "servers/rendering/rendering_device_driver.h" +#ifndef _MSC_VER +// Match current version used by MinGW, MSVC and Direct3D 12 headers use 500. +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" diff --git a/main/main.cpp b/main/main.cpp index 3841eb6c1ee3..74f986c7ddea 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1963,6 +1963,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_vulkan", true); GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_d3d12", true); + GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_opengl3", true); } { diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index b88d887af52c..145f9784fd01 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -589,12 +589,6 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis native_menu = memnew(NativeMenu); -#if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { - RasterizerGLES3::make_current(false); - } -#endif - #if defined(RD_ENABLED) rendering_context = nullptr; rendering_device = nullptr; @@ -607,13 +601,26 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_UNAVAILABLE; - return; +#if defined(GLES3_ENABLED) + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your device seem not to support Vulkan, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else +#endif + { + ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); + r_error = ERR_UNAVAILABLE; + return; + } } + } + if (rendering_context) { union { #ifdef VULKAN_ENABLED RenderingContextDriverVulkanAndroid::WindowPlatformData vulkan; @@ -653,6 +660,12 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis } #endif +#if defined(GLES3_ENABLED) + if (rendering_driver == "opengl3") { + RasterizerGLES3::make_current(false); + } +#endif + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 802fbefc0dbb..600fee75b35f 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -88,13 +88,26 @@ if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_UNAVAILABLE; - return; +#if defined(GLES3_ENABLED) + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else +#endif + { + ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); + r_error = ERR_UNAVAILABLE; + return; + } } + } + if (rendering_context) { if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) { ERR_PRINT(vformat("Failed to create %s window.", rendering_driver)); memdelete(rendering_context); diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index da4e1aa97cba..8d1c22699fb9 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1349,6 +1349,9 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win rendering_driver = p_rendering_driver; + bool driver_found = false; + String executable_name = OS::get_singleton()->get_executable_path().get_file(); + #ifdef RD_ENABLED #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { @@ -1358,12 +1361,36 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Could not initialize %s", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_CANT_CREATE; - return; +#if defined(GLES3_ENABLED) + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else +#endif // GLES3_ENABLED + { + r_error = ERR_CANT_CREATE; + + if (p_rendering_driver == "vulkan") { + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" + "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize Vulkan video driver"); + } + + ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver)); + } } + + driver_found = true; } #endif @@ -1429,30 +1456,58 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (fallback) { WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES."); rendering_driver = "opengl3_es"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; + + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n" + "You can enable the Vulkan driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize OpenGL video driver"); + ERR_FAIL_MSG("Could not initialize OpenGL."); } } else { RasterizerGLES3::make_current(true); + driver_found = true; } } if (rendering_driver == "opengl3_es") { egl_manager = memnew(EGLManagerWaylandGLES); - if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK) { + if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) { memdelete(egl_manager); egl_manager = nullptr; r_error = ERR_CANT_CREATE; - ERR_FAIL_MSG("Could not initialize GLES3."); + + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n" + "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n" + "You can enable the Vulkan driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize OpenGL ES video driver"); + + ERR_FAIL_MSG("Could not initialize OpenGL ES."); } RasterizerGLES3::make_current(false); + driver_found = true; } } #endif // GLES3_ENABLED + if (!driver_found) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Video driver not found."); + } + cursor_set_shape(CURSOR_BUSY); WindowData &wd = main_window; diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index af4e3de71791..9e2460c455ee 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -2055,7 +2055,7 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window return; } - if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN) { + if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN || window_get_mode(p_window) == WINDOW_MODE_MAXIMIZED) { Point2i position = screen_get_position(p_screen); Size2i size = screen_get_size(p_screen); @@ -3046,7 +3046,7 @@ void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_win XWindowAttributes xwa; XSync(x11_display, False); XGetWindowAttributes(x11_display, wd.x11_xim_window, &xwa); - if (xwa.map_state == IsViewable) { + if (xwa.map_state == IsViewable && _window_focus_check()) { _set_input_focus(wd.x11_xim_window, RevertToParent); } XSetICFocus(wd.xic); @@ -4315,7 +4315,7 @@ bool DisplayServerX11::_window_focus_check() { bool has_focus = false; for (const KeyValue &wid : windows) { - if (wid.value.x11_window == focused_window) { + if (wid.value.x11_window == focused_window || (wid.value.xic && wid.value.ime_active && wid.value.x11_xim_window == focused_window)) { has_focus = true; break; } @@ -5428,25 +5428,6 @@ Vector DisplayServerX11::get_rendering_drivers_func() { DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error)); - if (r_error != OK) { - if (p_rendering_driver == "vulkan") { - String executable_name = OS::get_singleton()->get_executable_path().get_file(); - OS::get_singleton()->alert( - vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" - "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" - "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" - "If you recently updated your video card drivers, try rebooting.", - executable_name), - "Unable to initialize Vulkan video driver"); - } else { - OS::get_singleton()->alert( - "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" - "If possible, consider updating your video card drivers.\n\n" - "If you recently updated your video card drivers, try rebooting.", - "Unable to initialize OpenGL video driver"); - } - } return ds; } @@ -6160,6 +6141,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode rendering_driver = p_rendering_driver; bool driver_found = false; + String executable_name = OS::get_singleton()->get_executable_path().get_file(); + + // Initialize context and rendering device. + #if defined(RD_ENABLED) #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { @@ -6169,11 +6154,33 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Could not initialize %s", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_CANT_CREATE; - return; +#if defined(GLES3_ENABLED) + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else +#endif // GLES3_ENABLED + { + r_error = ERR_CANT_CREATE; + + if (p_rendering_driver == "vulkan") { + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" + "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize Vulkan video driver"); + } + + ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver)); + } } driver_found = true; } @@ -6231,8 +6238,19 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (fallback) { WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES."); rendering_driver = "opengl3_es"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; + + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n" + "You can enable the Vulkan driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize OpenGL video driver"); + ERR_FAIL_MSG("Could not initialize OpenGL."); } } else { @@ -6243,11 +6261,18 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (rendering_driver == "opengl3_es") { gl_manager_egl = memnew(GLManagerEGL_X11); - if (gl_manager_egl->initialize() != OK) { + if (gl_manager_egl->initialize() != OK || gl_manager_egl->open_display(x11_display) != OK) { memdelete(gl_manager_egl); gl_manager_egl = nullptr; r_error = ERR_UNAVAILABLE; - ERR_FAIL_MSG("Could not initialize OpenGLES."); + + OS::get_singleton()->alert( + "Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n" + "If possible, consider updating your video card drivers.\n\n" + "If you recently updated your video card drivers, try rebooting.", + "Unable to initialize OpenGL ES video driver"); + + ERR_FAIL_MSG("Could not initialize OpenGL ES."); } driver_found = true; RasterizerGLES3::make_current(false); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 22586a777586..a63d1c688d4a 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1885,6 +1885,12 @@ was_fullscreen = true; } + bool was_maximized = false; + if (!was_fullscreen && NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { + [wd.window_object zoom:nil]; + was_maximized = true; + } + Rect2i srect = screen_get_usable_rect(p_screen); Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); Size2i wsize = window_get_size(p_window); @@ -1893,6 +1899,10 @@ wpos = wpos.clamp(srect.position, srect.position + srect.size - wsize / 3); window_set_position(wpos, p_window); + if (was_maximized) { + [wd.window_object zoom:nil]; + } + if (was_fullscreen) { // Re-enter fullscreen mode. [wd.window_object toggleFullScreen:nil]; @@ -2332,7 +2342,7 @@ wd.wb_offset = p_offset / scale; wd.wb_offset = wd.wb_offset.maxi(12); if (wd.window_button_view) { - [wd.window_button_view setOffset:NSMakePoint(wd.wb_offset.x, wd.wb_offset.y)]; + [(GodotButtonView *)wd.window_button_view setOffset:NSMakePoint(wd.wb_offset.x, wd.wb_offset.y)]; } } @@ -2700,7 +2710,7 @@ gl_manager_legacy->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED); } #endif -#if defined(VULKAN_ENABLED) +#if defined(RD_ENABLED) if (rendering_context) { rendering_context->window_set_vsync_mode(p_window, p_vsync_mode); } @@ -2717,7 +2727,7 @@ return (gl_manager_legacy->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); } #endif -#if defined(VULKAN_ENABLED) +#if defined(RD_ENABLED) if (rendering_context) { return rendering_context->window_get_vsync_mode(p_window); } @@ -3590,6 +3600,34 @@ //TODO - do Vulkan and OpenGL support checks, driver selection and fallback rendering_driver = p_rendering_driver; +#if defined(RD_ENABLED) +#if defined(VULKAN_ENABLED) + if (rendering_driver == "vulkan") { + rendering_context = memnew(RenderingContextDriverVulkanMacOS); + } +#endif + + if (rendering_context) { + if (rendering_context->initialize() != OK) { + memdelete(rendering_context); + rendering_context = nullptr; +#if defined(GLES3_ENABLED) + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else +#endif + { + r_error = ERR_CANT_CREATE; + ERR_FAIL_MSG("Could not initialize " + rendering_driver); + } + } + } +#endif + #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3_angle") { gl_manager_angle = memnew(GLManagerANGLE_MacOS); @@ -3598,8 +3636,13 @@ gl_manager_angle = nullptr; bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native"); if (fallback) { - WARN_PRINT("Your video card drivers seem not to support the required Metal version, switching to native OpenGL."); +#ifdef EGL_STATIC + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE, switching to native OpenGL."); +#else + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dylib and libGLESv2.dylib) are missing, switching to native OpenGL."); +#endif rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Could not initialize ANGLE OpenGL."); @@ -3617,22 +3660,6 @@ } } #endif -#if defined(RD_ENABLED) -#if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - rendering_context = memnew(RenderingContextDriverVulkanMacOS); - } -#endif - - if (rendering_context) { - if (rendering_context->initialize() != OK) { - memdelete(rendering_context); - rendering_context = nullptr; - r_error = ERR_CANT_CREATE; - ERR_FAIL_MSG("Could not initialize " + rendering_driver); - } - } -#endif Point2i window_position; if (p_position != nullptr) { diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index ef5644c7d884..ec4d5538062b 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -304,8 +304,8 @@ class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogContr } // IFileDialogEvents methods - HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *) { return S_OK; }; - HRESULT STDMETHODCALLTYPE OnFolderChange(IFileDialog *) { return S_OK; }; + HRESULT STDMETHODCALLTYPE OnFileOk(IFileDialog *) { return S_OK; } + HRESULT STDMETHODCALLTYPE OnFolderChange(IFileDialog *) { return S_OK; } HRESULT STDMETHODCALLTYPE OnFolderChanging(IFileDialog *p_pfd, IShellItem *p_item) { if (root.is_empty()) { @@ -317,18 +317,18 @@ class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogContr if (!lpw_path) { return S_FALSE; } - String path = String::utf16((const char16_t *)lpw_path).simplify_path(); + String path = String::utf16((const char16_t *)lpw_path).replace("\\", "/").trim_prefix(R"(\\?\)").simplify_path(); if (!path.begins_with(root.simplify_path())) { return S_FALSE; } return S_OK; } - HRESULT STDMETHODCALLTYPE OnHelp(IFileDialog *) { return S_OK; }; - HRESULT STDMETHODCALLTYPE OnSelectionChange(IFileDialog *) { return S_OK; }; - HRESULT STDMETHODCALLTYPE OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; }; - HRESULT STDMETHODCALLTYPE OnTypeChange(IFileDialog *pfd) { return S_OK; }; - HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; }; + HRESULT STDMETHODCALLTYPE OnHelp(IFileDialog *) { return S_OK; } + HRESULT STDMETHODCALLTYPE OnSelectionChange(IFileDialog *) { return S_OK; } + HRESULT STDMETHODCALLTYPE OnShareViolation(IFileDialog *, IShellItem *, FDE_SHAREVIOLATION_RESPONSE *) { return S_OK; } + HRESULT STDMETHODCALLTYPE OnTypeChange(IFileDialog *pfd) { return S_OK; } + HRESULT STDMETHODCALLTYPE OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; } // IFileDialogControlEvents methods HRESULT STDMETHODCALLTYPE OnItemSelected(IFileDialogCustomize *p_pfdc, DWORD p_ctl_id, DWORD p_item_idx) { @@ -338,14 +338,14 @@ class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogContr return S_OK; } - HRESULT STDMETHODCALLTYPE OnButtonClicked(IFileDialogCustomize *, DWORD) { return S_OK; }; + HRESULT STDMETHODCALLTYPE OnButtonClicked(IFileDialogCustomize *, DWORD) { return S_OK; } HRESULT STDMETHODCALLTYPE OnCheckButtonToggled(IFileDialogCustomize *p_pfdc, DWORD p_ctl_id, BOOL p_checked) { if (ctls.has(p_ctl_id)) { selected[ctls[p_ctl_id]] = (bool)p_checked; } return S_OK; } - HRESULT STDMETHODCALLTYPE OnControlActivating(IFileDialogCustomize *, DWORD) { return S_OK; }; + HRESULT STDMETHODCALLTYPE OnControlActivating(IFileDialogCustomize *, DWORD) { return S_OK; } Dictionary get_selected() { return selected; @@ -381,7 +381,7 @@ class FileDialogEventHandler : public IFileDialogEvents, public IFileDialogContr ctls[cid] = p_name; } - virtual ~FileDialogEventHandler(){}; + virtual ~FileDialogEventHandler() {} }; #if defined(__GNUC__) && !defined(__clang__) @@ -491,7 +491,7 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) { } if (filter_names.is_empty()) { filter_exts.push_back(String("*.*").utf16()); - filter_names.push_back(RTR("All Files").utf16()); + filter_names.push_back((RTR("All Files") + " (*)").utf16()); } Vector filters; @@ -542,7 +542,26 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) { pfd->SetOptions(flags | FOS_FORCEFILESYSTEM); pfd->SetTitle((LPCWSTR)fd->title.utf16().ptr()); - String dir = fd->current_directory.replace("/", "\\"); + String dir = ProjectSettings::get_singleton()->globalize_path(fd->current_directory); + if (dir == ".") { + dir = OS::get_singleton()->get_executable_path().get_base_dir(); + } + if (dir.is_relative_path() || dir == ".") { + Char16String current_dir_name; + size_t str_len = GetCurrentDirectoryW(0, nullptr); + current_dir_name.resize(str_len + 1); + GetCurrentDirectoryW(current_dir_name.size(), (LPWSTR)current_dir_name.ptrw()); + if (dir == ".") { + dir = String::utf16((const char16_t *)current_dir_name.get_data()).trim_prefix(R"(\\?\)").replace("\\", "/"); + } else { + dir = String::utf16((const char16_t *)current_dir_name.get_data()).trim_prefix(R"(\\?\)").replace("\\", "/").path_join(dir); + } + } + dir = dir.simplify_path(); + dir = dir.replace("/", "\\"); + if (!dir.is_network_share_path() && !dir.begins_with(R"(\\?\)")) { + dir = R"(\\?\)" + dir; + } IShellItem *shellitem = nullptr; hr = SHCreateItemFromParsingName((LPCWSTR)dir.utf16().ptr(), nullptr, IID_IShellItem, (void **)&shellitem); @@ -585,7 +604,7 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) { PWSTR file_path = nullptr; hr = result->GetDisplayName(SIGDN_FILESYSPATH, &file_path); if (SUCCEEDED(hr)) { - file_names.push_back(String::utf16((const char16_t *)file_path)); + file_names.push_back(String::utf16((const char16_t *)file_path).replace("\\", "/").trim_prefix(R"(\\?\)")); CoTaskMemFree(file_path); } result->Release(); @@ -599,7 +618,7 @@ void DisplayServerWindows::_thread_fd_monitor(void *p_ud) { PWSTR file_path = nullptr; hr = result->GetDisplayName(SIGDN_FILESYSPATH, &file_path); if (SUCCEEDED(hr)) { - file_names.push_back(String::utf16((const char16_t *)file_path)); + file_names.push_back(String::utf16((const char16_t *)file_path).replace("\\", "/").trim_prefix(R"(\\?\)")); CoTaskMemFree(file_path); } result->Release(); @@ -703,7 +722,7 @@ Error DisplayServerWindows::_file_dialog_with_options_show(const String &p_title GetWindowRect(fd->hwnd_owner, &crect); fd->wrect = Rect2i(crect.left, crect.top, crect.right - crect.left, crect.bottom - crect.top); } else { - fd->hwnd_owner = 0; + fd->hwnd_owner = nullptr; fd->wrect = Rect2i(CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT); } fd->appid = appname; @@ -1501,6 +1520,7 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod rendering_device->screen_create(window_id); } #endif + wd.initialized = true; return window_id; } @@ -1794,6 +1814,13 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi Size2 size = screen_get_size(p_screen); MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); + } else if (wd.maximized) { + Point2 pos = screen_get_position(p_screen) + _get_screens_origin(); + Size2 size = screen_get_size(p_screen); + + ShowWindow(wd.hWnd, SW_RESTORE); + MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); + ShowWindow(wd.hWnd, SW_MAXIMIZE); } else { Rect2i srect = screen_get_usable_rect(p_screen); Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); @@ -2039,7 +2066,7 @@ Size2i DisplayServerWindows::window_get_size_with_decorations(WindowID p_window) return Size2(); } -void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex) { +void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_initialized, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_minimized, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex) { // Windows docs for window styles: // https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles // https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles @@ -2048,12 +2075,16 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre r_style_ex = WS_EX_WINDOWEDGE; if (p_main_window) { r_style_ex |= WS_EX_APPWINDOW; - r_style |= WS_VISIBLE; + if (p_initialized) { + r_style |= WS_VISIBLE; + } } if (p_fullscreen || p_borderless) { r_style |= WS_POPUP; // p_borderless was WS_EX_TOOLWINDOW in the past. - if (p_maximized) { + if (p_minimized) { + r_style |= WS_MINIMIZE; + } else if (p_maximized) { r_style |= WS_MAXIMIZE; } if (!p_fullscreen) { @@ -2068,13 +2099,19 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre } } else { if (p_resizable) { - if (p_maximized) { + if (p_minimized) { + r_style = WS_OVERLAPPEDWINDOW | WS_MINIMIZE; + } else if (p_maximized) { r_style = WS_OVERLAPPEDWINDOW | WS_MAXIMIZE; } else { r_style = WS_OVERLAPPEDWINDOW; } } else { - r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + if (p_minimized) { + r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MINIMIZE; + } else { + r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + } } } @@ -2082,7 +2119,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre r_style_ex |= WS_EX_TOPMOST | WS_EX_NOACTIVATE; } - if (!p_borderless && !p_no_activate_focus) { + if (!p_borderless && !p_no_activate_focus && p_initialized) { r_style |= WS_VISIBLE; } @@ -2099,7 +2136,7 @@ void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repain DWORD style = 0; DWORD style_ex = 0; - _get_window_style(p_window == MAIN_WINDOW_ID, wd.fullscreen, wd.multiwindow_fs, wd.borderless, wd.resizable, wd.maximized, wd.maximized_fs, wd.no_focus || wd.is_popup, style, style_ex); + _get_window_style(p_window == MAIN_WINDOW_ID, wd.initialized, wd.fullscreen, wd.multiwindow_fs, wd.borderless, wd.resizable, wd.minimized, wd.maximized, wd.maximized_fs, wd.no_focus || wd.is_popup, style, style_ex); SetWindowLongPtr(wd.hWnd, GWL_STYLE, style); SetWindowLongPtr(wd.hWnd, GWL_EXSTYLE, style_ex); @@ -4703,9 +4740,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA break; } - DisplayServer::WindowID receiving_window_id = _get_focused_window_or_popup(); - if (receiving_window_id == INVALID_WINDOW_ID) { - receiving_window_id = window_id; + DisplayServer::WindowID receiving_window_id = window_id; + if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED || mouse_mode == MOUSE_MODE_CONFINED_HIDDEN) { + receiving_window_id = _get_focused_window_or_popup(); + if (receiving_window_id == INVALID_WINDOW_ID) { + receiving_window_id = window_id; + } } const BitField &mods = _get_mods(); @@ -5375,7 +5415,7 @@ void DisplayServerWindows::_process_key_events() { k->set_physical_keycode(physical_keycode); k->set_key_label(key_label); k->set_unicode(fix_unicode(unicode)); - if (k->get_unicode() && ke.altgr) { + if (k->get_unicode() && ke.altgr && windows[ke.window_id].ime_active) { k->set_alt_pressed(false); k->set_ctrl_pressed(false); } @@ -5451,7 +5491,7 @@ void DisplayServerWindows::_process_key_events() { } k->set_unicode(fix_unicode(unicode)); } - if (k->get_unicode() && ke.altgr) { + if (k->get_unicode() && ke.altgr && windows[ke.window_id].ime_active) { k->set_alt_pressed(false); k->set_ctrl_pressed(false); } @@ -5510,7 +5550,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, DWORD dwExStyle; DWORD dwStyle; - _get_window_style(window_id_counter == MAIN_WINDOW_ID, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MAXIMIZED, false, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), dwStyle, dwExStyle); + _get_window_style(window_id_counter == MAIN_WINDOW_ID, false, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MINIMIZED, p_mode == WINDOW_MODE_MAXIMIZED, false, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), dwStyle, dwExStyle); RECT WindowRect; @@ -5779,6 +5819,8 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, return id; } +BitField DisplayServerWindows::tested_drivers = 0; + // WinTab API. bool DisplayServerWindows::wintab_available = false; WTOpenPtr DisplayServerWindows::wintab_WTOpen = nullptr; @@ -5935,6 +5977,8 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) { DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { KeyMappingWindows::initialize(); + tested_drivers.clear(); + drop_events = false; key_event_pos = 0; @@ -6103,7 +6147,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win wc.lpszClassName = L"Engine"; if (!RegisterClassExW(&wc)) { - MessageBoxW(nullptr, L"Failed To Register The Window Class.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); r_error = ERR_UNAVAILABLE; return; } @@ -6114,11 +6157,13 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { rendering_context = memnew(RenderingContextDriverVulkanWindows); + tested_drivers.set_flag(DRIVER_ID_RD_VULKAN); } #endif #if defined(D3D12_ENABLED) if (rendering_driver == "d3d12") { rendering_context = memnew(RenderingContextDriverD3D12); + tested_drivers.set_flag(DRIVER_ID_RD_D3D12); } #endif @@ -6130,9 +6175,11 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (failed && fallback_to_vulkan && rendering_driver != "vulkan") { memdelete(rendering_context); rendering_context = memnew(RenderingContextDriverVulkanWindows); + tested_drivers.set_flag(DRIVER_ID_RD_VULKAN); if (rendering_context->initialize() == OK) { WARN_PRINT("Your video card drivers seem not to support Direct3D 12, switching to Vulkan."); rendering_driver = "vulkan"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); failed = false; } } @@ -6142,12 +6189,27 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (failed && fallback_to_d3d12 && rendering_driver != "d3d12") { memdelete(rendering_context); rendering_context = memnew(RenderingContextDriverD3D12); + tested_drivers.set_flag(DRIVER_ID_RD_D3D12); if (rendering_context->initialize() == OK) { WARN_PRINT("Your video card drivers seem not to support Vulkan, switching to Direct3D 12."); rendering_driver = "d3d12"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); failed = false; } } +#endif +#if defined(GLES3_ENABLED) + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (failed && fallback_to_opengl3 && rendering_driver != "opengl3") { + memdelete(rendering_context); + rendering_context = nullptr; + tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); + WARN_PRINT("Your video card drivers seem not to support Direct3D 12 or Vulkan, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + failed = false; + } #endif if (failed) { memdelete(rendering_context); @@ -6187,10 +6249,12 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win #endif } + bool gl_supported = true; if (fallback && (rendering_driver == "opengl3")) { Dictionary gl_info = detect_wgl(); bool force_angle = false; + gl_supported = gl_info["version"].operator int() >= 30003; Vector2i device_id = _get_device_ids(gl_info["name"]); Array device_list = GLOBAL_GET("rendering/gl_compatibility/force_angle_on_devices"); @@ -6212,35 +6276,56 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } if (force_angle || (gl_info["version"].operator int() < 30003)) { + tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); if (show_warning) { - WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE."); + if (gl_info["version"].operator int() < 30003) { + WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE."); + } else { + WARN_PRINT("Your video card drivers are known to have low quality OpenGL 3.3 support, switching to ANGLE."); + } } rendering_driver = "opengl3_angle"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } } + if (rendering_driver == "opengl3_angle") { + gl_manager_angle = memnew(GLManagerANGLE_Windows); + tested_drivers.set_flag(DRIVER_ID_COMPAT_ANGLE_D3D11); + + if (gl_manager_angle->initialize() != OK) { + memdelete(gl_manager_angle); + gl_manager_angle = nullptr; + bool fallback_to_native = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native"); + if (fallback_to_native && gl_supported) { +#ifdef EGL_STATIC + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE, switching to native OpenGL."); +#else + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dll and libGLESv2.dll) are missing, switching to native OpenGL."); +#endif + rendering_driver = "opengl3"; + } else { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Could not initialize ANGLE OpenGL."); + } + } + } if (rendering_driver == "opengl3") { gl_manager_native = memnew(GLManagerNative_Windows); + tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); if (gl_manager_native->initialize() != OK) { memdelete(gl_manager_native); gl_manager_native = nullptr; r_error = ERR_UNAVAILABLE; - return; + ERR_FAIL_MSG("Could not initialize native OpenGL."); } + } + if (rendering_driver == "opengl3") { RasterizerGLES3::make_current(true); } if (rendering_driver == "opengl3_angle") { - gl_manager_angle = memnew(GLManagerANGLE_Windows); - - if (gl_manager_angle->initialize() != OK) { - memdelete(gl_manager_angle); - gl_manager_angle = nullptr; - r_error = ERR_UNAVAILABLE; - return; - } - RasterizerGLES3::make_current(false); } #endif @@ -6290,7 +6375,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution), false, INVALID_WINDOW_ID); - ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window."); + if (main_window == INVALID_WINDOW_ID) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Failed to create main window."); + } joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); @@ -6300,6 +6388,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } + windows[MAIN_WINDOW_ID].initialized = true; show_window(MAIN_WINDOW_ID); #if defined(RD_ENABLED) @@ -6366,32 +6455,41 @@ Vector DisplayServerWindows::get_rendering_drivers_func() { DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error)); if (r_error != OK) { - if (p_rendering_driver == "vulkan") { - String executable_name = OS::get_singleton()->get_executable_path().get_file(); - OS::get_singleton()->alert( - vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" - "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" - "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" - "If you have recently updated your video card drivers, try rebooting.", - executable_name), - "Unable to initialize Vulkan video driver"); - } else if (p_rendering_driver == "d3d12") { + if (tested_drivers == 0) { + OS::get_singleton()->alert("Failed to register the window class.", "Unable to initialize DisplayServer"); + } else if (tested_drivers.has_flag(DRIVER_ID_RD_VULKAN) || tested_drivers.has_flag(DRIVER_ID_RD_D3D12)) { + Vector drivers; + if (tested_drivers.has_flag(DRIVER_ID_RD_VULKAN)) { + drivers.push_back("Vulkan"); + } + if (tested_drivers.has_flag(DRIVER_ID_RD_D3D12)) { + drivers.push_back("Direct3D 12"); + } String executable_name = OS::get_singleton()->get_executable_path().get_file(); OS::get_singleton()->alert( - vformat("Your video card drivers seem not to support the required DirectX 12 version.\n\n" + vformat("Your video card drivers seem not to support the required %s version.\n\n" "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" "You can enable the OpenGL 3 driver by starting the engine from the\n" "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" "If you have recently updated your video card drivers, try rebooting.", + String(" or ").join(drivers), executable_name), - "Unable to initialize DirectX 12 video driver"); + "Unable to initialize video driver"); } else { + Vector drivers; + if (tested_drivers.has_flag(DRIVER_ID_COMPAT_OPENGL3)) { + drivers.push_back("OpenGL 3.3"); + } + if (tested_drivers.has_flag(DRIVER_ID_COMPAT_ANGLE_D3D11)) { + drivers.push_back("Direct3D 11"); + } OS::get_singleton()->alert( - "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" - "If possible, consider updating your video card drivers.\n\n" - "If you have recently updated your video card drivers, try rebooting.", - "Unable to initialize OpenGL video driver"); + vformat( + "Your video card drivers seem not to support the required %s version.\n\n" + "If possible, consider updating your video card drivers.\n\n" + "If you have recently updated your video card drivers, try rebooting.", + String(" or ").join(drivers)), + "Unable to initialize video driver"); } } return ds; diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 03132bb0dbc9..653a7e6959fa 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -39,7 +39,6 @@ #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/os/os.h" -#include "drivers/unix/ip_unix.h" #include "drivers/wasapi/audio_driver_wasapi.h" #include "drivers/winmidi/midi_driver_winmidi.h" #include "servers/audio_server.h" @@ -394,6 +393,14 @@ class DisplayServerWindows : public DisplayServer { String tablet_driver; Vector tablet_drivers; + enum DriverID { + DRIVER_ID_COMPAT_OPENGL3 = 1 << 0, + DRIVER_ID_COMPAT_ANGLE_D3D11 = 1 << 1, + DRIVER_ID_RD_VULKAN = 1 << 2, + DRIVER_ID_RD_D3D12 = 1 << 3, + }; + static BitField tested_drivers; + enum TimerID { TIMER_ID_MOVE_REDRAW = 1, TIMER_ID_WINDOW_ACTIVATION = 2, @@ -516,6 +523,8 @@ class DisplayServerWindows : public DisplayServer { bool is_popup = false; Rect2i parent_safe_rect; + + bool initialized = false; }; JoypadWindows *joypad = nullptr; @@ -583,7 +592,7 @@ class DisplayServerWindows : public DisplayServer { HashMap pointer_last_pos; void _send_window_event(const WindowData &wd, WindowEvent p_event); - void _get_window_style(bool p_main_window, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex); + void _get_window_style(bool p_main_window, bool p_initialized, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_minimized, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex); MouseMode mouse_mode; int restore_mouse_trails = 0; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 54510576459b..34aaf4f557ef 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -34,6 +34,14 @@ #include "scene/resources/texture.h" #include "servers/display_server_headless.h" +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_context_driver_vulkan.h" +#undef CursorShape +#endif +#if defined(D3D12_ENABLED) +#include "drivers/d3d12/rendering_context_driver_d3d12.h" +#endif + DisplayServer *DisplayServer::singleton = nullptr; bool DisplayServer::hidpi_allowed = false; diff --git a/servers/display_server.h b/servers/display_server.h index d0fe76faff37..a4c9b50e3fca 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -367,6 +367,7 @@ class DisplayServer : public Object { INVALID_INDICATOR_ID = -1 }; +public: typedef int WindowID; typedef int IndicatorID;