setTextureRect on Renderers

Started by doomista, 29 August 2019, 12:23:31

doomista

Could you please add function setTextureRect to Renderers such as ButtonRenderer with the same semantics as sf::Sprite::setTextureRect?
So far, I cannot find a way how to display only a subset of a texture on a button.

Example usage:
auto btn = tgui::Button::create();
btn->getRenderer()->setTexture(myTilesetTexture); // tileset of 16x16 images
btn->getRenderer()->setTextureRect(sf::IntRect(16, 0, 16, 16)); // displaying second image
btn->setSize(16, 16);


Thanks

texus

Sorry for the later reply, I somehow missed your post.
The setTexture takes a tgui::Texture as parameter which already has the ability to load only a part of an image. Assuming myTilesetTexture is an sf::Texture, you can just do the following:
Code (cpp) Select
btn->getRenderer()->setTexture({myTilesetTexture, {16, 0, 16, 16}});

doomista

Quote from: texus on 31 August 2019, 20:01:38
Sorry for the later reply, I somehow missed your post.
The setTexture takes a tgui::Texture as parameter which already has the ability to load only a part of an image. Assuming myTilesetTexture is an sf::Texture, you can just do the following:
Code (cpp) Select
btn->getRenderer()->setTexture({myTilesetTexture, {16, 0, 16, 16}});

Thanks, this solves my problem! One more question though - what happens under the hood? Does this perform a conversion to sf::Image and back to texture or does this computation run directly on GPU?

texus

#3
This convert to sf::Image first.

Passing an sf::Texture to TGUI is actually not the best strategy if you want performance, as the texture can't be cached. Each time you pass the same sf::Texture to a function, the code creates a copy of the sf::Texture, assuming it is a completely new texture. Caching the tgui::Texture yourself or passing the filename each time will make sure the same texture is shared the whole time.

If you have a tilemap consisting out of e.g. 16 images, even when passing the filename to setTexture, the code is going to load the image 16 times in total. The cache currently works on both filename and partRect, so if you load a different part then it will reload the image as well. In the 0.9-dev branch that I started a while back but stopped working on, the image would be loaded only once. It would reuse the image and only create a new texture based on the partRect (if you didn't use the rect before), but it couldn't be done in 0.8 for backwards compatibility.

So for now loading different pieces of the same image is always going to be inefficient, but passing sf::Texture directly causes no caching to occur at all so it should be avoided if you care a lot about performance.

doomista

Thanks for clarification, this is really helpful