I have a program that creates a window in a class constructor, then passes its reference to a thread that handles the main game loop. I then poll the window events in the class constructor.
I'd like the window to go fullscreen when the user hits ctrl+F, and switch back to windowed when the hotkey is pressed again, and I've tried doing so by using
window.create(sf::VideoMode::getFullscreenModes()[0], "NESTRIS", sf::Style::Fullscreen);
both in the events polling loop and the game loop thread with no avail. The tutorial says "Events must be polled in the window's thread" So I suppose the window should be recreated in the class constructor, but even resizing the window,
without going fullscreen doesn't work: the window goes white and unresponseive.
Should I just close the window and recreate the thread? Is there a way to avoid that?
Class constructor:
sf::RenderWindow window(sf::VideoMode(tilerend.width_pixels, tilerend.height_pixels), "NESTRIS");
window.setPosition(...);
window.setSize(...);
window.setActive(false);
std::thread render_thread(&Window::render, this, std::ref(window), std::ref(tilerend));
fullscreen.store(false);
sf::Event event;
bool is_mouse_hidden = false;
while (window.isOpen()&&!close_window) {
if (window.waitEvent(event)) {
if (!is_mouse_hidden && hide_cursor.load()) {
window.setMouseCursorVisible(false);
is_mouse_hidden = true;
}
else if (is_mouse_hidden && event.type==sf::Event::MouseMoved) {
window.setMouseCursorVisible(true);
is_mouse_hidden = false;
}
event_queue.push(event);
}
if (toggle_fullscreen.load()) {
toggle_fullscreen.store(false);
if (fullscreen.load()) {
fullscreen.store(false);
window.create(sf::VideoMode(window_size_x.load(), window_size_y.load()), "NESTRIS");
}
else {
fullscreen.store(true);
//even this doesn't work: window.create(sf::VideoMode(window_size_x.load()*1.2, window_size_y.load()*1.2), "NESTRIS");
window.create(sf::VideoMode::getFullscreenModes()[0], "NESTRIS", sf::Style::Fullscreen);
}
}
}
if (render_thread.joinable())
render_thread.join();
window.setActive(true);
window.close();
Game loop part that processes the events, which should be fine:
while (event_queue.size() > 0)
{
sf::Event event = event_queue.pop();
switch (event.type) {
case sf::Event::Closed:
close_window.store(true);
break;
case sf::Event::KeyPressed: {
bool ctrl = sf::Keyboard::isKeyPressed(sf::Keyboard::LControl) || sf::Keyboard::isKeyPressed(sf::Keyboard::RControl);
if (window.hasFocus()) {
if ((event.key.code == sf::Keyboard::F && ctrl)) {
toggle_fullscreen.store(true);
}
}
}
break;
case sf::Event::Resized:
if (!fullscreen.load()) {
window_size_x.store(window.getSize().x);
window_size_y.store(window.getSize().y);
}
break;
}
}
The whole file, but without the fullscreen stuff:
https://github.com/Elanif/NESTRIS/blob/master/src/Window.cppEdit: I'm pretty sure the problem was the lack of mutexes and lock guards. After guarding some calls to Window::isOpen, clear, draw, display, it almost always works, except for a few times when the window turns completely black. In that case it still responds to events and it can be fixed by toggling fullscreen and back again.