How to save screenshots quickly?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Eduuu
Posts: 3
Joined: Tue Nov 15, 2022 8:46 pm

How to save screenshots quickly?

Post by Eduuu »

Hi there, I am working on a fork of minetest(which runs on irricht) and want to save screencaps of every frame. If I naively save a screenshot every frame then I end up getting roughly 8fps.

My first thought was that writing to file was taking a long time. This appears to be true to some extent - the two calls

Code: Select all

irr::video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
irr::video::IImage* const raw_image = driver->createScreenShot();

are fast. It is the call to

Code: Select all

driver->writeImageToFile(raw_image, (std::to_string(timestamp)+filename_ext).c_str(), quality);
which is slow.

My first thought was to wrap the method containing the above code in a call using async so that the writes don't block, but it ends up just writing out completely black screens, and also still runs at a similar framerate. I imagine that this is not a completely unheard of use case, so I was wondering if anyone could point me to a potential solution or knew of anyone trying to do something similar.

I am somewhat new to C++ and completely new to Irrlicht - thank you in advance for your patience.
CuteAlien
Admin
Posts: 9734
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How to save screenshots quickly?

Post by CuteAlien »

Doing your own movie recorder is not that trivial. Easiest way to record movies is usually not to code it yourself but use a tool like OBS.

The problem if you write image by image is that you tend to do compression and also write stuff like headers each time. And you often end up doing lots of memory allocations (which are slow). You could experiment with different formats which might vary in speed a lot. But there isn't really any optimized for writing movies in Irrlicht so far.

Another thing is that createScreenshot also isn't that fast. Sadly there isn't a simple fast solution in Irrlicht. createScreenShot has the problem that it allocates the image memory each frame and there isn't an option to pass an already allocated image which can be re-used

A slightly faster solution is usually to work with rendertargettextures. Those can be allocated once and it will also give you the option to chose the resolution, so you can experiment up to which resolution speed is still fast enough. The disadvantage is that it's more work than using createScreenshot. But should be worth it for speed. I don't know if minetest already works with rendertargets (in which case things obviously get easier). But basically instead of rendering directly to the screen you render into a texture. And then draw that texture to the screen (using a quad - aka 2 triangles). And for recording you can then lock the data from that texture and copy it into an IImage (copy already a bit expensive, but probably still acceptable if the IImage is pre-allocated and has the same resolution as the texture). You're still back to the same problem of using writeImageToFile in the end.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Eduuu
Posts: 3
Joined: Tue Nov 15, 2022 8:46 pm

Re: How to save screenshots quickly?

Post by Eduuu »

Thanks for the info. I think that we won't actually have to save every frame, so this kind of resolved itself - we will anyway be bottlenecked by how quickly all of this can be fed into a NN.
Post Reply