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

Author Topic: sf::Texture implemented in SFML 2  (Read 19190 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Texture implemented in SFML 2
« on: August 06, 2011, 11:30:53 pm »
Hi :)

I've finally managed to work on the old task of splitting sf::Image into two separate classes: sf::Image (with less features) and a new sf::Texture class.

Here is a list of modifications, and I let you read the doc for more detailed information:
- sf::Texture replaces sf::Image almost everywhere (sf::Image is now used only for pixels manipulation, not for drawing)
- sf::Sprite now takes a sf::Texture (Set/GetImage are now Set/GetTexture)
- There's no more sf::Sprite::GetPixel (see below)
- sf::RenderImage is not sf::RenderTexture
- sf::RenderWindow::Capture is back
- I also added sf::Image::FlipHorizontally and FlipVertically

The only drawback of this modification is that you can't retrieve pixels from a texture, and thus from a sprite, anymore. For pixel-perfect collision detection you must now store the collision data yourself (which allows more optimizations, by the way).

I've probably forgotten a few things, so don't hesitate to ask question :)
Laurent Gomila - SFML developer

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Texture implemented in SFML 2
« Reply #1 on: August 06, 2011, 11:44:48 pm »
Cool! I like that you created shortcuts for direct loading from sf::Texture :)

What does void Texture::Update(const Window&  window) exactly do? The documentation says "Update the texture from the contents of a window" which is not really more information than I am given by the function signature ;)

If it performs a screenshot, what's the difference to Image RenderWindow::Capture() const? Only the indirection via sf::Image?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Grimshaw

  • Hero Member
  • *****
  • Posts: 631
  • Nephilim SDK
    • View Profile
sf::Texture implemented in SFML 2
« Reply #2 on: August 07, 2011, 12:03:32 am »
Does it load the image anyway without regarding the GPU capacity like i've mentioned before? :)

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Texture implemented in SFML 2
« Reply #3 on: August 07, 2011, 12:19:04 am »
Another question, how do sf::Texture's methods void Update(const Image&) and bool LoadFromImage(const Image&) differ? The difference I have seen until now is that the former requires that the texture be created beforehand. Can't Update() fail? Maybe you should emphasize those points more explicitly in the documentation :)

And doesn't sf::Texture have a CreateMaskFromColor() anymore? Is it because the sf::Image doesn't really exist after loading, so this would have to be specified at texture creation time?
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
sf::Texture implemented in SFML 2
« Reply #4 on: August 07, 2011, 12:33:58 am »
If it's not possible to retrieve the pixel data from sf::texture, how can I store/make my own data for pixel-perfect collision?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Texture implemented in SFML 2
« Reply #5 on: August 07, 2011, 12:43:47 am »
Contadotempo, I think you can load a sf::Image with the pixels. Then, you are able to create the sf::Texture from it, as well as to access its pixels for your algorithm.

Alternatively, you can store a more memory-efficient solution than sf::Image. After all, you probably only need 1 bit per pixel (solid or not) instead of 32. But you still need a sf::Image first.

Unfortunately, this leads to unnecessary, expensive copies. If sf::Texture::LoadFromImage() took a sf::Image copy instead of const-reference, you could use C++0x std::move() to pass the image as argument – given that the automatic generation of an sf::Image move constructor is possible (no big three defined).
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Xp

  • Newbie
  • *
  • Posts: 13
    • View Profile
sf::Texture implemented in SFML 2
« Reply #6 on: August 07, 2011, 05:25:12 am »
is it me or i cannot compile this build? :roll:

LaurentGomila-SFML-b718464\include\SFML\Graphics\Font.hpp|243|error: declaration of 'sf::Texture sf::Font::Page::Texture'|

LaurentGomila-SFML-b718464\include\SFML\Graphics\Texture.hpp|48|error: changes meaning of 'Texture' from 'class sf::Texture'|


