Version/Branch of Dear ImGui:
Version: 1.73
Back-end/Renderer/Compiler/OS
Back-ends: imgui_impl_glut.cpp + imgui_impl_opengl2.cpp
Compiler: Visual Studio 2019
Operating System: Windows 10
My Issue/Question:
My application draws a normal white square, without using imgui everything works and is drawn as needed(Screenshot 1).
The Camera class I use to move around the scene, you can look at this link(suddenly it is to blame for this problem).
But with imgui nothing is drawn.
When you try to draw a simple text box, my scene stops drawing correctly. The imgui window is drawn, but there is nothing else, the square is not drawn(Screenshot 2).
What's wrong?
Screenshots/Video
Screenshot â„–1

Screenshot â„–2

Standalone, minimal, complete and verifiable example:
#include <iostream>
#include <chrono>
#include <vector>
#include <memory>
#include <GL/glut.h>
#include <soil.h>
#include "camera.h"
#include "imgui.h"
#include "imgui_impl_glut.h"
#include "imgui_impl_opengl2.h"
#ifdef _MSC_VER
#pragma warning (disable: 4505) // unreferenced local function has been removed
#endif
#define GL_CLAMP_TO_EDGE 0x812F
using namespace std;
constexpr auto FPS_RATE = 120;
int windowHeight = 600, windowWidth = 1000, windowDepth = 600;
//for camera
struct MyPoint3f { float x; float y; float z; };
MyPoint3f lastMousePos = { };
bool mouseButtonWasPressed = false;
float mouseSensitivity = 0.00125f;
int camMoveSpeed = 1;
float camPitchAngle = 0, camYawAngle = 0;
float currentCamPitchAngle = 0, currentCamYawAngle = 0;
Camera cam;
//OpenGL
int groundImageWidth = 0, groundImageHeight = 0;
unsigned char* groundImage = 0;
GLuint groundTexture = 0;
void init();
void displayFunction();
void idleFunction();
void reshapeFunction(int, int);
void keyboardFunction(unsigned char, int, int);
void specialKeysFunction(int, int, int);
void mouseFunc(int, int, int, int);
void motionFunction(int, int);
double getTime();
double getTime()
{
using Duration = std::chrono::duration<double>;
return std::chrono::duration_cast<Duration>(
std::chrono::high_resolution_clock::now().time_since_epoch()
).count();
}
const float frame_delay = 1.0f / FPS_RATE;
double last_render = 0;
void init()
{
//load texture image
groundImage = SOIL_load_image("groundTexture.jpg", &groundImageWidth, &groundImageHeight, 0, SOIL_LOAD_RGB);
if (!groundImage)
MessageBox(NULL, L"Load image falded", L"Error", MB_OK);
//generate 1 texture
glGenTextures(1, &groundTexture);
//setting callback functions
glutDisplayFunc(displayFunction);
glutIdleFunc(idleFunction);
glutReshapeFunc(reshapeFunction);
glutKeyboardFunc(keyboardFunction);
glutMouseFunc(mouseFunc);
glutMotionFunc(motionFunction);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glClearColor(117.0f / 255.0f, 187.0f / 255.0f, 253.0f / 255.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//setting cam
cam.SetPosition(glm::vec3(0.f, 100.f, 350.f));
cam.SetLookAt(glm::vec3(0.f, 100.f, 349.f));
cam.SetClipping(0.1f, 2000.f);
cam.SetFOV(45);
}
static bool showWindow = true;
void displayFunction()
{
if (abs(currentCamPitchAngle + -(camPitchAngle * mouseSensitivity)) < 0.90)
cam.ChangePitch(-(camPitchAngle * mouseSensitivity));
cam.ChangeHeading((camYawAngle * mouseSensitivity));
if (abs(currentCamPitchAngle + -(camPitchAngle * mouseSensitivity)) < 0.90)
currentCamPitchAngle += -(camPitchAngle * mouseSensitivity);
currentCamYawAngle += -(camYawAngle * mouseSensitivity);
camPitchAngle = 0; camYawAngle = 0;
//create imgui new frame
ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplGLUT_NewFrame();
//draw window
if (showWindow)
{
ImGui::Begin("Another Window", &showWindow); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
showWindow = false;
ImGui::End();
}
//clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//set camera
glm::mat4 model, view, projection;
cam.Update();
cam.GetMatricies(projection, view, model);
glm::mat4 mvp = projection * view * model;
glLoadMatrixf(glm::value_ptr(mvp));
glMatrixMode(GL_MODELVIEW);
//draw white polygon
glBegin(GL_POLYGON);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
//render
ImGui::Render();
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
glutSwapBuffers();
}
void idleFunction()
{
const double current_time = getTime();
if ((current_time - last_render) > frame_delay)
{
last_render = current_time;
glutPostRedisplay();
}
}
void reshapeFunction(int w, int h)
{
cam.SetViewport(0, 0, windowWidth, windowHeight);
}
void keyboardFunction(unsigned char key, int w, int h)
{
switch (key)
{
case '+': case '=':
break;
case '-': case '_':
break;
case 'w': case 'W':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(FORWARD);
break;
case 'a': case 'A':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(LEFT);
break;
case 's': case 'S':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(BACK);
break;
case 'd': case 'D':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(RIGHT);
break;
case 'q': case 'Q':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(DOWN);
break;
case 'e': case 'E':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(UP);
break;
case 27:
currentCamPitchAngle = 0;
currentCamYawAngle = 0;
break;
default:
cout << key << endl;
break;
}
}
void specialKeysFunction(int key, int x, int y)
{
cout << key << endl;
}
void mouseFunc(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouseButtonWasPressed = true;
lastMousePos.x = (float)x;
lastMousePos.y = (float)y;
}
}
void motionFunction(int mousePosX, int mousePosY)
{
if (mousePosX >= 0 && mousePosX < windowWidth && mousePosY >= 0 && mousePosY < windowHeight)
{
if (mouseButtonWasPressed)
{
camPitchAngle += -mousePosY + lastMousePos.y;
camYawAngle += (float)mousePosX - lastMousePos.x;
lastMousePos.x = (float)mousePosX;
lastMousePos.y = (float)mousePosY;
}
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) - windowWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - windowHeight) / 2);
glutCreateWindow("Window");
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
init();
//imgui setup
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();
ImGui_ImplGLUT_Init();
ImGui_ImplGLUT_InstallFuncs();
ImGui_ImplOpenGL2_Init();
glutMainLoop();
ImGui_ImplOpenGL2_Shutdown();
ImGui_ImplGLUT_Shutdown();
ImGui::DestroyContext();
return 0;
}
Hi prostargamer.
I don't use old style OpenGL and GLUT from long time, but I guess that you need to call your rendering procedure... after... ImGui render cycle... like this:
//create imgui new frame
ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplGLUT_NewFrame();
//draw window
if (showWindow)
{
ImGui::Begin("Another Window", &showWindow); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
showWindow = false;
ImGui::End();
}
//render
ImGui::Render();
ImGuiIO& io = ImGui::GetIO();
glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y);
//clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//set camera
glm::mat4 model, view, projection;
cam.Update();
cam.GetMatricies(projection, view, model);
glm::mat4 mvp = projection * view * model;
glLoadMatrixf(glm::value_ptr(mvp));
glMatrixMode(GL_MODELVIEW);
//draw white polygon
glBegin(GL_POLYGON);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
glutSwapBuffers();
glutPostRedisplay();
@BrutPitt, unfortunately it doesn't work, do you have any other ideas?
unfortunately your code is not properly standalone and minimal ... it depends from camera.h (Camera cam;) and soil.h.
Anyway I have commented a great part of your code to compile it... and it works for me (with my corrections):

