Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: problem with coloring tiles as separate sprites  (Read 2502 times)

0 Members and 1 Guest are viewing this topic.

C with a C

  • Newbie
  • *
  • Posts: 21
    • View Profile
problem with coloring tiles as separate sprites
« on: April 26, 2016, 03:54:15 pm »
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();
}
 
« Last Edit: April 26, 2016, 03:58:14 pm by C with a C »

C with a C

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: problem with coloring tiles as separate sprites
« Reply #1 on: April 27, 2016, 12:04:42 am »
I noticed why it was slowing down. I was recreating the Textures and Sprites every time I rendered stuff to the window. Essentially recreating everything from scratch every frame.

I solved the slow down:
  • turned my fontset and tileset into Textures
  • created two 2D vectors of Sprite pointers, one for text and one for graphics, assigned those two textures to every sprite in the respective vector, and set their x,y position.

Now I can simply use setTextureRect() to specify what part of the tilesets each sprite shows. I initialize them to the blank tile 0, and I keep the text Sprites* NULL so they don't overlap the graphics or be drawn unnecessarily when not being used. The graphics Sprites are all drawn every frame, so that I can use a background tile if I want.

Performance with this approach seems great.

I'm still open to better ideas, if anyone has any.

Mortal

  • Sr. Member
  • ****
  • Posts: 284
    • View Profile
Re: problem with coloring tiles as separate sprites
« Reply #2 on: April 27, 2016, 02:47:10 am »
great you solved performance issue but i would really recommend to use SelbaWard library. it has Bitmap text which is i believe this is what you want. here link to it:https://github.com/Hapaxia/SelbaWard/wiki/Bitmap-Text
« Last Edit: April 28, 2016, 01:57:36 am by MORTAL »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: problem with coloring tiles as separate sprites
« Reply #3 on: April 28, 2016, 02:27:16 am »
Mortal, thanks for recommending Selba Ward!  :)

The original post used the word Terminal more than once, mentioned separately colouring tiles and also actually said "Terminal::print()".
This bring me to think that you may find more suited to your application:
Selba Ward's Console Screen
Examples:

Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*