oh nevermind, changed Texture to sf::Texture in Font (243) and errors gone :twisted:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Texture implemented in SFML 2
« Reply #7 on: August 07, 2011, 10:07:42 am »
Quote
What does void Texture::Update(const Window& window) exactly do? The documentation says "Update the texture from the contents of a window" which is not really more information than I am given by the function signature

It copies the current contents of the window to the texture. What else can I say? Maybe "copy" is more relevant than "update" in the comments?

Quote
If it performs a screenshot, what's the difference to Image RenderWindow::Capture() const? Only the indirection via sf::Image?

Texture and Image are two different things, therefore updating a texture and updating an image (from a window) are also two different things. Both are optimized, using one to implement the other would be very ineficient.
Finally, I'd say that:
- The main purpose of Texture::Update(Window&) is to implement real-time post-effects with shaders, everything stays on the GPU
- The main purpose of RenderWindow::Capture() is to take screenshots of the application, it downloads the pixels to the system memory

Quote
Does it load the image anyway without regarding the GPU capacity like i've mentioned before?

Are you talking about texture size or memory capacity? For the first one it returns an error, but for the second one it prints a warning in the error output.

Quote
Another question, how do sf::Texture's methods void Update(const Image&) and bool LoadFromImage(const Image&) differ? The difference I have seen until now is that the former requires that the texture be created beforehand. Can't Update() fail? Maybe you should emphasize those points more explicitly in the documentation

Update only copies pixels, it doesn't create anything nor perform any check. It's a fast function that can be used to stream contents to a texture in real-time, like a video.
LoadFromXxx create the texture.

Quote
Can't Update() fail?

It does nothing if the texture has not been created yet.
It crashes if one of the parameters is wrong (size doesn't match, etc.) -- it provides maximum performances so you are responsible for providing correct parameters.

Quote
And doesn't sf::Texture have a CreateMaskFromColor() anymore? Is it because the sf::Image doesn't really exist after loading, so this would have to be specified at texture creation time?

Absolutely. sf::Texture only knows how to upload and download pixels to the graphics card. If you have custom processing to apply to these pixels, you must do it before providing the pixels to sf::Texture.

Quote
Unfortunately, this leads to unnecessary, expensive copies

Where are those copies?

Quote
is it me or i cannot compile this build?

Oops, I'll fix this ASAP, sorry.
Laurent Gomila - SFML developer

pdinklag

  • Sr. Member
  • ****
  • Posts: 330
  • JSFML Developer
    • View Profile
    • JSFML Website
sf::Texture implemented in SFML 2
« Reply #8 on: August 07, 2011, 11:39:04 am »
Nice stuff!
So simply put (application-wise), Texture replaces Image, and Image is needed only if you need to do pixel manipulation.

A minor thing I noticed, Image.hpp still includes Resource.hpp, that one seems to be obsolete now.
JSFML - The Java binding to SFML.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
sf::Texture implemented in SFML 2
« Reply #9 on: August 07, 2011, 12:57:08 pm »
Thanks for the explanations.

Quote from: "Laurent"
It copies the current contents of the window to the texture. What else can I say? Maybe "copy" is more relevant than "update" in the comments?
Maybe... But I was confused since most of the functionality of the old sf::Image was moved to sf::Texture. I also expected this to be the case for the screenshots, not thinking that sf::Texture wraps a pure OpenGL texture ;)

As far as I understand it, the sf::Texture::Update() overloads are rather an advanced feature, and one only needs them for low-level modification of the underlying OpenGL texture.

Quote from: "Laurent"
- The main purpose of RenderWindow::Capture() is to take screenshots of the application, it downloads the pixels to the system memory
Okay. By the way, why did you move this functionality to sf::RenderWindow again? If you leave it like this, you should maybe declare a single sf::Image in the implementation of Capture() and always return it. Some compilers disable NRVO (Named Return Value Optimization) if different objects are returned, leading to additional slow copies.