Obviously I had to change the size of the rectangle (GL_POLYGON) without a Camera
Below your sources that I commented/changed and compiled (on Linux)
#include <iostream>
#include <chrono>
#include <vector>
#include <memory>
#include <GL/glut.h>
//#include <soil.h>
//#include "camera.h"
#include "imgui.h"
#include "imgui_impl_glut.h"
#include "imgui_impl_opengl2.h"
#ifdef _MSC_VER
#pragma warning (disable: 4505) // unreferenced local function has been removed
#endif
#define GL_CLAMP_TO_EDGE 0x812F
using namespace std;
constexpr auto FPS_RATE = 120;
int windowHeight = 600, windowWidth = 1000, windowDepth = 600;
//for camera
struct MyPoint3f { float x; float y; float z; };
MyPoint3f lastMousePos = { };
bool mouseButtonWasPressed = false;
float mouseSensitivity = 0.00125f;
int camMoveSpeed = 1;
float camPitchAngle = 0, camYawAngle = 0;
float currentCamPitchAngle = 0, currentCamYawAngle = 0;
//Camera cam;
//OpenGL
int groundImageWidth = 0, groundImageHeight = 0;
unsigned char* groundImage = 0;
GLuint groundTexture = 0;
void init();
void displayFunction();
void idleFunction();
void reshapeFunction(int, int);
void keyboardFunction(unsigned char, int, int);
void specialKeysFunction(int, int, int);
void mouseFunc(int, int, int, int);
void motionFunction(int, int);
double getTime();
double getTime()
{
using Duration = std::chrono::duration<double>;
return std::chrono::duration_cast<Duration>(
std::chrono::high_resolution_clock::now().time_since_epoch()
).count();
}
const float frame_delay = 1.0f / FPS_RATE;
double last_render = 0;
static bool showWindow = true;
void displayFunction()
{
/*
if (abs(currentCamPitchAngle + -(camPitchAngle * mouseSensitivity)) < 0.90)
cam.ChangePitch(-(camPitchAngle * mouseSensitivity));
cam.ChangeHeading((camYawAngle * mouseSensitivity));
if (abs(currentCamPitchAngle + -(camPitchAngle * mouseSensitivity)) < 0.90)
currentCamPitchAngle += -(camPitchAngle * mouseSensitivity);
currentCamYawAngle += -(camYawAngle * mouseSensitivity);
camPitchAngle = 0; camYawAngle = 0;
*/
ImGui_ImplOpenGL2_NewFrame();
ImGui_ImplGLUT_NewFrame();
//draw window
if (showWindow)
{
ImGui::Begin("Another Window", &showWindow); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
showWindow = false;
ImGui::End();
}
//render
ImGui::Render();
ImGuiIO& io = ImGui::GetIO();
glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y);
//clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
//set camera
glm::mat4 model, view, projection;
cam.Update();
cam.GetMatricies(projection, view, model);
glm::mat4 mvp = projection * view * model;
glLoadMatrixf(glm::value_ptr(mvp));
glMatrixMode(GL_MODELVIEW);
*/
//draw white polygon
glBegin(GL_POLYGON);
glVertex3i(-1, 0, 0);
glVertex3i(0, 0, 0);
glVertex3i(0, -1, 0);
glVertex3i(-1, -1, 0);
glEnd();
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
glutSwapBuffers();
glutPostRedisplay();
}
void init()
{
/*
//load texture image
groundImage = SOIL_load_image("groundTexture.jpg", &groundImageWidth, &groundImageHeight, 0, SOIL_LOAD_RGB);
if (!groundImage)
MessageBox(NULL, L"Load image falded", L"Error", MB_OK);
//generate 1 texture
glGenTextures(1, &groundTexture);
*/
//setting callback functions
glutDisplayFunc(displayFunction);
glutIdleFunc(idleFunction);
glutReshapeFunc(reshapeFunction);
glutKeyboardFunc(keyboardFunction);
glutMouseFunc(mouseFunc);
glutMotionFunc(motionFunction);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glClearColor(117.0f / 255.0f, 187.0f / 255.0f, 253.0f / 255.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*
//setting cam
cam.SetPosition(glm::vec3(0.f, 100.f, 350.f));
cam.SetLookAt(glm::vec3(0.f, 100.f, 349.f));
cam.SetClipping(0.1f, 2000.f);
cam.SetFOV(45);
*/
}
void idleFunction()
{
const double current_time = getTime();
if ((current_time - last_render) > frame_delay)
{
last_render = current_time;
glutPostRedisplay();
}
}
void reshapeFunction(int w, int h)
{
//cam.SetViewport(0, 0, windowWidth, windowHeight);
}
void keyboardFunction(unsigned char key, int w, int h)
{
switch (key)
{
case '+': case '=':
break;
case '-': case '_':
break;
/*
case 'w': case 'W':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(FORWARD);
break;
case 'a': case 'A':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(LEFT);
break;
case 's': case 'S':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(BACK);
break;
case 'd': case 'D':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(RIGHT);
break;
case 'q': case 'Q':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(DOWN);
break;
case 'e': case 'E':
for (int z = 0; z < camMoveSpeed; ++z)
cam.Move(UP);
break;
case 27:
currentCamPitchAngle = 0;
currentCamYawAngle = 0;
break;
*/
default:
cout << key << endl;
break;
}
}
void specialKeysFunction(int key, int x, int y)
{
cout << key << endl;
}
void mouseFunc(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouseButtonWasPressed = true;
lastMousePos.x = (float)x;
lastMousePos.y = (float)y;
}
}
void motionFunction(int mousePosX, int mousePosY)
{
if (mousePosX >= 0 && mousePosX < windowWidth && mousePosY >= 0 && mousePosY < windowHeight)
{
if (mouseButtonWasPressed)
{
camPitchAngle += -mousePosY + lastMousePos.y;
camYawAngle += (float)mousePosX - lastMousePos.x;
lastMousePos.x = (float)mousePosX;
lastMousePos.y = (float)mousePosY;
}
}
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(windowWidth, windowHeight);
glutInitWindowPosition(0, 0);
glutCreateWindow("Window");
//glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
init();
//imgui setup
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
ImGui::StyleColorsDark();
ImGui_ImplGLUT_Init();
ImGui_ImplGLUT_InstallFuncs();
ImGui_ImplOpenGL2_Init();
glutMainLoop();
ImGui_ImplOpenGL2_Shutdown();
ImGui_ImplGLUT_Shutdown();
ImGui::DestroyContext();
return 0;
}
Tested on Linux, by curiosity, and I had to fix the build the same way.
Added -std=c++11 + -I/usr/include/SOIL in the makefile AND for the record, soil.h is SOIL.h on Linux (uppercase)
About camera.h, I found several solutions:
````
me@someMachine ~ $ find /usr/include -name camera.h
/usr/include/assimp/camera.h
/usr/include/dc1394/camera.h
/usr/include/config/soc/camera.h
/usr/include/config/leds/trigger/camera.h
/usr/include/config/video/via/camera.h
/usr/include/android-19/system/camera.h
/usr/include/android-19/hardware/camera.h
/usr/include/libcamera/camera.h
/usr/include/lib3ds/camera.h
````
I didn't investigate more after that. Wich one is the right API ?
At the end, I confirm the build is possible, and it works somewhat, but too much information is missing imho to help you more efficiently.
my 2 cts
Thanks @ebachard to confirm it.
I just didn't have SOIL OpenGL lib installed on my distribution, so I preferred to comment it (it's not really used outside of initialization) and the camera, in the source, depends also from glm (though i have and use frequently it).
However, it has been shown that the problem does not seem concern ImGui, but it is necessary to look elsewhere.
@BrutPitt
You are right : I forgot to mention glm, who caused no trouble, because I got it installed.
@ebachard, @BrutPitt, I'm sorry, I misspelled the link to the _Camera_ class implementation.
I found a problem line, the problem appears if these lines are active in _displayFunction()_
//set camera
glm::mat4 model, view, projection;
cam.Update();
cam.GetMatricies(projection, view, model);
glm::mat4 mvp = projection * view * model;
glLoadMatrixf(glm::value_ptr(mvp));
glMatrixMode(GL_MODELVIEW);
Here is a link to the implementation of the _Camera_ class, the problem is there, but I do not know why, the class itself works correctly and performs its functions without problems, but nothing is drawn.
@prostargamer try to move all your render code before ImGui render cycle...
(I don't see the link to Camera implementation)
@BrutPitt, Link to Camera class, now you can try to run this code yourself
@BrutPitt, i try move render code before ImGui render cycle, the problem remains.
The problem consists in the viewport of the cam:
//render
ImGui::Render();
ImGuiIO& io = ImGui::GetIO();
//glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y);
//clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/// ADD THIS LINE
cam.SetViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y);
//set camera
glm::mat4 model, view, projection;
cam.Update();
cam.GetMatricies(projection, view, model);
glm::mat4 mvp = projection * view * model;
glLoadMatrixf(glm::value_ptr(mvp));
glMatrixMode(GL_MODELVIEW);
glBegin(GL_POLYGON);
glVertex3i(-150, 150, 0);
glVertex3i(150, 150, 0);
glVertex3i(150, -150, 0);
glVertex3i(-150, -150, 0);
glEnd();
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
I just modified also reshape function (to update global values):
void reshapeFunction(int w, int h)
{
windowWidth = w; windowHeight = h; // I don't know if you need of this
cam.SetViewport(0, 0, windowWidth, windowHeight);
}

