jzy3d / jogl

Mirror of https://jogamp.org/cgit/jogl.git/
Other
6 stars 2 forks source link

Incorrect context on GLCanvas #24

Open jzy3d opened 2 years ago

jzy3d commented 2 years ago

https://forum.jogamp.org/Incorrect-context-on-GLCanvas-drawable-td4041391.html

Windows 10

From JOGL forum

I am using JOGL (2.4.0-rc-20210111) together with VTK 9.0.1.

In particular, I am using the GLCanvas component embedded into VTK's vtkJoglCanvasComponent.

My application works quite fine (both on Windows and on macOS - with Java 8 JRE).

However, I am facing a strange sporadic crash when I invoke a function in my application which removes the GLCanvas-based GUI panel from its container, and then adds it to a newly-created JFrame (it's a kind of "full screen mode" function of my application). This crash seems to happen only on Windows, while I've been unable to reproduce it on macOS so far.

In VTK's vtkJoglCanvasComponent class, there is a GLEventListener, whose init() callback gets called both upon initial display of the GLCanvas-based GUI panel, and then again when the GLCanvas-based GUI panel is added to the newly-created JFrame. Between the two init() calls, there is a dispose() call which is invoked when the GLCanvas-based GUI panel is removed form its original container.

Upon first invocation of the init() callback, if I call 'drawable.getContext()', I obtain an OpenGL 4.6 context, and everything works like a charm.

On the other side, upon the second invocation of the init() callback (after addition of the GLCanvas to the new JFrame), SOMETIMES calling 'drawable.getContext()', I obtain an OpenGL 1.1 context. When this happens, then VTK crashes, because VTK 9 requires at least OpenGL 3.2 in order to work properly.

I know that my description of the problem is quite limited, but can you guess why I SOMETIMES get an OpenGL 1.1 context upon init() with my GLCanvas-based panel?

This happens on many different Windows PCs with many different display adapters / drivers, when I invoke this "full screen mode" feature in my application (which works as described above: remove GLCanvas from its container --> create a new JFrame --> add the GLCanvas to the new JFrame).

It may be something in VTK, but I was just wondering if you could guess where the problem might be, and maybe point us in the correct direction.

Also, let me mention that for some reason this issue seems to appear more frequently with Jetbrain's Java 8 JRE, even though I have had a few occurrences of the issue even with Adopt OpenJDK Java 8 JRE.

Answer

I got confirmation from a collaborator having windows+Nvidia adapters that the erroneous GL version on windows with noddraw=true is fixed by adding opengl=true.

Answer

I confirm that an OpenGL 4.6 context is returned both in the case the noddraw system property is NOT passed, and in the case opengl=true is passed. This happens because, for some reason, in both cases just a single GraphicsConfiguration is returned for each GraphicsDevice.

On the other side, with noddraw=true, 6 GraphicsConfiguration are returned for each GraphicsDevice, and this seems to be the actual source of problems for the GLContext of my GLCanvas. BTW, these 6 GraphicsConfiguration are "similar" but not identical, as they only differ for their "pixel format" attribute.

Unfortunately, both workarounds (1. avoiding passing noddraw=true, 2. passing opengl=true) are NOT viable solutions for me.

In fact:

1) If I don't pass noddraw=true, I have rendering issues both with JOGL and within the rest of my application.

2) If I pass opengl=true, with many graphics adapters' device drivers I have Swing rendering artifacts and issues within my application. E.g., incorrect painting of toolbar buttons, etc.

So, I need to return to my initial question: why in the case 6 GraphicsConfigurations are returned, and getConfigurations() is called, then GLCanvas is initialized with an Open GL 1.1 context (at least with all NVIDIA adapters)? Is this something which can be corrected in JOGL?

jzy3d commented 2 years ago

Fix proposed by a VTK developer

We confirm the Java wrapping of VTK is also impacted by this behavior. We reproduce the problem described in this post with all the Windows+Nvidia configurations we tried. Here is our findings in case it helps:

The best workaround we have so far is to turn on the nopixfmt option: sun.awt.nopixfmt=true. This way we always get a single configuration returned and the expected OpenGL version is used.

Looking at the Win32GraphicsDevice source code, the number of configurations returned as well as the value of the default configuration depends on the default pixel format id.

Maybe using nopixfmt has influence on the default pixel format ID and results in the expected configuration being picked? Or maybe it has influence on the isDefaultDevice check at the start of getConfigurations()?