SFML fails in multithreading - c++

im new to sfml and c++.and I have a project that uses the sfml library's to draw the graphics but when I add an additional thread to my program it fails to execute the code inside the thread. this is my code:(please help me!)
#include <SFML\Graphics.hpp>
#include <SFML\window.hpp>
#include <SFML\system.hpp>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int h(sf::RenderWindow* win){
//do something
win->close();
this_thread::sleep_for(chrono::milliseconds(10));
return 0;
}
int main(){
sf::RenderWindow window(sf::VideoMode(800,600),"My window");
thread t1(h,&window);
_sleep(10000000);
t1.join();
return 0;
}

http://www.sfml-dev.org/tutorials/2.0/graphics-draw.php#drawing-from-threads
SFML supports multi-threaded drawing, and you don't even have to do
anything to make it work. The only thing to remember is to deactivate
a window before using it in another thread; that's because a window
(more precisely its OpenGL context) cannot be active in multiple
threads at the same time.
call window.setActive(false); in your main(), before you pass it off to the thread.
And remember that you must handle events in the GUI thread (the main thread) for maximum portability.

Related

How to use C++ PlaySound() function with sound from resources?

I'm trying to play the song in simple console executable. However after running the .exe the song doesn't play and the windows notification sound appears instead in loop. The resources are created properly (l am using Codeblocks so l can see them in /obj/debug/) so l suppose that's because the PlaySound() path that l set doesn't lead to the right directory.
How to set the path to resources in PlaySound() function? Thank you in advance
play/main.cpp:
#include <iostream>
#include <thread>
#include <windows.h>
#include <mmsystem.h>
void play() {
PlaySound(TEXT("a18.wav"), NULL, SND_FILENAME|SND_LOOP|SND_ASYNC);
}
int main() {
std::thread t(play);
system("pause>>nul");
t.join();
return 0;
}
play/song.rc:
song WAVE "/rsrc/a18.wav"
SND_FILENAME is the wrong flag to use when the audio is in a resource. You need to use the SND_RESOURCE flag instead.
The .rc you have shown is assigning a non-numeric ID song to the resource, you need to use that ID to play the resource. There is even an example of this in PlaySound's documentation: Playing WAVE Resources. In comments, you say you tried MAKEINTRESOURCE(IDR_WAVE1) as the resource ID to play, but MAKEINTRESOURCE() works only with numeric IDs.
Also, you are using the SND_ASYNC flag, which means PlaySound() will exit immediately, thus your thread will terminate immediately, making it useless. You don't really need the thread at all, unless you remove the SND_ASYNC flag.
Try this instead:
#include <windows.h>
#include <mmsystem.h>
#include <cstdlib>
int main() {
PlaySound(TEXT("song"), GetModuleHandle(NULL), SND_RESOURCE|SND_LOOP|SND_ASYNC);
std::system("pause>>nul");
PlaySound(NULL, NULL, 0);
return 0;
}
Alternatively:
#include <thread>
#include <atomic>
#include <cstdlib>
#include <windows.h>
#include <mmsystem.h>
std::atomic_bool stop(false);
void play() {
while (!stop.load()) {
PlaySound(TEXT("song"), GetModuleHandle(NULL), SND_RESOURCE);
}
}
int main() {
std::thread t(play);
std::system("pause>>nul");
stop.store(true);
t.join();
return 0;
}

Issues using multithreading in SFML for C++ [duplicate]

This question already has an answer here:
SFML fails in multithreading
(1 answer)
Closed 1 year ago.
I am trying to create a separate thread while using the SFML game library. This is a very simplified example.
I'm using WSL and the libsfml-dev library. My issue is that it seems like I cannot perform certain actions using the SFML library on threads other then my main thread. For example, in the code below, I get an error if I click escape. What's supposed to happen is the program simply exits as the loop conditions fail.
If you want to run the code yourself...
to grab the library: apt-get install libsfml-dev
g++ compiler arguments: g++ test.cpp -pthread -lsfml-graphics -lsfml-window -lsfml-system
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
// Create window object
sf::RenderWindow window(sf::VideoMode(800, 800), "");
using namespace std;
void *func(void *threadid) {
// Show thread was created
cout << "New thread was ran." << endl;
while (window.isOpen()) {
// This action kills the program and not in a nice way
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
window.close();
}
}
pthread_exit(NULL);
}
int main() {
// Create new thread
pthread_t threads[1];
int val;
val = pthread_create(&threads[0], NULL, func, (void *)1);
cout << "Main thread was ran." << endl;
// This is here so that the program doesn't exit
while (window.isOpen()) {}
return 0;
}
Error message
It is not uncommon to have to do all GUI updates from the main thread. It is likely that SFML is not even thread-safe. You need to communicate from your other threads to the main thread and let them do things like window.close().
If I modify your example and simply return from the second thread instead of calling window.close(), it does not crash.

