ImGui multisampling - c++

I render my scene to FBO with multisampling. The resulting texture I use as ImGui::Image content. But how can I disable multisampling for gui?
I tried:
glDisable(GL_MULTISAMPLE);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(Game::getWindow());
ImGui::NewFrame();
//...
// Some gui elements
//...
ImGui::Render();
ImGui::UpdatePlatformWindows();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glEnable(GL_MULTISAMPLE);
But this doesn't work. MSAA actually enabled when the gui drawing(text is blurred).

When it comes to window contexts, you can't disable MSAA after the window has been created. You need to recreate your window for it to take effect.
I'm not sure if the same thing is needed for FBOs, however, to my knowledge calling glDisable(GL_MULTISAMPLE) at runtime only cleans up some AA state, and you can't rely on it, since it's intended that you recreate your window to make changes to MSAA, so I'd guess it probably doesn't affect your FBO the way you expect it to either.
There's also an open issue on the ImGui repo about dealing with AA and fonts, though it seems to be "on hold" for now.

Related

Is there a way to change the number of MSAA samples of an existing GLFW window?

I am currently writing a game using C++, OpenGL and GLFW. I would like to allow users to change the number of samples the game uses for antialiasing, since users with old systems might want to disable antialising altogether for performance reasons.
The problem is that GLFW_SAMPLES is a window-creation hint, which means that it's applied when a window is created:
// Use 4 samples for antialiasing
glfwWindowHint(GLFW_SAMPLES, 4);
// The hint above is applied to the window that's created below
GLFWwindow* myWindow = glfwCreateWindow(widthInPix, heightInPix, title.c_str(), glfwGetPrimaryMonitor(), nullptr);
// Disable antialiasing
// This hint is not applied to the previously created window
glfwWindowHint(GLFW_SAMPLES, 4);
The GLFW documentation doesn't contain any information about how to change the number of samples of an existing window. Has anyone faced this problem in the past?
No, you must create a new window and destroy the old one. Preferably sharing the two contexts, so that non-container objects won't be lost in the shuffle.
Alternatively, you can create multisampled textures or renderbuffers, render to an FBO, and then blit the rendered data to a non-multisampled window. That way, you have complete control over the number of samples, and you can easily destroy and recreate such images at your leisure.

SDL resetting glViewport

I'm testing supporting multiple resolutions in an application using SDL2 with OpenGL. To create my "letterbox" functionality I set my glViewport to an appropriate value and everything works perfectly.
However, if I create my window with the SDL_WINDOW_ALLOW_HIGHDPI flag set, whenever I move my window (after receiving the SDL_WINDOWEVENT_MOVED event) SDL modifies the viewport to the full size of the window, which can be verified by calling SDL_GL_GetDrawableSize during the event.
If I do not set SDL_WINDOW_ALLOW_HIGHDPI when creating the window, the viewport is not reset. I do believe this to be a bug, but cannot find anything through the SDL bugzilla so I thought to ask if anyone has seen similar behavior.
You may need to have a retina MacBook Pro to experience this behavior.
Just do what you should be doing anyway: Always re-/set the viewport at the beginning of drawing each frame. As soon as you want to implement a HUD, use framebuffer objects or similar things you'll have to set the viewport (several times) for drawing each frame.

Draw content of QOpenGLFramebufferObject onto QOpenGLWidget

I am currently porting from Qt4 to Qt5. While Qt5 still provides the QGLWidget etc. classes, these are to be replaced by QOpenGLWidget etc.
Currently I am drawing complicated stuff into a framebuffer object once. Then I draw it on the screen (into the GL widget) using drawTexture() method:
target->drawTexture(rect, fb->texture());
Afterwards, I overdraw with other temporary things. So whenever I need to update the temporary stuff, I can just re-use the framebuffer object instead of redrawing the complicated stuff.
With QOpenGLWidget, as well as QOpenGLContext, however, there is no convenient drawTexture() method anymore. Drawing the texture by-hand with OpenGL would be a minimum of 20 lines of complicated stuff. Textbook stuff, I admit.
Is there any elegant/Qt way of getting my fbo contents onto the screen? For example, it is documented that QOpenGLWidget also uses an fbo as a backend. Instead of drawing the texture, we could also blit the FBOs. But how?

Is glutSwapBuffer command required to get background color?

I didn't understand the functionality of glutSwapBuffer properly. In my code if I don't use the glutSwapBuffer than no background color came in window and it remain transparent, capturing whatever is there in its background. I think that the background color is actually assigned by glClearColor, than how come without using glutSwapBuffer I didn't get any background color.
This question comes up over and over, I think what you are describing is actually what happens when you draw exclusively into the front-buffer in a compositing window manager.
Without swapping buffers, it does not draw your window correctly, so the window appears transparent. Double buffering is required for compositing window managers and it seems it is also required for many hybrid integrated/discrete GPU implementations (e.g. nVIDIA Optimus). In short, there is no real reason to use single-buffered rendering on a desktop platform these days.
To be certain, does your situation resemble this? This screenshot shows what happens when a window that only uses single-buffering is moved in a compositing window manager.
If so, a more thorough explanation can be found here.
opengl usually is configured to use double buffering.
You first draw to one buffer... then Swap it with the second and present it on the screen.
Without calling glutSwapBuffer you will not see anything and it is correct behavior.
about double (and more) buffering in opengl

Hide GLUT window

Is it possible to hide OpenGL window and the rendering are still running? I use glutHideWindow which will never trigger display function.
If that is not possible, is it possible in the program to change the focus of the current window? I want to run opengl program but I don't need that window. In fact, I want to use the framebuffer that opengl updates at each frame in another program. But it's always annoying to toggle between the two programs. (They both have window)
Is it possible to hide OpenGL window and the rendering are still running?
Yes and No to both parts of the question.
If you hide a window, all the pixels of the window's viewport will fail the pixel ownership test when rendering. So you can't use a hidden window as a drawable for OpenGL to operate on.
What you need is an off-screen drawable to draw to.
The modern variant are Framebuffer Objects (FBOs), which you can create on a regular OpenGL context, that might even work on a hidden window. FBOs take some drawable attachments (render buffers, textures) and allow OpenGL to draw to these instead to the window.
An older method are PBuffers, also widely supported, but not as easy to use as FBOs.
Note that if you want to perform off-screen rendering on Linux/X11 the X server must be active, i.e. owning the VT so that the GPU actually processes the commands. So you can't just start an X server "in the background" but have another X server use the display device.
After creating the window, you can use glutHideWindow() to go offscreen. Then you still render as nomal and use glReadPixels to read back and get buffer to use it later.