Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: How to approach multiple windows over multiple threads  (Read 2096 times)

0 Members and 1 Guest are viewing this topic.

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
How to approach multiple windows over multiple threads
« on: February 01, 2020, 05:28:58 pm »
To be honest, I work right now on a cheat for a specific game. I have to use threads as I need to perform different instructions at regular time intervals and I also don't want to block the main thread. While some of them are just for computation (such as a console, fetching game data, etc) I also have some that should handle different windows. As example: I need to make a thread which creates a window that will draw a radar. I managed it to open, but not to close, which means it works partially. Below is a resume of the part that involves SFML:

Code: [Select]
void modifyRadar() {
if (radarActive) {
radarWindow = new sf::RenderWindow(sf::VideoMode(200, 200), "", sf::Style::None);
radarWindow->setFramerateLimit(fps);
radarDrawThread = new std::thread([&]() {
while (radarWindow->isOpen()) {
radarWindow->clear();
for (auto circle : radar)
if (circle->getPosition().x != -99999)
radarWindow->draw(*circle);
radarWindow->display();
}
delete radarWindow;
radarWindow = 0;
});
return;
}
radarWindow->close();
radarDrawThread->join();
delete radarDrawThread;
}

All the variable are available in the outer scope. I did read posts about what I want to do and tried changes such as:

Code: [Select]
radarDrawThread = new std::thread([&]() {
sf::Context context;
radarWindow->setActive();
while (radarWindow->isOpen()) {
radarWindow->clear();
for (auto circle : radar)

In the first example, this is what stdout shows:

Code: [Select]
...

An internal OpenGL call failed in RenderTarget.cpp(152).
Expression:
   glClearColor(color.r / 255.f, color.g / 255.f, color.b / 255.f, color.a / 255.f)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

An internal OpenGL call failed in RenderTarget.cpp(153).
Expression:
   glClear(GL_COLOR_BUFFER_BIT)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

An internal OpenGL call failed in Texture.cpp(782).
Expression:
   glBindTexture(GL_TEXTURE_2D, 0)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

...

The functions in the while loop are not hit anymore since the window has closed (expected behavior). When I use the example with sf::Context, when the sf::Context object has to destruct itself an exception is thrown:

Code: [Select]
Exception thrown: read access violation.
this-> was 0xFFFFFFFFFFFFFFE7.

I do realize that there may be better options for the thing I want to do, especially that I didn't shown the full code due to its size, and while I appreciate very much the opinions, I would like to know how to render different windows in different threads at least for knowledge. I tried different combinations of the sf::Context, setActive(), and the order the windows are created. Before the exception is thrown, this is what stdout has:

Code: [Select]
Failed to activate OpenGL context: The operation completed successfully.

From what I understand: to draw multiple windows u can use the default sf::Context and use setActive() to manage where the OpenGL calls go, or use multiple sf::Context and no need for setActive() since every window has its context. I also seen that setActive() shall be called also when I render a specific window in another thread rather than where it was made

Raincode

  • Full Member
  • ***
  • Posts: 118
    • View Profile
Re: How to approach multiple windows over multiple threads
« Reply #1 on: February 02, 2020, 01:43:15 pm »
Hi,

take my information with a grain of salt, but I seem to remember the windows message loop must be run from the main thread, and from the main thread only. In other words, you cannot create a window and handle events from another thread.

Correct me if I'm wrong...

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
Re: How to approach multiple windows over multiple threads
« Reply #2 on: February 02, 2020, 04:12:36 pm »
I just seen the mistake. I don't handle events in the other thread, but indeed may cause problems later, so I updated how to thread works:

Code: [Select]
drawThread = new std::thread([&]() {
window = new sf::RenderWindow(sf::VideoMode(200, 200), "", sf::Style::None);
window->setFramerateLimit(fps);
handle = window->getSystemHandle();
while (window->isOpen()) {
window->clear();
for (auto circle : radar)
if (circle->getPosition().x != -99999)
window->draw(*circle);
window->display();
}
delete window;
window = 0;
});

The results are EXACTLY the same, regardless using sf::Context or setActive(). Do u have any idea from here?

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
Re: How to approach multiple windows over multiple threads
« Reply #3 on: February 02, 2020, 05:36:54 pm »
I fixed the problem. Regardless the last code edit, I had to make sure to close() the window from the thread it was created. I expected this one to work from a different thread

If someone use this thread as reference for his problem, I had change the while within thread from while(window->isOpen()) to while(settings.radarActive) which leads to the close() function be actually called by the window destructor (since I do delete at end) rather than me manually (which I did in order to make window->isOpen() return false)