How do you control a SFML window from a separate thread? - c++

I'm currently working on a game where I wanted to create a loading screen that basically shows the process of loading all the resources. To do this, I decided to create a separate thread that handles the window. I'm aware that there could be more efficient solutions, but I wanted to create a special mouse cursor and that way was the only way that allowed me to do that without having a buggy mouse when the application is loading a big file.
I read up on the threads on the SFML tutorial page and I learned that I have to do window.setActive(false) in the main thread and then window.setActive(true) in the separate thread in order to have access to the window in the separate thread without getting any problems. This works fine, it doesn't throw any errors and it displays the loading screen very nicely. However, I can't move the window around or interact with it in any way. The mouse cursor is covered by the blue ring from the mouse when it's loading, and I can neither close nor move nor resize the window even though I used sf::Style::Default, so it should be possible.
Can anyone help me out here?

You have it backwards. You blocked the main thread with loading your resources and created a new thread to keep the UI responsive. Not only is that not going to go well in the long term, but in the short term, your operating system still thinks your app is blocked, because the main thread is unresponsive. The OS does not know you created a second thread to keep the user entertained.
You should instead keep the responsive UI on the main thread and create an extra thread for doing the heavy lifting and blocking work. This way you don't have to struggle with your graphics library all the way (and it does not matter whether that's SFML, because they all do this) plus your operating system will not behave as if you blocked your application.

Related

How to share frame rendering between two proceses

Im designing a game menu for an arcade machine as a personal project and to get more familiar with IPC. The project runs on a raspberry Pi rendering to a LED matrix using Hzeller's led matrix library. The menu would present the user a list of games rendered on the matrix. When the user selects a game, the main process will fork and spawn the game in a new process. The game will start and render to the matrix. At any point the user can exit the game which will return the user back to the game menu. Presumably there will be communication between processes so each aren't simultaneously rendering to the matrix at the same time.
Now where I am uncertain is how to actually share resources that are needed to render to the matrix. The library has a background updater thread that cannot be running in both process. Im not certain how this is typically done but here are the solutions I came up with:
Resources needed for rendering are cleaned up and reinitialized before switching contexts between parent and child processes
The Child will serialize the underlying framebuffer data and send it to the main process for rendering.
The first solution seems a little hacky and requires me to make small changes to the library. I also want to create an interface to decouple the menu/game processes from where graphics are actually rendered. This way I can make a separate implementation of the interface to render to a GUI on a computer screen. Choosing this option would be synonymous of creating an entirely new window for the child process (not sharing the same window).
The second solution would require copying the framebuffer data twice per frame. Once to shared memory and then again when the parent process copies out of shared memory and rendered. I worry about latency and how to manage frame rate in this solution. Ive looked into initializing the framebuffer in shared memory, but the library handles the initiation of this buffer. In addition, I am utilizing the library's vsync capability and am unsure how the child would utilize this if rendering were done in the parent process
My questions are:
Are there any other solutions? If not which of the two are better
design wise.
If I go option two, how would the child take advantage of the vsync functionality and how would I manage framerate in this scenario?
A game will typically involve real-time rendering to the LED matrix, and will have other requirements for user interaction to that are specific to the game and a lot more demanding than the requirements of your simple menu. It would not be good design practice to delegate these things to the menu process via some IPC mechanism. That mechanism could only get in the way, and you'd be forced to implement many of the game's requirements inside the menu process. The game should be able to control the display directly, while the menu should only have to do its easy menu things.
This should be very simple to arrange. Your menu process should shut down its display loop before it launches the game process, and should then resume its display loop when the game process ends.
The best way to do detect the completion of the child process is usually to pipe stdout on the child process into a parent process file handle. The parent process should read from this handle until it is automatically closed by the child process exiting. This is a universally reliable signal that works on all linux/unix/windows platforms.

share OpenGL context between multiple threads

I'm working on an OpenGL project where there are many scenes. I have successfully implemented the functionality of switching scenes at runtime, so the user can change to another scene by choosing a scene name through the ImGui menu. When that happens, the current scene is deleted to clean up dirty OpenGL internal states, then the new scene will be loaded from a factory pattern. Everything works fine, except that the window will freeze for a few seconds during the transition because unloading/loading scenes takes quite a while to finish.
What I want to do now is to create a loading screen, which will be displayed in between. The task of unloading/loading scenes is scheduled asynchronously using std::async and std::future, so that the caller is non-blocking and my loading screen can show up. However, since I'm creating the new scene in background in another thread, that thread cannot see the OpenGL context in the main thread, as a result, any glxxxx() calls would cause access violation so the new scene cannot be created.
I know that OpenGL is a global state machine which does not support multithreading quite well. I've also read somewhere that it is driver-dependent. Most threads on this topic is old, I wonder if it is still difficult to use multithreading in OpenGL as of 2021. From what I see, loading screen and switching scenes are just very basic functionalities, many applications are able to do so, and I believe there're a bunch of them using OpenGL, why is this problem still not commonly addressed today?
Does anyone know of any external libraries in this regard? Or is there another workaround without using multiple threads?

