Hello,
The search feature of this forum is currently broken on my end so I don't know if anybody already posted this request.
However, I found those issues:
- https://github.com/SFML/SFML/issues/695
- https://github.com/SFML/SFML/issues/1113
When using SFML for an OpenGL program (so, without using sf::RenderWindow) the only way to switch to fullscreen mode is to recreate the window.
This may not be a problem when using sf::RenderWindow because this class probably saves the OpenGL state and is able to restore it when the window is recreated.
However, when using sf::Window, users will have to save the paramters sent to sf::Window::create() + the current OpenGL state (calls to glEnable/glDisable/glClearColor and probably other things).
This is a real problem because it causes obscure bugs, and imo it shouldn't be up to the users to deal with that.
What is your opinion on that matter?
EDIT: Minimal example for glClearColor:
#include <SFML/OpenGL.hpp>
#include <SFML/Window.hpp>
int main(int, char **) {
sf::ContextSettings settings;
settings.depthBits = 24;
settings.stencilBits = 8;
settings.antialiasingLevel = 0;
settings.majorVersion = 2;
settings.minorVersion = 1;
sf::Window window;
window.create(sf::VideoMode(800, 600), "OpenGL", sf::Style::Close, settings);
auto desktop = sf::VideoMode::getDesktopMode();
window.setPosition(sf::Vector2i(
desktop.width / 2 - window.getSize().x / 2,
desktop.height / 2 - window.getSize().y / 2
));
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
bool running = true;
bool fullscreen = false;
while (running) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)) {
running = false;
}
else if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::A) {
window.create(sf::VideoMode(800, 600), "OpenGL", sf::Style::Close, settings);
}
else if (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Z) {
window.create(sf::VideoMode(800, 600), "OpenGL", sf::Style::Close, settings);
auto desktop = sf::VideoMode::getDesktopMode();
window.setPosition(sf::Vector2i(
desktop.width / 2 - window.getSize().x / 2,
desktop.height / 2 - window.getSize().y / 2
));
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
}
}
glClear(GL_COLOR_BUFFER_BIT);
window.display();
}
window.close();
return 0;
}
When you press 'A', the window is recreated but nothing is setup, so it resets to its original position and the clear color goes back to black.
When you press 'Z', the window is recreated but both the position and the clear color are setup again so it's fine.
However, I don't think the user should have to store and re-setup all those things (position, video mode, caption, style, context settings, glEnable/Disable/ClearColor, etc...).
SFML only ensures its own states, since it can't know of your custom states, as such it's your responsibility to keep track of your own states.
Yep, that's why I'm requesting for a feature to toggle fullscreen mode during runtime, because this is the right way to fix this problem. Users shouldn't have to keep track of their OpenGL state.
glfw, SDL and most of the window/OS event management libraries I know are capable of setting a window to fullscreen, I don't understand why SFML can't.
[/quote]
I found this on The Old New Thing and it works as a nice toggle while maintaining all OpenGL state:
void ToggleFullscreen(sf::Window& window, WINDOWPLACEMENT& g_wpPrev)
{
#ifdef WINDOWS
sf::WindowHandle hwnd = window.getSystemHandle();
DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
if (dwStyle & WS_OVERLAPPEDWINDOW) {
MONITORINFO mi = { sizeof(mi) };
if (GetWindowPlacement(hwnd, &g_wpPrev) &&
GetMonitorInfo(MonitorFromWindow(hwnd,
MONITOR_DEFAULTTOPRIMARY), &mi)) {
SetWindowLong(hwnd, GWL_STYLE,
dwStyle & ~WS_OVERLAPPEDWINDOW);
SetWindowPos(hwnd, HWND_TOP,
mi.rcMonitor.left, mi.rcMonitor.top,
mi.rcMonitor.right - mi.rcMonitor.left,
mi.rcMonitor.bottom - mi.rcMonitor.top,
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
}
else {
SetWindowLong(hwnd, GWL_STYLE,
dwStyle | WS_OVERLAPPEDWINDOW);
SetWindowPlacement(hwnd, &g_wpPrev);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
SWP_NOOWNERZORDER | SWP_FRAMECHANGED);
}
#endif
}
If you couldn't tell, it is Windows only, but it is quite fast. The only additional setup you need is to keep track of a WINDOWPLACEMENT variable and initialize it with
g_wpPrev.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(window.getSystemHandle(), &g_wpPrev);
after creating your window.