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

Author Topic: How to best handle Textures  (Read 11480 times)

0 Members and 1 Guest are viewing this topic.

gws923

  • Jr. Member
  • **
  • Posts: 60
    • View Profile
How to best handle Textures
« on: December 29, 2012, 09:48:59 pm »
Hello all.  I've gotten some wonderful help here in the past, and my friend and I have a problem that we can't seem to answer ourselves, so we thought we'd turn to you.

We are developing a game with some fairly intricate animations.  Some of our characters have as many as 70 different frames across their running, jumping, etc. animations.

We are currently loading one texture for each character and each frame setting that character's sprite to a different subrectangle of the texture (which seems to be the preferred method around here).  As suggested here: http://en.sfml-dev.org/forums/index.php?topic=9855.0

Here is our problem:
When we had others try our game on their machines, many of them encountered problems as our textures were too large.  Many reported an error that said their maximum texture size was 1024 x 1024.  That seems tiny.  (EDIT: Many of our sprite frames are around 200 x 200 or even 300 x 300 pixels in size to retain image quality.  We could make them smaller and scale them up, but it looks bad) Is this a reasonable maximum texture size?  How new of a system would someone need to increase the maximum to, say, 8192 x 8192? Especially considering if we have animation frames that are 100 x 100 (doesn't seem unreasonable), that means we can only have about 10 animation frames per texture if we go 1024 x 1024.

Should we load multiple textures and cycle through them?  Should we create multiple sprites and cycle through those?  How do we deal with this limited texture size?

Here are the hypothetical approaches we discussed: (Objective is efficient, GPU-independent display of animations)
1. Load a texture for each frame of an animation.  Obviously this comes with a greater load time.
2. Load a single texture from one of two files: a large texture for strong machines and a scaled-down, smaller texture for slower machines. Scale the sprite up for the slow machines. (We tried this and it looks awful)

We checked out Thor's Animation library which has bigTexture and bigSprite.  We are curious how that works exactly.  Does the library need to be in a writable directory?  In other words, is it creating new files somehow?  If so, that could be problematic.  If not, it seems like it might be our answer.
« Last Edit: December 29, 2012, 10:31:13 pm by gws923 »

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: How to best handle Textures
« Reply #1 on: December 29, 2012, 10:00:44 pm »
No, it doesn't create files, it's open source, you can check it out yourself.
https://github.com/Bromeon/Thor/blob/master/src/BigTexture.cpp
Back to C++ gamedev with SFML in May 2023

gws923

  • Jr. Member
  • **
  • Posts: 60
    • View Profile
Re: How to best handle Textures
« Reply #2 on: December 29, 2012, 10:11:14 pm »
Cool.  Will check it out.  It does seem like it will suit our needs, but I am still wondering if anyone has encountered the same problem we have and handled it any particular way?  (Maybe that particular was is to use Thor...)

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: How to best handle Textures
« Reply #3 on: December 29, 2012, 10:16:12 pm »
I have no idea what the problem is, I just can't imagine need for that much space.
BTW:One 1024x1024 can hold 100(not 10) 100x100 animation frames.
Back to C++ gamedev with SFML in May 2023

gws923

  • Jr. Member
  • **
  • Posts: 60
    • View Profile
Re: How to best handle Textures
« Reply #4 on: December 29, 2012, 10:17:46 pm »
Sorry, you're right.  I meant 100 frames.  What I should say to clarify is that we'd like to have frames as big as, say, 300 x 300.  Maybe that just doesn't make sense and we need to scale down our animations, but we don't want to lose too much quality.

In addition, we have, for example, a "level" texture, that is the entire hand-drawn level.  Perhaps we need to break that up into smaller textures, but those are easily 3000 x 3000 + in size.

gws923

  • Jr. Member
  • **
  • Posts: 60
    • View Profile
Re: How to best handle Textures
« Reply #5 on: December 29, 2012, 11:12:10 pm »
So we tried using Thor's BigTexture and BigSprite, but apparently thor can't animate BigSprite because it doesn't have a setSubRectangle() method.  And, you can't set an sf::Sprite's texture to a BigTexture, so I guess this doesn't really help us.  It seems like BigTexture is only useful for static (as in non-animating) images.

If that's the case, our question still stands at: How do we best animate large animations?  Do we use multiple textures?  Multiple sprites?  Thor doesn't seem to help us in this case.

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: How to best handle Textures
« Reply #6 on: December 29, 2012, 11:27:36 pm »
Just write your own classes to do that..
Back to C++ gamedev with SFML in May 2023

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10830
    • View Profile
    • development blog
    • Email
Re: How to best handle Textures
« Reply #7 on: December 29, 2012, 11:34:11 pm »
If you don't think about sprite sheets, then you'd simply go and load x sf::Textures and swap them for the animation; if you now load one huge texture or a few smaller textures, it shouldn't have a enormous effect on the loading time.
Also you could simply split up each animation into one texture and when a different animation is needed swap the sprite sheet, or do you use more than 100 frames for one animation? If so then you should rethink your design, because that's just a too much information to handle in mostly all cases... ;)

So here are the possibilities again:
  • One sprite sheet for each character: Too large.
  • One sprite sheet for each animation: Should fit nicely.
  • One texture for each frame: Way too many textures.
« Last Edit: December 29, 2012, 11:41:53 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: How to best handle Textures
« Reply #8 on: December 30, 2012, 12:09:37 am »
We checked out Thor's Animation library which has bigTexture and bigSprite.  We are curious how that works exactly.
Don't confuse animations and big textures/sprites, those are independent features. If the latter don't help, you can still animate your character using thor::Animator. Also, if you have a specific question, don't hesitate to ask :)

You can also look at the API documentation or the examples in the Git repository.


So we tried using Thor's BigTexture and BigSprite, but apparently thor can't animate BigSprite because it doesn't have a setSubRectangle() method.
Yes, this is planned, but it will probably take some months before I have time to implement it (I need to find a final API for Thor 2.0 first, and at the moment I've a lot of other stuff to do)...

But is your animation that big? 300x300 shouldn't be a problem for any graphics card of the past years.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

gws923

  • Jr. Member
  • **
  • Posts: 60
    • View Profile
Re: How to best handle Textures
« Reply #9 on: December 30, 2012, 02:10:36 am »
If you don't think about sprite sheets, then you'd simply go and load x sf::Textures and swap them for the animation; if you now load one huge texture or a few smaller textures, it shouldn't have a enormous effect on the loading time.
Also you could simply split up each animation into one texture and when a different animation is needed swap the sprite sheet, or do you use more than 100 frames for one animation? If so then you should rethink your design, because that's just a too much information to handle in mostly all cases... ;)

So here are the possibilities again:
  • One sprite sheet for each character: Too large.
  • One sprite sheet for each animation: Should fit nicely.
  • One texture for each frame: Way too many textures.

Thanks, Exploiter, this makes a lot of sense.  I think you're right, we'll go with one texture per animation.  I'm curious, though, is sprite.setTexture() particularly cpu intensive?  Should we have one sprite for each character or one sprite for each animation for each character?

We checked out Thor's Animation library which has bigTexture and bigSprite.  We are curious how that works exactly.
Don't confuse animations and big textures/sprites, those are independent features. If the latter don't help, you can still animate your character using thor::Animator. Also, if you have a specific question, don't hesitate to ask :)

You can also look at the API documentation or the examples in the Git repository.


So we tried using Thor's BigTexture and BigSprite, but apparently thor can't animate BigSprite because it doesn't have a setSubRectangle() method.
Yes, this is planned, but it will probably take some months before I have time to implement it (I need to find a final API for Thor 2.0 first, and at the moment I've a lot of other stuff to do)...

But is your animation that big? 300x300 shouldn't be a problem for any graphics card of the past years.

Gotcha. Thank you, too, Nexus.  Good to hear the BigSprite animation is planned.  Great work on the whole thing, by the way, it's very nice to know this exists.  We very well may need other features of it even if BigSprite wasn't quite what we were looking for (at the moment).

Animation isn't huge, 300x300 is probably our biggest sprite size.  The problem is when a single animation has 20-30 frames.  But I think as others have said, if we are smarter about how we use sf::Texture we can make this work.

Thank you, all, for helping us think this through.  We mostly needed folks other than ourselves to make sure we were making any sort of sense.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10830
    • View Profile
    • development blog
    • Email
AW: Re: How to best handle Textures
« Reply #10 on: December 30, 2012, 06:53:02 am »
I'm curious, though, is sprite.setTexture() particularly cpu intensive?  Should we have one sprite for each character or one sprite for each animation for each character?
Not really, since most of the work is simply changing the rederence, which is kind of cheap, but I think OpenGL has to do a bit more work, that's why setTextureRect is often better.
If you want to really know then write a benchmark and test both. ;)

PS: Don't add full quotes if you only related to parts of it, it will only make it harder to read. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: AW: Re: How to best handle Textures
« Reply #11 on: December 30, 2012, 10:24:41 am »
Not really, since most of the work is simply changing the rederence, which is kind of cheap, but I think OpenGL has to do a bit more work, that's why setTextureRect is often better.
I think texture switching is relatively expensive. But it depends of course on the use case, for a few animations there won't be an issue.

The problem is, thor::BigTexture does not avoid texture switching. It internally keeps multiple textures that fit into the video memory, so when a thor::BigSprite is rendered, multiple textures are used. thor::BigSprite can however use less textures than if every frame had its own texture.

gws923, you can also have one file with all the frames and load it with sf::Image. Then you can load different textures from it, that take only a rectangular part, using sf::Texture::loadFromImage().
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: How to best handle Textures
« Reply #12 on: December 30, 2012, 12:09:50 pm »
It can't be expensive, it's just swapping a single pointer. OpenGL was probably binding the texture every frame already so it'll now just be binding a different one.
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: How to best handle Textures
« Reply #13 on: December 30, 2012, 01:25:06 pm »
Switching the texture at the graphics card level is a very expensive operation. It's a lot more than just switching two pointers ;)

Remove the texture cache optimization in SFML, and you'll see the difference.
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: How to best handle Textures
« Reply #14 on: December 30, 2012, 01:26:52 pm »
It can't be expensive, it's just swapping a single pointer.
On the CPU side, yes. I'm talking about the GPU...

OpenGL was probably binding the texture every frame already so it'll now just be binding a different one.
Do you know how texture binding works? It's not "probably every frame already", it's when you call glBindTexture().

Interestingly, a month ago you have expressed the exact opposite of your current statement ;)
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything