(Breaking) Backends: OpenGL3: added ImGui_ImplOpenGL3_SetClipOrigin. Default to GL_LOWER_LEFT. (#2186, #3998, #3146, #3143, #8640)

This commit is contained in:
ocornut 2026-10-01 17:36:59 +02:00
parent fe33b77f64
commit a3f3e4944a
4 changed files with 34 additions and 11 deletions

View File

@ -24,7 +24,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (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-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-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) // 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 HasPolygonMode;
bool HasBindSampler; bool HasBindSampler;
bool HasClipOrigin; bool HasClipOrigin;
bool ClipOriginLowerLeft; GLenum ClipOriginRequest; // Default = GL_LOWER_LEFT. Change using ImGui_ImplOpenGL3_SetClipOrigin().
GLenum ClipOriginCurrent;
bool UseBufferSubData; bool UseBufferSubData;
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
GLuint TexSamplers[2]; // Used if HasBindSimpler. (0=linear, 1=nearest) 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 R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y; float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.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] = const float ortho_projection[4][4] =
{ {
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f }, { 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; 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. // OpenGL3 Render function.
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly. // 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. // 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 #endif
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT) // Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
bd->ClipOriginLowerLeft = true; bd->ClipOriginCurrent = bd->ClipOriginRequest;
if (bd->ClipOriginCurrent == 0)
{
bd->ClipOriginCurrent = GL_LOWER_LEFT;
#if defined(GL_CLIP_ORIGIN) #if defined(GL_CLIP_ORIGIN)
if (bd->HasClipOrigin) if (bd->HasClipOrigin)
{ glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&bd->ClipOriginCurrent);
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin);
bd->ClipOriginLowerLeft = (current_clip_origin != GL_UPPER_LEFT);
}
#endif #endif
}
// Setup desired GL state // 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) // 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; bd->HasClipOrigin = true;
} }
#endif #endif
bd->ClipOriginCurrent = bd->ClipOriginRequest = GL_LOWER_LEFT;
return true; return true;
} }

View File

@ -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. // (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); 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: // Configuration flags to add in your imconfig file:
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten) //#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) //#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)

View File

@ -303,6 +303,7 @@ typedef khronos_uint16_t GLushort;
#define GL_LINK_STATUS 0x8B82 #define GL_LINK_STATUS 0x8B82
#define GL_INFO_LOG_LENGTH 0x8B84 #define GL_INFO_LOG_LENGTH 0x8B84
#define GL_CURRENT_PROGRAM 0x8B8D #define GL_CURRENT_PROGRAM 0x8B8D
#define GL_LOWER_LEFT 0x8CA1
#define GL_UPPER_LEFT 0x8CA2 #define GL_UPPER_LEFT 0x8CA2
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);

View File

@ -53,6 +53,9 @@ Breaking Changes:
- DirectX12: Removed support for legacy `ImGui_ImplDX12_Init()` signature, which was - 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 obsoleted in 1.91.6 (December 2014), because it needed to forcefully disable support
for `ImGuiBackendFlags_RendererHasTextures`. Use the new signature! (#9487) 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: Other Changes:
@ -148,8 +151,11 @@ Other Changes:
callback to request using the sampler associated already associated to a texture. (#9378) callback to request using the sampler associated already associated to a texture. (#9378)
- OpenGL2, OpenGL3: fixed `DrawCallback_ResetRenderState` handler not reseting all states - OpenGL2, OpenGL3: fixed `DrawCallback_ResetRenderState` handler not reseting all states
in the glTexParameter() path. (#9378) in the glTexParameter() path. (#9378)
- OpenGL3: avoid querying `glGetIntegerv(GL_CLIP_ORIGIN)` again when using `DrawCallback_ResetRenderState`, - OpenGL3: added `ImGui_ImplOpenGL3_SetClipOrigin()` to specify origin between
at it appear to stall some drivers. (#2186, #3998, #3146, #3143, #8640) `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 - SDL2: fixed querying framebuffer scale/density when using Metal without
going through a SDL_Renderer. (#5592) [@lailoken] going through a SDL_Renderer. (#5592) [@lailoken]
- SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378) - SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378)