Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[imgui] issue with opengl bindings #14753

Closed
cloudhan opened this issue Nov 24, 2020 · 27 comments · Fixed by #15063
Closed

[imgui] issue with opengl bindings #14753

cloudhan opened this issue Nov 24, 2020 · 27 comments · Fixed by #15063
Assignees
Labels
category:port-bug The issue is with a library, which is something the port should already support depends:upstream-changes Waiting on a change to the upstream project

Comments

@cloudhan
Copy link
Member


Is your feature request related to a problem? Please describe.
vcpkg install imgui[opengl3-glbinding-binding,glfw-binding]:x64-windows will build with glew.

resulting

[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewActiveTexture referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBlendEquation referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBlendFuncSeparate referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBindBuffer referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBufferData referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewDeleteBuffers referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGenBuffers referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewAttachShader referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBlendEquationSeparate referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewCompileShader referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewCreateProgram referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewCreateShader referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewDeleteProgram referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewDeleteShader referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewDetachShader referenced in function "void __cdecl ImGui_ImplOpenGL3_DestroyDeviceObjects(void)" (?ImGui_ImplOpenGL3_DestroyDeviceObjects@@YAXXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewEnableVertexAttribArray referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGetAttribLocation referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGetProgramInfoLog referenced in function "bool __cdecl CheckProgram(unsigned int,char const *)" (?CheckProgram@@YA_NIPEBD@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGetProgramiv referenced in function "bool __cdecl CheckProgram(unsigned int,char const *)" (?CheckProgram@@YA_NIPEBD@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGetShaderInfoLog referenced in function "bool __cdecl CheckShader(unsigned int,char const *)" (?CheckShader@@YA_NIPEBD@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGetShaderiv referenced in function "bool __cdecl CheckShader(unsigned int,char const *)" (?CheckShader@@YA_NIPEBD@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGetUniformLocation referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewLinkProgram referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewShaderSource referenced in function "bool __cdecl ImGui_ImplOpenGL3_CreateDeviceObjects(void)" (?ImGui_ImplOpenGL3_CreateDeviceObjects@@YA_NXZ) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewUniform1i referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewUniformMatrix4fv referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewUseProgram referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewVertexAttribPointer referenced in function "void __cdecl ImGui_ImplOpenGL3_SetupRenderState(struct ImDrawData *,int,int,unsigned int)" (?ImGui_ImplOpenGL3_SetupRenderState@@YAXPEAUImDrawData@@HHI@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewDrawElementsBaseVertex referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBindSampler referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewBindVertexArray referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewDeleteVertexArrays referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]
[build] imguid.lib(imgui_impl_opengl3.cpp.obj) : error LNK2019: unresolved external symbol __imp___glewGenVertexArrays referenced in function "void __cdecl ImGui_ImplOpenGL3_RenderDrawData(struct ImDrawData *)" (?ImGui_ImplOpenGL3_RenderDrawData@@YAXPEAUImDrawData@@@Z) [****.vcxproj]

Proposed solution

So lets make the problem clear first. For opengl there are two types of helper library commonly used.

  1. OpenGL symbol loader: e.g. glbinding, glew, gl3w, etc.
  2. OpenGL window and context helper: e.g. glfw, glut

In this case, imgui[opengl3-glbinding-binding,glfw-binding] is actually built as imgui[opengl3-glew-binding,glfw-binding], resulting glew symbols in the imguid.lib file.

This should be fix.

Describe alternatives you've considered

Even the above issue is fixed, there will be potential problem:

  1. project A use glew + glfw
  2. project B use glbinding + glfw
  3. project C use DX12
  4. ...

since there will be no way to let one installation of vcpkg to supply polymorphic imgui.lib, this problem will never be solved if vcpkg building bindings into library code.

The only solution I can come up with is copying bindings imgui_impl_*.cpp files into imgui's include folder. Let the use do

// imgui_impl.cpp file
// assuming the user use glbinding + glfw

// user do necessary definition

#include <bindings/imgui_impl_glfw.cpp>
#include <bindings/imgui_impl_opengl3.cpp>

and let the user compile this source and link the obj file to its executable.

@JackBoosY JackBoosY added the requires:repro The issue is not currently repro-able label Nov 25, 2020
@JackBoosY
Copy link
Contributor

Is this a build issue or usage issue? I can build imgui succesfully.
Imgui use unofficial CMakeLists.txt to be built currentlly, and it has some problems. See ocornut/imgui#1713

@cloudhan
Copy link
Member Author

Build Issue. glew symbol is included, when it should not.

@cloudhan
Copy link
Member Author

See this minimum reproduce.

issue-14753.zip

@JackBoosY
Copy link
Contributor

Confirmed.

@JackBoosY JackBoosY added category:port-bug The issue is with a library, which is something the port should already support and removed requires:repro The issue is not currently repro-able labels Nov 26, 2020
@JackBoosY
Copy link
Contributor

@RT222 Seems most of these binding features are missing export the dependency libraries. Can you confirm this?

@RT2Code
Copy link
Contributor

RT2Code commented Dec 4, 2020

I'm sorry about this, but this problem is beyond my comprehension, and I currently lack the time to dig into it. If it helps, I can revert my changes to get back to the old fashioned way of including the sources files manually.

@JackBoosY
Copy link
Contributor

@RT222 Fine, I will handle this.

@xarthurx
Copy link
Contributor

xarthurx commented Dec 18, 2020

Same issue here.
Using libigl with imgui support, and got exactly the same errors.

@MrSimbax
Copy link

MrSimbax commented Feb 21, 2021

Problem

I have both GLEW and Glad installed by Vcpkg, as I need them both for different projects. Dear ImGui doesn't work for the project with Glad (and it was working fine before).

The latter project uses the Glad loader with SDL2 window therefore I used the following command to install Dear ImGui:

./vcpkg.exe install imgui[sdl2-binding,opengl3-glad-binding]

However, this resulted in linker errors similar to the ones in the OP's post. imguid.lib contained some Glew symbols. So I tried installing the Glew bindings too even though my application doesn't use Glew.

./vcpkg.exe install imgui[sdl2-binding,opengl3-glad-binding,opengl3-glew-binding]

My application then linked fine but it crashed on ImGui_ImplOpenGL3_NewFrame() with access violation exception.

Root cause

I've found out with Visual Studio debugger that ImGui_ImplOpenGL3_NewFrame() was trying to call glCreateShader() but it expanded to wrong memory address 0 (nullptr). This usually means that the loader library wasn't properly initialized with a function like gladLoadGLLoader() beforehand but I found no such issue in my code.

Turns out that ImGui was compiled by Vcpkg with wrong header included in imgui_impl_opengl3.cpp.

The question is, why was the GLEW header used instead of Glad header? So it seems that the OpenGL loader is automatically detected by preprocessor based on available header files. Unfortunately, due to the order of ifs it seems Vcpkg compiled the ImGui with the GLEW bindings instead of the Glad bindings.

Workaround

I guess uninstalling Glew or using separate Vcpkg installation with only one loader installed would work. However, I find those workarounds too annoying and managed to find another way to fix it. See the following change in Vcpkg:

diff --git a/ports/imgui/CMakeLists.txt b/ports/imgui/CMakeLists.txt
index f6f85b29e..4aa77096e 100644
--- a/ports/imgui/CMakeLists.txt
+++ b/ports/imgui/CMakeLists.txt
@@ -81,6 +81,7 @@ endif()
 if(IMGUI_BUILD_OPENGL3_GLAD_BINDING)
     find_package(glad CONFIG REQUIRED)
     target_link_libraries(${PROJECT_NAME} PUBLIC glad::glad)
+    target_compile_definitions(${PROJECT_NAME} PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD)
     target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
 endif()

I hope it helps somebody with a similar issue.

Also, please consider adding the compile definitions for all loaders. It will ensure that the correct variant is installed even when there are multiple OpenGL loaders installed already. Another thing to consider is to somehow make it so that multiple ImGui variants can be installed at the same time in one Vcpkg installation but that's another issue.

@JackBoosY JackBoosY reopened this Feb 22, 2021
@JackBoosY
Copy link
Contributor

@MrSimbax According to the code in exmaples/example_glfw_opengl3/main/cpp line 83-99:

#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;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
    bool err = gladLoadGL(glfwGetProcAddress) == 0; // glad2 recommend using the windowing library loader instead of the (optionally) bundled one.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
    bool err = false;
    glbinding::Binding::initialize();
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
    bool err = false;
    glbinding::initialize([](const char* name) { return (glbinding::ProcAddress)glfwGetProcAddress(name); });
#else
    bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to requires some form of initialization.
#endif

Does this confirm that these features are in conflict?

@mathisloge
Copy link
Contributor

@JackBoosY
Copy link
Contributor

JackBoosY commented Jul 30, 2021

@mathisloge Therefore, these definitions should not be added to the compilation options, because they will be automatically defined.
@MrSimbax According to the source code, you should include the following headers before include imgui_impl_*.h.

@JackBoosY JackBoosY added category:question This issue is a question and removed category:port-bug The issue is with a library, which is something the port should already support labels Jul 30, 2021
@mathisloge
Copy link
Contributor

mathisloge commented Jul 30, 2021

@JackBoosY the auto detection is just a fallback and might interfere with system includes or eg. if glew is already installed in vcpkg. We should be really explicit here and don't use the auto detection. I think @Dylan-Davies has a point there (#19231 (comment)). Since these preprocessors would be evaluated at vcpkg-build time.
So we could at opengl targets (since it only affects opengl) which all specify the correct compile definitions.
e.g.

add_library(imgui-glew ${CMAKE_CURRENT_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
target_compile_definitions(imgui-glew PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLEW)

add_library(imgui-glad ${CMAKE_CURRENT_SOURCE_DIR}/backends/imgui_impl_opengl3.cpp)
target_compile_definitions(imgui-glew PUBLIC IMGUI_IMPL_OPENGL_LOADER_GLAD)

and so on.

@mathisloge
Copy link
Contributor

mathisloge commented Jul 30, 2021

Just as a sidenode: if there is a loader defined beforehand, the auto detection would be disabled.
https://github.com/ocornut/imgui/blob/ad5d1a8429ea219d3d34e6a36a48918650402697/backends/imgui_impl_opengl3.h#L47

@JackBoosY
Copy link
Contributor

@mathisloge Make sence, but we should wait for the upstream reply first.

@mathisloge
Copy link
Contributor

anyone pinged upstream? 😄

@JackBoosY
Copy link
Contributor

@dg0yt what do you think about since you are the contributor.

@dg0yt
Copy link
Contributor

dg0yt commented Aug 2, 2021

@dg0yt what do you think about since you are the contributor.

@JackBoosY Contributor of what?

@JackBoosY
Copy link
Contributor

@dg0yt what do you think about since you are the contributor.

@JackBoosY Contributor of what?

Sorry for ping the wrong guy.

@JackBoosY
Copy link
Contributor

cc @ocornut, the imgui owner.

@ocornut
Copy link

ocornut commented Aug 9, 2021

Hello, I posted an answer at ocornut/imgui#4390

@JackBoosY JackBoosY added category:port-bug The issue is with a library, which is something the port should already support and removed category:question This issue is a question labels Aug 11, 2021
@mathisloge
Copy link
Contributor

@JackBoosY so with the answer ocornut gave:
Should I open a PR that adds new targets for each of the opengl loaders?
Or do you already working on it?

@JackBoosY
Copy link
Contributor

@mathisloge Will fix later.

@JackBoosY
Copy link
Contributor

@mathisloge Yes, I will fix this in the nearly feature.

@ocornut
Copy link

ocornut commented Aug 18, 2021

We decided to bite the bullet and we are working toward embedding our own minimalist OpenGL loader into the backend, in order to put in end to that endless amount of confusion/misery caused by the OpenGL loaders.

We already have a version working and we'll either aim to use it in 1.84 or right after 1.84 is released.

TL;DR; ihmo don't put effort into solving this on your end.

@ocornut
Copy link

ocornut commented Aug 19, 2021

The dear imgui opengl backend now embeds its own loader, simplifying a lot the trouble people had and hte packaging problem for vcpkg. See ocornut/imgui#4445

@JackBoosY JackBoosY added the depends:upstream-changes Waiting on a change to the upstream project label Sep 28, 2021
@JackBoosY
Copy link
Contributor

Close this PR until upstream fixes this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category:port-bug The issue is with a library, which is something the port should already support depends:upstream-changes Waiting on a change to the upstream project
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants