Imgui with GLFW breaks my textures #602

Closed
opened 2016-04-21 22:29:06 +00:00 by shosanna · 4 comments
shosanna commented 2016-04-21 22:29:06 +00:00 (Migrated from github.com)

I am having problem with using Imgui + Glfw in my game.
My main loop looks like this:

  while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // my draw calls

    ImGui_ImplGlfwGL3_NewFrame();
    ImGui::Begin("he");
    ImGui::Text("Hello");
    ImGui::End();

    ImGui::Render();

    glfwSwapBuffers(window);
  }

And my game looks like this (the broken one with the ImGui text):

image

But it should look like this (when commenting out the begin, text and end):

image

It also broke my key callback and it is no longer responsive for key presses.

I am having problem with using Imgui + Glfw in my game. My main loop looks like this: ``` while (!glfwWindowShouldClose(window)) { glfwPollEvents(); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // my draw calls ImGui_ImplGlfwGL3_NewFrame(); ImGui::Begin("he"); ImGui::Text("Hello"); ImGui::End(); ImGui::Render(); glfwSwapBuffers(window); } ``` And my game looks like this (the broken one with the ImGui text): ![image](https://cloud.githubusercontent.com/assets/3513118/14726188/a2a93776-0820-11e6-965b-14ec220b29fc.png) But it should look like this (when commenting out the begin, text and end): ![image](https://cloud.githubusercontent.com/assets/3513118/14726208/c620ebea-0820-11e6-86c5-59b9e99aa4bb.png) It also broke my key callback and it is no longer responsive for key presses.
Cthutu commented 2016-04-21 22:35:08 +00:00 (Migrated from github.com)

Check that you're restoring your OpenGL state correctly after rendering the
command lists. ImGUI cannot possibly break your rendering since it has
nothing to do with the rendering - it merely gives data that your renderer
will use. Looks like your texture wrapping state is not restored. I may
be wrong.

On Thu, 21 Apr 2016 at 18:29 Zuzana Dostálová notifications@github.com
wrote:

I am having problem with using Imgui + Glfw in my game.
My main loop looks like this:

while (!glfwWindowShouldClose(window)) {
glfwPollEvents();

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

// my draw calls

ImGui_ImplGlfwGL3_NewFrame();
ImGui::Begin("he");
ImGui::Text("Hello");
ImGui::End();

ImGui::Render();

glfwSwapBuffers(window);

}

And my game looks like this (the broken one with the ImGui text):

[image: image]
https://cloud.githubusercontent.com/assets/3513118/14726188/a2a93776-0820-11e6-965b-14ec220b29fc.png

But it should look like this (when commenting out the begin, text and end):

[image: image]
https://cloud.githubusercontent.com/assets/3513118/14726208/c620ebea-0820-11e6-86c5-59b9e99aa4bb.png

It also broke my key callback and it is no longer responsive for key
presses.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/ocornut/imgui/issues/602

Check that you're restoring your OpenGL state correctly after rendering the command lists. ImGUI cannot possibly break your rendering since it has nothing to do with the rendering - it merely gives data that your renderer will use. Looks like your texture wrapping state is not restored. I may be wrong. On Thu, 21 Apr 2016 at 18:29 Zuzana Dostálová notifications@github.com wrote: > I am having problem with using Imgui + Glfw in my game. > My main loop looks like this: > > while (!glfwWindowShouldClose(window)) { > glfwPollEvents(); > > ``` > glClearColor(0.2f, 0.3f, 0.3f, 1.0f); > glClear(GL_COLOR_BUFFER_BIT); > > // my draw calls > > ImGui_ImplGlfwGL3_NewFrame(); > ImGui::Begin("he"); > ImGui::Text("Hello"); > ImGui::End(); > > ImGui::Render(); > > glfwSwapBuffers(window); > ``` > > } > > And my game looks like this (the broken one with the ImGui text): > > [image: image] > https://cloud.githubusercontent.com/assets/3513118/14726188/a2a93776-0820-11e6-965b-14ec220b29fc.png > > But it should look like this (when commenting out the begin, text and end): > > [image: image] > https://cloud.githubusercontent.com/assets/3513118/14726208/c620ebea-0820-11e6-86c5-59b9e99aa4bb.png > > It also broke my key callback and it is no longer responsive for key > presses. > > — > You are receiving this because you are subscribed to this thread. > Reply to this email directly or view it on GitHub > https://github.com/ocornut/imgui/issues/602
ocornut commented 2016-04-22 06:27:37 +00:00 (Migrated from github.com)

Hello Zuzana,

Assuming you are using the unmodified imgui_impl_glfw_gl3.cpp renderer (please confirm!), it looks like it may be modifying some global GL state. It is in theory saving and restoring all GL state it modifies but looks like something's not being saved.

Publishing what your code is actually doing may help in tracking it down.

Another technique is that you can comment huge chunks of the code in ImGui_ImplGlfwGL3_RenderDrawLists() to diagnose which part of that code is affecting your code.
First comment out the entire rendering loop (the for (int n = 0; n < draw_data->CmdListsCount; n++)) see if it fixes your rendering. Then you can comment the lines starting from after the Backup GL state block, etc. If you can isolate which line(s) are most immediately affecting your rendering we can devise a fix.

Callbacks:
When calling ImGui_ImplGlfwGL3_Init() the second parameter bool install_callback override 4 glfw callbacks. If you need the callback for your own work you should set this parameter to false and call the 4 callbacks yourself (listed in imgui_impl_glfw_gl3.h).

Hello Zuzana, Assuming you are using the unmodified imgui_impl_glfw_gl3.cpp renderer (please confirm!), it looks like it may be modifying some global GL state. It is in theory saving and restoring all GL state it modifies but looks like something's not being saved. Publishing what your code is actually doing may help in tracking it down. Another technique is that you can comment huge chunks of the code in ImGui_ImplGlfwGL3_RenderDrawLists() to diagnose which part of that code is affecting your code. First comment out the entire rendering loop (the `for (int n = 0; n < draw_data->CmdListsCount; n++)`) see if it fixes your rendering. Then you can comment the lines starting from after the `Backup GL state` block, etc. If you can isolate which line(s) are most immediately affecting your rendering we can devise a fix. Callbacks: When calling ImGui_ImplGlfwGL3_Init() the second parameter `bool install_callback` override 4 glfw callbacks. If you need the callback for your own work you should set this parameter to false and call the 4 callbacks yourself (listed in imgui_impl_glfw_gl3.h).
shosanna commented 2016-04-28 21:13:05 +00:00 (Migrated from github.com)

Hi,

Thanks all for a great help. Yes, I am using the unmodified renderer.
I managed to find out which line exactly is causing the problem, when I comment it out, it works just fine:

////// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
    glEnable(GL_BLEND);
    glBlendEquation(GL_FUNC_ADD);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_CULL_FACE);
    glDisable(GL_DEPTH_TEST);
    glEnable(GL_SCISSOR_TEST);
    //glActiveTexture(GL_TEXTURE0);
    GLint new_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &new_texture);

