OpenGL FBO using ImGui::Image is black

Viewed 53

I have the following renderer class for reference:

void Renderer::InitApp()
{
    // initialize glfw
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // create a fullscreen window
    GLFWmonitor* primaryMonitor = glfwGetPrimaryMonitor();
    mode = glfwGetVideoMode(primaryMonitor);
    glfwWindowHint(GLFW_RED_BITS, mode->redBits);
    glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
    glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
    glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);
    window = glfwCreateWindow(mode->width, mode->height, "Game Engine", primaryMonitor, NULL);

    // make the window the current context
    glfwMakeContextCurrent(window);

    // so that we can use OpenGL functions
    gladLoadGL();

    // create a viewport
    glViewport(0, 0, mode->width, mode->height);

    // enable blending
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // initialize ImGui
    IMGUI_CHECKVERSION();
    ImGuiContext* context = ImGui::CreateContext();
    ImGui::SetCurrentContext(context);
    ImGui::StyleColorsDark();
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");
    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_DockingEnable;

    unsigned int framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    unsigned int framebufferTexture;
    glGenTextures(1, &framebufferTexture);
    glBindTexture(GL_TEXTURE_2D, framebufferTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, mode->width, mode->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glGenerateMipmap(GL_TEXTURE_2D);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
        std::cout << "FBO success" << std::endl;
    else
        std::cout << "FBO failed" << std::endl;
}

void Renderer::NewFrame()
{
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    // give the window a color and clean the back buffer
    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // tell ImGui we are starting a new frame
    ImGui_ImplOpenGL3_NewFrame();
    ImGui_ImplGlfw_NewFrame();
    ImGui::NewFrame();

    // make the whole screen dockable
    ImGui::DockSpaceOverViewport(ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
}

void Renderer::DrawSprites()
{
    // draw every sprite in the vector
    for (int i = 0; i < spritesToDraw.size(); i++)
        spritesToDraw[i]->DrawSprite();
}

void Renderer::DrawEngineUI()
{
    ImGui::Begin("Placeholder 1");
    ImGui::End();
    ImGui::Begin("Placeholder 2");
    ImGui::End();
    ImGui::Begin("Placeholder 3");
    ImGui::End();
    ImGui::Begin("Placeholder 4");
    ImGui::End();

    ImGui::Begin("Viewport");
    ImGui::Image((void*)(intptr_t)framebuffer, ImVec2(mode->width, mode->height));
    ImGui::End();
}

void Renderer::UpdateApp()
{
    // draw the ui
    ImGui::Render();
    ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

    // swap buffers and process events
    glfwSwapBuffers(window);
    glfwPollEvents();
}

void Renderer::AddSpriteToDraw(SpriteRenderer* sr)
{
    // append a sprite to the vector
    spritesToDraw.push_back(sr);
}

My goal is to create a viewport by passing the framebuffers' texture to ImGui as an image to display on the viewport. However this isn't working all it shows is a black screen so I have made some progress, I think the FBO is kind of working except all it shows is black and not what has been renderered. For reference the main while loop is called like this:

while (!glfwWindowShouldClose(renderer.window))
{
    // new frame gives our viewport a BG color and tells ImGui we are starting a new frame
    // then we draw all the sprites then we draw the engine ui and update our app
    renderer.NewFrame();
    renderer.DrawSprites();
    renderer.DrawEngineUI();
    renderer.UpdateApp();
}

Here is a picture of the viewport:

Black Viewport

0 Answers
Related