WIP on configurable OpenGL loader. (#2001, #2002)
diff --git a/examples/example_glfw_opengl3/Makefile b/examples/example_glfw_opengl3/Makefile
index 8cfc9f3..3f5a372 100644
--- a/examples/example_glfw_opengl3/Makefile
+++ b/examples/example_glfw_opengl3/Makefile
@@ -18,17 +18,28 @@
 SOURCES = main.cpp
 SOURCES += ../imgui_impl_glfw.cpp ../imgui_impl_opengl3.cpp
 SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp
-SOURCES += ../libs/gl3w/GL/gl3w.c
 OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
 
 UNAME_S := $(shell uname -s)
 
+# Default OpenGL loader: gl3w
+SOURCES += ../libs/gl3w/GL/gl3w.c
+CXXFLAGS = -I../libs/gl3w
+
+# You can switch to glad by changing the following compilation options,
+# and changing the rule L73 of this Makefile
+# SOURCES += ../libs/glad/src/glad.c
+# CXXFLAGS = -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD
+
+# You can also use glew are you OpenGL loader
+# This assumes a system-wide installation
+# CXXFLAGS = -lGLEW -DIMGUI_IMPL_OPENGL_LOADER_GLEW
 
 ifeq ($(UNAME_S), Linux) #LINUX
 	ECHO_MESSAGE = "Linux"
 	LIBS = -lGL `pkg-config --static --libs glfw3`
 
-	CXXFLAGS = -I../ -I../../ -I../libs/gl3w `pkg-config --cflags glfw3`
+	CXXFLAGS += -I../ -I../../  `pkg-config --cflags glfw3`
 	CXXFLAGS += -Wall -Wformat
 	CFLAGS = $(CXXFLAGS)
 endif
@@ -39,7 +50,7 @@
 	#LIBS += -L/usr/local/lib -lglfw3
 	LIBS += -L/usr/local/lib -lglfw
 
-	CXXFLAGS = -I../ -I../../ -I../libs/gl3w -I/usr/local/include
+	CXXFLAGS += -I../ -I../../ -I/usr/local/include
 	CXXFLAGS += -Wall -Wformat
 	CFLAGS = $(CXXFLAGS)
 endif
@@ -48,7 +59,7 @@
    ECHO_MESSAGE = "Windows"
    LIBS = -lglfw3 -lgdi32 -lopengl32 -limm32
 
-   CXXFLAGS = -I../ -I../../ -I../libs/gl3w `pkg-config --cflags glfw3`
+   CXXFLAGS += -I../ -I../../ `pkg-config --cflags glfw3`
    CXXFLAGS += -Wall -Wformat
    CFLAGS = $(CXXFLAGS)
 endif
@@ -64,6 +75,7 @@
 	$(CXX) $(CXXFLAGS) -c -o $@ $<
 
 %.o:../libs/gl3w/GL/%.c
+# %.o:../libs/glad/src/%.c
 	$(CC) $(CFLAGS) -c -o $@ $<
 
 all: $(EXE)
diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp
index 1ed377c..d99ec3b 100644
--- a/examples/example_glfw_opengl3/main.cpp
+++ b/examples/example_glfw_opengl3/main.cpp
@@ -8,10 +8,16 @@
 #include "imgui_impl_opengl3.h"
 #include <stdio.h>
 
-#include <GL/gl3w.h>    // This example is using gl3w to access OpenGL functions. You may use another OpenGL loader/header such as: glew, glext, glad, glLoadGen, etc.
-//#include <glew.h>
-//#include <glext.h>
-//#include <glad/glad.h>
+// This example is using gl3w to access OpenGL functions. You may use another OpenGL loader/header such as: glew, glext, glad, glLoadGen, etc.
+#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
+#include <GL/gl3w.h>
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
+#include <GL/glew.h>
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
+#include <glad/glad.h>
+#else
+#pragma error("Cannot use custom loader for example application.")
+#endif
 
 #include <GLFW/glfw3.h> // Include glfw3.h after our OpenGL definitions
 
@@ -50,7 +56,19 @@
         return 1;
     glfwMakeContextCurrent(window);
     glfwSwapInterval(1); // Enable vsync
-    gl3wInit();
+#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
+    GLenum err = gl3wInit();
+    if (!err) {
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
+    GLenum err = glewInit();
+    if (GLEW_OK != err) {
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
+    GLenum err = gladLoadGL();
+    if (!err) {
+#endif
+        fprintf(stderr, "Failed to initialize OpenGL\n");
+        return 1;
+    }
 
     // Setup Dear ImGui binding
     IMGUI_CHECKVERSION();
@@ -67,8 +85,8 @@
     //ImGui::StyleColorsClassic();
 
     // Load Fonts
-    // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. 
-    // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. 
+    // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
+    // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
     // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
     // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
     // - Read 'misc/fonts/README.txt' for more instructions and details.
@@ -115,7 +133,7 @@
             ImGui::Checkbox("Demo Window", &show_demo_window);      // Edit bools storing our window open/close state
             ImGui::Checkbox("Another Window", &show_another_window);
 
-            ImGui::SliderFloat("float", &f, 0.0f, 1.0f);            // Edit 1 float using a slider from 0.0f to 1.0f    
+            ImGui::SliderFloat("float", &f, 0.0f, 1.0f);            // Edit 1 float using a slider from 0.0f to 1.0f
             ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
 
             if (ImGui::Button("Button"))                            // Buttons return true when clicked (most widgets return true when edited/activated)
@@ -146,7 +164,7 @@
         glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
         glClear(GL_COLOR_BUFFER_BIT);
         ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
-    	
+
         glfwMakeContextCurrent(window);
         glfwSwapBuffers(window);
     }
diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp
index 5f7095c..16a9eb4 100644
--- a/examples/imgui_impl_opengl3.cpp
+++ b/examples/imgui_impl_opengl3.cpp
@@ -9,7 +9,7 @@
 // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp.
 // https://github.com/ocornut/imgui
 
-// CHANGELOG 
+// CHANGELOG
 // (minor and older changes stripped away, please see git history for details)
 //  2018-08-09: OpenGL: Default to OpenGL ES 3 on iOS and Android. GLSL version default to "#version 300 ES".
 //  2018-07-30: OpenGL: Support for GLSL 300 ES and 410 core. Fixes for Emscripten compilation.
@@ -76,10 +76,17 @@
 // (About OpenGL function loaders: modern OpenGL doesn't have a standard header file and requires individual functions to be loaded manually. 
 //  Helper libraries are often used for this purpose! Here we are using gl3w.h, which requires a call to gl3wInit(). 
 //  You may use another any other loader/header of your choice, such as glew, glext, glad, glLoadGen, etc.)
+#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
 #include <GL/gl3w.h>
-//#include <glew.h>
-//#include <glext.h>
-//#include <glad/glad.h>
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
+#include <GL/glew.h>
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
+#include <glad/glad.h>
+#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEXT)
+#include <glext.h>
+#else
+#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
+#endif
 #endif
 
 // OpenGL Data
@@ -120,7 +127,7 @@
 
 // OpenGL3 Render function.
 // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
-// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. 
+// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
 void    ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
 {
     // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
@@ -136,7 +143,9 @@
     glActiveTexture(GL_TEXTURE0);
     GLint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
     GLint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
+#ifdef GL_SAMPLER_BINDING
     GLint last_sampler; glGetIntegerv(GL_SAMPLER_BINDING, &last_sampler);
+#endif
     GLint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer);
     GLint last_vertex_array; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array);
 #ifdef GL_POLYGON_MODE
@@ -186,7 +195,7 @@
 #ifdef GL_SAMPLER_BINDING
     glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
 #endif
-    // Recreate the VAO every time 
+    // Recreate the VAO every time
     // (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.)
     GLuint vao_handle = 0;
     glGenVertexArrays(1, &vao_handle);
diff --git a/examples/imgui_impl_opengl3.h b/examples/imgui_impl_opengl3.h
index 8593b9f..b5e93b0 100644
--- a/examples/imgui_impl_opengl3.h
+++ b/examples/imgui_impl_opengl3.h
@@ -11,7 +11,7 @@
 
 // About OpenGL function loaders:
 // Modern OpenGL requires individual functions to be loaded manually. Helper libraries are often used for this purpose.
-// Here we are using gl3w.h, which requires a call to gl3wInit(). 
+// Here we are using gl3w.h, which requires a call to gl3wInit().
 // You may use another any other loader/header of your choice, such as glew, glext, glad, glLoadGen, etc.
 
 // About GLSL version:
@@ -19,6 +19,14 @@
 // On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
 // Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
 
+// Set default OpenGL 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)
+#define IMGUI_IMPL_OPENGL_LOADER_GL3W
+#endif
+
 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();