retain screen contents during switch to/from Fullscreen

I have an app that works with backingMode(RETAINED). I’d like to allow the user to switch between displayMode(STANDARD) and FULLSCREEN. However, whenever the screen switches, all the screen contents are wiped.

Is there a way to retain the screen contents when switching displayModes? What is causing the wipe – is setup() being called? If there’s not a way to retain it, could someone perhaps help me understand if there’s a way to store / restore the contents? Is there some pop/push mechanism for saving all of the current screen drawing and later restore it?

Thanks for any help!

keeping retained mode between STANDARD and FULLSCREEN seems tricky because then you would have to stretch out the image to fit to the new dimensions.

Have you seen setContext(image)? That’s probably the best way to accomplish what you want. Basically if you initialize an image with image = image(width,height) and then do setContext(image), all calls to line/rect/ellipse/sprite/etc will now draw to the image instead of the screen. Then at the end you do setContext() without an argument to go back to regular mode and finally do sprite(image,0,0,WIDTH,HEIGHT) to draw it on the screen.

That way the image is your retained background that you only have to create once. And on the plus side, if you have moving stuff on top of that image you can draw that after you draw the image.

I hope I made at least some sense

Thanks ruilov. Very interesting.

I had hoped there’d be a way to retain the image, and let it be simply cropped (or stuck on one side or the other) during the switch between Standard and Fullscreen. That’s the behavior I’d like, anyway…rather than a stretch.

I looked at setContext, but to be honest got scared off. When I draw to the image, does that mean it doesn’t also draw to the screen? So do I make two calls for each draw?

I’m working on a drawing program, so it’s important that the user sees their work appearing on the screen in real time. I could try setContext, so long as it doesn’t slow down the rate at which new shapes appear in a way that’s visible to the user.

Others could probably comment on the speed, but I would guess you’re not going to run into trouble into the respect. You would do

setContext(image)
line(0,0,10,10)
setContext()
sprite(image,0,0)

it’s not much slower than

line(0,0,10,10)

Then when the user switches to full mode you can still do sprite(image,0,0) and I believe it will show cropped up as you want.

Edit: oh and to answer your question, no you wouldn’t make two calls for each draw. See the example above. The line() call happens once. Then at the end all you need to do is sprite(image,0,0) and it should show on the screen.

and don’t be scared of setContext, it’s really useful. It lets you draw stuff to an invisible screen that the user doesn’t see. Then when you’re done drawing to that invisible screen, you can reveal it to the user with sprite(image,0,0). It’s useful.

in fact I bet that if TLL had added this feature in the first version, they wouldn’t even have added the retained mode thing (not blaming TLL, I also thought retained mode was useful until they came up with the setContext thing, then it became clear setContext was a better way to do it)

@ruilov’s method is the best way to do this.

Thanks ruilov, I really appreciate the detailed code sample. It will help me to overcome my fear!

Simeon, for curiosity’s sake, why is it that a displayMode change wipes the screen? Is that as designed, or an oversight, or to avoid having to deal with image cropping, or a subtle message that playing around with backingMode(RETAINED) is dancing with the devil and we deserve what we get?

It’s by design. Changing the display mode changes the resolution of the OpenGL buffer, so Codea has to re-allocate the frame buffer which wipes the contents. Codea could try to restore the contents - but since the aspect ratio and resolution are different after the display change the best we could do is just stretch the old image out. Which wouldn’t be desirable in most cases.

setContext() will give you a lot more flexibility and allow you to retain and even save the image data (like @Mark’s Spritely does).

Thanks for explaining!