Added
Because cam.Update() override glViewportcall with parameters passed to cam.SetViewport...
so you can comment/delete glViewport(0, 0, (GLsizei)io.DisplaySize.x, (GLsizei)io.DisplaySize.y);
@BrutPitt, @ebachard, Thank you very much, this problem is solved.
But unfortunately, imgui took away my control over the callback functions of the mouse and keyboard. Do you know what the problem might be?
The call ImGui_ImplGLUT_InstallFuncs(); install the ALL ImGui GLUT callbacks ... so if you have installed yours (before), it overwrite them... and viceversa
As written inside the ImGui GLUT example:
// We will also call ImGui_ImplGLUT_InstallFuncs() to get all the other functions installed for us,
// otherwise it is possible to install our own functions and call the imgui_impl_glut.h functions ourselves.
You have some possibilities:
ImGui_ImplGLUT_InstallFuncs();) and inside them call ImGui funcs (look inside imgui_impl_glut.cpp)This last feature is not available in ImGui/GLUT... because (still) as written in ImGui GLUT example:
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2019, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
@BrutPitt, Thank you so much for your help.
I don't want to torment you with questions again, but I don't want to create a new issue for the sake of a small question.
Q: Can I get the dimensions and coordinates of the window created by ImGui? Can I manage these parameters?
For this and other simple questions/dubious I advise you to look at the files imgui.cpp (at begin there is documentation and the FAQs) imgui.h and the file imgui_demo.cpp that are all well documented...
Indeed, in imgui.h there is:
IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList API)
IMGUI_API ImVec2 GetWindowSize(); // get current window size
and
// Prefer using SetNextXXX functions (before Begin) rather that SetXXX functions (after Begin).
IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc.
IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin()
Thanks you.