From 21af6fecf142882b08e1f2aa006bb406a3631e96 Mon Sep 17 00:00:00 2001 From: binary1248 Date: Sun, 26 Mar 2023 04:44:05 +0200 Subject: [PATCH] Fixed OpenGL entry points being loaded from OpenGL32.dll instead of failing to load if they are not provided by the vendor provided library on Windows. --- src/SFML/Window/GlContext.cpp | 23 --------------- src/SFML/Window/Win32/WglContext.cpp | 42 ++++++++++++++++++++++------ src/SFML/Window/Win32/WglContext.hpp | 1 + 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/SFML/Window/GlContext.cpp b/src/SFML/Window/GlContext.cpp index ce7336ac..636ed6cd 100644 --- a/src/SFML/Window/GlContext.cpp +++ b/src/SFML/Window/GlContext.cpp @@ -945,29 +945,6 @@ void GlContext::initialize(const ContextSettings& requestedSettings) void GlContext::checkSettings(const ContextSettings& requestedSettings) const { // Perform checks to inform the user if they are getting a context they might not have expected - - auto glGetStringFunc = reinterpret_cast(getFunction("glGetString")); - - if (!glGetStringFunc) - { - err() << "Could not load glGetString function" << std::endl; - - return; - } - - // Detect any known non-accelerated implementations and warn - const char* vendorName = reinterpret_cast(glGetStringFunc(GL_VENDOR)); - const char* rendererName = reinterpret_cast(glGetStringFunc(GL_RENDERER)); - - if (vendorName && rendererName) - { - if (std::string_view(vendorName) == "Microsoft Corporation" && std::string_view(rendererName) == "GDI Generic") - { - err() << "Warning: Detected \"Microsoft Corporation GDI Generic\" OpenGL implementation" << '\n' - << "The current OpenGL implementation is not hardware-accelerated" << std::endl; - } - } - int version = static_cast(m_settings.majorVersion * 10u + m_settings.minorVersion); int requestedVersion = static_cast(requestedSettings.majorVersion * 10u + requestedSettings.minorVersion); diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp index 0833f84f..7d6016e3 100644 --- a/src/SFML/Window/Win32/WglContext.cpp +++ b/src/SFML/Window/Win32/WglContext.cpp @@ -51,6 +51,18 @@ namespace WglContextImpl thread_local sf::priv::WglContext* currentContext(nullptr); +// We use a different loader for wgl functions since we load them directly from OpenGL32.dll +sf::GlFunctionPointer getOpenGl32Function(const char* name) +{ + static const HMODULE module = GetModuleHandleA("OpenGL32.dll"); + + if (module) + return reinterpret_cast(GetProcAddress(module, reinterpret_cast(name))); + + return nullptr; +} + + //////////////////////////////////////////////////////////// void ensureInit() { @@ -59,7 +71,7 @@ void ensureInit() { initialized = true; - gladLoadWGL(nullptr, sf::priv::WglContext::getFunction); + gladLoadWGL(nullptr, getOpenGl32Function); } } @@ -74,7 +86,7 @@ void ensureExtensionsInit(HDC deviceContext) // We don't check the return value since the extension // flags are cleared even if loading fails - gladLoadWGL(deviceContext, sf::priv::WglContext::getFunction); + gladLoadWGL(deviceContext, getOpenGl32Function); } } } // namespace WglContextImpl @@ -186,6 +198,8 @@ WglContext::~WglContext() //////////////////////////////////////////////////////////// GlFunctionPointer WglContext::getFunction(const char* name) { + assert(WglContextImpl::currentContext != nullptr); + auto address = reinterpret_cast(wglGetProcAddress(reinterpret_cast(name))); if (address) @@ -197,13 +211,9 @@ GlFunctionPointer WglContext::getFunction(const char* name) return address; } - static HMODULE module = nullptr; - - if (!module) - module = GetModuleHandleA("OpenGL32.dll"); - - if (module) - return reinterpret_cast(GetProcAddress(module, reinterpret_cast(name))); + // If we are using the generic GDI implementation, try loading directly from OpenGL32.dll as well + if (WglContextImpl::currentContext->m_isGeneric) + return WglContextImpl::getOpenGl32Function(name); return nullptr; } @@ -460,6 +470,20 @@ void WglContext::updateSettingsFromPixelFormat() return; } + // Detect if we are running using the generic GDI implementation and warn + if (actualFormat.dwFlags & PFD_GENERIC_FORMAT) + { + m_isGeneric = true; + + err() << "Warning: Detected \"Microsoft Corporation GDI Generic\" OpenGL implementation" << std::endl; + + // Detect if the generic GDI implementation is not accelerated + if (!(actualFormat.dwFlags & PFD_GENERIC_ACCELERATED)) + err() << "Warning: The \"Microsoft Corporation GDI Generic\" OpenGL implementation is not " + "hardware-accelerated" + << std::endl; + } + if (SF_GLAD_WGL_ARB_pixel_format) { const int attributes[] = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB}; diff --git a/src/SFML/Window/Win32/WglContext.hpp b/src/SFML/Window/Win32/WglContext.hpp index 54be1964..1624409c 100644 --- a/src/SFML/Window/Win32/WglContext.hpp +++ b/src/SFML/Window/Win32/WglContext.hpp @@ -181,6 +181,7 @@ private: HDC m_deviceContext{}; //!< Device context associated to the context HGLRC m_context{}; //!< OpenGL context bool m_ownsWindow{}; //!< Do we own the target window? + bool m_isGeneric{}; //!< Is this context provided by the generic GDI implementation? }; } // namespace sf::priv