Also, what is weird, when I output the current and last texture just bellow the code from above:

    std::cout << "last " << last_texture << ", new " << new_texture << std::endl;

it gaves me the same IDs....

here is my game loop (I rewrite it to SDL meanwhile, but the error is still the same):

void game_loop(SDL_Window* window) {
  // Setup ImGui binding
  ImGui_ImplSdlGL3_Init(window);

  GLuint vao;
  glGenVertexArrays(1, &vao);
  glBindVertexArray(vao);

  glViewport(0, 0, 2 * WIDTH, 2 * HEIGHT);

  // Nacteni obrazku

  std::vector<unsigned char> background;
  unsigned width, height;
  lodepng::decode(background, width, height, "grass.png");

  std::vector<unsigned char> image;
  unsigned width2, height2;
  lodepng::decode(image, width2, height2, "kuratko.png");

  // Inicializovani indexu TEXTUR
  GLuint textures[2];
  glGenTextures(2, textures);

  // PRVNI TEXTURE
  // Prepnuti se na prvni texturu
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, textures[0]);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA,
               GL_UNSIGNED_BYTE, background.data());
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  // DRUHA TEXTURA
  // Prepnuti se na druhou texturu

  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, textures[1]);

  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width2, height2, 0, GL_RGBA,
               GL_UNSIGNED_BYTE, image.data());
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

  ShaderProgram program("vertex.glsl", "fragment.glsl");

  GLuint vbo;
  glGenBuffers(1, &vbo);
  glBindBuffer(GL_ARRAY_BUFFER, vbo);

  program.use();
  program.setupAttributes();

  float tile_size = 0.1f;
  int tile_count = 2 / tile_size;
  std::vector<float> background_data;

  for (int i = 0; i < tile_count; i++) {
    for (int j = 0; j < tile_count; j++) {
      float x = j * tile_size - 1 + tile_size / 2;
      float y = -(i * tile_size - 1 + tile_size / 2);
      tile_at(background_data, x, y, tile_size);
    }
  }

  Stopwatch st;

  SDL_Event event;

  GLint u_activeTex = glGetUniformLocation(program.shaderProgram, "activeTex");
  while (true) {
    st.start();
    ImGui_ImplSdlGL3_NewFrame(window);

    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_QUIT || (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE)) {
        return;
      }
      ImGui_ImplSdlGL3_ProcessEvent(&event);
    }

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glUniform1i(u_activeTex, 0);
    draw_vector_triangles(background_data);

    std::vector<float> vbo_data;
    {
      float x = current_x * tile_size - 1 + tile_size / 2;
      float y = -(current_y * tile_size - 1 + tile_size / 2);
      glUniform1i(u_activeTex, 1);
      tile_at(vbo_data, x, y, tile_size);
    }

    draw_vector_triangles(vbo_data);

    ImGui::Begin("he");
    ImGui::Text("Hello");
    ImGui::End();

    ImGui::Render();

    // std::cout << "frame " << st.ms_float() << "ms" << std::endl;
    SDL_GL_SwapWindow(window);
  }
}

