5
\$\begingroup\$

The picture rapresents what i want to achieve. ImGui window placed over custom drawing.

I read, somewhere on the Internet, that you can render the fbo and pass that fbo as a texture to render into the ImGui window. The problem is that I don't even know what an FBO is, and how to create it. I just want to have the scene rendered into my ImGui window (just like the scene window in Unity)

How do i do it?

\$\endgroup\$
4
\$\begingroup\$

First you need to render you scene to a Frame Buffer Object (here is a good course on FBO: https://learnopengl.com/#!Advanced-OpenGL/Framebuffers)

After that you will end up with a Texture (of type GLuint) containing your rendered scene. To print it into Dear imGUI, just call a Draw Image Command.

Here is an example:

// My Game has a different viewport than the editor's one:
const int W = 1080 / 2;
const int H = 1920 / 2;
// We set the same viewport size (plus margin) to the next window (if first use)
ImGui::SetNextWindowSize(ImVec2(W + 10, H + 10),
                           ImGuiSetCond_FirstUseEver);
  ImGui::Begin("Game rendering");
  {
    // Get the current cursor position (where your window is)
    ImVec2 pos = ImGui::GetCursorScreenPos();

    // A boolean to allow me to stop the game rendering
    if (runApp) {
      glViewport(0, 0, W, H);
      // Render the scene into an FBO
      game->render(time);
      // Restore previous viewport
      glViewport(0, 0, w, h);
    }
    // Get the texture associated to the FBO
    auto tex = game->getRendered();

    // Ask ImGui to draw it as an image:
    // Under OpenGL the ImGUI image type is GLuint
    // So make sure to use "(void *)tex" but not "&tex"
    ImGui::GetWindowDrawList()->AddImage(
        (void *)tex, ImVec2(ImGui::GetItemRectMin().x + pos.x,
                            ImGui::GetItemRectMin().y + pos.y),
        ImVec2(pos.x + h / 2, pos.y + w / 2), ImVec2(0, 1), ImVec2(1, 0));
  }
  ImGui::End();
\$\endgroup\$
  • \$\begingroup\$ I don't understand what the the last two parameters of AddImage mean \$\endgroup\$ – user1754322 Sep 27 '17 at 9:32
  • \$\begingroup\$ These two ImVec2 are UV mapping \$\endgroup\$ – FloFu Sep 28 '17 at 8:57
  • \$\begingroup\$ but shouldn't it be (0, 0), (1, 1) instead? \$\endgroup\$ – user1754322 Sep 28 '17 at 10:16
  • \$\begingroup\$ In my case UV mapping required to be flipped. Sorry for the late answer. \$\endgroup\$ – FloFu Oct 29 '17 at 13:44
  • \$\begingroup\$ What is ImVec2(ImGui::GetItemRectMin().x + pos.x, ImGui::GetItemRectMin().y + pos.y), and ImVec2(pos.x + h / 2, pos.y + w / 2) ? I got working the fbo and the texture is correct(i applied it to a quad) but the imGui window is not displaying it correctly.. \$\endgroup\$ – user100681 Nov 1 '17 at 9:19
0
\$\begingroup\$

Rendering to a FBO and using as a texture is just fancy speak for rendering to texture and then using that texture in a subsequent render. All geometry generated by imgui are just texture triangles.

FBO stands for FrameBuffer Object, it is a collection of images that you can use as a rendertarget. Opengl is initialized with the window as the default target FBO.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy