compile error in example if IMGUI_IMPL_OPENGL_LOADER_CUSTOM is defined #2178

Closed
opened 2018-11-08 03:13:52 +00:00 by doug-moen · 5 comments
doug-moen commented 2018-11-08 03:13:52 +00:00 (Migrated from github.com)

Version/Branch of Dear ImGui:

Version 1.65 :

Back-end file/Renderer/OS: (or specify if you are using a custom engine back-end)

Back-ends: imgui_impl_opengl3.cpp, imgui_impl_glfw.cpp
OS: Ubuntu 16.04
Compiler: gcc 5.4.0

My Issue/Question: (please provide context)

examples/example_glfw_opengl3/main.cpp fails to compile
if IMGUI_IMPL_OPENGL_LOADER_CUSTOM is defined.
The problem is here:

    // Initialize OpenGL loader
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
    bool err = gl3wInit() != 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
    bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
    bool err = gladLoadGL() != 0;
#endif
    if (err)
    {
        fprintf(stderr, "Failed to initialize OpenGL loader!\n");
        return 1;
    }

If IMGUI_IMPL_OPENGL_LOADER_CUSTOM is defined,
then none of IMGUI_IMPL_OPENGL_LOADER_{GL3W,GLEW,GLAD} are defined,
thus the local variable err is not defined,
and thus you get a compile time error:

/.../imgui/examples/example_glfw_opengl3/main.cpp: In function ‘int main(int, char**)’:
/.../imgui/examples/example_glfw_opengl3/main.cpp:69:9: error: ‘err’ was not declared in this scope
     if (err)
         ^

I suspect that the bug was introduced with the changes for #2001.

**Version/Branch of Dear ImGui:** Version 1.65 : **Back-end file/Renderer/OS:** _(or specify if you are using a custom engine back-end)_ Back-ends: imgui_impl_opengl3.cpp, imgui_impl_glfw.cpp OS: Ubuntu 16.04 Compiler: gcc 5.4.0 **My Issue/Question:** _(please provide context)_ `examples/example_glfw_opengl3/main.cpp` fails to compile if `IMGUI_IMPL_OPENGL_LOADER_CUSTOM` is defined. The problem is here: ``` // Initialize OpenGL loader #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) bool err = gl3wInit() != 0; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() != 0; #endif if (err) { fprintf(stderr, "Failed to initialize OpenGL loader!\n"); return 1; } ``` If `IMGUI_IMPL_OPENGL_LOADER_CUSTOM` is defined, then none of `IMGUI_IMPL_OPENGL_LOADER_{GL3W,GLEW,GLAD}` are defined, thus the local variable `err` is not defined, and thus you get a compile time error: ``` /.../imgui/examples/example_glfw_opengl3/main.cpp: In function ‘int main(int, char**)’: /.../imgui/examples/example_glfw_opengl3/main.cpp:69:9: error: ‘err’ was not declared in this scope if (err) ^ ``` I suspect that the bug was introduced with the changes for #2001.
ocornut commented 2018-11-08 07:05:58 +00:00 (Migrated from github.com)

Hello,

What do you expect should happen or be done? The examples’ main.cpp can’t implement initialization for an unknown loader. This define makes sense to use the imgui_impl_opengl3 file in your own code, how are you trying to use it here?

Hello, What do you expect should happen or be done? The examples’ main.cpp can’t implement initialization for an unknown loader. This define makes sense to use the imgui_impl_opengl3 file in your own code, how are you trying to use it here?
doug-moen commented 2018-11-08 13:01:00 +00:00 (Migrated from github.com)

I started OpenGL programming by copying another project on github and modifying it. As a result, my code doesn't use a loader library, because the project I copied doesn't. I just ask GLFW to include the OpenGL headers for me, with no loader library. My custom header does this:

#define GLFW_INCLUDE_GLEXT
#define GL_GLEXT_PROTOTYPES
#include <GLFW/glfw3.h>

I modified examples/example_glfw_opengl3/main.cpp, changing this:

#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
    bool err = gl3wInit() != 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
    bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
    bool err = gladLoadGL() != 0;
#endif

to this:

#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
    bool err = gl3wInit() != 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
    bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
    bool err = gladLoadGL() != 0;
#else
    bool err = false;
#endif

and everything works fine on Linux. The ImGui example works, and my code that uses ImGui also works. The new code also looks more correct from a pure programming perspective, since the variable err is now defined in all cases.

I didn't bother to learn about OpenGL loader libraries until now. Somehow I've managed to work on my project for several years without having this knowledge. Now that I've researched the topic, I see claims that just including the opengl headers doesn't work; you need to use a loader library. I use OpenGL3 with shaders, so my code shouldn't work as written. I'm going to make a guess that this claim is more true on Windows and MacOS than it is on Linux.

If you are saying that ImGui requires a loader, and that using OpenGL without a loader is not supported by the ImGui examples, then just close this issue.

I'm going to try and modify my project to use GLAD, since that appears to be the most popular loader.

