2
\$\begingroup\$

I am learning OpenGL by glfw3 lib and I am using imgui to make a interesting application.
However, I can not render what I want in a imgui window.

I searched google and get below link:

  1. Render in a imGui Window
  2. How can I render an OpenGL scene into an ImGui window?

I tried about two days and I have rendered a triangle in a imgui window.
However, when I try to render content as this link(Tutorial and Code) shows me.
The box in my imgui window will not spin! It is a stationary photo.
What's wrong with my code?

#define __abc__is a value to test.
Xhader.h just is the header file in the tutorial, also .vs and .fs files.
The only difference is the tutorial uses glad.h and I use glew.h.

#define __abc__ #define STB_IMAGE_IMPLEMENTATION #include <iostream> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <stb_image.h> #include <glm/glm.hpp> #include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/type_ptr.hpp> #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" #include "Xhader.h" void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow* window); GLFWwindow* Proinit(); void imguiSetup(GLFWwindow* window); // settings const unsigned int SCR_WIDTH = 800; const unsigned int SCR_HEIGHT = 600; int main() { GLFWwindow* window = Proinit(); imguiSetup(window); int view3d_width = 100; int view3d_height = 200; // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); // build and compile our shader zprogram // ------------------------------------ Xhader ourShader("shader/vs.txt", "shader/fs.txt"); // set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ float vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; GLuint VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); GLuint VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); //--------------------------------------- FBO -----------------------------// #ifdef __abc__ unsigned int fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint TOF; glGenTextures(1, &TOF); glBindTexture(GL_TEXTURE_2D, TOF); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 400, 300, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); #else ; #endif // load and create a texture // ------------------------- unsigned int texture1, texture2; // texture 1 // --------- glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // set the texture wrapping parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // set texture filtering parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // load image, create texture and generate mipmaps int width, height, nrChannels; stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded texture's on the y-axis. std::string s1 = "resources/textures/container.jpg"; std::string s2 = "resources/textures/awesomeface.png"; unsigned char* data = stbi_load(s1.c_str(), &width, &height, &nrChannels, 0); if (data) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Failed to load texture" << std::endl; } stbi_image_free(data); // texture 2 // --------- glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // set the texture wrapping parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // set texture filtering parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // load image, create texture and generate mipmaps data = stbi_load(s2.c_str(), &width, &height, &nrChannels, 0); if (data) { // note that the awesomeface.png has transparency and thus an alpha channel, so make sure to tell OpenGL the data type is of GL_RGBA glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); } else { std::cout << "Failed to load texture" << std::endl; } stbi_image_free(data); // tell opengl for each sampler to which texture unit it belongs to (only has to be done once) // ------------------------------------------------------------------------------------------- ourShader.use(); ourShader.setInt("texture1", 0); ourShader.setInt("texture2", 1); // render loop // ----------- while (!glfwWindowShouldClose(window)) { #ifdef __abc__ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TOF, 0); #endif if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) { std::cout << "FRAMEBUFFER SUCCESS" << std::endl; glViewport(0, 0, 400, 300); // render // ------ glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // also clear the depth buffer now! // bind textures on corresponding texture units glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture1); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); // activate shader ourShader.use(); // create transformations glm::mat4 model = glm::mat4(1.0f); // make sure to initialize matrix to identity matrix first glm::mat4 view = glm::mat4(1.0f); glm::mat4 projection = glm::mat4(1.0f); float time = (float)glfwGetTime(); std::cout << time << std::endl; model = glm::rotate(model,time , glm::vec3(0.5f, 1.0f, 0.0f)); view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f)); projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); // retrieve the matrix uniform locations unsigned int modelLoc = glGetUniformLocation(ourShader.ID, "model"); unsigned int viewLoc = glGetUniformLocation(ourShader.ID, "view"); // pass them to the shaders (3 different ways) glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model)); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, &view[0][0]); // note: currently we set the projection matrix each frame, //but since the projection matrix rarely changes it's often best practice //to set it outside the main loop only once. ourShader.setMat4("projection", projection); // render box glBindVertexArray(VAO); glDrawArrays(GL_TRIANGLES, 0, 36); #ifdef __abc__ glBindFramebuffer(GL_FRAMEBUFFER, 0); #endif } else { std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl; } #ifdef __abc__ // Start the Dear ImGui frame ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplGlfw_NewFrame(); ImGui::NewFrame(); bool View_3D = true; if (View_3D) { ImGui::Begin("3D View", &View_3D); view3d_height = ImGui::GetWindowSize().x; view3d_width = ImGui::GetWindowSize().y; ImVec2 pos = ImGui::GetCursorScreenPos(); ImGui::GetWindowDrawList()->AddImage( (void*)TOF, ImVec2(ImGui::GetCursorScreenPos()), ImVec2(ImGui::GetCursorScreenPos().x + ImGui::GetWindowSize().x - 15, ImGui::GetCursorScreenPos().y + ImGui::GetWindowSize().y - 35), ImVec2(0, 1), ImVec2(1, 0) ); ImGui::End(); } // input // ----- processInput(window); ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // render ImGui::Render(); int display_w, display_h; glfwGetFramebufferSize(window, &display_w, &display_h); glViewport(0, 0, display_w, display_h); glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); #endif // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) // ------------------------------------------------------------------------------- glfwSwapBuffers(window); glfwPollEvents(); } // optional: de-allocate all resources once they've outlived their purpose: // ------------------------------------------------------------------------ glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // glfw: terminate, clearing all previously allocated GLFW resources. // ------------------------------------------------------------------ glfwTerminate(); return 0; } // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly // --------------------------------------------------------------------------------------------------------- void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); } // glfw: whenever the window size changed (by OS or user resize) this callback function executes // --------------------------------------------------------------------------------------------- void framebuffer_size_callback(GLFWwindow* window, int width, int height) { // make sure the viewport matches the new window dimensions; note that width and // height will be significantly larger than specified on retina displays. glViewport(0, 0, width, height); } GLFWwindow* Proinit() { //glfwSetErrorCallback(glfw_error_callback); if (!glfwInit()) return (GLFWwindow*)1; #ifdef __APPLE__ // GL 3.2 + GLSL 150 const char* glsl_version = "#version 150"; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac #else const char* glsl_version = "#version 130"; glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only #endif GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Shader3D", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return (GLFWwindow*)-1; } glfwMakeContextCurrent(window); //glfwSwapInterval(1); // Enable vsync //glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); #if defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() == 0; #else bool err = false; #endif if (err) { fprintf(stderr, "Failed to initialize OpenGL loader!\n"); return (GLFWwindow*)1; } return window; } void imguiSetup(GLFWwindow* window) { // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls ImGui::StyleColorsDark(); ImGui_ImplGlfw_InitForOpenGL(window, true); //Setup Platform bindings #ifdef __APPLE__ ImGui_ImplOpenGL3_Init("#version 150"); //Setup Renderer bindings #else ImGui_ImplOpenGL3_Init("#version 130"); #endif } 
\$\endgroup\$
2
  • \$\begingroup\$ Does it spin if you render directly to the default framebuffer? \$\endgroup\$ Commented Apr 1, 2020 at 16:59
  • \$\begingroup\$ yes, it spin if you use default buffer. \$\endgroup\$ Commented Apr 1, 2020 at 19:18

1 Answer 1

2
\$\begingroup\$

Move these lines inside the while loop.

unsigned int fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); GLuint TOF; glGenTextures(1, &TOF); glBindTexture(GL_TEXTURE_2D, TOF); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 400, 300, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

Then once all your rendering is done you have to delete the frame buffer and texture object every time inside the loop.

glDeleteFramebuffers(1, &fbo); glDeleteTextures(1, &TOF); 

The idea is for each and every time inside the loop, the frame buffer needs to be created, utilized and the deleted. Other wise the buffer will not refresh.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.