1
Graphique / [Résolu] Créer une sf::Texture dans un std::thread
« le: Juin 29, 2014, 02:16:58 pm »
Bonjour
En cherchant à faire de la sérialisation bête et méchante, j'ai voulu créer une sf::Texture dans un thread (std::thread).
J'obtiens l'erreur suivante (Debian GNU/Linux, SFML 2.1)
J'ai suivi ce que le message d'erreur suggére (cela corrige bien l'erreur) mais je ne souhaite pas avoir une solution pour X11 uniquement.
J'ai placé un mutex pour créer la texture et le rendu d'une frame :
Est-ce une bonne solution (je n'ai pas encore testé sous Windows et OS X) ?
Qu'elles sont les autres solutions possibles (à part «ne pas utiliser de thread» et «créer les textures à l'avance») ?
Merci d'avance.
En cherchant à faire de la sérialisation bête et méchante, j'ai voulu créer une sf::Texture dans un thread (std::thread).
J'obtiens l'erreur suivante (Debian GNU/Linux, SFML 2.1)
[xcb] Unknown request in queue while dequeuing
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
main_sfml: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
Abandon
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
main_sfml: ../../src/xcb_io.c:179: dequeue_pending_request: Assertion `!xcb_xlib_unknown_req_in_deq' failed.
Abandon
J'ai suivi ce que le message d'erreur suggére (cela corrige bien l'erreur) mais je ne souhaite pas avoir une solution pour X11 uniquement.
J'ai placé un mutex pour créer la texture et le rendu d'une frame :
// g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++11 -pedantic -fopenmp -lsfml-window -lsfml-graphics -lsfml-system main_sfml.cpp -o main_sfml && ./main_sfml
// g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++98 -pedantic -fopenmp -lsfml-window -lsfml-graphics -lsfml-system main_sfml.cpp -o main_sfml && ./main_sfml
#include <vector>
#include <thread>
#include <mutex>
#include <SFML/Graphics.hpp>
//#include <X11/Xlib.h>
int main()
{
//XInitThreads();
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
sf::Image image; image.create(200, 200, sf::Color::White);
std::vector<sf::Sprite> sprites;
std::mutex mutex;
std::thread t
(
[&]() -> void
{
std::this_thread::sleep_for(std::chrono::seconds(1));
mutex.lock();
sf::Texture texture_thread;
mutex.unlock();
texture_thread.loadFromImage(image);
sprites.emplace_back(texture_thread);
}
);
while (window.isOpen())
{
mutex.lock();
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed) { window.close(); }
}
}
window.clear();
for (auto const & sprite : sprites)
{
window.draw(sprite);
}
window.display();
mutex.unlock();
}
t.join();
return 0;
}
// g++ -Wall -Wextra -Wconversion -Wsign-conversion -std=c++98 -pedantic -fopenmp -lsfml-window -lsfml-graphics -lsfml-system main_sfml.cpp -o main_sfml && ./main_sfml
#include <vector>
#include <thread>
#include <mutex>
#include <SFML/Graphics.hpp>
//#include <X11/Xlib.h>
int main()
{
//XInitThreads();
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
sf::Image image; image.create(200, 200, sf::Color::White);
std::vector<sf::Sprite> sprites;
std::mutex mutex;
std::thread t
(
[&]() -> void
{
std::this_thread::sleep_for(std::chrono::seconds(1));
mutex.lock();
sf::Texture texture_thread;
mutex.unlock();
texture_thread.loadFromImage(image);
sprites.emplace_back(texture_thread);
}
);
while (window.isOpen())
{
mutex.lock();
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed) { window.close(); }
}
}
window.clear();
for (auto const & sprite : sprites)
{
window.draw(sprite);
}
window.display();
mutex.unlock();
}
t.join();
return 0;
}
Est-ce une bonne solution (je n'ai pas encore testé sous Windows et OS X) ?
Qu'elles sont les autres solutions possibles (à part «ne pas utiliser de thread» et «créer les textures à l'avance») ?
Merci d'avance.