I started OpenGL programming by copying another project on github and modifying it. As a result, my code doesn't use a loader library, because the project I copied doesn't. I just ask GLFW to include the OpenGL headers for me, with no loader library. My custom header does this: ``` #define GLFW_INCLUDE_GLEXT #define GL_GLEXT_PROTOTYPES #include <GLFW/glfw3.h> ``` I modified `examples/example_glfw_opengl3/main.cpp`, changing this: ``` #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) bool err = gl3wInit() != 0; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() != 0; #endif ``` to this: ``` #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) bool err = gl3wInit() != 0; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() != 0; #else bool err = false; #endif ``` and everything works fine on Linux. The ImGui example works, and my code that uses ImGui also works. The new code also looks more correct from a pure programming perspective, since the variable `err` is now defined in all cases. I didn't bother to learn about OpenGL loader libraries until now. Somehow I've managed to work on my project for several years without having this knowledge. Now that I've researched the topic, I see claims that just including the opengl headers doesn't work; you need to use a loader library. I use OpenGL3 with shaders, so my code shouldn't work as written. I'm going to make a guess that this claim is more true on Windows and MacOS than it is on Linux. If you are saying that ImGui requires a loader, and that using OpenGL without a loader is not supported by the ImGui examples, then just close this issue. I'm going to try and modify my project to use GLAD, since that appears to be the most popular loader.
ocornut commented 2018-11-08 14:32:06 +00:00 (Migrated from github.com)

You are right here, it's just that I didn't expect the examples/ main.cpp file to ever compile as-is with any other loaders (when using IMGUI_IMPL_OPENGL_LOADER_CUSTOM). But at it happens, glext.h does not requires any initialization and saw your setup works perfectly. Given that I made the change you have requested. Thanks!

There's some friction to provide a IMGUI_IMPL_OPENGL_LOADER_GLEXT out of the box: glext.h is not available by default under Windows, and gl.h+glext.h tend to requires specific os-related included which would increase the size of the include blocks in main.cpp and _opengl3.cpp - but that's possible to do later, I just need to investigate it a little further. Basically we need to be copying what's done in glfw3.h or glfw3native.h which is a little messy.

You are right here, it's just that I didn't expect the examples/ main.cpp file to ever compile as-is with any other loaders (when using IMGUI_IMPL_OPENGL_LOADER_CUSTOM). But at it happens, `glext.h` does not requires any initialization and saw your setup works perfectly. Given that I made the change you have requested. Thanks! There's some friction to provide a IMGUI_IMPL_OPENGL_LOADER_GLEXT out of the box: glext.h is not available by default under Windows, and gl.h+glext.h tend to requires specific os-related included which would increase the size of the include blocks in main.cpp and _opengl3.cpp - but that's possible to do later, I just need to investigate it a little further. Basically we need to be copying what's done in `glfw3.h` or `glfw3native.h` which is a little messy.
ocornut commented 2018-11-08 14:48:38 +00:00 (Migrated from github.com)

For the records, here's a block to add in main.cpp/imgui_impl_opengl3.cpp to use glext without GLFW. It's only tested under Windows however.
Given the mess/nature of using glext.h I think it is preferable to not add support for IMGUI_IMPL_OPENGL_LOADER_GLEXT and let the user go through a third-party like you are with GLFW_INCLUDE_GLEXT.

#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEXT)
#if defined(_WIN32) && !defined(APIENTRY)
#define APIENTRY __stdcall
#endif
#if defined(_WIN32) && !defined(WINGDIAPI)
#define WINGDIAPI __declspec(dllimport)
#endif
#include <GL/gl.h>
#include <GL/glext.h>   // No initialization is required for glext.h, but including gl.h + glext.h requires extra definitions on Windows.
#else
#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif

Link to #2001, #2002.

For the records, here's a block to add in main.cpp/imgui_impl_opengl3.cpp to use glext _without_ GLFW. It's only tested under Windows however. Given the mess/nature of using glext.h I think it is preferable to not add support for `IMGUI_IMPL_OPENGL_LOADER_GLEXT` and let the user go through a third-party like you are with `GLFW_INCLUDE_GLEXT`. ``` #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEXT) #if defined(_WIN32) && !defined(APIENTRY) #define APIENTRY __stdcall #endif #if defined(_WIN32) && !defined(WINGDIAPI) #define WINGDIAPI __declspec(dllimport) #endif #include <GL/gl.h> #include <GL/glext.h> // No initialization is required for glext.h, but including gl.h + glext.h requires extra definitions on Windows. #else #include IMGUI_IMPL_OPENGL_LOADER_CUSTOM #endif ``` Link to #2001, #2002.
doug-moen commented 2018-11-09 21:20:55 +00:00 (Migrated from github.com)

Thanks @ocornut.
FYI, libepoxy is another loader library that doesn't require initialization code. I haven't tried it. The advantages are no initialization and lazy loading.

Thanks @ocornut. FYI, libepoxy is another loader library that doesn't require initialization code. I haven't tried it. The advantages are no initialization and lazy loading.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ocornut/imgui#2178
No description provided.