I've been having a similar problem using sf::RenderTexture. I'm using a thread to load a map file (which works fine) then create a set of entities via an entity manager based on the loaded map data (eg spawn points etc). The entity manager loads the corresponding textures and passes references to them to the entities it creates, which actually draw fine, but entities which use a render texture internally to create their sprite texture do not draw. As far as I can see the actual render texture is not clear/draw/displaying during the entity's draw() call. For example if I add a clear() call immediately after create() with sf::color::green the entity will draw from the main thread as a green sprite... but the entity's draw function should be clearing it yellow.
#include <SFML/system.hpp>
#include <SFML/graphics.hpp>
#include <SFML/window.hpp>
#include <memory>
#include <vector>
#include <atomic>
#include <iostream>
class MyEntity
{
public:
MyEntity()
{
m_renderTexture.create(40u, 40u);
m_renderTexture.setActive(false); //deactivate because created in another thread
}
void Draw(sf::RenderTarget& rt)
{
m_renderTexture.clear(sf::Color::Yellow);
m_renderTexture.display();
rt.draw(sf::Sprite(m_renderTexture.getTexture()));
}
private:
sf::RenderTexture m_renderTexture;
};
class MyEntityManager
{
public:
MyEntityManager(){};
void CreateEntities()
{
//load resources needed for entity here
m_entities.push_back(std::unique_ptr<MyEntity>(new MyEntity()));
}
void Draw(sf::RenderTarget& rt)
{
for(auto ent = m_entities.begin(); ent != m_entities.end(); ++ent)
{
MyEntity& myEnt = **ent;
myEnt.Draw(rt);
}
};
private:
std::vector< std::unique_ptr<MyEntity> > m_entities;
};
//---------------------------------------------------------//
MyEntityManager entManager;
std::atomic<bool> loaded(false);
void ThreadFunc()
{
//load map data here first
//create entities based on loaded map data
entManager.CreateEntities();
loaded = true;
std::cout << "Thread Quitting" << std::endl;
}
int main()
{
sf::RenderWindow window(sf::VideoMode(800u, 600u), "rt test");
//MyEntity ent;
sf::Thread thread(&ThreadFunc);
thread.launch();
while(window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed) window.close();
}
//draw test item - this works
/*window.clear();
ent.Draw(window);
window.display();*/
if(loaded) //drawing this doesn't
{
window.clear();
entManager.Draw(window);
window.display();
}
}
thread.wait();
return 0;
}
This is using the latest SFML compiled from source, and happens using gcc/mingw and VS11 compilers. I've also tested it on WinXP / nVidia GTS450, Vista64 / Radeon 7970 and Win7-64 / Radeon 7750 with latest drivers and they all exhibit the problem.
I've tried putting break points on the render texture's clear/draw call but in debug mode I get 'expression can not be evaluated' and in release mode VS tells me it can't insert a break point there as the compiler has optimised it out...