diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index b3a510bcd525..987b0740eca8 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -22,6 +22,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-04-16: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447) // 2024-01-09: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" and variants, fixing regression on distros missing a symlink. // 2023-11-08: OpenGL: Update GL3W based imgui_impl_opengl3_loader.h to load "libGL.so" instead of "libGL.so.1", accommodating for NetBSD systems having only "libGL.so.3" available. (#6983) // 2023-10-05: OpenGL: Rename symbols in our internal loader so that LTO compilation with another copy of gl3w is possible. (#6875, #6668, #4445) @@ -177,9 +178,10 @@ #endif // Desktop GL 2.0+ has extension and glPolygonMode() which GL ES and WebGL don't have.. +// A desktop ES context can technically compile fine with our loader, so we also perform a runtime checks #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) #define IMGUI_IMPL_OPENGL_HAS_EXTENSIONS // has glGetIntegerv(GL_NUM_EXTENSIONS) -#define IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE // has glPolygonMode() +#define IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE // may have glPolygonMode() #endif // Desktop GL 2.1+ and GL ES 3.0+ have glBindBuffer() with GL_PIXEL_UNPACK_BUFFER target. @@ -230,6 +232,7 @@ struct ImGui_ImplOpenGL3_Data unsigned int VboHandle, ElementsHandle; GLsizeiptr VertexBufferSize; GLsizeiptr IndexBufferSize; + bool HasPolygonMode; bool HasClipOrigin; bool UseBufferSubData; @@ -294,16 +297,13 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) bd->GlProfileIsES2 = true; #else // Desktop or GLES 3 + const char* gl_version_str = (const char*)glGetString(GL_VERSION); GLint major = 0; GLint minor = 0; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); if (major == 0 && minor == 0) - { - // Query GL_VERSION in desktop GL 2.x, the string will start with "." - const char* gl_version = (const char*)glGetString(GL_VERSION); - sscanf(gl_version, "%d.%d", &major, &minor); - } + sscanf(gl_version_str, "%d.%d", &major, &minor); // Query GL_VERSION in desktop GL 2.x, the string will start with "." bd->GlVersion = (GLuint)(major * 100 + minor * 10); #if defined(GL_CONTEXT_PROFILE_MASK) if (bd->GlVersion >= 320) @@ -313,6 +313,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) #if defined(IMGUI_IMPL_OPENGL_ES3) bd->GlProfileIsES3 = true; +#else + if (strncmp(gl_version_str, "OpenGL ES 3", 11) == 0) + bd->GlProfileIsES3 = true; #endif bd->UseBufferSubData = false; @@ -327,7 +330,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) #endif #ifdef IMGUI_IMPL_OPENGL_DEBUG - printf("GlVersion = %d\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG] + printf("GlVersion = %d, \"%s\"\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, gl_version_str, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG] #endif #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET @@ -359,6 +362,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) glGetIntegerv(GL_TEXTURE_BINDING_2D, ¤t_texture); // Detect extensions we support +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE + bd->HasPolygonMode = (!bd->GlProfileIsES2 && !bd->GlProfileIsES3); +#endif bd->HasClipOrigin = (bd->GlVersion >= 450); #ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS GLint num_extensions = 0; @@ -412,8 +418,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid if (bd->GlVersion >= 310) glDisable(GL_PRIMITIVE_RESTART); #endif -#ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE + if (bd->HasPolygonMode) + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); #endif // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) @@ -501,8 +508,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) #ifdef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY GLuint last_vertex_array_object; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object); #endif -#ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE - GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE + GLint last_polygon_mode[2]; if (bd->HasPolygonMode) { glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode); } #endif GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport); GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box); @@ -640,18 +647,10 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) if (bd->GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); } #endif -#ifdef IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE +#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE // Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons - if (bd->GlVersion <= 310 || bd->GlProfileIsCompat) - { - glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); - glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); - } - else - { - glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); - } -#endif // IMGUI_IMPL_OPENGL_HAS_POLYGON_MODE + if (bd->HasPolygonMode) { if (bd->GlVersion <= 310 || bd->GlProfileIsCompat) { glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); } else { glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); } } +#endif // IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index fdf2919939eb..5f8654ce2c5a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -48,6 +48,8 @@ Other changes: duplicate with this fix. (#7399, #7404) [@GamingMinds-DanielC] - Text, DrawList: Improved handling of long single-line wrapped text. Faster and mitigitate issues with reading vertex indexing limits with 16-bit indices. (#7496, #5720) +- Backends: OpenGL: Detect ES3 contexts on desktop based on version string, + to e.g. avoid calling glPolygonMode() on them. (#7447) [@afraidofdark, @ocornut] - Backends: SDL3: Fixed text inputs. Re-enable calling SDL_StartTextInput()/SDL_StopTextInput() as SDL3 no longer enables it by default. (#7452, #6306, #6071, #1953) [@Green-Sky] - Examples: GLFW+WebGPU: Added support for WebGPU-native/Dawn (#7435, #7132) [@eliasdaler, @Zelif]