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:
