GLFW3, how to tell if a window is currently maximized? - opengl

Is there a way to tell if a window is currently maximized in GLFW3? Not fullscreen, but maximized in windowed mode.

From https://www.glfw.org/docs/3.3/window_guide.html#window_maximize
int maximized = glfwGetWindowAttrib(window, GLFW_MAXIMIZED);

I've been looking through the GLFW3 docs (http://www.glfw.org/docs/latest/) and nothing has immediatly jumped out at me which is strange because you'd think it would be a window attribute but here are a few alternatives:
Keeping Track - This is the easiest method. You could just create a boolean variable to keep track of when the user maximizes (or minimizes) the window. You could then query this to determine which state the window is currently in.
Getting the Size - This is not entirely reliable because it changes depending on your monitor resolution but it is fairly simple to implement. Simply get the size of the window using the following code:
int width, height;
glfwGetWindowSize(window, &width, &height);
Then check to see if it matches the maximum window resolutions.
OS Specifics - If you are on Windows then it might be worth checking out the microsoft documentation on how to check for these attributes using the GLFW's window handle. The specific page to look at would be this: http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633518(v=vs.85).aspx

Related

How to determine size of the drawable area of an OpenGL 3.3 window using GLFW

I'm trying to create an game / application using GLFW and OpenGL 3.3. I'd like to be able to detect collision with the sides of the window, but it seems that the drawable area of the window differs from the size of the window set using glfwCreateWindow().
So my question is, how do I get that drawable area, ie. the size of the window minus the border? I'd rather not have to use the WinAPI so as to make it more cross-platform, and glfwGetWindowFrameSize() is in GLFW 3.1, which isn't completed yet.
Edit: My question makes it seem like I need to use GLFW do accomplish this, which isn't true. I just wanted to note that I'm using GLFW as a window / input handler.
You want glfwGetFramebufferSize.
glfwGetVideoMode returns the video mode of the specified monitor, not the size of your window. For fullscreen windows, they happen to be the same, but for other windows they are likely to be very different.
From the looks of it, you do not need to know the size of the window, I'm assuming in pixels? If you want to do collision detection with the border of the window, you just need to detect the the NDC of your vertex, and once it reaches x or y = (-1, 1) then you would've had a collision. Nonetheless, if you want to get the size in pixels of your OpenGL context then use glfwGetVideoMode().

Improving window resize behaviour, possibly by manually setting bigger framebuffer size

I was considering using glfw in my application, while developing on mac
After successfully writing a very simple program to render a triangle on a colored backround,
I noticed that when resizing the window, it takes quite some time to rerender the scene, as I suspect due to framebuffer resize.
This is not the case when I am repeating the experiment with NSOpenGLView. Is there a way to hint glfw to use bigger framebuffer size on start, to avoid expensive resizes?
I am using GLFW 3.
Could you also help me with enabling High DPI for retina display. Couldn't find something in docs on that, but it supported in version 3.
Obtaining a larger framebuffer
Try to obtain a large initial frame-buffer by calling glfwCreateWindow() with large values for width & height and immediately switching to displaying a smaller window using glfwSetWindowSize() with the actual initial window size desired.
Alternately, register your own framebuffer size callback function using glfwSetFramebufferSizeCallback() and set the framebuffer to a large size according to your requirement as follows :
void custom_fbsize_callback(GLFWwindow* window, int width, int height)
{
/* use system width,height */
/* glViewport(0, 0, width, height); */
/* use custom width,height */
glViewport(0, 0, <CUSTOM_WIDTH>, <CUSTOM_HEIGHT>);
}
UPDATE :
The render pipeline stall seen during the window re-size(and window drag) operation is due to the blocking behavior implemented in the window manager.
To mitigate this in one's app, one needs to install handler functions for the window messages and run the render pipeline in a separate thread independent from the main app(GUI) thread.
High DPI support
The GLFW documentation says :
GLFW now supports high-DPI monitors on both Windows and OS X, giving
windows full resolution framebuffers where other UI elements are
scaled up. To achieve this, glfwGetFramebufferSize() and
glfwSetFramebufferSizeCallback() have been added. These work with
pixels, while the rest of the GLFW API work with screen coordinates.
AFAIK, that seems to be pretty much everything about high-DPI in the documentation.
Going through the code we can see that on Windows, glfw hooks into the SetProcessDPIAware() and calls it during platformInit. Currently i am not able to find any similar code for high-DPI support on mac.

Handling maximized windows using SDL

