From b8a9c4f19018c72ae7c8327cb4fd111e4129c2e8 Mon Sep 17 00:00:00 2001
From: Lyzev <lyzev.info@gmail.com>
Date: Sat, 1 Feb 2025 20:56:02 +0100
Subject: [PATCH] fix(ImGuiImplGl3): enhance OpenGL compatibility checks for
 sampler objects

---
 .../src/main/java/imgui/gl3/ImGuiImplGl3.java  | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java b/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java
index 1137716a..9ddc3f2c 100644
--- a/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java
+++ b/imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java
@@ -11,6 +11,8 @@
 import imgui.flag.ImGuiConfigFlags;
 import imgui.flag.ImGuiViewportFlags;
 import imgui.type.ImInt;
+import org.lwjgl.opengl.GL;
+import org.lwjgl.opengl.GLCapabilities;
 
 import java.nio.ByteBuffer;
 import java.util.regex.Matcher;
@@ -157,6 +159,7 @@ protected static class Data {
 //        protected boolean glProfileIsES3;
         protected boolean glProfileIsCompat;
         protected int glProfileMask;
+        protected GLCapabilities glCapabilities = null;
         protected String glslVersion = "";
         protected int fontTexture = 0;
         protected int shaderHandle = 0;
@@ -273,6 +276,15 @@ public boolean init(final String glslVersion) {
             data.glVersion = major * 100 + minor * 10;
             data.glProfileMask = glGetInteger(GL_CONTEXT_PROFILE_MASK);
             data.glProfileIsCompat = (data.glProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
+            if (data.glVersion < 330) { // Ignore in higher GL versions since they support sampler objects anyway
+                try {
+                    data.glCapabilities = GL.getCapabilities();
+                } catch (IllegalStateException ignored) {
+                    // IllegalStateException – if setCapabilities has never been called in the current thread or was last called with a null value
+                    // This exception can be safely ignored as it does not impact the initialization process.
+                    // GL_ARB_sampler_objects will be unavailable (and therefore not supported) if the GL version is less than 3.3.
+                }
+            }
         }
 
         // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
@@ -381,7 +393,7 @@ protected void setupRenderState(final ImDrawData drawData, final int fbWidth, fi
         glUniform1i(data.attribLocationTex, 0);
         glUniformMatrix4fv(data.attribLocationProjMtx, false, props.orthoProjMatrix);
 
-        if (data.glVersion >= 330) {
+        if (data.glVersion >= 330 || (data.glCapabilities != null && data.glCapabilities.GL_ARB_sampler_objects)) {
             glBindSampler(0, 0);
         }
 
@@ -421,7 +433,7 @@ public void renderDrawData(final ImDrawData drawData) {
         glActiveTexture(GL_TEXTURE0);
         glGetIntegerv(GL_CURRENT_PROGRAM, props.lastProgram);
         glGetIntegerv(GL_TEXTURE_BINDING_2D, props.lastTexture);
-        if (data.glVersion >= 330) {
+        if (data.glVersion >= 330 || (data.glCapabilities != null && data.glCapabilities.GL_ARB_sampler_objects)) {
             glGetIntegerv(GL_SAMPLER_BINDING, props.lastSampler);
         }
         glGetIntegerv(GL_ARRAY_BUFFER_BINDING, props.lastArrayBuffer);
@@ -525,7 +537,7 @@ public void renderDrawData(final ImDrawData drawData) {
             glUseProgram(props.lastProgram[0]);
         }
         glBindTexture(GL_TEXTURE_2D, props.lastTexture[0]);
-        if (data.glVersion >= 330) {
+        if (data.glVersion >= 330 || (data.glCapabilities != null && data.glCapabilities.GL_ARB_sampler_objects)) {
             glBindSampler(0, props.lastSampler[0]);
         }
         glActiveTexture(props.lastActiveTexture[0]);