C++ std::thread makes segmentation fault error when it was used with SFML [duplicate]

im new to sfml and c++.and I have a project that uses the sfml library's to draw the graphics but when I add an additional thread to my program it fails to execute the code inside the thread. this is my code:(please help me!)
#include <SFML\Graphics.hpp>
#include <SFML\window.hpp>
#include <SFML\system.hpp>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int h(sf::RenderWindow* win){
//do something
win->close();
this_thread::sleep_for(chrono::milliseconds(10));
return 0;
}
int main(){
sf::RenderWindow window(sf::VideoMode(800,600),"My window");
thread t1(h,&window);
_sleep(10000000);
t1.join();
return 0;
}
http://www.sfml-dev.org/tutorials/2.0/graphics-draw.php#drawing-from-threads
SFML supports multi-threaded drawing, and you don't even have to do
anything to make it work. The only thing to remember is to deactivate
a window before using it in another thread; that's because a window
(more precisely its OpenGL context) cannot be active in multiple
threads at the same time.
call window.setActive(false); in your main(), before you pass it off to the thread.
And remember that you must handle events in the GUI thread (the main thread) for maximum portability.

Segmentation Fault in SFML After calling sf::Window::close

I'm trying to run an SFML window on a separate thread from main(). Calling sf::Window::close doesn't cause any immediate problems, however at the end of main(), possibly when the UI object is destructed, a segmentation fault error occurs. No segmentation fault occurs if sf::Window::close isn't called.
I'm running a fully updated Debian 10 install.
#include <thread>
#include <SFML/Graphics.hpp>
int main() {
sf::Window window(sf::VideoMode(500,500), "Test");
std::thread th(&sf::Window::close, &window);
th.join();
}
I found the problem. You have to deactivate the window before closing in another thread, like so. I missed this in the documentation initially.
#include <thread>
#include <SFML/Graphics.hpp>
int main() {
sf::Window window(sf::VideoMode(500,500), "Test");
window.setActive(false);
std::thread th(&sf::Window::close, &window);
th.join();
}

Is there a simple way to play a sound in a background thread using SFML

I am trying to play a song in a background thread of my GUI application so that the song doesn't block the GUI thread. Is there a simple way to do this with either std::thread or SFML Threads?
I have tried using std::thread for this, but it still blocks the GUI thread when I call my_thread.join().
Here is an example of what I want to do:
#include <thread>
#include <SFML/Audio.hpp>
#include <unistd.h>
#include <iostream>
void func() {
sf::Music music;
music.openFromFile("mysong.wav");
music.play();
// if I don't have usleep here the function exits immediately
// why is that exactly???
usleep(100000000);
}
int main() {
std::thread my_thread(func);
my_thread.join();
// this is where I would process events/build windows in GUI
while(1)
std::cout << "here"; // <--- Want this to run while song plays
}
in SFML you need to have a valid sf::Sound or sf::Music for music to play, when that variable gets destroyed you will no longer have a valid reference to that object a possible solution for the code you posted would be something like this:
#include <SFML/Audio.hpp>
#include <unistd.h>
#include <iostream>
class CAudio
{
sf::Music music;
public:
void func()
{
music.openFromFile("mysong.wav");
music.play();
}
sf::Status getStatus()
{
return music.getStatus();
}
}
int main() {
CAudio my_music;
my_music.func();
// http://www.sfml-dev.org/documentation/2.0/SoundSource_8hpp_source.php
while(my_music.getStatus() == sf::Status::Playing)
{
std::cout << "here"; // <--- Want this to run while song plays
}
}
Also, always use brackets, regardless if its a 1 line statement always use brackets, I know its allowed but it will make your life easier when you troubleshoot later on.