Backends: OpenGL3: Attempt to automatically detect default GL loader by using __has_include. Followup to 44cd8e3 (#2798)
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index fa5d3d1..29b993f 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -74,6 +74,7 @@
usage has never been reported as a problem, so this is merely a touch of overzealous luxury. (#2636)
- Backends: OpenGL3: Tweaked initialization code allow application calling ImGui_ImplOpenGL3_CreateFontsTexture()
before ImGui_ImplOpenGL3_NewFrame() if for some reason they wanted.
+- Backends: OpenGL3: Attempt to automatically detect default GL loader by using __has_include. (#2798) [@o-micron]
- Backends: DX11: Fixed GSGetShader() call not passing an initialized instance count,
would generally make the debug layer complain (Added in 1.72).
- Backends: Vulkan: Added support for specifying multisample count.
diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp
index 76174a1..4833d1b 100644
--- a/examples/example_glfw_opengl3/main.cpp
+++ b/examples/example_glfw_opengl3/main.cpp
@@ -7,9 +7,10 @@
#include "imgui_impl_opengl3.h"
#include <stdio.h>
-// About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually.
-// Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad.
-// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
+// About Desktop OpenGL function loaders:
+// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
+// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
+// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp
index ae1ef5b..19d34e9 100644
--- a/examples/example_sdl_opengl3/main.cpp
+++ b/examples/example_sdl_opengl3/main.cpp
@@ -9,9 +9,10 @@
#include <stdio.h>
#include <SDL.h>
-// About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual function pointers to be loaded manually.
-// Helper libraries are often used for this purpose! Here we are supporting a few common ones: gl3w, glew, glad.
-// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
+// About Desktop OpenGL function loaders:
+// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function pointers.
+// Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad).
+// You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own.
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp
index 199638e..189814f 100644
--- a/examples/imgui_impl_opengl3.cpp
+++ b/examples/imgui_impl_opengl3.cpp
@@ -1,5 +1,5 @@
// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
-// - Desktop GL: 3.x 4.x
+// - Desktop GL: 2.x 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
@@ -13,6 +13,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility.
// 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call.
// 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
@@ -79,12 +80,21 @@
// Auto-detect GL version
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3)
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
-#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
+#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
+#undef IMGUI_IMPL_OPENGL_LOADER_GL3W
+#undef IMGUI_IMPL_OPENGL_LOADER_GLEW
+#undef IMGUI_IMPL_OPENGL_LOADER_GLAD
+#undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#elif defined(__EMSCRIPTEN__)
-#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
+#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
+#undef IMGUI_IMPL_OPENGL_LOADER_GL3W
+#undef IMGUI_IMPL_OPENGL_LOADER_GLEW
+#undef IMGUI_IMPL_OPENGL_LOADER_GLAD
+#undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif
#endif
+// GL includes
#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h>
#elif defined(IMGUI_IMPL_OPENGL_ES3)
@@ -149,6 +159,23 @@
strcpy(g_GlslVersionString, glsl_version);
strcat(g_GlslVersionString, "\n");
+ // Dummy construct to make it easily visible in the IDE and debugger which GL loader has been selected.
+ // The code actually never uses the 'gl_loader' variable! It is only here so you can read it!
+ // If auto-detection fails or doesn't select the same GL loader file as used by your application,
+ // you are likely to get a crash below.
+ // You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
+ const char* gl_loader = "Unknown";
+ IM_UNUSED(gl_loader);
+#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
+ gl_loader = "GL3W";
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
+ gl_loader = "GLEW";
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
+ gl_loader = "GLAD";
+#else IMGUI_IMPL_OPENGL_LOADER_CUSTOM
+ gl_loader = "Custom";
+#endif
+
// Make a dummy GL call (we don't actually need the result)
// IF YOU GET A CRASH HERE: it probably means that you haven't initialized the OpenGL function loader used by this code.
// Desktop OpenGL 3/4 need a function loader. See the IMGUI_IMPL_OPENGL_LOADER_xxx explanation above.
diff --git a/examples/imgui_impl_opengl3.h b/examples/imgui_impl_opengl3.h
index fbf2417..1cb790b 100644
--- a/examples/imgui_impl_opengl3.h
+++ b/examples/imgui_impl_opengl3.h
@@ -1,5 +1,5 @@
// dear imgui: Renderer for modern OpenGL with shaders / programmatic pipeline
-// - Desktop GL: 3.x 4.x
+// - Desktop GL: 2.x 3.x 4.x
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
// This needs to be used along with a Platform Binding (e.g. GLFW, SDL, Win32, custom..)
@@ -23,37 +23,42 @@
#pragma once
-// Specific OpenGL versions
-//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
-//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
-
-// Set default OpenGL3 loader to be gl3w
-#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
- && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
- && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
- && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
- // to avoid problem with non-clang compilers not having this macro.
- #if defined(__has_include)
- // check if the header exists, then automatically define the macros ..
- #if __has_include(<GL/glew.h>)
- #define IMGUI_IMPL_OPENGL_LOADER_GLEW
- #elif __has_include(<glad/glad.h>)
- #define IMGUI_IMPL_OPENGL_LOADER_GLAD
- #else
- #define IMGUI_IMPL_OPENGL_LOADER_GL3W
- #endif
- #else
- #define IMGUI_IMPL_OPENGL_LOADER_GL3W
- #endif
-#endif
-
+// Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = NULL);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
-// Called by Init/NewFrame/Shutdown
+// (Optional) Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
+
+// Specific OpenGL versions
+//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten
+//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android
+
+// Desktop OpenGL: attempt to detect default GL loader based on available header files.
+// If auto-detection fails or doesn't select the same GL loader file as used by your application,
+// you are likely to get a crash in ImGui_ImplOpenGL3_Init().
+// You can explicitly select a loader by using '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
+#if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \
+ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \
+ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \
+ && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
+ #if defined(__has_include)
+ #if __has_include(<GL/glew.h>)
+ #define IMGUI_IMPL_OPENGL_LOADER_GLEW
+ #elif __has_include(<glad/glad.h>)
+ #define IMGUI_IMPL_OPENGL_LOADER_GLAD
+ #elif __has_include(<GL/gl3w.h>)
+ #define IMGUI_IMPL_OPENGL_LOADER_GL3W
+ #else
+ #error "Cannot detect OpenGL loader!"
+ #endif
+ #else
+ #define IMGUI_IMPL_OPENGL_LOADER_GL3W // Default to GL3W
+ #endif
+#endif
+