Render full surface even if obscured

Started by Aisaaax, July 10, 2020, 09:28:12

Previous topic - Next topic


I am writing application on Java using Swing for GUI (I can't change that)

I am doing it by creating an AWT Canvas on the main JFrame (It's a heavyweight element), and then resulvind drawingSurface from it. I then create OpenGL context that renders directly to that surface as a target.
This allows me tho avoid the performance dip that happens if you'd use paint() method in swing.

Here's the thing. When rendering to a heavyweight element, some parts of the surface may be obscured by another window, for example. Also, I am using AWT's setComponentMixingCutoutShape() function to describe "Cutouts" for lightweight element. The idea is that I make part of my canvas's surface invisible.

I am then rendering at 30 FPS approximately (refresh rate is dynamic, but 30 is a target it tries to achieve).

It all works well, save for one small thing.
Let's say I have a window that obscures part of canvas with my 3d render. Then I hide that window.
What happens is that because SWING runs in a different thread than my 3d (obviously), the window may be hidden between frame updates. The result is that for a split second I see a gaping hole in my 3d picture, because the previous frame was rendered excluding this part of the drawing surface. Note that the hole appears in the 3d rendered image - and I can see canvas's basic surface color through it, because Swing re-draws it in place of the hidden element. But the 3d-render fragments are not there. Then the frame updates and the hole disappears.

It's not a huge problem, but it is a problem for the end user, because it looks extremely wanky.
Below is an example I made in GIMP. I can't really screenshot a 1-frame-long bug. Note that you can still see shadow from the overlying window here. Also note that cream-brown is the base color of Canvas onto which I render the 3d image. So I am seeing Canvas itself and not some element below it. The hole is in a 3d rendered content, not in the canvas.

What I suspect is happening is that internally (I know not on which level) the obscured parts of the surface are not rendered by OpenGL at all. And it makes sense - why would you render something that is obscured anyway? But because the obscuring object can disappear between frames - it leave a hole before the next frame is pushed out.

My question is:
Can I work around that issue? For example, can I ALWAYS render the entire rectangle of the Canvas surface, regardless of which parts of it are obscured? And then obscure those parts afterwards if needed?
Or maybe there's some other solution.


So I didn't find any solution for it, but what worked in my case was changing canvas's background to a most common color of my scene (light-green). It's a crutch, but it helps, in case someone struggles with the same thing.