From d7b96a424fdd939aa7de65153e3b9baa20edf626 Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sat, 16 Jan 2021 16:43:05 +0100 Subject: Codechange: [OpenGL] Use new-style extension testing introduced with OpenGL 3.0. --- src/video/opengl.cpp | 36 +++++++++++++++++++++++++++++++++--- src/video/opengl.h | 9 +++++++-- src/video/win32_v.cpp | 8 +++++++- 3 files changed, 47 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp index 4d759e60f..c811be2ef 100644 --- a/src/video/opengl.cpp +++ b/src/video/opengl.cpp @@ -32,6 +32,8 @@ /* static */ OpenGLBackend *OpenGLBackend::instance = nullptr; +GetOGLProcAddressProc GetOGLProcAddress; + /** * Find a substring in a string made of space delimited elements. The substring * has to match the complete element, partial matches don't count. @@ -65,7 +67,31 @@ static const char *FindStringInExtensionList(const char *string, const char *sub */ static bool IsOpenGLExtensionSupported(const char *extension) { - return FindStringInExtensionList((const char *)glGetString(GL_EXTENSIONS), extension) != nullptr; + static PFNGLGETSTRINGIPROC glGetStringi = nullptr; + static bool glGetStringi_loaded = false; + + /* Starting with OpenGL 3.0 the preferred API to get the extensions + * has changed. Try to load the required function once. */ + if (!glGetStringi_loaded) { + if (IsOpenGLVersionAtLeast(3, 0)) glGetStringi = (PFNGLGETSTRINGIPROC)GetOGLProcAddress("glGetStringi"); + glGetStringi_loaded = true; + } + + if (glGetStringi != nullptr) { + /* New style: Each supported extension can be queried and compared independently. */ + GLint num_exts; + glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts); + + for (GLint i = 0; i < num_exts; i++) { + const char *entry = (const char *)glGetStringi(GL_EXTENSIONS, i); + if (strcmp(entry, extension) == 0) return true; + } + } else { + /* Old style: A single, space-delimited string for all extensions. */ + return FindStringInExtensionList((const char *)glGetString(GL_EXTENSIONS), extension) != nullptr; + } + + return false; } static byte _gl_major_ver = 0; ///< Major OpenGL version. @@ -78,7 +104,7 @@ static byte _gl_minor_ver = 0; ///< Minor OpenGL version. * @pre OpenGL was initialized. * @return True if the OpenGL version is equal or higher than the requested one. */ -static bool IsOpenGLVersionAtLeast(byte major, byte minor) +bool IsOpenGLVersionAtLeast(byte major, byte minor) { return (_gl_major_ver > major) || (_gl_major_ver == major && _gl_minor_ver >= minor); } @@ -86,11 +112,15 @@ static bool IsOpenGLVersionAtLeast(byte major, byte minor) /** * Create and initialize the singleton back-end class. + * @param get_proc Callback to get an OpenGL function from the OS driver. + * @return nullptr on success, error message otherwise. */ -/* static */ const char *OpenGLBackend::Create() +/* static */ const char *OpenGLBackend::Create(GetOGLProcAddressProc get_proc) { if (OpenGLBackend::instance != nullptr) OpenGLBackend::Destroy(); + GetOGLProcAddress = get_proc; + OpenGLBackend::instance = new OpenGLBackend(); return OpenGLBackend::instance->Init(); } diff --git a/src/video/opengl.h b/src/video/opengl.h index 9db1be5f5..08ef56b9a 100644 --- a/src/video/opengl.h +++ b/src/video/opengl.h @@ -14,7 +14,12 @@ #include "../core/alloc_type.hpp" -/** Platform-independent back-end singleton class for OpenGL video drivers. */ +typedef void (*OGLProc)(); +typedef OGLProc (*GetOGLProcAddressProc)(const char *proc); + +bool IsOpenGLVersionAtLeast(byte major, byte minor); + +/** Platform-independent back-end class for OpenGL video drivers. */ class OpenGLBackend : public ZeroedMemoryAllocator { private: static OpenGLBackend *instance; ///< Singleton instance pointer. @@ -33,7 +38,7 @@ public: { return OpenGLBackend::instance; } - static const char *Create(); + static const char *Create(GetOGLProcAddressProc get_proc); static void Destroy(); bool Resize(int w, int h, bool force = false); diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index c97dccf44..ddfe365f7 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -1331,6 +1331,12 @@ void VideoDriver_Win32GDI::PaintThread() # define PFD_SUPPORT_COMPOSITION 0x00008000 #endif +/** Platform-specific callback to get an OpenGL funtion pointer. */ +static OGLProc GetOGLProcAddressCallback(const char *proc) +{ + return reinterpret_cast(wglGetProcAddress(proc)); +} + static FVideoDriver_Win32OpenGL iFVideoDriver_Win32OpenGL; const char *VideoDriver_Win32OpenGL::Start(const StringList ¶m) @@ -1412,7 +1418,7 @@ const char *VideoDriver_Win32OpenGL::AllocateContext() if (this->gl_rc == 0) return "Can't create OpenGL context"; if (!wglMakeCurrent(this->dc, this->gl_rc)) return "Can't active GL context"; - return OpenGLBackend::Create(); + return OpenGLBackend::Create(&GetOGLProcAddressCallback); } bool VideoDriver_Win32OpenGL::ToggleFullscreen(bool full_screen) -- cgit v1.2.3-70-g09d2