From a3f3e4944a2aa6053e8876fe55a4ebad404d08d6 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 1 Oct 2026 17:36:59 +0200 Subject: [PATCH] (Breaking) Backends: OpenGL3: added ImGui_ImplOpenGL3_SetClipOrigin. Default to GL_LOWER_LEFT. (#2186, #3998, #3146, #3143, #8640) --- backends/imgui_impl_opengl3.cpp | 31 ++++++++++++++++++++-------- backends/imgui_impl_opengl3.h | 3 +++ backends/imgui_impl_opengl3_loader.h | 1 + docs/CHANGELOG.txt | 10 +++++++-- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index 7c07eb008..568067c5f 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -24,7 +24,9 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2026-10-01: OpenGL: Avoid querying glGetIntegerv(GL_CLIP_ORIGIN) again when using DrawCallback_ResetRenderState. (#2186, #3998, #3146, #3143, #8640) +// 2026-10-01: OpenGL: Added ImGui_ImplOpenGL3_SetClipOrigin() to specify clip origins (GL_LOWER_LEFT/GL_UPPER_LEFT, or use 0 to autodetect). (#2186, #3998, #3146, #3143, #8640) +// (Breaking): we now default to GL_LOWER_LEFT instead of 0=autodetect. Because 1) detection is not reliable and 2) is slow. +// 2026-10-01: OpenGL: Avoid querying glGetIntegerv(GL_CLIP_ORIGIN) multiple times when using DrawCallback_ResetRenderState. (#2186, #3998, #3146, #3143, #8640) // 2026-09-17: OpenGL: Added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378) // 2026-09-07: OpenGL: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628) // 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473) @@ -260,7 +262,8 @@ struct ImGui_ImplOpenGL3_Data bool HasPolygonMode; bool HasBindSampler; bool HasClipOrigin; - bool ClipOriginLowerLeft; + GLenum ClipOriginRequest; // Default = GL_LOWER_LEFT. Change using ImGui_ImplOpenGL3_SetClipOrigin(). + GLenum ClipOriginCurrent; bool UseBufferSubData; #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER GLuint TexSamplers[2]; // Used if HasBindSimpler. (0=linear, 1=nearest) @@ -370,7 +373,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x; float T = draw_data->DisplayPos.y; float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y; - if (!bd->ClipOriginLowerLeft) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left + if (bd->ClipOriginCurrent == GL_UPPER_LEFT) { float tmp = T; T = B; B = tmp; } // Swap top and bottom const float ortho_projection[4][4] = { { 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, @@ -452,6 +455,14 @@ static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerFromTex(const ImDrawList*, render_state->UseTexParameterFilter = false; } +// Default is GL_LOWER_LEFT since 2026/10/01. Used to be auto. +void ImGui_ImplOpenGL3_SetClipOrigin(unsigned int clip_origin) +{ + IM_ASSERT(clip_origin == 0 || clip_origin == GL_UPPER_LEFT || clip_origin == GL_LOWER_LEFT); + ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData(); + bd->ClipOriginRequest = clip_origin; +} + // OpenGL3 Render function. // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly. // This is in order to be able to run within an OpenGL engine that doesn't do so. @@ -514,14 +525,15 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data) #endif // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) - bd->ClipOriginLowerLeft = true; -#if defined(GL_CLIP_ORIGIN) - if (bd->HasClipOrigin) + bd->ClipOriginCurrent = bd->ClipOriginRequest; + if (bd->ClipOriginCurrent == 0) { - GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin); - bd->ClipOriginLowerLeft = (current_clip_origin != GL_UPPER_LEFT); - } + bd->ClipOriginCurrent = GL_LOWER_LEFT; +#if defined(GL_CLIP_ORIGIN) + if (bd->HasClipOrigin) + glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&bd->ClipOriginCurrent); #endif + } // Setup desired GL state // Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts) @@ -1149,6 +1161,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) bd->HasClipOrigin = true; } #endif + bd->ClipOriginCurrent = bd->ClipOriginRequest = GL_LOWER_LEFT; return true; } diff --git a/backends/imgui_impl_opengl3.h b/backends/imgui_impl_opengl3.h index e1d999bd3..17a49cd51 100644 --- a/backends/imgui_impl_opengl3.h +++ b/backends/imgui_impl_opengl3.h @@ -44,6 +44,9 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); // (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = nullptr to handle this manually. IMGUI_IMPL_API void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex); +// (Advanced) Specify clip origin, same value as glClipControl() or 0 for auto-detection. +IMGUI_IMPL_API void ImGui_ImplOpenGL3_SetClipOrigin(unsigned int gl_clip_origin); + // Configuration flags to add in your imconfig file: //#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten) //#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android) diff --git a/backends/imgui_impl_opengl3_loader.h b/backends/imgui_impl_opengl3_loader.h index 34b262dff..47f9fb364 100644 --- a/backends/imgui_impl_opengl3_loader.h +++ b/backends/imgui_impl_opengl3_loader.h @@ -303,6 +303,7 @@ typedef khronos_uint16_t GLushort; #define GL_LINK_STATUS 0x8B82 #define GL_INFO_LOG_LENGTH 0x8B84 #define GL_CURRENT_PROGRAM 0x8B8D +#define GL_LOWER_LEFT 0x8CA1 #define GL_UPPER_LEFT 0x8CA2 typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 8fbc0b8ed..e0d0d9264 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -53,6 +53,9 @@ Breaking Changes: - DirectX12: Removed support for legacy `ImGui_ImplDX12_Init()` signature, which was obsoleted in 1.91.6 (December 2014), because it needed to forcefully disable support for `ImGuiBackendFlags_RendererHasTextures`. Use the new signature! (#9487) + - OpenGL3: Does not attempt to read `GL_CLIP_ORIGIN` by default as the detection is + sub-optimal and not reliable on some setup. Use `ImGui_ImplOpenGL3_SetClipOrigin(0)` + to enable auto-detection, or e.g. `ImGui_ImplOpenGL3_SetClipOrigin(GL_UPPER_LEFT)`. Other Changes: @@ -148,8 +151,11 @@ Other Changes: callback to request using the sampler associated already associated to a texture. (#9378) - OpenGL2, OpenGL3: fixed `DrawCallback_ResetRenderState` handler not reseting all states in the glTexParameter() path. (#9378) - - OpenGL3: avoid querying `glGetIntegerv(GL_CLIP_ORIGIN)` again when using `DrawCallback_ResetRenderState`, - at it appear to stall some drivers. (#2186, #3998, #3146, #3143, #8640) + - OpenGL3: added `ImGui_ImplOpenGL3_SetClipOrigin()` to specify origin between + `GL_LOWER_LEFT` (new default), `GL_UPPER_LEFT` and `0` (autodetect, old default). + - OpenGL3: avoid querying `glGetIntegerv(GL_CLIP_ORIGIN)` multiple times when using + when using default and using `DrawCallback_ResetRenderState`, at it appear to stall + some drivers. (#2186, #3998, #3146, #3143, #8640) - SDL2: fixed querying framebuffer scale/density when using Metal without going through a SDL_Renderer. (#5592) [@lailoken] - SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378)