We recently ported Bitfighter from GLUT to SDL. There were numerous benefits to doing this, but a few drawbacks as well, especially in the area of window management.
Bitfighter runs in a fixed-aspect-ratio window (800x600 pixels). Users can make their window any size they want, but we capture the resize event and make adjustments to the requested size to ensure the window keeps the correct proportions (using SDL_SetVideoMode).
(The following problem applies to Windows, but has not yet been tested on other platforms. What I describe below refers specifically to Windows, though I am looking for a platform-independent solution.)
Ordinarily, this works great, except when users maximze their window by double clicking on the title bar or using the maximize button. In that case, the window resize event is called with the a window size approximating the screen size (minus some pixels for window ornamentation). Unfortunately, when the window is maximized, SDL_SetVideoMode has no effect (unlike GLUT which was able to resize a maximized window). Furthermore, subsequent calls to SDL_GetVideoInfo report the size we requested, not the actual current size of the window, so it is hard to tell if the attempted resizing worked.
I am looking for a platform independent way to do any of the following (in descending order of preference):
Resize a window after it's been maximized
Detect when a window has been maximized so that, knowing I can't resize it, I can at least adjust the video to be centered
Prevent a window from being maximized (block double clicks on window title bar, use of the maximize button, and dragging the window to the top of the screen)
Bitfighter is written in C++, and we're using the latest official release of SDL.
Migrate to SDL 2.0 (which it seems you already have)
SDL 2.0 provides a better API to window management (it actually provides one). While there are still many bugs in Windows management in SDL 2.0 (especially on the Linux side), it has vastly improved since the 1.2 days.
I assume, that you use OpenGL with SDL, because you used GLUT before. I don't know any solutions for that problem, exept point 2. If you want the Video to have a specific size, just leave the SDL-Window like it is, and call
glViewport(0, 0, width, height);
with the right size with the right proportions.
With that solutions you will still have a black border in your window, but It only shows as much, as you want. (with the first 2 arguments you can also set the position of the Viewport in the window ;) )

When using SDL_SetVideoMode, is there a way to get the internal SDL_Window pointer or ID?

If you create a window by using SDL_SetVideoMode(), you are returned a surface, not a window handle. Is there a way to get the SDL_Window handle? I know there is a SDL_GetWindowFromID function, but I'm also not sure how to get the ID, other than the SDL_GetWindowID function, which would require me to already have the window handle.
Any suggestions? Note that it is very important that I maintain cross platform portability, so I prefer to stick with built in SDL functionality if at all possible.
If it helps any, I'm trying to get and set the window position and window size, and those functions require a window handle.
Thanks!
EDIT: I should mention also that I am changing video modes at the user's request, so I cannot just use the default ID of 1, since this ID changes every time I call SDL_SetVideoMode().
I had the same problem with SDL-1.2.15 for windows ,but the problem solved by GetActiveWindow.
You can get SDL window handle like this :
...
screen = SDL_SetVideoMode(w, h, 0, flags);
...
HWND hnd= GetActiveWindow();
See this :
GetActiveWindow function
I had this exact problem - old SDL 1.2 only uses one window, so it keeps the handle to itself. Here's the method I found from reading the source code:
Include SDL_syswm.h then get the window handle using SDL_GetWMInfo
e.g. my code for getting the handle in Windows:
SDL_SysWMinfo wmInfo;
SDL_GetWMInfo(&wmInfo);
HWND window = wmInfo.window;
SDL_SetVideoMode returns a surface based on the video frame buffer, not on a window (just like SDL_GetVideoSurface). You seem to assume that all surfaces correspond to windows, but that is not the case.

Best Method for Minimizable Fullscreen Window

I'm coding a short game in C++ and Win32, and I want to be able to make it in fullscreen with a fixed size. I also want the user to be able to switch focus between the game window and other windows as much as he/she wants without any weird screen glitches.
So far I know of the ChangeDisplaySettings function and creating the window with the WS_POPUP style at initialization to make it fullscreen. To detect the user switching focus to other windows by way of alt+tab or otherwise, what messages should I be handling on the window's WndProc or should I be using another function? When loss of focus is detected should I only call ChangeDisplaySettings(NULL, 0); or are there other functions I should call as well? And what method should I use to handle focus back into the window?
Also can anyone give me some info on how to make it work smoothly for different screen sizes?
Thanks for any help.
If you want an exclusive full screen window, use DirectX.
But I don't recommend it. Changing the display mode causes glitches, rearranges the users icons and so on. Whether done by you, or Direct X.
Rather create a normal window at your native res, and let the user maximize it if wanted.
You could also use the GDI+ library of Windows XP (and newer) to use hardware-accelerated stretching (draw in 640x480, let GDI+ resize it to the native resolution). Then you don't need exclusive mode of DirectDraw nor ChangeDisplaySettings.
Also drawing into a 640x480 big background buffer and bit blitting it on the drawing surface via StretchBlt can be a performant solution.