I figured out what is going on. Because the RenderTexture's context is created on a different thread, the context stays there. When that thread dies, its context dies with it.
So, one easy way to fix it would be to keep the thread alive for as long as you use the RenderTexture.
I found some interesting behavior though. I'm having the
createTexture thread wait once it's finished, calling
rt.setActive(true) on the main thread, then letting the
createTexture thread continue and exit.
When doing this, I can clear from the RenderTexture, but I can't draw to it:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <SFML/Graphics.hpp>
bool created;
void createTexture(sf::RenderTexture& rt, sf::Sprite& sprite, std::condition_variable& cv)
{
std::mutex mutex;
rt.setActive(true);
rt.create(512, 480);
sprite.setTexture(rt.getTexture());
rt.setActive(false);
created = true;
std::unique_lock<std::mutex> lk(mutex);
cv.wait(lk);
}
int main()
{
sf::RenderWindow window(sf::VideoMode(512, 480), "Test");
window.setFramerateLimit(60);
sf::RenderTexture rt;
sf::Sprite sprite;
created = false;
bool contextMoved = false;
// just a triangle to draw for tests
sf::VertexArray triangle(sf::Triangles, 3);
triangle[0].position = sf::Vector2f(10, 10);
triangle[1].position = sf::Vector2f(100, 10);
triangle[2].position = sf::Vector2f(100, 100);
triangle[0].color = sf::Color::Red;
triangle[1].color = sf::Color::Blue;
triangle[2].color = sf::Color::Green;
std::condition_variable cv;
std::thread loadingThread(&createTexture, std::ref(rt), std::ref(sprite), std::ref(cv));
while(window.isOpen())
{
sf::Event event;
while(window.pollEvent(event))
{
if(event.type == sf::Event::Closed)
window.close();
}
window.clear();
if(created)
{
// the createTexture function is finished by this point
if(!contextMoved)
{
rt.setActive(true);
cv.notify_all();
contextMoved = true;
}
rt.clear(sf::Color::White);
rt.draw(triangle);
rt.display();
window.draw(sprite);
}
window.display();
}
loadingThread.join();
return 0;
}
I'm clearing
sf::Color::White in the
sf::RenderTexture, and clearing
sf::Color::Black on the window. I'm also drawing
triangles to the
sf::RenderTexture. All that shows is white.
(See attached photo if needed.)
Whereas before I made this change, clearing
sf::Color::White on the
sf::RenderTexture would still show all black.