setTextureRect on Renderers

  • 4 Replies
  • 61 Views
setTextureRect on Renderers
« on: 29 August 2019, 12:23:31 »
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

  • *****
  • 1463
    • View Profile
    • Texus's Blog
Re: setTextureRect on Renderers
« Reply #1 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:
btn->getRenderer()->setTexture({myTilesetTexture, {16, 0, 16, 16}});

Re: setTextureRect on Renderers
« Reply #2 on: 31 August 2019, 22:36:16 »
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:
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

  • *****
  • 1463
    • View Profile
    • Texus's Blog
Re: setTextureRect on Renderers
« Reply #3 on: 01 September 2019, 09:49:02 »
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.
« Last Edit: 01 September 2019, 10:29:54 by texus »

Re: setTextureRect on Renderers
« Reply #4 on: 01 September 2019, 15:46:43 »
Thanks for clarification, this is really helpful