Render to same target from multiple threads

I am working on an old C++ project on Windows, where I am upgrading the app's DirectX rendering engine (using DX11). The new engine that I made currently coexists with the old one, but it runs in a different thread and has its own DX device and context. Until now, I've been using two separate windows to display the results of the old and new rendering processes at the same time, which allows me to verify that the new engine correctly replicates the behavior of the old one.
Now I want to merge these windows and swap between them at runtime, i.e I would hook a button press, or some other control to pause one render thread and (re)start the other. Both would draw their results to the same window (i.e using the same HWND to create the render target and swap chain), but only one thread would be active at any one time. A good analogy would be some remastered games where they let you swap between the old and new graphics.
What is the most ideal way to achieve this? I was thinking of doing a "hot swap", i.e letting one thread start rendering without even waiting for the other thread to finish, since we know it will stop in the next frame, and I don't need them to be working together. Does this carry the risk of crashing, or any other problems? If all it would cause is a few incorrect frames during the swap, then I don't mind.
I tested it, no ill effects as far as I can tell, besides some flickering if both threads happen to try to draw at the same time.

How to find why win32 dialog drawing hangs?

I have a win32 application which updates a lot of rectangles in a dialog quite fast. (now via bitblt(a bit of double buffering), before it was a different method - it doesnt matter).
And after random time passed - random dialog(from that application, with updating rectangles) just hangs on my PC. And by hanging i mean its redrawing hangs, if i push a menu button which popups something it works, but dialog doesnt shows anything just stays stuck. And it stays stuck until resized ! Or application restarted, ofc.
This only happens on my 'fast' PC with 3 desktops(controlled via different gpus).
My 'slow' laptop doesn't reproduce this, or maybe it would need more time to reproduce this(not a night, lets say) since its slower ?
I am really new in c++, windows dialogs programming - i may misused something or done something wrong. i checked everything i can, revisited microsoft tutorials on dialogs(and every drawing function) usage, checked everything - didnt quite found anything.
Maybe someone can offer me something smarter than disabling random functionality and waiting will it hang or not ? I would like to understand why it crashes(hangs), and why like this.
OS: Microsoft Windows 7 64
Compiler: Visual studio 2013
Addition: The debugger when stopped: Main thread shows only entrance of main dialog. DialogBox function, that's all. Ofc that thread is running all the other dialogs, but those dialogs are ran from main dialog called by DialogBox. Drawing is done by different thread, and it doesnt even notice that dialog hanged. The main thread doesn't 'hang' since other dialogs runs quite fine. and that 'hanged' dialog is fixed if resized, so strange.
Drawing by different thread means: dialogs are ran by main thread, other thread(actually couple of them and lower priority than other threads) is responsible for biblt and other drawing logic operations on those dialogs(since up to 600 rectangles can be updated up to 100Hz, it draws CPU quite well). I did addressed critical section problems and resources freeing when not used quite well but first thing i will do will be - rechecking those.
You're simply not supposed to draw from other threads.
It is however safe for a single thread to draw to a bitmap (i.e. in memory), and then hand off that bitmap to the main thread for bitblt'ing. That can scale in the sense that you can have multiple threads prepare multiple bitmaps, and have the main thread bitblt each of those in turn.

Best Drawing approach

I have developed an application in wxWidgets in which I am using bitmap for drawing. So First time when my application launches, it reads coordinates from file and draw lines accordingly. The application also receives UDP packets from network, UDP packets also contain some x y coordinates information which has to be drawn on the screen, so when the packet are received I redraw the bitmap image, and display on screen, I also need to refresh the bitmap on mouse move event because on mouse move there is some new drawing which I have to draw on screen.
All this increases the operational cost and slows down my GUI. So kindly suggest me some alternative drawing approach which you think might be efficient in this situation.
I have searched out on Google and got the option of OpenGL, but due to time shortage I don't want to use openGL, because I haven't any experience of OpenGL.
It sounds as if your problem is that your GUI is unresponsive to user input because the application is busy redrawing the display. There are a couple of general solutions to this kind of problem.
Draw the bitmap in memory using a worker thread. While this is going on the main thread can continue to interact with the user. Once the bitmap has been redrawn, the worker thread signals the main thread, and the main thread then copied the completed bitmap to the screen - which is extremely fast.
Use the main thread to draw the bitmap directly to the screen, but sprinkle the drawing code with calls to wxApp::Yield(). This will allow the GUI to remain responsive to the user during a lengthy drawing process.
Option 1 is the 'best', especially when running on multicore machines, but it is a challenge to keep the two threads synchronized and prevent contention between them, unless you have significant experience with multithreading design. Option 2 is much simpler, though you still have to be careful that the user interaction doesn't start another drawing process before the first is finished.
Save off the data to draw instead of always refreshing the bitmap and have the main loop make refreshes of the bitmap from time to time.
This way you can make the program never hog down. The backside is of course that the reactivity will be lower (ie. when data comes, it won't be seen on screen for another 20 milliseconds instead of right away).