// The MAIN function, from here we start the application and run the game loop
int main(int, char**) {
  //auto res = load_tiles("xmlova.tmx");

  SDL_Window* window = setupSDL();
  if (!window) return -1;

  SDL_GLContext context = SDL_GL_CreateContext(window);
  if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
    std::cout << "Failed to initialize OpenGL context" << std::endl;
    return 1;
  }

  game_loop(window);

  SDL_GL_DeleteContext(context);
  SDL_DestroyWindow(window);
  SDL_Quit();

  return 0;
}
Hi, Thanks all for a great help. Yes, I am using the unmodified renderer. I managed to find out which line exactly is causing the problem, when I comment it out, it works just fine: ``` ////// Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); glEnable(GL_SCISSOR_TEST); //glActiveTexture(GL_TEXTURE0); GLint new_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, &new_texture); ``` Also, what is weird, when I output the current and last texture just bellow the code from above: ``` std::cout << "last " << last_texture << ", new " << new_texture << std::endl; ``` it gaves me the same IDs.... here is my game loop (I rewrite it to SDL meanwhile, but the error is still the same): ``` void game_loop(SDL_Window* window) { // Setup ImGui binding ImGui_ImplSdlGL3_Init(window); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glViewport(0, 0, 2 * WIDTH, 2 * HEIGHT); // Nacteni obrazku std::vector<unsigned char> background; unsigned width, height; lodepng::decode(background, width, height, "grass.png"); std::vector<unsigned char> image; unsigned width2, height2; lodepng::decode(image, width2, height2, "kuratko.png"); // Inicializovani indexu TEXTUR GLuint textures[2]; glGenTextures(2, textures); // PRVNI TEXTURE // Prepnuti se na prvni texturu glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, background.data()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // DRUHA TEXTURA // Prepnuti se na druhou texturu glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, textures[1]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width2, height2, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.data()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ShaderProgram program("vertex.glsl", "fragment.glsl"); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); program.use(); program.setupAttributes(); float tile_size = 0.1f; int tile_count = 2 / tile_size; std::vector<float> background_data; for (int i = 0; i < tile_count; i++) { for (int j = 0; j < tile_count; j++) { float x = j * tile_size - 1 + tile_size / 2; float y = -(i * tile_size - 1 + tile_size / 2); tile_at(background_data, x, y, tile_size); } } Stopwatch st; SDL_Event event; GLint u_activeTex = glGetUniformLocation(program.shaderProgram, "activeTex"); while (true) { st.start(); ImGui_ImplSdlGL3_NewFrame(window); while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT || (event.type == SDL_KEYUP && event.key.keysym.sym == SDLK_ESCAPE)) { return; } ImGui_ImplSdlGL3_ProcessEvent(&event); } glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUniform1i(u_activeTex, 0); draw_vector_triangles(background_data); std::vector<float> vbo_data; { float x = current_x * tile_size - 1 + tile_size / 2; float y = -(current_y * tile_size - 1 + tile_size / 2); glUniform1i(u_activeTex, 1); tile_at(vbo_data, x, y, tile_size); } draw_vector_triangles(vbo_data); ImGui::Begin("he"); ImGui::Text("Hello"); ImGui::End(); ImGui::Render(); // std::cout << "frame " << st.ms_float() << "ms" << std::endl; SDL_GL_SwapWindow(window); } } // The MAIN function, from here we start the application and run the game loop int main(int, char**) { //auto res = load_tiles("xmlova.tmx"); SDL_Window* window = setupSDL(); if (!window) return -1; SDL_GLContext context = SDL_GL_CreateContext(window); if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) { std::cout << "Failed to initialize OpenGL context" << std::endl; return 1; } game_loop(window); SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); SDL_Quit(); return 0; } ```
ocornut commented 2016-04-30 17:06:47 +00:00 (Migrated from github.com)

OK I think it is fixed now, saving and restoring the glActiveTexture() value.
It broke your code because your code never sets that values again (while it works here and is perfectly legal, it is a little unusual to just set state during initialization and expect it to stay untouched during whole program lifetime. Usually in a bigger application you may want to setup GL state before rendering an object, etc.)

Could you confirm the fix?
Thanks for the report!

OK I think it is fixed now, saving and restoring the glActiveTexture() value. It broke your code because your code never sets that values again (while it works here and is perfectly legal, it is a little unusual to just set state during initialization and expect it to stay untouched during whole program lifetime. Usually in a bigger application you may want to setup GL state before rendering an object, etc.) Could you confirm the fix? Thanks for the report!
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#602
No description provided.