With a function void Image::CopyScreen(const RenderWindow& window) however, you could avoid this copy without relying on optimizations. Apart from that, a void Image::CopyTexture(const Texture& texture) could be used instead of Image Texture::CopyToImage() const, so this would be handled in a centralized and uniform way. Or create Copy() overloads. Plus, you can later add error checking (bool return value). But maybe the implementation can't be located inside the sf::Image class, and you don't consider friend-outsourcing appropriate either...

Quote
Update only copies pixels, it doesn't create anything nor perform any check. [...]
LoadFromXxx create the texture.
So LoadFromXY() is basically a Create() followed by Update()?

Quote from: "Laurent"
Where are those copies?
Ah, they are nowhere :)

Sorry, I first thought sf::Texture::LoadFromImage() would store a copy of the image, but in fact it directly initializes the OpenGL texture. There is just one temporary sf::Image, but that cannot be avoided anyway.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Texture implemented in SFML 2
« Reply #10 on: August 07, 2011, 01:47:59 pm »
Quote
So simply put (application-wise), Texture replaces Image, and Image is needed only if you need to do pixel manipulation.

Absolutely.

Quote
A minor thing I noticed, Image.hpp still includes Resource.hpp, that one seems to be obsolete now.

Thanks :)

Quote
As far as I understand it, the sf::Texture::Update() overloads are rather an advanced feature, and one only needs them for low-level modification of the underlying OpenGL texture.

Correct.

Quote
Okay. By the way, why did you move this functionality to sf::RenderWindow again?

Previously the Texture::Update(Window) and RenderWindow::Capture() features were merged. That's why it was available as Image::CopyScreen(Window&).
But now that its only purpose is to take screenshots, I went back to the most convenient interface.

Quote
Apart from that, a void Image::CopyTexture(const Texture& texture) could be used instead of Image Texture::CopyToImage() const, so this would be handled in a centralized and uniform way. Or create Copy() overloads.

I didn't want sf::Image to know about sf::Texture. It's purely a design decision ;)
In my opinion, CopyToImage is a single-shot operation, I can't think of a use case that would require updating the same image again and again from a texture.

Quote
So LoadFromXY() is basically a Create() followed by Update()?

This is exactly how they are implemented :)
Laurent Gomila - SFML developer

Contadotempo

  • Full Member
  • ***
  • Posts: 167
  • Firelink Shrine
    • View Profile
sf::Texture implemented in SFML 2
« Reply #11 on: August 07, 2011, 04:18:22 pm »
Think I understand these more clearly now.
Kind of panicked a little because I was actually working on a pixel-perfect collision algorithm when this commit came out and I thought I would need to change a bunch of code, but turns out nothing much changed I guess.

Thank you.

OniLinkPlus

  • Hero Member
  • *****
  • Posts: 500
    • View Profile
sf::Texture implemented in SFML 2
« Reply #12 on: August 07, 2011, 10:54:38 pm »
Quote from: "Laurent"
I didn't want sf::Image to know about sf::Texture. It's purely a design decision ;)
So sf::Image developed split personality disorder and doesn't realize it?
I use the latest build of SFML2

Groogy

  • Hero Member
  • *****
  • Posts: 1469
    • MSN Messenger - groogy@groogy.se
    • View Profile
    • http://www.groogy.se
    • Email
sf::Texture implemented in SFML 2
« Reply #13 on: August 17, 2011, 12:13:02 pm »
Why does it have to come when I'm busy? Anyway great change and I'll get right on getting it into rbSFML. Got really interested on creating images bigger than max texture size. Should be possible with this change.
Developer and Maker of rbSFML and Programmer at Paradox Development Studio

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
sf::Texture implemented in SFML 2
« Reply #14 on: August 17, 2011, 12:22:00 pm »
Quote
Got really interested on creating images bigger than max texture size. Should be possible with this change.

Indeed it is.
Laurent Gomila - SFML developer