DavidYawCSpeed
Topic Author
Posts: 3
Joined: 20 Aug 2020, 21:04

Capturing a Screenshot

10 Jun 2021, 01:09

I'm currently doing this to capture a screenshot of my application, but I'm not 100% sure that this is the correct way to do it. I see a bunch of methods on RenderContext like Begin/End Render, SetRenderTarget, etc., and it makes me paranoid that my little one-liner is missing some step. What I have works, but if it were doing something bad behind the scenes (big memory leak? failing to release some texture? Forcing Noesis to take extra steps because I skipped something?), I'd have a hard time detecting it.

Here's what I'm doing, please let me know if this is correct.

At startup:
RenderContext mainRenderContext = created from Application.CreateRenderContext();
RenderTarget renderTarget = mainRenderContext.Device.CreateRenderTarget("Screenshot RT", width, height, sampleCount: 1);
When a screenshot is requested:
// This is run on the dispatcher thread.
ImageCapture imageCapture = mainRenderContext.CaptureRenderTarget(renderTarget);
SavePngFile(imageCapture.Pixels, imageCapture.Width, imageCapture.Height); // Details of reading the byte[] and saving as PNG not important here...
That's it, just the one call to CaptureRenderTarget, No BeginRender, no EndRender, nothing. It works, but It's so simple it makes me think I'm missing something.

I assume that the image I get would be the last one that was sent to the screen, that it doesn't have any changes from the last 1/60th of a second. I'm fine with that.
 
KeldorKatarn
Posts: 193
Joined: 30 May 2014, 10:26

Re: Capturing a Screenshot

10 Jun 2021, 06:51

Is your application exclusively Noesis UI or is there more to capture? If you just need to capture what Noesis does, then you could use these approaches
provided Noesis provides all the necessary API equivalents

https://stackoverflow.com/questions/512 ... wpf-window
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Capturing a Screenshot

10 Jun 2021, 10:23

Hi David,

The RenderContext.CaptureRenderTarget() method will copy the pixels from the specified render target's texture, so you first need to render to that render target. This is done by with a code like this:
context.BeginRender();

Renderer renderer = view.Renderer;
renderer.UpdateRenderTree();
renderer.RenderOffscreen();
device.SetRenderTarget(rt);

Tile tile = new Tile { X = 0, Y = 0, Width = width, Height = height };
device.BeginTile(tile, width, height);
renderer.Render();
device.EndTile();

device.ResolveRenderTarget(rt, new Tile[] { tile });

context.EndRender();
If you are not doing that, how are you updating the contents of the render target's texture?
 
DavidYawCSpeed
Topic Author
Posts: 3
Joined: 20 Aug 2020, 21:04

Re: Capturing a Screenshot

10 Jun 2021, 18:42

Is your application exclusively Noesis UI or is there more to capture?
There are two modes my application can be in. For this mode, yes, it's exclusively Noesis UI.

(In the other mode, I read from the Linux Framebuffer instead. But doing it all internal to the application (when it's possible to do so) is better.)
If you are not doing that, how are you updating the contents of the render target's texture?
The normal rendering of the application's main Window. I don't need a separate capture, with a separate rendering phase. I literally want the exact pixels that were displayed on the screen for the last 1/60th of a second.

This is working for me: I am able to get the pixels of the UI and save them as a PNG. Tested on Windows with RenderContextWGL and on Linux with RenderContextEGL. I'm mostly just looking for confirmation that I'm not doing something bad that will cause problems down the road.
 
User avatar
sfernandez
Site Admin
Posts: 2983
Joined: 22 Dec 2011, 19:20

Re: Capturing a Screenshot

21 Jun 2021, 09:43

Hi, it is working fine with GL render contexts because those use the active framebuffer to capture the pixels (and the passed RenderTarget is ignored).
It is fine to use those CaptureRenderTarget functions, although we just created them for our own testing, so they are not optimized and should be used with that in mind.

Who is online

Users browsing this forum: Google [Bot] and 69 guests