How do i render my game scene into an imgui window?
I want to get from this:
to this :
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It only takes a minute to sign up.
Sign up to join this communityFirst of all we need to create what is called Frame Buffer Object, or FBO for short. I'll leave you a great tutorial on (pretty much everything regarding OpenGL)FBOs right here: https://learnopengl.com/#!Advanced-OpenGL/Framebuffers
Now that we created an FBO, we should have a texture. This texture contains the image of what is rendered on the FBO. At this point all we need to do is to "put" this image inside of a dear ImGui Window. Let's see how to do this:
//this is our main game loop
while (!window.Closed())
{
//we need to clear the window,
//This is how the clear method is structured:
//void Window::Clear(float x, float y, float z, bool enableGLDepth,bool clearImGUIframe)const
//{
// //clear the color of the window with an alpha value of 1.0f
// glClearColor(x, y, z, 1.0f);
// if (clearImGUIframe)
// {
// ImGui_ImplGlfwGL3_NewFrame();
// }
// if (enableGLDepth)
// {
// //enable the GL_DEPTH_TEST to be able to see 3D object correctly
// glEnable(GL_DEPTH_TEST);
// //clear both the color buffer bit and the depth buffer bit
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// }
// else
// {
// //clear just the color buffer bit
// glClear(GL_COLOR_BUFFER_BIT);
// }
//}
window.Clear(0.5f, 0.5f, 0.5f,true,true);
//switch to our custom FBO
//window.bindFBO is the same as writing glBindFramebuffer(GL_FRAMEBUFFER,FBO);
window.bindFBO();
//we need to call clear twice
window.Clear(1.0f, 1.0f, 1.0f, true, false);
//Draw our simple triangle
shader.Use();
glBindVertexArray(Tvao);
glDrawArrays(GL_TRIANGLES, 0, 3);
//switch to the default FBO
//again, unbindFBO() is the same as glBindFramebuffer(GL_FRAMEBUFFER,0)
window.unbindFBO();
//create our ImGui window
ImGui::Begin("Scene Window");
//get the mouse position
ImVec2 pos = ImGui::GetCursorScreenPos();
//pass the texture of the FBO
//window.getRenderTexture() is the texture of the FBO
//the next parameter is the upper left corner for the uvs to be applied at
//the third parameter is the lower right corner
//the last two parameters are the UVs
//they have to be flipped (normally they would be (0,0);(1,1)
ImGui::GetWindowDrawList()->AddImage(
(void *)window.getRenderTexture(),
ImVec2(ImGui::GetCursorScreenPos()),
ImVec2(ImGui::GetCursorScreenPos().x + window.getWidth()/2,
ImGui::GetCursorScreenPos().y + window.getHeight()/2), ImVec2(0, 1), ImVec2(1, 0));
//we are done working with this window
ImGui::End();
//swap the buffers and check for events
window.Update();
}
after all this you should get this result:
Hope this helped someone! I'll also leave the entire code i am using down here:
Main.cpp
#include "Engine.h"
using namespace Engine;
using namespace graphics;
int main()
{
Window window("Advent3D", 800,600, false);
Shader shader("Res/Shaders/Unlit.shader");
//TRIANGLE CREATION//
float Tvertices[] = {-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f,0.0f, 0.5f, 0.0f};
unsigned int Tvbo, Tvao;
glGenVertexArrays(1, &Tvao);
glGenBuffers(1, &Tvbo);
glBindVertexArray(Tvao);
glBindBuffer(GL_ARRAY_BUFFER, Tvbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(Tvertices), Tvertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!window.Closed())
{
//we need to clear the window,
window.Clear(0.5f, 0.5f, 0.5f,true,true);
//switch to the custom fbo
window.bindFBO();
window.Clear(1.0f, 1.0f, 1.0f, true, false);
shader.Use();
glBindVertexArray(Tvao);
glDrawArrays(GL_TRIANGLES, 0, 3);
//switch to the default fbo
window.unbindFBO();
ImGui::Begin("Scene Window");
ImVec2 pos = ImGui::GetCursorScreenPos();
ImGui::GetWindowDrawList()->AddImage(
(void *)window.getRenderTexture(), ImVec2(ImGui::GetCursorScreenPos()),
ImVec2(ImGui::GetCursorScreenPos().x + window.getWidth()/2, ImGui::GetCursorScreenPos().y + window.getHeight()/2), ImVec2(0, 1), ImVec2(1, 0));
ImGui::End();
window.Update();
}
}