I'm using a bitmap font and a tileset to display everything, from text to the ui, etc, and I have the rendering assigned to a separate class called Terminal.
The way I figured out to place all the text and graphics on the screen was to use an sf::Image as a buffer, where everything gets
printed and drawn into, and then at the time to render I pass into a Texture, into a Sprite, and into the RenderWindow.
But now I want to apply different colors to certain tiles, so I can have a menu option selected and colored, or anything else I can think of.
Since there doesn't seem to be a way to color an sf::Image in the same way you can color an sf::Sprite with setColor(), the only way I figured to do this was by, instead of
printing directly to the buffer Image, I created a stack of Sprites and their respective Textures (std::pairs) that are colored as they are created and kept there until it's time to render each of them and empty the stack.
It does work, but the problem is now I'm noticing a slow down... While cycling through the menu options, in game, the interaction doesn't seem fully responsive, sometimes I press a key and nothing happens (it's worth noting that the stack, currently, only applies to text, not the rest of the graphics, so I imagine it could get even worse).
I'd like to know if anyone would have a better (and faster) idea on how to achieve this. I'd rather deal with a single buffer than a stack of separate sprites, but I can't think of any other way to do it. I never tried using sf::RenderTexture as buffer, as the process for using it seems even more convoluted, but I also don't know if it could help...
EDIT: note - I'm doing the rendering separately so the rest of the code can deal only with grid coords, in small numbers of rows and columns. It's less confusing to me.
Don't know how relevant it is to show the code, but this is my Terminal::print() function:
void Terminal::print(int16_t row, int16_t col, string str)
{
if (str.size() == 0) return;
sf::Image img;
img.create(str.size()*TS, TS, BLACK); // TS = tile size (16) | BLACK = sf::Color::Black
for (uint8_t i = 0; i < str.size(); i++)
img.copy( *fStrip, i*TS, 0, sf::IntRect(str[i]*TS, 0, TS, TS) );
// fStrip is where the font is stored (sf::Image)
sf::Texture tex;
tex.loadFromImage(img);
sf::Sprite spr;
spr.setColor(color); // Terminal::setColor(sf::Color) is used before Terminal::print()
spr.setPosition(col*TS, row*TS); // convert from grid coords to pixel coords
bufstack.push( make_pair(tex, spr) ); // stack<pair<sf::Texture, sf::Sprite> > bufstack;
bufstack.top().second.setTexture(bufstack.top().first);
}
And my Terminal::render() function
void Terminal::render(sf::RenderWindow* window)
{
sf::Texture tex;
sf::Sprite spr;
tex.loadFromImage(buffer); // still using the buffer sf::Image for the rest
spr.setTexture(tex);
window->draw(spr);
while (!bufstack.empty()) // maybe while loop slows it down?
{
window->draw(bufstack.top().second);
bufstack.pop();
}
clearBuffer();
}