SFML community forums

Help => Graphics => Topic started by: xNidhogg on May 18, 2012, 04:14:32 pm

Title: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 18, 2012, 04:14:32 pm
I can't find anything in the documentation and googling brings results for 1.6 or older 2.0 builds but not from 2.0 RC. Also if it's possible is there a resolution limit?
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: Laurent on May 18, 2012, 04:16:42 pm
rtexture.getTexture().copyToImage().saveToFile("toto.png");
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 18, 2012, 04:18:41 pm
rtexture.getTexture().copyToImage().saveToFile("toto.png");

how...how did I miss .getTexture()? My eyes are trolling me sometimes...thank you for such a lightning-fast reply! Really having a good time with this framework.
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 08:23:45 am
It seems I do have to follow up on this question again as I can't seem to get it working.
During runtime when I press my button to save the screenshot I get this printed to stderr:
Quote from: stderr date=1337350721
radeon: The kernel rejected CS, see dmesg for more information

Here are last few lines of dmesg:
Quote from: dmesg
[ 1493.222196] [drm:radeon_cs_parser_relocs] *ERROR* gem object lookup failed 0x13
[ 1493.222201] [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation -2!

Here is the drawing code (I hid the drawing code to the vertexarray because it doesn't even work simplified like this):
template<class TMap, class TCell, class TCodes>
void TileMap<TMap, TCell, TCodes>::SaveToFile(sf::String const& path)
{
  using namespace sf;
  RenderTexture texture;
  int mapWidth(GetMapWidth());
  int mapHeight(GetMapHeight());

  texture.create(mapWidth * _tileWidth, mapHeight * _tileHeight);
  texture.clear(Color::Black);
  VertexArray vMap(Quads, mapWidth * mapHeight * 4);
 /* actual drawing code hidden because irrelevant */
  texture.draw(vMap, &_tileSheet);
  texture.display();
  texture.getTexture().copyToImage().saveToFile(path);
}

It creates the file and it has the right dimensions, but it's transparent and not black as expected (in this simplified version).
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: Laurent on May 21, 2012, 08:31:49 am
Can you write a complete and minimal code that reproduces the problem, so that I can try it?
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 08:45:16 am
Can you write a complete and minimal code that reproduces the problem, so that I can try it?

Actually no. When I do it like this:

int main(int argc, char** argv)
{
  using namespace sf;
  RenderTexture texture;
  texture.create(800,600);
  texture.clear(Color::Black);
  texture.display();
  texture.getTexture().copyToImage().saveToFile("test.png");
}
 

it works, but when I copy&paste this function body to my function where it should happen I get the error again.

For additional information that may help: I am calling the function in my update loop, which means the last command sent to my usual RenderWindow was renderWindow.display(). Maybe there is some internal context switching problems or something where the opengl of the normal RenderWindow and RenderTexture clashes internally? Is that possible?
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: Laurent on May 21, 2012, 08:50:49 am
Quote
Maybe there is some internal context switching problems or something where the opengl of the normal RenderWindow and RenderTexture clashes internally? Is that possible?
No, especially if you don't use threads.

If the complete and minimal code works, then there's something wrong in your code that we can't see here. We won't be able to help you, you have to do some debugging and find what makes your code different from the minimal one that works.
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 08:52:55 am
I managed to produce a minimal example of non working code

#include <SFML/Graphics.hpp>
int main(int argc, char** argv)
{
  using namespace sf;
  RenderWindow rWindow(sf::VideoMode(640,480), "Test",
                       Style::Close | Style::Titlebar, ContextSettings());

  rWindow.clear(Color::Blue);
  rWindow.display();

  RenderTexture rTexture;
  rTexture.create(800,600);
  rTexture.clear(Color::Black);
  rTexture.display();
  rTexture.getTexture().copyToImage().saveToFile("test.png");

  rWindow.clear(Color::Blue);
  rWindow.display();
}
 

This reflects the order of stuff that goes on and produces the error.

It creates test.png but it's transparent (and now with garbage data in it) see here: http://imgur.com/uuNSs (http://imgur.com/uuNSs)

I'm running Ubuntu 12.04 LTS 64-Bit with opensource radeon drivers on a ATI Radeon Mobility HD 5650

I'm compiling 64 bit binaries with gcc-4.7 and -std=C++11
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: Laurent on May 21, 2012, 09:08:59 am
Thanks, I'll test that as soon as I can :)

By the way, can you use the [code=cpp] tag so that I don't have to edit all your posts?
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 09:18:43 am
Thanks, I'll test that as soon as I can :)

By the way, can you use the [code=cpp] tag so that I don't have to edit all your posts?

yes, sure I just noticed that you did that =p

I think it may be because of the two different sizes of the output? Thing is I really need two different sizes for this. Scratch that, tested and still failed.
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: Laurent on May 21, 2012, 09:40:11 am
You can try something: replace the RenderWindow with this:
sf::Context context;
If it still produces the error, try to move it after "rtexture.create".

(this is just some debug stuff to help me figure out what happens)
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 09:53:13 am
You can try something: replace the RenderWindow with this:
sf::Context context;
If it still produces the error, try to move it after "rtexture.create".

(this is just some debug stuff to help me figure out what happens)

int main(int argc, char** argv)
{
  using namespace sf;
  /*
  RenderWindow rWindow(sf::VideoMode(640,480), "Test",
                       Style::Close | Style::Titlebar, ContextSettings());

  rWindow.clear(Color::Blue);
  rWindow.display();
  */


  Context context;
  RenderTexture rTexture;  
  rTexture.create(800,600);
  rTexture.clear(Color::Black);
  rTexture.display();
  rTexture.getTexture().copyToImage().saveToFile("test.png");

  /*
  rWindow.clear(Color::Blue);
  rWindow.display();
  */

}
 

Causes screen to flicker black, locks up OS and ultimately forces me to restart (complete crash and unresponsive).

int main(int argc, char** argv)
{
  using namespace sf;
  /*
  RenderWindow rWindow(sf::VideoMode(640,480), "Test",
                       Style::Close | Style::Titlebar, ContextSettings());

  rWindow.clear(Color::Blue);
  rWindow.display();
  */


  RenderTexture rTexture;
  Context context;
  rTexture.create(800,600);
  rTexture.clear(Color::Black);
  rTexture.display();
  rTexture.getTexture().copyToImage().saveToFile("test.png");

  /*
  rWindow.clear(Color::Blue);
  rWindow.display();
  */

}
 

Works as expected.

#include <SFML/Graphics.hpp>
int main(int argc, char** argv)
{
  using namespace sf;
  RenderWindow rWindow(sf::VideoMode(640,480), "Test",
                       Style::Close | Style::Titlebar, ContextSettings());

  rWindow.clear(Color::Blue);
  rWindow.display();


  RenderTexture rTexture;
  Context context;
  rTexture.create(800,600);
  rTexture.clear(Color::Black);
  rTexture.display();
  rTexture.getTexture().copyToImage().saveToFile("test.png");


  rWindow.clear(Color::Blue);
  rWindow.display();
}
 

Testing this one now, wrote this before testing it so be back in a sec if it crashes.

Seems to work this way. No crashes, no errors. Testing it with my actual code now.

Strange, getting flash&crash in actual code again.
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: Laurent on May 21, 2012, 10:04:30 am
Are your graphics drivers up to date?
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 10:09:56 am
#include <SFML/Graphics.hpp>
int main(int argc, char** argv)
{
  using namespace sf;
  RenderWindow rWindow(sf::VideoMode(640,480), "Test",
                       Style::Close | Style::Titlebar, ContextSettings());

  for(int i = 0; i < 2; ++i)
  {
    rWindow.clear(Color::Blue);
    rWindow.display();

    RenderTexture rTexture;
    Context context;
    rTexture.create(800,600);
    rTexture.clear(Color::Red);
    rTexture.display();
    rTexture.getTexture().copyToImage().saveToFile("test.png");

    rWindow.clear(Color::Blue);
    rWindow.display();
  }
}
 

Cause flicker & crash in a minimal case. Produces transparent png of the right size.

I'm using the open source ATI drivers (propietary doesn't allow 3 monitors) and according to my package manager it is up 2 date.

I have another linux + windows machine with a propietary Nvidia driver. I can test the code there but I don't have access to it for atleast 7 more hours so I would need to report back then.

I understand if you can't support the opensource ones and would probably just disable screenshot function under linux if it other wise would work.
Title: Re: Is it possible to save the image of a rendertexture to a file? [SFML2.0]
Post by: xNidhogg on May 21, 2012, 05:48:27 pm
Here's the promised update: It works on my Linux 64-bit with propietary Nvidia drivers and Windows with Nvidia.

So I guess it's a bug with the opensource drivers, I can live with that.

Thank you very much Laurent for the fast support. It really shows how dedicated you are and it amazes me that you find the time helping so many people in between coding.