summaryrefslogtreecommitdiffstats
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/display_server_android.cpp2
-rw-r--r--platform/android/platform_gl.h43
-rw-r--r--platform/ios/display_server_ios.mm2
-rw-r--r--platform/ios/platform_config.h2
-rw-r--r--platform/ios/platform_gl.h40
-rw-r--r--platform/linuxbsd/platform_config.h2
-rw-r--r--platform/linuxbsd/platform_gl.h41
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp2
-rw-r--r--platform/linuxbsd/x11/gl_manager_x11.cpp1
-rw-r--r--platform/macos/SCsub1
-rw-r--r--platform/macos/detect.py9
-rw-r--r--platform/macos/display_server_macos.h5
-rw-r--r--platform/macos/display_server_macos.mm116
-rw-r--r--platform/macos/doc_classes/EditorExportPlatformMacOS.xml3
-rw-r--r--platform/macos/export/export_plugin.cpp23
-rw-r--r--platform/macos/gl_manager_macos_angle.h63
-rw-r--r--platform/macos/gl_manager_macos_angle.mm70
-rw-r--r--platform/macos/gl_manager_macos_legacy.h25
-rw-r--r--platform/macos/gl_manager_macos_legacy.mm73
-rw-r--r--platform/macos/godot_content_view.mm6
-rw-r--r--platform/macos/platform_config.h1
-rw-r--r--platform/macos/platform_gl.h52
-rw-r--r--platform/web/display_server_web.cpp2
-rw-r--r--platform/web/platform_config.h2
-rw-r--r--platform/web/platform_gl.h40
-rw-r--r--platform/windows/SCsub4
-rw-r--r--platform/windows/detect.py25
-rw-r--r--platform/windows/display_server_windows.cpp116
-rw-r--r--platform/windows/display_server_windows.h8
-rw-r--r--platform/windows/doc_classes/EditorExportPlatformWindows.xml3
-rw-r--r--platform/windows/export/export_plugin.cpp32
-rw-r--r--platform/windows/gl_manager_windows_angle.cpp70
-rw-r--r--platform/windows/gl_manager_windows_angle.h61
-rw-r--r--platform/windows/gl_manager_windows_native.cpp (renamed from platform/windows/gl_manager_windows.cpp)112
-rw-r--r--platform/windows/gl_manager_windows_native.h (renamed from platform/windows/gl_manager_windows.h)28
-rw-r--r--platform/windows/platform_config.h2
-rw-r--r--platform/windows/platform_gl.h53
-rw-r--r--platform/windows/wgl_detect_version.cpp189
-rw-r--r--platform/windows/wgl_detect_version.h40
39 files changed, 1132 insertions, 237 deletions
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index f02b292868..3904d3afc4 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -543,7 +543,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- RasterizerGLES3::make_current();
+ RasterizerGLES3::make_current(false);
}
#endif
diff --git a/platform/android/platform_gl.h b/platform/android/platform_gl.h
new file mode 100644
index 0000000000..af6edb103d
--- /dev/null
+++ b/platform/android/platform_gl.h
@@ -0,0 +1,43 @@
+/**************************************************************************/
+/* platform_gl.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PLATFORM_GL_H
+#define PLATFORM_GL_H
+
+#ifndef GLES_API_ENABLED
+#define GLES_API_ENABLED // Allow using GLES.
+#endif
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES3/gl3.h>
+#include <GLES3/gl3ext.h>
+
+#endif // PLATFORM_GL_H
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index 7d91274a0c..33eb16279f 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -103,7 +103,7 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
ERR_FAIL_MSG("Failed to create iOS OpenGLES rendering layer.");
}
- RasterizerGLES3::make_current();
+ RasterizerGLES3::make_current(false);
}
#endif
diff --git a/platform/ios/platform_config.h b/platform/ios/platform_config.h
index fc0e165d6b..01b0a12b5d 100644
--- a/platform/ios/platform_config.h
+++ b/platform/ios/platform_config.h
@@ -30,8 +30,6 @@
#include <alloca.h>
-#define OPENGL_INCLUDE_H <ES3/gl.h>
-
#define PTHREAD_RENAME_SELF
#define _weakify(var) __weak typeof(var) GDWeak_##var = var;
diff --git a/platform/ios/platform_gl.h b/platform/ios/platform_gl.h
new file mode 100644
index 0000000000..974ea9d2c2
--- /dev/null
+++ b/platform/ios/platform_gl.h
@@ -0,0 +1,40 @@
+/**************************************************************************/
+/* platform_gl.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PLATFORM_GL_H
+#define PLATFORM_GL_H
+
+#ifndef GLES_API_ENABLED
+#define GLES_API_ENABLED // Allow using GLES.
+#endif
+
+#include <ES3/gl.h>
+
+#endif // PLATFORM_GL_H
diff --git a/platform/linuxbsd/platform_config.h b/platform/linuxbsd/platform_config.h
index 82c9c54879..c372ef28f6 100644
--- a/platform/linuxbsd/platform_config.h
+++ b/platform/linuxbsd/platform_config.h
@@ -43,5 +43,3 @@
#define PTHREAD_BSD_SET_NAME
#endif
#endif
-
-#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h"
diff --git a/platform/linuxbsd/platform_gl.h b/platform/linuxbsd/platform_gl.h
new file mode 100644
index 0000000000..1c19c4518a
--- /dev/null
+++ b/platform/linuxbsd/platform_gl.h
@@ -0,0 +1,41 @@
+/**************************************************************************/
+/* platform_gl.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PLATFORM_GL_H
+#define PLATFORM_GL_H
+
+#ifndef GL_API_ENABLED
+#define GL_API_ENABLED // Allow using desktop GL.
+#endif
+
+#include "thirdparty/glad/glad/egl.h"
+#include "thirdparty/glad/glad/gl.h"
+
+#endif // PLATFORM_GL_H
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index d20a591299..897a6438d2 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -5821,7 +5821,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
driver_found = true;
if (true) {
- RasterizerGLES3::make_current();
+ RasterizerGLES3::make_current(true);
} else {
memdelete(gl_manager);
gl_manager = nullptr;
diff --git a/platform/linuxbsd/x11/gl_manager_x11.cpp b/platform/linuxbsd/x11/gl_manager_x11.cpp
index 13b5dedb1e..25c4272607 100644
--- a/platform/linuxbsd/x11/gl_manager_x11.cpp
+++ b/platform/linuxbsd/x11/gl_manager_x11.cpp
@@ -368,6 +368,7 @@ void GLManager_X11::set_use_vsync(bool p_use) {
GLXDrawable drawable = glXGetCurrentDrawable();
glXSwapIntervalEXT(disp.x11_display, drawable, val);
} else {
+ WARN_PRINT("Could not set V-Sync mode. V-Sync is not supported.");
return;
}
use_vsync = p_use;
diff --git a/platform/macos/SCsub b/platform/macos/SCsub
index 7ffb80f70b..30202e5de7 100644
--- a/platform/macos/SCsub
+++ b/platform/macos/SCsub
@@ -24,6 +24,7 @@ files = [
"tts_macos.mm",
"joypad_macos.cpp",
"vulkan_context_macos.mm",
+ "gl_manager_macos_angle.mm",
"gl_manager_macos_legacy.mm",
]
diff --git a/platform/macos/detect.py b/platform/macos/detect.py
index 6abe121407..c97cd19211 100644
--- a/platform/macos/detect.py
+++ b/platform/macos/detect.py
@@ -32,6 +32,7 @@ def get_opts():
BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN)", False),
BoolVariable("use_tsan", "Use LLVM/GCC compiler thread sanitizer (TSAN)", False),
BoolVariable("use_coverage", "Use instrumentation codes in the binary (e.g. for code coverage)", False),
+ ("angle_libs", "Path to the ANGLE static libraries", ""),
]
@@ -255,7 +256,13 @@ def configure(env: "Environment"):
if env["opengl3"]:
env.Append(CPPDEFINES=["GLES3_ENABLED"])
- env.Append(LINKFLAGS=["-framework", "OpenGL"])
+ if env["angle_libs"] != "":
+ env.AppendUnique(CPPDEFINES=["EGL_STATIC"])
+ env.Append(LINKFLAGS=["-L" + env["angle_libs"]])
+ env.Append(LINKFLAGS=["-lANGLE.macos." + env["arch"]])
+ env.Append(LINKFLAGS=["-lEGL.macos." + env["arch"]])
+ env.Append(LINKFLAGS=["-lGLES.macos." + env["arch"]])
+ env.Prepend(CPPPATH=["#thirdparty/angle/include"])
env.Append(LINKFLAGS=["-rpath", "@executable_path/../Frameworks", "-rpath", "@executable_path"])
diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h
index 69f6008043..c03b4765f8 100644
--- a/platform/macos/display_server_macos.h
+++ b/platform/macos/display_server_macos.h
@@ -35,6 +35,7 @@
#include "servers/display_server.h"
#if defined(GLES3_ENABLED)
+#include "gl_manager_macos_angle.h"
#include "gl_manager_macos_legacy.h"
#endif // GLES3_ENABLED
@@ -127,7 +128,8 @@ public:
private:
#if defined(GLES3_ENABLED)
- GLManager_MacOS *gl_manager = nullptr;
+ GLManagerLegacy_MacOS *gl_manager_legacy = nullptr;
+ GLManagerANGLE_MacOS *gl_manager_angle = nullptr;
#endif
#if defined(VULKAN_ENABLED)
VulkanContextMacOS *context_vulkan = nullptr;
@@ -244,7 +246,6 @@ public:
void mouse_enter_window(WindowID p_window);
void mouse_exit_window(WindowID p_window);
- void window_update(WindowID p_window);
void window_destroy(WindowID p_window);
void window_resize(WindowID p_window, int p_width, int p_height);
void window_set_custom_window_buttons(WindowData &p_wd, bool p_enabled);
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index bc78f343ee..1742ef05e7 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -185,9 +185,13 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
}
#endif
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
- ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context");
+ if (gl_manager_legacy) {
+ Error err = gl_manager_legacy->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height);
+ ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context.");
+ }
+ if (gl_manager_angle) {
+ Error err = gl_manager_angle->window_create(window_id_counter, nullptr, (__bridge void *)[wd.window_view layer], p_rect.size.width, p_rect.size.height);
+ ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context.");
}
window_set_vsync_mode(p_vsync_mode, window_id_counter);
#endif
@@ -219,8 +223,11 @@ DisplayServerMacOS::WindowID DisplayServerMacOS::_create_window(WindowMode p_mod
}
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_resize(id, wd.size.width, wd.size.height);
+ if (gl_manager_legacy) {
+ gl_manager_legacy->window_resize(id, wd.size.width, wd.size.height);
+ }
+ if (gl_manager_angle) {
+ gl_manager_angle->window_resize(id, wd.size.width, wd.size.height);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -279,8 +286,8 @@ void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabl
[layer setOpaque:NO];
}
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_set_per_pixel_transparency_enabled(p_window, true);
+ if (gl_manager_legacy) {
+ gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, true);
}
#endif
wd.layered_window = true;
@@ -299,8 +306,8 @@ void DisplayServerMacOS::_set_window_per_pixel_transparency_enabled(bool p_enabl
[layer setOpaque:YES];
}
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_set_per_pixel_transparency_enabled(p_window, false);
+ if (gl_manager_legacy) {
+ gl_manager_legacy->window_set_per_pixel_transparency_enabled(p_window, false);
}
#endif
wd.layered_window = false;
@@ -730,18 +737,10 @@ bool DisplayServerMacOS::get_is_resizing() const {
return is_resizing;
}
-void DisplayServerMacOS::window_update(WindowID p_window) {
-#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_update(p_window);
- }
-#endif
-}
-
void DisplayServerMacOS::window_destroy(WindowID p_window) {
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_destroy(p_window);
+ if (gl_manager_legacy) {
+ gl_manager_legacy->window_destroy(p_window);
}
#endif
#ifdef VULKAN_ENABLED
@@ -754,8 +753,11 @@ void DisplayServerMacOS::window_destroy(WindowID p_window) {
void DisplayServerMacOS::window_resize(WindowID p_window, int p_width, int p_height) {
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_resize(p_window, p_width, p_height);
+ if (gl_manager_legacy) {
+ gl_manager_legacy->window_resize(p_window, p_width, p_height);
+ }
+ if (gl_manager_angle) {
+ gl_manager_angle->window_resize(p_window, p_width, p_height);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3370,8 +3372,11 @@ int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, W
}
#ifdef GLES3_ENABLED
case OPENGL_CONTEXT: {
- if (gl_manager) {
- return (int64_t)gl_manager->get_context(p_window);
+ if (gl_manager_legacy) {
+ return (int64_t)gl_manager_legacy->get_context(p_window);
+ }
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_context(p_window);
}
return 0;
}
@@ -3398,8 +3403,11 @@ ObjectID DisplayServerMacOS::window_get_attached_instance_id(WindowID p_window)
void DisplayServerMacOS::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_make_current(p_window_id);
+ if (gl_manager_legacy) {
+ gl_manager_legacy->window_make_current(p_window_id);
+ }
+ if (gl_manager_angle) {
+ gl_manager_angle->window_make_current(p_window_id);
}
#endif
}
@@ -3407,8 +3415,11 @@ void DisplayServerMacOS::gl_window_make_current(DisplayServer::WindowID p_window
void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
+ if (gl_manager_angle) {
+ gl_manager_angle->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
+ }
+ if (gl_manager_legacy) {
+ gl_manager_legacy->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3421,8 +3432,11 @@ void DisplayServerMacOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_
DisplayServer::VSyncMode DisplayServerMacOS::window_get_vsync_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
+ if (gl_manager_angle) {
+ return (gl_manager_angle->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
+ }
+ if (gl_manager_legacy) {
+ return (gl_manager_legacy->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -3805,8 +3819,11 @@ void DisplayServerMacOS::make_rendering_thread() {
void DisplayServerMacOS::swap_buffers() {
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->swap_buffers();
+ if (gl_manager_angle) {
+ gl_manager_angle->swap_buffers();
+ }
+ if (gl_manager_legacy) {
+ gl_manager_legacy->swap_buffers();
}
#endif
}
@@ -3917,6 +3934,7 @@ Vector<String> DisplayServerMacOS::get_rendering_drivers_func() {
#endif
#if defined(GLES3_ENABLED)
drivers.push_back("opengl3");
+ drivers.push_back("opengl3_angle");
#endif
return drivers;
@@ -4155,13 +4173,22 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- GLManager_MacOS::ContextType opengl_api_type = GLManager_MacOS::GLES_3_0_COMPATIBLE;
- gl_manager = memnew(GLManager_MacOS(opengl_api_type));
- if (gl_manager->initialize() != OK) {
- memdelete(gl_manager);
- gl_manager = nullptr;
+ gl_manager_legacy = memnew(GLManagerLegacy_MacOS);
+ if (gl_manager_legacy->initialize() != OK) {
+ memdelete(gl_manager_legacy);
+ gl_manager_legacy = nullptr;
r_error = ERR_UNAVAILABLE;
- ERR_FAIL_MSG("Could not initialize OpenGL");
+ ERR_FAIL_MSG("Could not initialize OpenGL.");
+ return;
+ }
+ }
+ if (rendering_driver == "opengl3_angle") {
+ gl_manager_angle = memnew(GLManagerANGLE_MacOS);
+ if (gl_manager_angle->initialize() != OK) {
+ memdelete(gl_manager_angle);
+ gl_manager_angle = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ ERR_FAIL_MSG("Could not initialize OpenGL.");
}
}
#endif
@@ -4199,7 +4226,10 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- RasterizerGLES3::make_current();
+ RasterizerGLES3::make_current(true);
+ }
+ if (rendering_driver == "opengl3_angle") {
+ RasterizerGLES3::make_current(false);
}
#endif
#if defined(VULKAN_ENABLED)
@@ -4230,9 +4260,13 @@ DisplayServerMacOS::~DisplayServerMacOS() {
// Destroy drivers.
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- memdelete(gl_manager);
- gl_manager = nullptr;
+ if (gl_manager_legacy) {
+ memdelete(gl_manager_legacy);
+ gl_manager_legacy = nullptr;
+ }
+ if (gl_manager_angle) {
+ memdelete(gl_manager_angle);
+ gl_manager_angle = nullptr;
}
#endif
#if defined(VULKAN_ENABLED)
diff --git a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml
index 7ba1379fd0..99187fe60e 100644
--- a/platform/macos/doc_classes/EditorExportPlatformMacOS.xml
+++ b/platform/macos/doc_classes/EditorExportPlatformMacOS.xml
@@ -22,6 +22,9 @@
<member name="application/copyright_localized" type="Dictionary" setter="" getter="">
Copyright notice for the bundle visible to the user (localized).
</member>
+ <member name="application/export_angle" type="int" setter="" getter="">
+ If set to [code]1[/code], ANGLE libraries are exported with the exported application. If set to [code]0[/code], ANGLE libraries are exported only if [member ProjectSettings.rendering/gl_compatibility/driver] is set to [code]"opengl3_angle"[/code].
+ </member>
<member name="application/icon" type="String" setter="" getter="">
Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/macos_native_icon], and then to [member ProjectSettings.application/config/icon].
</member>
diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp
index 559c2c4e62..639a7699ee 100644
--- a/platform/macos/export/export_plugin.cpp
+++ b/platform/macos/export/export_plugin.cpp
@@ -384,6 +384,7 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::DICTIONARY, "application/copyright_localized", PROPERTY_HINT_LOCALIZABLE_STRING), Dictionary()));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_macos_version"), "10.12"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_angle", PROPERTY_HINT_ENUM, "Auto,Yes,No"), 0, true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/platform_build"), "14C18"));
@@ -1618,6 +1619,14 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
// Now process our template.
bool found_binary = false;
+ int export_angle = p_preset->get("application/export_angle");
+ bool include_angle_libs = false;
+ if (export_angle == 0) {
+ include_angle_libs = String(GLOBAL_GET("rendering/gl_compatibility/driver.macos")) == "opengl3_angle";
+ } else if (export_angle == 1) {
+ include_angle_libs = true;
+ }
+
while (ret == UNZ_OK && err == OK) {
// Get filename.
unz_file_info info;
@@ -1665,6 +1674,20 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p
continue; // next
}
+ if (file == "Contents/Frameworks/libEGL.dylib") {
+ if (!include_angle_libs) {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; // skip
+ }
+ }
+
+ if (file == "Contents/Frameworks/libGLESv2.dylib") {
+ if (!include_angle_libs) {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; // skip
+ }
+ }
+
if (file == "Contents/Info.plist") {
_fix_plist(p_preset, data, pkg_name);
}
diff --git a/platform/macos/gl_manager_macos_angle.h b/platform/macos/gl_manager_macos_angle.h
new file mode 100644
index 0000000000..919b8ec9c8
--- /dev/null
+++ b/platform/macos/gl_manager_macos_angle.h
@@ -0,0 +1,63 @@
+/**************************************************************************/
+/* gl_manager_macos_angle.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef GL_MANAGER_MACOS_ANGLE_H
+#define GL_MANAGER_MACOS_ANGLE_H
+
+#if defined(MACOS_ENABLED) && defined(GLES3_ENABLED)
+
+#include "core/error/error_list.h"
+#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "drivers/egl/egl_manager.h"
+#include "servers/display_server.h"
+
+#include <AppKit/AppKit.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <CoreVideo/CoreVideo.h>
+
+class GLManagerANGLE_MacOS : public EGLManager {
+private:
+ virtual const char *_get_platform_extension_name() const override;
+ virtual EGLenum _get_platform_extension_enum() const override;
+ virtual EGLenum _get_platform_api_enum() const override;
+ virtual Vector<EGLAttrib> _get_platform_display_attributes() const override;
+ virtual Vector<EGLint> _get_platform_context_attribs() const override;
+
+public:
+ void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {}
+
+ GLManagerANGLE_MacOS() {}
+ ~GLManagerANGLE_MacOS() {}
+};
+
+#endif // MACOS_ENABLED && GLES3_ENABLED
+
+#endif // GL_MANAGER_MACOS_ANGLE_H
diff --git a/platform/macos/gl_manager_macos_angle.mm b/platform/macos/gl_manager_macos_angle.mm
new file mode 100644
index 0000000000..ec0ca3e1f3
--- /dev/null
+++ b/platform/macos/gl_manager_macos_angle.mm
@@ -0,0 +1,70 @@
+/**************************************************************************/
+/* gl_manager_macos_angle.mm */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "gl_manager_macos_angle.h"
+
+#if defined(MACOS_ENABLED) && defined(GLES3_ENABLED)
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <EGL/eglext_angle.h>
+
+const char *GLManagerANGLE_MacOS::_get_platform_extension_name() const {
+ return "EGL_ANGLE_platform_angle";
+}
+
+EGLenum GLManagerANGLE_MacOS::_get_platform_extension_enum() const {
+ return EGL_PLATFORM_ANGLE_ANGLE;
+}
+
+Vector<EGLAttrib> GLManagerANGLE_MacOS::_get_platform_display_attributes() const {
+ Vector<EGLAttrib> ret;
+ ret.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ ret.push_back(EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE);
+ ret.push_back(EGL_NONE);
+
+ return ret;
+}
+
+EGLenum GLManagerANGLE_MacOS::_get_platform_api_enum() const {
+ return EGL_OPENGL_ES_API;
+}
+
+Vector<EGLint> GLManagerANGLE_MacOS::_get_platform_context_attribs() const {
+ Vector<EGLint> ret;
+ ret.push_back(EGL_CONTEXT_CLIENT_VERSION);
+ ret.push_back(3);
+ ret.push_back(EGL_NONE);
+
+ return ret;
+}
+
+#endif // MACOS_ENABLED && GLES3_ENABLED
diff --git a/platform/macos/gl_manager_macos_legacy.h b/platform/macos/gl_manager_macos_legacy.h
index 94d966f4ed..bafe825efb 100644
--- a/platform/macos/gl_manager_macos_legacy.h
+++ b/platform/macos/gl_manager_macos_legacy.h
@@ -45,17 +45,12 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14
-class GLManager_MacOS {
-public:
- enum ContextType {
- GLES_3_0_COMPATIBLE,
- };
+typedef CGLError (*CGLEnablePtr)(CGLContextObj ctx, CGLContextEnable pname);
+typedef CGLError (*CGLSetParameterPtr)(CGLContextObj ctx, CGLContextParameter pname, const GLint *params);
+typedef CGLContextObj (*CGLGetCurrentContextPtr)(void);
-private:
+class GLManagerLegacy_MacOS {
struct GLWindow {
- int width = 0;
- int height = 0;
-
id window_view = nullptr;
NSOpenGLContext *context = nullptr;
};
@@ -68,23 +63,21 @@ private:
Error create_context(GLWindow &win);
bool use_vsync = false;
- ContextType context_type;
+ CGLEnablePtr CGLEnable = nullptr;
+ CGLSetParameterPtr CGLSetParameter = nullptr;
+ CGLGetCurrentContextPtr CGLGetCurrentContext = nullptr;
public:
Error window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height);
void window_destroy(DisplayServer::WindowID p_window_id);
void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
- int window_get_width(DisplayServer::WindowID p_window_id = 0);
- int window_get_height(DisplayServer::WindowID p_window_id = 0);
-
void release_current();
void make_current();
void swap_buffers();
void window_make_current(DisplayServer::WindowID p_window_id);
- void window_update(DisplayServer::WindowID p_window_id);
void window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled);
Error initialize();
@@ -94,8 +87,8 @@ public:
NSOpenGLContext *get_context(DisplayServer::WindowID p_window_id);
- GLManager_MacOS(ContextType p_context_type);
- ~GLManager_MacOS();
+ GLManagerLegacy_MacOS();
+ ~GLManagerLegacy_MacOS();
};
#pragma clang diagnostic push
diff --git a/platform/macos/gl_manager_macos_legacy.mm b/platform/macos/gl_manager_macos_legacy.mm
index 550e2d5c59..3e5a96bffd 100644
--- a/platform/macos/gl_manager_macos_legacy.mm
+++ b/platform/macos/gl_manager_macos_legacy.mm
@@ -38,7 +38,7 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations" // OpenGL is deprecated in macOS 10.14
-Error GLManager_MacOS::create_context(GLWindow &win) {
+Error GLManagerLegacy_MacOS::create_context(GLWindow &win) {
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAClosestPolicy,
@@ -64,10 +64,8 @@ Error GLManager_MacOS::create_context(GLWindow &win) {
return OK;
}
-Error GLManager_MacOS::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
+Error GLManagerLegacy_MacOS::window_create(DisplayServer::WindowID p_window_id, id p_view, int p_width, int p_height) {
GLWindow win;
- win.width = p_width;
- win.height = p_height;
win.window_view = p_view;
if (create_context(win) != OK) {
@@ -80,16 +78,13 @@ Error GLManager_MacOS::window_create(DisplayServer::WindowID p_window_id, id p_v
return OK;
}
-void GLManager_MacOS::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
+void GLManagerLegacy_MacOS::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
if (!windows.has(p_window_id)) {
return;
}
GLWindow &win = windows[p_window_id];
- win.width = p_width;
- win.height = p_height;
-
GLint dim[2];
dim[0] = p_width;
dim[1] = p_height;
@@ -104,25 +99,7 @@ void GLManager_MacOS::window_resize(DisplayServer::WindowID p_window_id, int p_w
[win.context update];
}
-int GLManager_MacOS::window_get_width(DisplayServer::WindowID p_window_id) {
- if (!windows.has(p_window_id)) {
- return 0;
- }
-
- GLWindow &win = windows[p_window_id];
- return win.width;
-}
-
-int GLManager_MacOS::window_get_height(DisplayServer::WindowID p_window_id) {
- if (!windows.has(p_window_id)) {
- return 0;
- }
-
- GLWindow &win = windows[p_window_id];
- return win.height;
-}
-
-void GLManager_MacOS::window_destroy(DisplayServer::WindowID p_window_id) {
+void GLManagerLegacy_MacOS::window_destroy(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return;
}
@@ -134,7 +111,7 @@ void GLManager_MacOS::window_destroy(DisplayServer::WindowID p_window_id) {
windows.erase(p_window_id);
}
-void GLManager_MacOS::release_current() {
+void GLManagerLegacy_MacOS::release_current() {
if (current_window == DisplayServer::INVALID_WINDOW_ID) {
return;
}
@@ -142,7 +119,7 @@ void GLManager_MacOS::release_current() {
[NSOpenGLContext clearCurrentContext];
}
-void GLManager_MacOS::window_make_current(DisplayServer::WindowID p_window_id) {
+void GLManagerLegacy_MacOS::window_make_current(DisplayServer::WindowID p_window_id) {
if (current_window == p_window_id) {
return;
}
@@ -156,7 +133,7 @@ void GLManager_MacOS::window_make_current(DisplayServer::WindowID p_window_id) {
current_window = p_window_id;
}
-void GLManager_MacOS::make_current() {
+void GLManagerLegacy_MacOS::make_current() {
if (current_window == DisplayServer::INVALID_WINDOW_ID) {
return;
}
@@ -168,21 +145,12 @@ void GLManager_MacOS::make_current() {
[win.context makeCurrentContext];
}
-void GLManager_MacOS::swap_buffers() {
+void GLManagerLegacy_MacOS::swap_buffers() {
GLWindow &win = windows[current_window];
[win.context flushBuffer];
}
-void GLManager_MacOS::window_update(DisplayServer::WindowID p_window_id) {
- if (!windows.has(p_window_id)) {
- return;
- }
-
- GLWindow &win = windows[p_window_id];
- [win.context update];
-}
-
-void GLManager_MacOS::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) {
+void GLManagerLegacy_MacOS::window_set_per_pixel_transparency_enabled(DisplayServer::WindowID p_window_id, bool p_enabled) {
if (!windows.has(p_window_id)) {
return;
}
@@ -198,26 +166,28 @@ void GLManager_MacOS::window_set_per_pixel_transparency_enabled(DisplayServer::W
[win.context update];
}
-Error GLManager_MacOS::initialize() {
+Error GLManagerLegacy_MacOS::initialize() {
return OK;
}
-void GLManager_MacOS::set_use_vsync(bool p_use) {
+void GLManagerLegacy_MacOS::set_use_vsync(bool p_use) {
use_vsync = p_use;
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_use ? 1 : 0;
- CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval);
+ if (CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval) != kCGLNoError) {
+ WARN_PRINT("Could not set V-Sync mode.");
+ }
use_vsync = p_use;
}
}
-bool GLManager_MacOS::is_using_vsync() const {
+bool GLManagerLegacy_MacOS::is_using_vsync() const {
return use_vsync;
}
-NSOpenGLContext *GLManager_MacOS::get_context(DisplayServer::WindowID p_window_id) {
+NSOpenGLContext *GLManagerLegacy_MacOS::get_context(DisplayServer::WindowID p_window_id) {
if (!windows.has(p_window_id)) {
return nullptr;
}
@@ -226,11 +196,16 @@ NSOpenGLContext *GLManager_MacOS::get_context(DisplayServer::WindowID p_window_i
return win.context;
}
-GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) {
- context_type = p_context_type;
+GLManagerLegacy_MacOS::GLManagerLegacy_MacOS() {
+ CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
+ CFBundleLoadExecutable(framework);
+
+ CGLEnable = (CGLEnablePtr)CFBundleGetFunctionPointerForName(framework, CFSTR("CGLEnable"));
+ CGLSetParameter = (CGLSetParameterPtr)CFBundleGetFunctionPointerForName(framework, CFSTR("CGLSetParameter"));
+ CGLGetCurrentContext = (CGLGetCurrentContextPtr)CFBundleGetFunctionPointerForName(framework, CFSTR("CGLGetCurrentContext"));
}
-GLManager_MacOS::~GLManager_MacOS() {
+GLManagerLegacy_MacOS::~GLManagerLegacy_MacOS() {
release_current();
}
diff --git a/platform/macos/godot_content_view.mm b/platform/macos/godot_content_view.mm
index 8b6e1cdb79..22a9aa14c0 100644
--- a/platform/macos/godot_content_view.mm
+++ b/platform/macos/godot_content_view.mm
@@ -139,12 +139,6 @@
return [[CAMetalLayer class] layer];
}
-- (void)updateLayer {
- DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton();
- ds->window_update(window_id);
- [super updateLayer];
-}
-
- (BOOL)wantsUpdateLayer {
return YES;
}
diff --git a/platform/macos/platform_config.h b/platform/macos/platform_config.h
index 65a898dcc1..1a571b689a 100644
--- a/platform/macos/platform_config.h
+++ b/platform/macos/platform_config.h
@@ -30,5 +30,4 @@
#include <alloca.h>
-#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h"
#define PTHREAD_RENAME_SELF
diff --git a/platform/macos/platform_gl.h b/platform/macos/platform_gl.h
new file mode 100644
index 0000000000..3bad9d5a5f
--- /dev/null
+++ b/platform/macos/platform_gl.h
@@ -0,0 +1,52 @@
+/**************************************************************************/
+/* platform_gl.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PLATFORM_GL_H
+#define PLATFORM_GL_H
+
+#ifndef GL_API_ENABLED
+#define GL_API_ENABLED // Allow using desktop GL.
+#endif
+
+#ifndef GLES_API_ENABLED
+#define GLES_API_ENABLED // Allow using GLES (ANGLE).
+#endif
+
+#ifdef EGL_STATIC
+#define KHRONOS_STATIC 1
+#include "thirdparty/angle/include/EGL/egl.h"
+#include "thirdparty/angle/include/EGL/eglext.h"
+#undef KHRONOS_STATIC
+#else
+#include "thirdparty/glad/glad/egl.h"
+#endif
+#include "thirdparty/glad/glad/gl.h"
+
+#endif // PLATFORM_GL_H
diff --git a/platform/web/display_server_web.cpp b/platform/web/display_server_web.cpp
index 93b0496d74..aac1401f23 100644
--- a/platform/web/display_server_web.cpp
+++ b/platform/web/display_server_web.cpp
@@ -817,7 +817,7 @@ DisplayServerWeb::DisplayServerWeb(const String &p_rendering_driver, WindowMode
if (!emscripten_webgl_enable_extension(webgl_ctx, "OVR_multiview2")) {
print_verbose("Failed to enable WebXR extension.");
}
- RasterizerGLES3::make_current();
+ RasterizerGLES3::make_current(false);
} else {
OS::get_singleton()->alert(
diff --git a/platform/web/platform_config.h b/platform/web/platform_config.h
index 78deaadcfd..c3189bccfb 100644
--- a/platform/web/platform_config.h
+++ b/platform/web/platform_config.h
@@ -29,5 +29,3 @@
/**************************************************************************/
#include <alloca.h>
-
-#define OPENGL_INCLUDE_H "platform/web/godot_webgl2.h"
diff --git a/platform/web/platform_gl.h b/platform/web/platform_gl.h
new file mode 100644
index 0000000000..be6e1462a7
--- /dev/null
+++ b/platform/web/platform_gl.h
@@ -0,0 +1,40 @@
+/**************************************************************************/
+/* platform_gl.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PLATFORM_GL_H
+#define PLATFORM_GL_H
+
+#ifndef GLES_API_ENABLED
+#define GLES_API_ENABLED // Allow using GLES.
+#endif
+
+#include "platform/web/godot_webgl2.h"
+
+#endif // PLATFORM_GL_H
diff --git a/platform/windows/SCsub b/platform/windows/SCsub
index d7dd224199..1b6908d2bb 100644
--- a/platform/windows/SCsub
+++ b/platform/windows/SCsub
@@ -16,7 +16,9 @@ common_win = [
"tts_windows.cpp",
"windows_terminal_logger.cpp",
"vulkan_context_win.cpp",
- "gl_manager_windows.cpp",
+ "gl_manager_windows_native.cpp",
+ "gl_manager_windows_angle.cpp",
+ "wgl_detect_version.cpp",
]
common_win_wrap = [
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 6e56f2a525..340b95e4ab 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -186,6 +186,7 @@ def get_opts():
BoolVariable("use_asan", "Use address sanitizer (ASAN)", False),
BoolVariable("debug_crt", "Compile with MSVC's debug CRT (/MDd)", False),
BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False),
+ ("angle_libs", "Path to the ANGLE static libraries", ""),
]
@@ -431,7 +432,16 @@ def configure_msvc(env, vcvars_msvc_config):
if env["opengl3"]:
env.AppendUnique(CPPDEFINES=["GLES3_ENABLED"])
- LIBS += ["opengl32"]
+ if env["angle_libs"] != "":
+ env.AppendUnique(CPPDEFINES=["EGL_STATIC"])
+ env.Append(LIBPATH=[env["angle_libs"]])
+ LIBS += [
+ "libANGLE.windows." + env["arch"],
+ "libEGL.windows." + env["arch"],
+ "libGLES.windows." + env["arch"],
+ ]
+ LIBS += ["dxgi", "d3d9", "d3d11"]
+ env.Prepend(CPPPATH=["#thirdparty/angle/include"])
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
@@ -614,7 +624,18 @@ def configure_mingw(env):
if env["opengl3"]:
env.Append(CPPDEFINES=["GLES3_ENABLED"])
- env.Append(LIBS=["opengl32"])
+ if env["angle_libs"] != "":
+ env.AppendUnique(CPPDEFINES=["EGL_STATIC"])
+ env.Append(LIBPATH=[env["angle_libs"]])
+ env.Append(
+ LIBS=[
+ "EGL.windows." + env["arch"],
+ "GLES.windows." + env["arch"],
+ "ANGLE.windows." + env["arch"],
+ ]
+ )
+ env.Append(LIBS=["dxgi", "d3d9", "d3d11"])
+ env.Prepend(CPPPATH=["#thirdparty/angle/include"])
env.Append(CPPDEFINES=["MINGW_ENABLED", ("MINGW_HAS_SECURE_API", 1)])
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 7a24e887b0..86178da923 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -31,6 +31,7 @@
#include "display_server_windows.h"
#include "os_windows.h"
+#include "wgl_detect_version.h"
#include "core/config/project_settings.h"
#include "core/io/marshalls.h"
@@ -1070,8 +1071,11 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
}
#endif
#ifdef GLES3_ENABLED
- if (gl_manager) {
- gl_manager->window_destroy(p_window);
+ if (gl_manager_angle) {
+ gl_manager_angle->window_destroy(p_window);
+ }
+ if (gl_manager_native) {
+ gl_manager_native->window_destroy(p_window);
}
#endif
@@ -1089,8 +1093,11 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
void DisplayServerWindows::gl_window_make_current(DisplayServer::WindowID p_window_id) {
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_make_current(p_window_id);
+ if (gl_manager_angle) {
+ gl_manager_angle->window_make_current(p_window_id);
+ }
+ if (gl_manager_native) {
+ gl_manager_native->window_make_current(p_window_id);
}
#endif
}
@@ -1106,14 +1113,18 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
}
#if defined(GLES3_ENABLED)
case WINDOW_VIEW: {
- if (gl_manager) {
- return (int64_t)gl_manager->get_hdc(p_window);
+ if (gl_manager_native) {
+ return (int64_t)gl_manager_native->get_hdc(p_window);
+ } else {
+ return (int64_t)GetDC(windows[p_window].hWnd);
}
- return 0;
}
case OPENGL_CONTEXT: {
- if (gl_manager) {
- return (int64_t)gl_manager->get_hglrc(p_window);
+ if (gl_manager_native) {
+ return (int64_t)gl_manager_native->get_hglrc(p_window);
+ }
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_context(p_window);
}
return 0;
}
@@ -1447,8 +1458,11 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
}
#endif
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->window_resize(p_window, w, h);
+ if (gl_manager_native) {
+ gl_manager_native->window_resize(p_window, w, h);
+ }
+ if (gl_manager_angle) {
+ gl_manager_angle->window_resize(p_window, w, h);
}
#endif
@@ -2318,8 +2332,11 @@ void DisplayServerWindows::make_rendering_thread() {
void DisplayServerWindows::swap_buffers() {
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->swap_buffers();
+ if (gl_manager_angle) {
+ gl_manager_angle->swap_buffers();
+ }
+ if (gl_manager_native) {
+ gl_manager_native->swap_buffers();
}
#endif
}
@@ -2490,8 +2507,11 @@ void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsyn
#endif
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- gl_manager->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED);
+ if (gl_manager_native) {
+ gl_manager_native->set_use_vsync(p_window, p_vsync_mode != DisplayServer::VSYNC_DISABLED);
+ }
+ if (gl_manager_angle) {
+ gl_manager_angle->set_use_vsync(p_vsync_mode != DisplayServer::VSYNC_DISABLED);
}
#endif
}
@@ -2505,8 +2525,11 @@ DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_
#endif
#if defined(GLES3_ENABLED)
- if (gl_manager) {
- return gl_manager->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED;
+ if (gl_manager_native) {
+ return gl_manager_native->is_using_vsync(p_window) ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED;
+ }
+ if (gl_manager_angle) {
+ return gl_manager_angle->is_using_vsync() ? DisplayServer::VSYNC_ENABLED : DisplayServer::VSYNC_DISABLED;
}
#endif
@@ -4224,10 +4247,20 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
#endif
#ifdef GLES3_ENABLED
- if (gl_manager) {
- if (gl_manager->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) != OK) {
- memdelete(gl_manager);
- gl_manager = nullptr;
+ if (gl_manager_native) {
+ if (gl_manager_native->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) != OK) {
+ memdelete(gl_manager_native);
+ gl_manager_native = nullptr;
+ windows.erase(id);
+ ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create an OpenGL window.");
+ }
+ window_set_vsync_mode(p_vsync_mode, id);
+ }
+
+ if (gl_manager_angle) {
+ if (gl_manager_angle->window_create(id, nullptr, wd.hWnd, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) != OK) {
+ memdelete(gl_manager_angle);
+ gl_manager_angle = nullptr;
windows.erase(id);
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Failed to create an OpenGL window.");
}
@@ -4523,18 +4556,36 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
#if defined(GLES3_ENABLED)
if (rendering_driver == "opengl3") {
- GLManager_Windows::ContextType opengl_api_type = GLManager_Windows::GLES_3_0_COMPATIBLE;
+ int gl_version = detect_wgl_version();
+ if (gl_version < 30003) {
+ WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE.");
+ rendering_driver = "opengl3_angle";
+ }
+ }
+
+ if (rendering_driver == "opengl3") {
+ gl_manager_native = memnew(GLManagerNative_Windows);
- gl_manager = memnew(GLManager_Windows(opengl_api_type));
+ if (gl_manager_native->initialize() != OK) {
+ memdelete(gl_manager_native);
+ gl_manager_native = nullptr;
+ r_error = ERR_UNAVAILABLE;
+ return;
+ }
- if (gl_manager->initialize() != OK) {
- memdelete(gl_manager);
- gl_manager = nullptr;
+ 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();
+ RasterizerGLES3::make_current(false);
}
#endif
@@ -4608,6 +4659,7 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
#endif
#ifdef GLES3_ENABLED
drivers.push_back("opengl3");
+ drivers.push_back("opengl3_angle");
#endif
return drivers;
@@ -4693,9 +4745,13 @@ DisplayServerWindows::~DisplayServerWindows() {
SystemParametersInfoA(SPI_SETMOUSETRAILS, restore_mouse_trails, 0, 0);
}
#ifdef GLES3_ENABLED
- if (gl_manager) {
- memdelete(gl_manager);
- gl_manager = nullptr;
+ if (gl_manager_angle) {
+ memdelete(gl_manager_angle);
+ gl_manager_angle = nullptr;
+ }
+ if (gl_manager_native) {
+ memdelete(gl_manager_native);
+ gl_manager_native = nullptr;
}
#endif
if (tts) {
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 59c4442604..28f2f7e6ff 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -59,8 +59,9 @@
#endif
#if defined(GLES3_ENABLED)
-#include "gl_manager_windows.h"
-#endif
+#include "gl_manager_windows_angle.h"
+#include "gl_manager_windows_native.h"
+#endif // GLES3_ENABLED
#include <io.h>
#include <stdio.h>
@@ -335,7 +336,8 @@ class DisplayServerWindows : public DisplayServer {
Point2i center;
#if defined(GLES3_ENABLED)
- GLManager_Windows *gl_manager = nullptr;
+ GLManagerANGLE_Windows *gl_manager_angle = nullptr;
+ GLManagerNative_Windows *gl_manager_native = nullptr;
#endif
#if defined(VULKAN_ENABLED)
diff --git a/platform/windows/doc_classes/EditorExportPlatformWindows.xml b/platform/windows/doc_classes/EditorExportPlatformWindows.xml
index fc068efc75..2a286de100 100644
--- a/platform/windows/doc_classes/EditorExportPlatformWindows.xml
+++ b/platform/windows/doc_classes/EditorExportPlatformWindows.xml
@@ -18,6 +18,9 @@
<member name="application/copyright" type="String" setter="" getter="">
Copyright notice for the bundle visible to the user. Optional. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
</member>
+ <member name="application/export_angle" type="int" setter="" getter="">
+ If set to [code]1[/code], ANGLE libraries are exported with the exported application. If set to [code]0[/code], ANGLE libraries are exported only if [member ProjectSettings.rendering/gl_compatibility/driver] is set to [code]"opengl3_angle"[/code].
+ </member>
<member name="application/file_description" type="String" setter="" getter="">
File description to be presented to users. Required. See [url=https://learn.microsoft.com/en-us/windows/win32/menurc/stringfileinfo-block]StringFileInfo[/url].
</member>
diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp
index d2d4d78113..4185c36d77 100644
--- a/platform/windows/export/export_plugin.cpp
+++ b/platform/windows/export/export_plugin.cpp
@@ -179,6 +179,35 @@ Error EditorExportPlatformWindows::modify_template(const Ref<EditorExportPreset>
}
Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ int export_angle = p_preset->get("application/export_angle");
+ bool include_angle_libs = false;
+ if (export_angle == 0) {
+ include_angle_libs = String(GLOBAL_GET("rendering/gl_compatibility/driver.windows")) == "opengl3_angle";
+ } else if (export_angle == 1) {
+ include_angle_libs = true;
+ }
+
+ if (include_angle_libs) {
+ String custom_debug = p_preset->get("custom_template/debug");
+ String custom_release = p_preset->get("custom_template/release");
+ String arch = p_preset->get("binary_format/architecture");
+
+ String template_path = p_debug ? custom_debug : custom_release;
+
+ template_path = template_path.strip_edges();
+
+ if (template_path.is_empty()) {
+ template_path = find_export_template(get_template_file_name(p_debug ? "debug" : "release", arch));
+ }
+ Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ if (da->file_exists(template_path.get_base_dir().path_join("libEGL." + arch + ".dll"))) {
+ da->copy(template_path.get_base_dir().path_join("libEGL." + arch + ".dll"), p_path.get_base_dir().path_join("libEGL.dll"), get_chmod_flags());
+ }
+ if (da->file_exists(template_path.get_base_dir().path_join("libGLESv2." + arch + ".dll"))) {
+ da->copy(template_path.get_base_dir().path_join("libGLESv2." + arch + ".dll"), p_path.get_base_dir().path_join("libGLESv2.dll"), get_chmod_flags());
+ }
+ }
+
bool export_as_zip = p_path.ends_with("zip");
bool embedded = p_preset->get("binary_format/embed_pck");
@@ -311,7 +340,7 @@ bool EditorExportPlatformWindows::get_export_option_visibility(const EditorExpor
// Hide resources.
bool mod_res = p_preset->get("application/modify_resources");
- if (!mod_res && p_option != "application/modify_resources" && p_option.begins_with("application/")) {
+ if (!mod_res && p_option != "application/modify_resources" && p_option != "application/export_angle" && p_option.begins_with("application/")) {
return false;
}
@@ -350,6 +379,7 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_angle", PROPERTY_HINT_ENUM, "Auto,Yes,No"), 0, true));
String run_script = "Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'\n"
"$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'\n"
diff --git a/platform/windows/gl_manager_windows_angle.cpp b/platform/windows/gl_manager_windows_angle.cpp
new file mode 100644
index 0000000000..3086edc7f2
--- /dev/null
+++ b/platform/windows/gl_manager_windows_angle.cpp
@@ -0,0 +1,70 @@
+/**************************************************************************/
+/* gl_manager_windows_angle.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#include "gl_manager_windows_angle.h"
+
+#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <EGL/eglext_angle.h>
+
+const char *GLManagerANGLE_Windows::_get_platform_extension_name() const {
+ return "EGL_ANGLE_platform_angle";
+}
+
+EGLenum GLManagerANGLE_Windows::_get_platform_extension_enum() const {
+ return EGL_PLATFORM_ANGLE_ANGLE;
+}
+
+Vector<EGLAttrib> GLManagerANGLE_Windows::_get_platform_display_attributes() const {
+ Vector<EGLAttrib> ret;
+ ret.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ ret.push_back(EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE);
+ ret.push_back(EGL_NONE);
+
+ return ret;
+}
+
+EGLenum GLManagerANGLE_Windows::_get_platform_api_enum() const {
+ return EGL_OPENGL_ES_API;
+}
+
+Vector<EGLint> GLManagerANGLE_Windows::_get_platform_context_attribs() const {
+ Vector<EGLint> ret;
+ ret.push_back(EGL_CONTEXT_CLIENT_VERSION);
+ ret.push_back(3);
+ ret.push_back(EGL_NONE);
+
+ return ret;
+}
+
+#endif // WINDOWS_ENABLED && GLES3_ENABLED
diff --git a/platform/windows/gl_manager_windows_angle.h b/platform/windows/gl_manager_windows_angle.h
new file mode 100644
index 0000000000..d8dc651cfd
--- /dev/null
+++ b/platform/windows/gl_manager_windows_angle.h
@@ -0,0 +1,61 @@
+/**************************************************************************/
+/* gl_manager_windows_angle.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef GL_MANAGER_WINDOWS_ANGLE_H
+#define GL_MANAGER_WINDOWS_ANGLE_H
+
+#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
+
+#include "core/error/error_list.h"
+#include "core/os/os.h"
+#include "core/templates/local_vector.h"
+#include "drivers/egl/egl_manager.h"
+#include "servers/display_server.h"
+
+#include <windows.h>
+
+class GLManagerANGLE_Windows : public EGLManager {
+private:
+ virtual const char *_get_platform_extension_name() const override;
+ virtual EGLenum _get_platform_extension_enum() const override;
+ virtual EGLenum _get_platform_api_enum() const override;
+ virtual Vector<EGLAttrib> _get_platform_display_attributes() const override;
+ virtual Vector<EGLint> _get_platform_context_attribs() const override;
+
+public:
+ void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {}
+
+ GLManagerANGLE_Windows(){};
+ ~GLManagerANGLE_Windows(){};
+};
+
+#endif // WINDOWS_ENABLED && GLES3_ENABLED
+
+#endif // GL_MANAGER_WINDOWS_ANGLE_H
diff --git a/platform/windows/gl_manager_windows.cpp b/platform/windows/gl_manager_windows_native.cpp
index d3972c7bbc..2e41946eb2 100644
--- a/platform/windows/gl_manager_windows.cpp
+++ b/platform/windows/gl_manager_windows_native.cpp
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* gl_manager_windows.cpp */
+/* gl_manager_windows_native.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#include "gl_manager_windows.h"
+#include "gl_manager_windows_native.h"
#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
@@ -52,11 +52,14 @@
#if defined(__GNUC__)
// Workaround GCC warning from -Wcast-function-type.
-#define wglGetProcAddress (void *)wglGetProcAddress
#define GetProcAddress (void *)GetProcAddress
#endif
+typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXT)(HDC);
+typedef BOOL(APIENTRY *PFNWGLDELETECONTEXT)(HGLRC);
+typedef BOOL(APIENTRY *PFNWGLMAKECURRENT)(HDC, HGLRC);
typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *);
+typedef void *(APIENTRY *PFNWGLGETPROCADDRESS)(LPCSTR);
static String format_error_message(DWORD id) {
LPWSTR messageBuffer = nullptr;
@@ -102,7 +105,7 @@ static bool nvapi_err_check(const char *msg, int status) {
// On windows we have to disable threaded optimization when using NVIDIA graphics cards
// to avoid stuttering, see https://github.com/microsoft/vscode-cpptools/issues/6592
// also see https://github.com/Ryujinx/Ryujinx/blob/master/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs
-void GLManager_Windows::_nvapi_disable_threaded_optimization() {
+void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() {
HMODULE nvapi = 0;
#ifdef _WIN64
nvapi = LoadLibraryA("nvapi64.dll");
@@ -116,7 +119,7 @@ void GLManager_Windows::_nvapi_disable_threaded_optimization() {
void *(__cdecl * NvAPI_QueryInterface)(unsigned int interface_id) = 0;
- NvAPI_QueryInterface = (void *(__cdecl *)(unsigned int))GetProcAddress(nvapi, "nvapi_QueryInterface");
+ NvAPI_QueryInterface = (void *(__cdecl *)(unsigned int))(void *)GetProcAddress(nvapi, "nvapi_QueryInterface");
if (NvAPI_QueryInterface == NULL) {
print_verbose("Error getting NVAPI NvAPI_QueryInterface");
@@ -235,7 +238,7 @@ void GLManager_Windows::_nvapi_disable_threaded_optimization() {
NvAPI_DRS_DestroySession(session_handle);
}
-int GLManager_Windows::_find_or_create_display(GLWindow &win) {
+int GLManagerNative_Windows::_find_or_create_display(GLWindow &win) {
// find display NYI, only 1 supported so far
if (_displays.size()) {
return 0;
@@ -297,19 +300,36 @@ static Error _configure_pixel_format(HDC hDC) {
return OK;
}
-Error GLManager_Windows::_create_context(GLWindow &win, GLDisplay &gl_display) {
+PFNWGLCREATECONTEXT gd_wglCreateContext;
+PFNWGLMAKECURRENT gd_wglMakeCurrent;
+PFNWGLDELETECONTEXT gd_wglDeleteContext;
+PFNWGLGETPROCADDRESS gd_wglGetProcAddress;
+
+Error GLManagerNative_Windows::_create_context(GLWindow &win, GLDisplay &gl_display) {
Error err = _configure_pixel_format(win.hDC);
if (err != OK) {
return err;
}
- gl_display.hRC = wglCreateContext(win.hDC);
+ HMODULE module = LoadLibraryW(L"opengl32.dll");
+ if (!module) {
+ return ERR_CANT_CREATE;
+ }
+ gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
+ gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
+ gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
+ gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
+ if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
+ return ERR_CANT_CREATE;
+ }
+
+ gl_display.hRC = gd_wglCreateContext(win.hDC);
if (!gl_display.hRC) // Are We Able To Get A Rendering Context?
{
return ERR_CANT_CREATE; // Return FALSE
}
- if (!wglMakeCurrent(win.hDC, gl_display.hRC)) {
+ if (!gd_wglMakeCurrent(win.hDC, gl_display.hRC)) {
ERR_PRINT("Could not attach OpenGL context to newly created window: " + format_error_message(GetLastError()));
}
@@ -323,45 +343,45 @@ Error GLManager_Windows::_create_context(GLWindow &win, GLDisplay &gl_display) {
}; //zero indicates the end of the array
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = nullptr; //pointer to the method
- wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
+ wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)gd_wglGetProcAddress("wglCreateContextAttribsARB");
if (wglCreateContextAttribsARB == nullptr) //OpenGL 3.0 is not supported
{
- wglDeleteContext(gl_display.hRC);
+ gd_wglDeleteContext(gl_display.hRC);
gl_display.hRC = 0;
return ERR_CANT_CREATE;
}
HGLRC new_hRC = wglCreateContextAttribsARB(win.hDC, 0, attribs);
if (!new_hRC) {
- wglDeleteContext(gl_display.hRC);
+ gd_wglDeleteContext(gl_display.hRC);
gl_display.hRC = 0;
return ERR_CANT_CREATE;
}
- if (!wglMakeCurrent(win.hDC, nullptr)) {
+ if (!gd_wglMakeCurrent(win.hDC, nullptr)) {
ERR_PRINT("Could not detach OpenGL context from newly created window: " + format_error_message(GetLastError()));
}
- wglDeleteContext(gl_display.hRC);
+ gd_wglDeleteContext(gl_display.hRC);
gl_display.hRC = new_hRC;
- if (!wglMakeCurrent(win.hDC, gl_display.hRC)) // Try To Activate The Rendering Context
+ if (!gd_wglMakeCurrent(win.hDC, gl_display.hRC)) // Try to activate the rendering context.
{
ERR_PRINT("Could not attach OpenGL context to newly created window with replaced OpenGL context: " + format_error_message(GetLastError()));
- wglDeleteContext(gl_display.hRC);
+ gd_wglDeleteContext(gl_display.hRC);
gl_display.hRC = 0;
return ERR_CANT_CREATE;
}
if (!wglSwapIntervalEXT) {
- wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
+ wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)gd_wglGetProcAddress("wglSwapIntervalEXT");
}
return OK;
}
-Error GLManager_Windows::window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, int p_width, int p_height) {
+Error GLManagerNative_Windows::window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, int p_width, int p_height) {
HDC hDC = GetDC(p_hwnd);
if (!hDC) {
return ERR_CANT_CREATE;
@@ -374,8 +394,6 @@ Error GLManager_Windows::window_create(DisplayServer::WindowID p_window_id, HWND
}
GLWindow win;
- win.width = p_width;
- win.height = p_height;
win.hwnd = p_hwnd;
win.hDC = hDC;
@@ -395,24 +413,11 @@ Error GLManager_Windows::window_create(DisplayServer::WindowID p_window_id, HWND
return OK;
}
-void GLManager_Windows::_internal_set_current_window(GLWindow *p_win) {
+void GLManagerNative_Windows::_internal_set_current_window(GLWindow *p_win) {
_current_window = p_win;
}
-void GLManager_Windows::window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {
- get_window(p_window_id).width = p_width;
- get_window(p_window_id).height = p_height;
-}
-
-int GLManager_Windows::window_get_width(DisplayServer::WindowID p_window_id) {
- return get_window(p_window_id).width;
-}
-
-int GLManager_Windows::window_get_height(DisplayServer::WindowID p_window_id) {
- return get_window(p_window_id).height;
-}
-
-void GLManager_Windows::window_destroy(DisplayServer::WindowID p_window_id) {
+void GLManagerNative_Windows::window_destroy(DisplayServer::WindowID p_window_id) {
GLWindow &win = get_window(p_window_id);
if (_current_window == &win) {
_current_window = nullptr;
@@ -420,17 +425,17 @@ void GLManager_Windows::window_destroy(DisplayServer::WindowID p_window_id) {
_windows.erase(p_window_id);
}
-void GLManager_Windows::release_current() {
+void GLManagerNative_Windows::release_current() {
if (!_current_window) {
return;
}
- if (!wglMakeCurrent(_current_window->hDC, nullptr)) {
+ if (!gd_wglMakeCurrent(_current_window->hDC, nullptr)) {
ERR_PRINT("Could not detach OpenGL context from window marked current: " + format_error_message(GetLastError()));
}
}
-void GLManager_Windows::window_make_current(DisplayServer::WindowID p_window_id) {
+void GLManagerNative_Windows::window_make_current(DisplayServer::WindowID p_window_id) {
if (p_window_id == -1) {
return;
}
@@ -444,33 +449,33 @@ void GLManager_Windows::window_make_current(DisplayServer::WindowID p_window_id)
}
const GLDisplay &disp = get_display(win.gldisplay_id);
- if (!wglMakeCurrent(win.hDC, disp.hRC)) {
+ if (!gd_wglMakeCurrent(win.hDC, disp.hRC)) {
ERR_PRINT("Could not switch OpenGL context to other window: " + format_error_message(GetLastError()));
}
_internal_set_current_window(&win);
}
-void GLManager_Windows::make_current() {
+void GLManagerNative_Windows::make_current() {
if (!_current_window) {
return;
}
const GLDisplay &disp = get_current_display();
- if (!wglMakeCurrent(_current_window->hDC, disp.hRC)) {
+ if (!gd_wglMakeCurrent(_current_window->hDC, disp.hRC)) {
ERR_PRINT("Could not switch OpenGL context to window marked current: " + format_error_message(GetLastError()));
}
}
-void GLManager_Windows::swap_buffers() {
+void GLManagerNative_Windows::swap_buffers() {
SwapBuffers(_current_window->hDC);
}
-Error GLManager_Windows::initialize() {
+Error GLManagerNative_Windows::initialize() {
_nvapi_disable_threaded_optimization();
return OK;
}
-void GLManager_Windows::set_use_vsync(DisplayServer::WindowID p_window_id, bool p_use) {
+void GLManagerNative_Windows::set_use_vsync(DisplayServer::WindowID p_window_id, bool p_use) {
GLWindow &win = get_window(p_window_id);
GLWindow *current = _current_window;
@@ -480,7 +485,12 @@ void GLManager_Windows::set_use_vsync(DisplayServer::WindowID p_window_id, bool
if (wglSwapIntervalEXT) {
win.use_vsync = p_use;
- wglSwapIntervalEXT(p_use ? 1 : 0);
+
+ if (!wglSwapIntervalEXT(p_use ? 1 : 0)) {
+ WARN_PRINT("Could not set V-Sync mode.");
+ }
+ } else {
+ WARN_PRINT("Could not set V-Sync mode. V-Sync is not supported.");
}
if (current != _current_window) {
@@ -489,29 +499,27 @@ void GLManager_Windows::set_use_vsync(DisplayServer::WindowID p_window_id, bool
}
}
-bool GLManager_Windows::is_using_vsync(DisplayServer::WindowID p_window_id) const {
+bool GLManagerNative_Windows::is_using_vsync(DisplayServer::WindowID p_window_id) const {
return get_window(p_window_id).use_vsync;
}
-HDC GLManager_Windows::get_hdc(DisplayServer::WindowID p_window_id) {
+HDC GLManagerNative_Windows::get_hdc(DisplayServer::WindowID p_window_id) {
return get_window(p_window_id).hDC;
}
-HGLRC GLManager_Windows::get_hglrc(DisplayServer::WindowID p_window_id) {
+HGLRC GLManagerNative_Windows::get_hglrc(DisplayServer::WindowID p_window_id) {
const GLWindow &win = get_window(p_window_id);
const GLDisplay &disp = get_display(win.gldisplay_id);
return disp.hRC;
}
-GLManager_Windows::GLManager_Windows(ContextType p_context_type) {
- context_type = p_context_type;
-
+GLManagerNative_Windows::GLManagerNative_Windows() {
direct_render = false;
glx_minor = glx_major = 0;
_current_window = nullptr;
}
-GLManager_Windows::~GLManager_Windows() {
+GLManagerNative_Windows::~GLManagerNative_Windows() {
release_current();
}
diff --git a/platform/windows/gl_manager_windows.h b/platform/windows/gl_manager_windows_native.h
index 482b00a1ba..829c53b3d2 100644
--- a/platform/windows/gl_manager_windows.h
+++ b/platform/windows/gl_manager_windows_native.h
@@ -1,5 +1,5 @@
/**************************************************************************/
-/* gl_manager_windows.h */
+/* gl_manager_windows_native.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
-#ifndef GL_MANAGER_WINDOWS_H
-#define GL_MANAGER_WINDOWS_H
+#ifndef GL_MANAGER_WINDOWS_NATIVE_H
+#define GL_MANAGER_WINDOWS_NATIVE_H
#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
@@ -43,17 +43,10 @@
typedef bool(APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval);
typedef int(APIENTRY *PFNWGLGETSWAPINTERVALEXTPROC)(void);
-class GLManager_Windows {
-public:
- enum ContextType {
- GLES_3_0_COMPATIBLE,
- };
-
+class GLManagerNative_Windows {
private:
// any data specific to the window
struct GLWindow {
- int width = 0;
- int height = 0;
bool use_vsync = false;
// windows specific
@@ -86,7 +79,6 @@ private:
bool direct_render;
int glx_minor, glx_major;
- ContextType context_type;
private:
void _nvapi_disable_threaded_optimization();
@@ -96,11 +88,7 @@ private:
public:
Error window_create(DisplayServer::WindowID p_window_id, HWND p_hwnd, HINSTANCE p_hinstance, int p_width, int p_height);
void window_destroy(DisplayServer::WindowID p_window_id);
- void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height);
-
- // get directly from the cached GLWindow
- int window_get_width(DisplayServer::WindowID p_window_id = 0);
- int window_get_height(DisplayServer::WindowID p_window_id = 0);
+ void window_resize(DisplayServer::WindowID p_window_id, int p_width, int p_height) {}
void release_current();
void make_current();
@@ -116,10 +104,10 @@ public:
HDC get_hdc(DisplayServer::WindowID p_window_id);
HGLRC get_hglrc(DisplayServer::WindowID p_window_id);
- GLManager_Windows(ContextType p_context_type);
- ~GLManager_Windows();
+ GLManagerNative_Windows();
+ ~GLManagerNative_Windows();
};
#endif // WINDOWS_ENABLED && GLES3_ENABLED
-#endif // GL_MANAGER_WINDOWS_H
+#endif // GL_MANAGER_WINDOWS_NATIVE_H
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
index ae4e51e3fb..964e341ce4 100644
--- a/platform/windows/platform_config.h
+++ b/platform/windows/platform_config.h
@@ -29,5 +29,3 @@
/**************************************************************************/
#include <malloc.h>
-
-#define OPENGL_INCLUDE_H "thirdparty/glad/glad/gl.h"
diff --git a/platform/windows/platform_gl.h b/platform/windows/platform_gl.h
new file mode 100644
index 0000000000..e4af8b0ccd
--- /dev/null
+++ b/platform/windows/platform_gl.h
@@ -0,0 +1,53 @@
+/**************************************************************************/
+/* platform_gl.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef PLATFORM_GL_H
+#define PLATFORM_GL_H
+
+#ifndef GL_API_ENABLED
+#define GL_API_ENABLED // Allow using desktop GL.
+#endif
+
+#ifndef GLES_API_ENABLED
+#define GLES_API_ENABLED // Allow using GLES (ANGLE).
+#endif
+
+#ifdef EGL_STATIC
+#define KHRONOS_STATIC 1
+#include "thirdparty/angle/include/EGL/egl.h"
+#include "thirdparty/angle/include/EGL/eglext.h"
+#undef KHRONOS_STATIC
+#else
+#include "thirdparty/glad/glad/egl.h"
+#endif
+
+#include "thirdparty/glad/glad/gl.h"
+
+#endif // PLATFORM_GL_H
diff --git a/platform/windows/wgl_detect_version.cpp b/platform/windows/wgl_detect_version.cpp
new file mode 100644
index 0000000000..264cd525c5
--- /dev/null
+++ b/platform/windows/wgl_detect_version.cpp
@@ -0,0 +1,189 @@
+/**************************************************************************/
+/* wgl_detect_version.cpp */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
+
+#include "wgl_detect_version.h"
+#include "os_windows.h"
+
+#include "core/string/print_string.h"
+#include "core/string/ustring.h"
+
+#include <windows.h>
+
+#include <dwmapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
+#define WGL_CONTEXT_FLAGS_ARB 0x2094
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_VENDOR 0x1F00
+#define WGL_RENDERER 0x1F01
+#define WGL_VERSION 0x1F02
+
+#if defined(__GNUC__)
+// Workaround GCC warning from -Wcast-function-type.
+#define GetProcAddress (void *)GetProcAddress
+#endif
+
+typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXT)(HDC);
+typedef BOOL(APIENTRY *PFNWGLDELETECONTEXT)(HGLRC);
+typedef BOOL(APIENTRY *PFNWGLMAKECURRENT)(HDC, HGLRC);
+typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *);
+typedef void *(APIENTRY *PFNWGLGETPROCADDRESS)(LPCSTR);
+typedef const char *(APIENTRY *PFNWGLGETSTRINGPROC)(unsigned int);
+
+int detect_wgl_version() {
+ int major = 0;
+ int minor = 0;
+
+ PFNWGLCREATECONTEXT gd_wglCreateContext;
+ PFNWGLMAKECURRENT gd_wglMakeCurrent;
+ PFNWGLDELETECONTEXT gd_wglDeleteContext;
+ PFNWGLGETPROCADDRESS gd_wglGetProcAddress;
+
+ HMODULE module = LoadLibraryW(L"opengl32.dll");
+ if (!module) {
+ return 0;
+ }
+ gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
+ gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
+ gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
+ gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
+ if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
+ return 0;
+ }
+
+ LPCWSTR class_name = L"EngineWGLDetect";
+ HINSTANCE hInstance = static_cast<OS_Windows *>(OS::get_singleton())->get_hinstance();
+ WNDCLASSW wc = {};
+
+ wc.lpfnWndProc = DefWindowProcW;
+ wc.hInstance = hInstance;
+ wc.lpszClassName = class_name;
+
+ RegisterClassW(&wc);
+
+ HWND hWnd = CreateWindowExW(WS_EX_APPWINDOW, class_name, L"", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);
+ if (hWnd) {
+ HDC hDC = GetDC(hWnd);
+ if (hDC) {
+ static PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
+ 1,
+ PFD_DRAW_TO_WINDOW | // Format Must Support Window
+ PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
+ PFD_DOUBLEBUFFER,
+ (BYTE)PFD_TYPE_RGBA,
+ (BYTE)(OS::get_singleton()->is_layered_allowed() ? 32 : 24),
+ (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Color Bits Ignored
+ (BYTE)(OS::get_singleton()->is_layered_allowed() ? 8 : 0), // Alpha Buffer
+ (BYTE)0, // Shift Bit Ignored
+ (BYTE)0, // No Accumulation Buffer
+ (BYTE)0, (BYTE)0, (BYTE)0, (BYTE)0, // Accumulation Bits Ignored
+ (BYTE)24, // 24Bit Z-Buffer (Depth Buffer)
+ (BYTE)0, // No Stencil Buffer
+ (BYTE)0, // No Auxiliary Buffer
+ (BYTE)PFD_MAIN_PLANE, // Main Drawing Layer
+ (BYTE)0, // Reserved
+ 0, 0, 0 // Layer Masks Ignored
+ };
+
+ int pixel_format = ChoosePixelFormat(hDC, &pfd);
+ SetPixelFormat(hDC, pixel_format, &pfd);
+
+ HGLRC hRC = gd_wglCreateContext(hDC);
+ if (hRC) {
+ if (gd_wglMakeCurrent(hDC, hRC)) {
+ int attribs[] = {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
+ WGL_CONTEXT_MINOR_VERSION_ARB, 3,
+ WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
+ WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ 0
+ };
+
+ PFNWGLCREATECONTEXTATTRIBSARBPROC gd_wglCreateContextAttribsARB = nullptr;
+ gd_wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)gd_wglGetProcAddress("wglCreateContextAttribsARB");
+ if (gd_wglCreateContextAttribsARB) {
+ HGLRC new_hRC = gd_wglCreateContextAttribsARB(hDC, 0, attribs);
+ if (new_hRC) {
+ if (gd_wglMakeCurrent(hDC, new_hRC)) {
+ PFNWGLGETSTRINGPROC gd_wglGetString = (PFNWGLGETSTRINGPROC)GetProcAddress(module, "glGetString");
+ if (gd_wglGetString) {
+ const char *prefixes[] = {
+ "OpenGL ES-CM ",
+ "OpenGL ES-CL ",
+ "OpenGL ES ",
+ "OpenGL SC ",
+ nullptr
+ };
+ const char *version = (const char *)gd_wglGetString(WGL_VERSION);
+ if (version) {
+ const String device_vendor = String::utf8((const char *)gd_wglGetString(WGL_VENDOR)).strip_edges();
+ const String device_name = String::utf8((const char *)gd_wglGetString(WGL_RENDERER)).strip_edges();
+ for (int i = 0; prefixes[i]; i++) {
+ size_t length = strlen(prefixes[i]);
+ if (strncmp(version, prefixes[i], length) == 0) {
+ version += length;
+ break;
+ }
+ }
+#ifdef _MSC_VER
+ sscanf_s(version, "%d.%d", &major, &minor);
+#else
+ sscanf(version, "%d.%d", &major, &minor);
+#endif
+ print_verbose(vformat("Native OpenGL API detected: %d.%d: %s - %s", major, minor, device_vendor, device_name));
+ }
+ }
+ }
+ gd_wglMakeCurrent(nullptr, nullptr);
+ gd_wglDeleteContext(new_hRC);
+ }
+ }
+ }
+ gd_wglMakeCurrent(nullptr, nullptr);
+ gd_wglDeleteContext(hRC);
+ }
+ ReleaseDC(hWnd, hDC);
+ }
+ DestroyWindow(hWnd);
+ }
+ UnregisterClassW(class_name, hInstance);
+
+ return major * 10000 + minor;
+}
+
+#endif // WINDOWS_ENABLED && GLES3_ENABLED
diff --git a/platform/windows/wgl_detect_version.h b/platform/windows/wgl_detect_version.h
new file mode 100644
index 0000000000..0be2923ba3
--- /dev/null
+++ b/platform/windows/wgl_detect_version.h
@@ -0,0 +1,40 @@
+/**************************************************************************/
+/* wgl_detect_version.h */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+#ifndef WGL_DETECT_VERSION_H
+#define WGL_DETECT_VERSION_H
+
+#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
+
+int detect_wgl_version();
+
+#endif // WINDOWS_ENABLED && GLES3_ENABLED
+
+#endif // WGL_DETECT_VERSION_H