grabScreen vs loadScreenData vs ofFbo

Hi, I wonder what is the difference between ofImage.grabScreen and ofTexture.loadScreenData.

I see no difference between

img.grabScreen(300, 300, 200, 200);
img.draw(0,0);

and

img.getTexture().allocate(200, 200, GL_RGBA);
img.getTexture().loadScreenData(300, 300, 200, 200);
img.getTexture().draw(0, 0);

both of them showed the same result.
But the second one was more efficient than the first one.
Then why do we need grabScreen and when to use it if it’s slower than loadScreenData?

Also, ofFbo can achieve the same thing using fbo.begin() and fbo.end().
Performance wise, using fbo was faster than grabScreen and similar to loadScreenData.
I would like to know what are ofFbo’s advantage/disadvantage compared to these two.

FBO’s have another use, they can be used for kind of compositing various layers and then treating the resulting composite as a single layer for processing with a shader, not needing to draw to the screen or for manipulating all together in some other way.

For example you could draw things off screen at a high resolution and save the fbo to an image file, if you use the load screen data you are limited to the screen resolution, whereas with the FBO you can pick a larger resolution, this way no matter the device or screen size you can always save out a full HD file.

Drawing a lot of text and images into an fbo will let you fade, or apply a shader or other manipulation to the resulting composite image without needing to first draw the results on screen, or being able to apply the manipulation to all the elements at once as they can be accessed as a single texture (fbo.getTexture())

FBO’s, also make it easy to give yourself small preview windows for live work where you can see the output to a projector on a control screen by just drawing the FBO twice, once at a preview size and once for the output. This is useful if you have a lot of elements to draw, drawing a smaller version of the FBO texture is pretty efficient.

This is also useful for situations where your output size changes, say you use different screens or projectors. You can set up a complex coordinate drawing system to align and place your images and not have it based on screen size, when you need to move to a different output resolution you can just draw the FBO to the appropriate size and position.

Lastly, if you are using something like spout or syphon, it is much easier to share an image in real time that is made of several layers as you can publish the texture from the FBO in one fast command.

I am sure someone can give a really great super technical explanation, but these have been the super practical use cases for me.

1 Like

the main difference between using a texture or fbo and using image::grabScreen is that with the first 2 the capture stays in the graphics card, that’s why it’s faster. using ofImage::grabScreen the image is downloaded to the pixels of the image in the cpu memory which allows to for example save it to a file later but it’s slower.

so if you only need to draw the capture use the texture or fbo methods, if you need to somehow process the capture in the cpu, save it… use grabScreen or a combination of fbo/texture + readToPixels

1 Like

@fresla @arturo
Thank you so much for the explanation. That was really helpful :slight_smile: