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

Author Topic: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)  (Read 7233 times)

0 Members and 3 Guests are viewing this topic.

SirusDoma

  • Newbie
  • *
  • Posts: 9
  • Just another ordinary O2Jammer
    • View Profile
I try to create Texture atlas on the fly from a sets of image. Initially, I create my own class, let's say TextureAtlas, it contains a sf::Texture. Later on, the image will be updated to this sf::Texture

in the construction phase of TextureAtlas , let say, the first image is being uploaded to texture data:
    sf::Texture texture;
    if (!texture.loadFromFile("something.png")) // let's assume the image size is 80x80
    {
        // error...
    }
 

Now, when a new image is need to be uploaded into the atlas, the first thing that comes from my mind is to resize the texture then update the texture with the new image.

For example, the new image contains 100x100 image, since the last image size is 80x80 and i want to advance horizontally (X axis) so the next image will be placed on x:80 y:0 while the image need to resize to 180x100

It appears that if I call sf::Texture::update(), the new image *seems* uploaded but the sf::Texture size will remain the same. in above case, the sf::Texture remain 80x80, while the new image uploaded on x:80, that means the new image is not included and nothing changed to the sf:Texture!

So... how do I achieve this with SFML?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #1 on: December 08, 2016, 06:37:49 pm »
Backup your texture data to an image, re-recreate the texture with the new size, copy the previous data back into the new texture and finally add your new data (both with Texture::update).

Or you can work in a sf::Image until everything's done, and convert it to a sf::Texture at the end of the process.
Laurent Gomila - SFML developer

SirusDoma

  • Newbie
  • *
  • Posts: 9
  • Just another ordinary O2Jammer
    • View Profile
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #2 on: December 08, 2016, 08:11:14 pm »
Backup your texture data to an image, re-recreate the texture with the new size, copy the previous data back into the new texture and finally add your new data (both with Texture::update).

Or you can work in a sf::Image until everything's done, and convert it to a sf::Texture at the end of the process.

Interesting, the first method sounds simple, but it seems it require additional OpenGL calls. i mean, before recreating the texture, I must destroy the last texture which I suppose dispose the OpenGL Texture and it require OpenGL call to do so as well as sending back the image data to the texture (CMIIW)

the 2nd one may give better performance, but not sure it is really better in term of performance and how to implement it

Anyway, which one you think will be faster in term of performance? the creation of the texture atlas might / might not as often as draw calls, that's why i'm considering which one that give me better performance

Thanks in advance
« Last Edit: December 08, 2016, 08:13:59 pm by SirusDoma »

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #3 on: December 08, 2016, 08:47:43 pm »
Maybe approach this a bit differently. What are you trying to do? You could do most scaling just by rendering, without having to modify the texture.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #4 on: December 08, 2016, 10:32:49 pm »
Quote
the first method sounds simple, but it seems it require additional OpenGL calls
And? What's wrong with OpenGL being called by SFML?

Quote
Anyway, which one you think will be faster in term of performance?
I don't understand why you're so worried about performances. Creation of the texture atlas will happen once, preferably during init/loading, so the time it takes should never be an issue (as long as you don't do something wrong that makes it take several seconds). Just use an implementation that you like, and/or that is simple enough.

Quote
What are you trying to do?
He's building a texture atlas. Which means that he's gathering several small textures into big ones to limit the number of texture switches and optimize performances.
Laurent Gomila - SFML developer

SirusDoma

  • Newbie
  • *
  • Posts: 9
  • Just another ordinary O2Jammer
    • View Profile
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #5 on: December 09, 2016, 01:50:10 am »
And? What's wrong with OpenGL being called by SFML?

Yea, additional OpenGL calls. It may doesn't affect the performance if i do it in initialization, it may only take few ms but as we know we should minimize any OpenGL calls in the game loop.

Quote
I don't understand why you're so worried about performances. Creation of the texture atlas will happen once, preferably during init/loading, so the time it takes should never be an issue (as long as you don't do something wrong that makes it take several seconds). Just use an implementation that you like, and/or that is simple enough.

Oops, my bad not to explain whole things in the first post. The TextureAtlas class can be used any purpose, indeed it obviously to compose a sets of Texture (or Image?) to the single Texture  ;D but it may ideal to other purpose, such as Sprite batching.

When the very first render is called, the sprite batch gathers all information about sprite that pushed into it as well as push the sprite texture into the texture atlas.The texture is cached inside the atlas, so whenever any sprite is added with same texture, it shouldn't add it again, the number of texture inside texture atlas remain the same.

As the game progress, a new sprite with unique texture may appear and pushed into sprite batch, in other words the texture atlas can be used to construct dynamic sprite batching and the newly added sprite texture need to updated into atlas.

Though this is one of its example (but yea, I intended to use this for sprite batching), there maybe other applicable implementation beyond my thinking which probably i need on later.

Therefore, I need to determine which is the best approach to achieve this
Anyway, thanks for your reply
« Last Edit: December 09, 2016, 01:53:17 am by SirusDoma »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #6 on: December 09, 2016, 07:38:59 am »
Quote
as we know we should minimize any OpenGL calls in the game loop
That's a strange rule. If those OpenGL calls allow to do some processing on the GPU while the CPU is busy, then they will probably be a good choice. You can't just say "avoid OpenGL calls", because doing the equivalent without OpenGL (ie. on the CPU) may be worse. It really depends on the use case, and on what the rest of the application is doing at this moment.

I'm not sure that building a texture atlas on the fly is a good idea. It will cause latency at random times during the game (when a new texture appears, or worse, when the texture atlas needs to grow), and you cannot predict the behaviour. Precomputing atlases at chosen points (game init, level loading, ...), or better, precomputing the texture data offline with an image editor, will be a better strategy in most cases, in my opinion.

To answer your question: I have no idea which method will be the fastest. You should probably test both and figure out by yourself.
Laurent Gomila - SFML developer

SirusDoma

  • Newbie
  • *
  • Posts: 9
  • Just another ordinary O2Jammer
    • View Profile
Re: How do I resize / extend sf::Texture (yes sf::Texture not sf::Sprite)
« Reply #7 on: December 09, 2016, 10:01:15 am »
Thanks for your reply, I will consider to create it in initialization instead, or implement with your suggestion. Thanks

 

anything