SFML community forums

Help => Graphics => Topic started by: panithadrum on November 06, 2015, 08:10:20 am

Title: Can't render in a thread
Post by: panithadrum on November 06, 2015, 08:10:20 am
Hi guys!

I'm using SFML v2.3, Mingw32 v4.9.2 and Windows 10.

I'm trying to render in a thread, and runtime errors keep coming no matter what I do (Failed to activate the window's context). Here's the code I'm using.

#include <future>
#include <SFML/Graphics.hpp>

int main()
{
    // create the window
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
    window.setVerticalSyncEnabled(true);

    // run the program as long as the window is open
    while (window.isOpen()) {

        // handle events
        {
            sf::Event event;
            while (window.pollEvent(event)) {
                // "close requested" event: we close the window
                if (event.type == sf::Event::Closed) {
                    window.close();
                }
            }
        }

        // clear the window with black color
        window.clear(sf::Color::Black);

        window.setActive(false);
        std::async(std::launch::async, [&]() {
            window.draw(sf::CircleShape(20));
        }).wait();

        // end the current frame
        window.display();
    }

    return 0;
}

Am I missing something? Thanks.
Title: Re: Can't render in a thread
Post by: eXpl0it3r on November 06, 2015, 08:18:58 am
Honestly you shouldn't render in a separated thread. OpenGL is not multi-threadable, all your calls get put onto the OpenGL queue and get processed one at a time, thus you don't really gain anything from doing it multi-threaded.

Aside that, you'll have to call setActive in your separate thread.
Title: Re: Can't render in a thread
Post by: mkalex777 on November 06, 2015, 08:25:23 am
Try to place entire content of main method in separate thread (include window constructor and message loop)
Title: Re: Can't render in a thread
Post by: Nexus on November 06, 2015, 08:53:29 am
Try to place entire content of main method in separate thread (include window constructor and message loop)
...the point of which is?
Title: Re: Can't render in a thread
Post by: mkalex777 on November 06, 2015, 04:59:24 pm
Try to place entire content of main method in separate thread (include window constructor and message loop)
...the point of which is?

In that way you can open second window and render it, but create window and render code should work from the same thread. I'm not sure if it supported by SFML (because it may use per process shared objects), but technicaly it possible.

Just tested it, and it seems that it works, at least I tested it with simple graphics (circleShape, etc). Two window works simultaneously and each window works in it's own separate thread.
So, he can utilize second thread to open second helper window with separate message loop and it will works in parallel with the main window.
Title: Re: Can't render in a thread
Post by: StevenC on November 08, 2015, 06:01:21 am
Am I missing something? Thanks.

The thing you are missing may not be obvious right now, but the drawing code should all be in the same thread from beginning to end. And since the main thread is a valid thread, you should really just not bother with creating that thread. There are really no advantage to rendering using multiple threads. There are other processing tasks you can do with threads, like updating parts of your game simulation that aren't being rendered.
Title: Re: Can't render in a thread
Post by: Nexus on November 08, 2015, 06:17:05 pm
@mkalex777: You talked about the entire content of main(), not about a second window or message loop (don't assume we can read your thoughts). And running the whole main() function in a separate thread is nothing more than a single-threaded application written in an unnecessarily complicated way.
Title: Re: Can't render in a thread
Post by: mkalex777 on November 09, 2015, 04:15:40 am
@mkalex777: You talked about the entire content of main(), not about a second window or message loop (don't assume we can read your thoughts). And running the whole main() function in a separate thread is nothing more than a single-threaded application written in an unnecessarily complicated way.

I talked about the example. I will try to explain it. You can open main window from the main thread in usual way and start second thread with separate render loop and window initialization. The second window will works in parallel with the main one.

As I mention before, I checked if it will works in SFML and it seems that all works OK. I created a small test app which opens two windows and they works in parallel. I can pause render loop in the main thread and the second window continue to update it's content.