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 Shaders failing to compile #8104

Closed
Azurefarer opened this issue Oct 27, 2024 · 2 comments
Closed

ImGui Shaders failing to compile #8104

Azurefarer opened this issue Oct 27, 2024 · 2 comments

Comments

@Azurefarer
Copy link

Azurefarer commented Oct 27, 2024

Version/Branch of Dear ImGui:

Version 1.91.0, Branch: master

Back-ends:

imgui_impl_Glfw.cpp + imgui_impl_OpenGL3.cpp

Compiler, OS:

Gcc, Windows 11

Full config/build information:

No response

Details:

This is the error I am receiving :
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile vertex shader! With GLSL: #version 130

ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile fragment shader! With GLSL: #version 130

ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link shader program! With GLSL #version 130

Here's my setup :

Context::Context(int width, int height, std::string title) 
    : m_width(width), m_height(height), m_cursor_pos_x(width/2), m_cursor_pos_y(height/2) {
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    m_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
	if (m_window == NULL) {
		glfwTerminate();
        throw std::runtime_error("Failed to create GLFW window");
	}
    glfwMakeContextCurrent(m_window);

    Context::set_callbacks();

	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		throw std::runtime_error("Failed to initialize GLAD");
	}
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_DEPTH_TEST);
    gui = std::make_shared<Gui>(m_window);

    glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}

Here is my ImGui init :

Gui::Gui(GLFWwindow *context) { 
    // Setup Dear ImGui context
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
    ImGui::StyleColorsDark();
    ImGui_ImplGlfw_InitForOpenGL(context, true);
    ImGui_ImplOpenGL3_Init(nullptr);

Here's the ImGui loop that is called inside my main render loop :

void Gui::run() {
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();
    ImGui::Begin("Scene Editor");
    Gui::update_frame();
    
    ImGuiIO& io = ImGui::GetIO(); (void)io;
    ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
    ImGui::End();
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

Here's the main render loop :

void Renderer::run() {
    while(m_context->is_live()) {
        glfwPollEvents();
        Renderer::update_for_gui();
        m_gui->run();
        Renderer::update_from_gui();
        glClearColor(0.35f, 0.7f, 0.9f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        Renderer::set_transforms(glm::vec3(0.0f));
        m_shader->use();
        m_batch->run_batch();
        Renderer::set_shader_uniforms();

        m_shape_man->draw("CUBE");
        Renderer::set_transforms(glm::vec3(10.0f, 7.0f, -3.0f));
        Renderer::set_shader2_uniforms();
        m_shader2->use();
        m_shape_man->draw("CUBE");
        Renderer::context_updates();
    }
}

The error happens when this fct is called ImGui_ImplOpenGL3_NewFrame();
the debug trail takes me into a portion of imgui where shaders are being compiled and linked into a program. afaik this is supposed to happen, however I'm getting the errors shown above.

I have tried Replacing nullptr with glsl version strings (tried 430 core, 330 core, 330, 430, etc. )

My internet research has not provided me with many other potential solutions.

Thanks, AzureFarer

Screenshots/Video:

No response

Minimal, Complete and Verifiable Example code:

No response

EDIT :
I found this difference in debugging a working version from my current version.
In the ImGui_ImplOpenGL3_CreateDeviceObjects() function, when creating GLuint shader handles, the glCreateShader will return a value.
In the broken version, glCreateShader returns a value of 0 & 0 respectively for the VS and FS, indicating something went wrong during creation of the shader objs.
In the working version, glCreateShader returns a value of 7 & 8 respectively for the VS and FS.

@ocornut
Copy link
Owner

ocornut commented Oct 28, 2024

I have tried Replacing nullptr with glsl version strings (tried 430 core, 330 core, 330, 430, etc. )

Are you sure you used the right syntax? The string should be e.g. "#version 430 core".

I found this difference in debugging a working version from my current version.
In the ImGui_ImplOpenGL3_CreateDeviceObjects() function, when creating GLuint shader handles, the glCreateShader will return a value. [...] In the broken version, glCreateShader returns a value of 0 & 0 respectively for the VS and FS, indicating something went wrong during creation of the shader objs.

Ah.
Try to apply my change 81b689b (you may easily apply it manually) then uncomment the line saying //#define IMGUI_IMPL_OPENGL_DEBUG at the top of imgui_impl_opengl3.cpp.

At this point the issue to debug is why does glCreateShader() returns a valid handle in your setup? you may investigate and debug that without even using most of imgui_impl_opengl3.cpp code. May add a dummy glCreateShader() call at the top of ImGui_ImplOpenGL3_NewFrame() and check the return value.

Because OpenGL symbols are loaded differently depending on the compilation unit (the path to call glCreateShader() in imgui_impl_opengl3.cpp will be different from the path to call glCreateShader() in your own source where you use GLAD), it may be also useful to attempt calling the function from BOTH locations to see if there is a difference.

@Azurefarer
Copy link
Author

Hey, thanks for the help on where to begin debugging! :D
I found it was something kinda of fundamental to cpp knowledge as opposed to ImGui or OpenGL.
I was improperly using unique pointers which caused my Context's destructor to be called Context::~Context() {glfwterminate()}
I fixed it by properly using unique pointers in main.cpp
int main() {
auto context = std::make_unique(1920, 1080, std::string("OpenGL Application"));
Renderer renderer(std::move(context));
renderer.run();
return 0;
}
Thanks for a great API :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants