It would be something like this. The number on the left (1337) displays fine, the number on the right (7331, loaded in a separate thread) doesn't show up at all.
main.cpp:
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include "DigitDisplay.hpp"
typedef sf::Vector2<float> float2;
sf::RenderWindow window;
DigitDisplay numberNormal;
DigitDisplay numberThread;
void LoadResources(void)
{
numberThread.Load("data/digits.png", "7331");
}
int main(void)
{
numberNormal.Load("data/digits.png", "1337");
numberNormal.SetPosition(float2(300.0f, 300.0f));
sf::Thread thread(LoadResources);
thread.launch();
thread.wait();
numberThread.SetPosition(float2(600.0f, 300.0f));
window.create(sf::VideoMode(800, 600, 32), "SFML Framework",
sf::Style::Titlebar | sf::Style::Close);
window.setVerticalSyncEnabled(true);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
window.clear(sf::Color::Black);
numberNormal.Render();
numberThread.Render();
window.display();
}
return EXIT_SUCCESS;
}
DigitDisplay.hpp:
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
typedef unsigned int uint;
typedef sf::Vector2<int> int2;
typedef sf::Vector2<float> float2;
extern sf::RenderWindow window;
class DigitDisplay
{
private:
sf::Texture digitImage;
std::vector<sf::Sprite> digits;
sf::RenderTexture renderTexture;
sf::Sprite textureSprite;
std::string text;
float2 position;
void CreateRenderTexture(void);
inline int GetDigit(char c);
public:
void Load(std::string filename, std::string _text = "");
void Render(void);
void SetPosition(float2 _position);
};
DigitDisplay.cpp:
#include "DigitDisplay.hpp"
void DigitDisplay::CreateRenderTexture(void)
{
int2 size(digitImage.getSize().x * text.size() / 10, digitImage.getSize().y);
renderTexture.create(size.x, size.y);
textureSprite.setTexture(renderTexture.getTexture());
textureSprite.setTextureRect(sf::IntRect(0, 0, size.x, size.y));
}
int DigitDisplay::GetDigit(char c)
{
switch (c)
{
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
default:
return -1;
}
}
void DigitDisplay::Load(std::string filename, std::string _text)
{
digitImage.loadFromFile(filename);
uint digitWidth = digitImage.getSize().x / 10;
uint frameHeight = digitImage.getSize().y;
digits.resize(10);
for (int i = 0 ; i < 10 ; ++i)
{
digits[i].setTexture(digitImage);
digits[i].setTextureRect(sf::IntRect(i * digitWidth, 0, digitWidth, frameHeight));
}
text = _text;
if (text.size())
{
CreateRenderTexture();
}
}
void DigitDisplay::Render(void)
{
renderTexture.clear(sf::Color::Transparent);
float digitWidth = digitImage.getSize().x * 0.1f;
for (uint i = 0 ; i < text.size() ; ++i)
{
int digit = GetDigit(text[i]);
digits[digit].setPosition(i * digitWidth, 0.0f);
renderTexture.draw(digits[digit]);
}
renderTexture.display();
textureSprite.setPosition(position);
window.draw(textureSprite);
}
void DigitDisplay::SetPosition(float2 _position)
{
position = _position;
}
======================================================================
Edit: I've made some progress. I found out that when I call DigitDisplay::CreateRenderTexture() from the 2nd thread nothing shows up on the screen. However, when I call it from the main thread (after loading the image and setting up sf::Sprite in DigitDisplay in 2nd thread) the image shows up on the screen and everything seems to be working fine.
Can't I use sf::RenderTexture::create() in another thread? If I can, how to do it correctly?