jzy3d / jogl

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

Incorrect GL Version - Win10 + Nvidia + JDK 8 #5

Closed jzy3d closed 2 years ago

jzy3d commented 2 years ago

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

This test program (see below) simply creates a JFrame on the default GraphicsConfiguration for my first screen, and adds an empty GLCanvas to this JFrame. While creating the GUI, this test program enumerates all GraphicsDevice's available on my PC, and for each GraphicsDevice, all available GraphicsConfigurations. Finally, in the init() callback of my GLEventListener, I simply print the GLVersion of my drawable.getContext().

On my Windows 10 development PC, which has two screens attached to a NVIDIA GeForce GTX 1060 6 GB graphics adapter, here is what I get on the stdout:

Screen device # 0: \Display0
Screen device # 0, configuration # 0:
Screen device # 1: \Display1
Screen device # 1, configuration # 0:
NewFrame created in thread [15], isEDT: true
* Context GL version: 4.6 (Compat profile, arb, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.6.0 NVIDIA 456.71

So far, so good. In my init() callback, I get an OpenGL 4.6 context, and that's great. VTK would work fine with such a context.

However, if I just pass "-Dsun.java2d.noddraw=true" system property to my JVM (which is required to run both JOGL and my application smoothly), here is what I get:

Screen device # 0: \Display0
Screen device # 0, configuration # 0:
Screen device # 0, configuration # 1:
Screen device # 0, configuration # 2:
Screen device # 0, configuration # 3:
Screen device # 0, configuration # 4:
Screen device # 0, configuration # 5:
Screen device # 1: \Display1
Screen device # 1, configuration # 0:
Screen device # 1, configuration # 1:
Screen device # 1, configuration # 2:
Screen device # 1, configuration # 3:
Screen device # 1, configuration # 4:
Screen device # 1, configuration # 5:
NewFrame created in thread [15], isEDT: true
*** Context GL version: 1.1 (Compat profile, arb, compat[], FBO, hardware) - 1.1.0**

As you can see, with this system property, first of all I get 6 different GraphicsConfiguration per each screen (I am uncertain why, but this certainly doesn't depend on JOGL), and then the GLContext I get in my init() callback is an OpenGL 1.1 context (and I believe this depends on JOGL and shouldn't happen)!

Even stranger, if in my test case code I simply remove the call to GraphicsDevice.getConfigurations() (but always passing "-Dsun.java2d.noddraw=true"), then again I am getting a correct OpenGL 4.6 context. Here is the output I obtain in this last test configuration:

NewFrame created in thread [15], isEDT: true
* Context GL version: 4.6 (Compat profile, arb, compat[ES2, ES3, ES31, ES32], FBO, hardware) - 4.6.0 NVIDIA 456.71

I looks like the fact that I call GraphicsDevice.getConfigurations() (which apparently should do nothing) is changing something in the way JOGL creates its GLContext in the GLCanvas.

I would really appreciate your feedback, now that I've been able to put together a complete and very simple test case.

package vtk.sample.rendering;

import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class JoglContextTestCase
{
  private static JFrame mainFrame = null;

  private static void buildSceneAndCheckConfigurations()
  {
    GraphicsEnvironment graphEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice[] graphDevsOrig = graphEnv.getScreenDevices();

    GraphicsConfiguration gcDef = graphDevsOrig[0].getDefaultConfiguration();

    // *************************************************************************
    // NOTE: if I comment the following loop, which apparently does NOTHING
    // (except calling .getGraphicsConfigurations()), this test case
    // returns "GL version: 4.6" on my PC, while with the following loop
    // uncommented, it returns "GL version: 1.1" --> this would cause VTK
    // to CRASH!
    // The single call responsible for the "GL 1.1" issue, for some reason,
    // seems to be 'graphDevsOrig[i].getConfigurations();'
    // *************************************************************************    
    for (int i = 0; i < graphDevsOrig.length; i++)
    {
      System.out.println("Screen device # " + i + ": " + graphDevsOrig[i].getIDstring());
      GraphicsConfiguration[] graphConfs = graphDevsOrig[i].getConfigurations();

      for (int j = 0; j < graphConfs.length; j++)
      {
        System.out.println("Screen device # " + i + ", configuration # " + j + ":");
      }
    }

    buildScene(gcDef);    
  }

  private static void buildScene(GraphicsConfiguration graphConf)
  {
    GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getMaximum(true)));
    glCanvas.addGLEventListener(new GLEventListener()
    {
      @Override
      public void init(final GLAutoDrawable drawable)
      {
//        final GL gl = drawable.getGL();
//        System.out.println(JoglVersion.getGLInfo(gl, null));
//        System.out.println("* Context = " + drawable.getContext().toString());
        System.out.println("* Context GL version: " + drawable.getContext().getGLVersion());
      }

      @Override
      public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height)
      {
      }

      @Override
      public void display(final GLAutoDrawable drawable)
      {
      }

      @Override
      public void dispose(final GLAutoDrawable drawable)
      {
      }
    });

    // UI part
    mainFrame = new JFrame("SimpleVTK", graphConf);
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    mainFrame.getContentPane().setLayout(new BorderLayout());

    mainFrame.setSize(1000, 600);
    mainFrame.setLocationRelativeTo(null);
    mainFrame.setVisible(true);
    mainFrame.getContentPane().add(glCanvas, BorderLayout.CENTER);
    glCanvas.requestFocus();

    System.out.println("NewFrame created in thread [" + Thread.currentThread().getId() + "], isEDT: " + SwingUtilities.isEventDispatchThread());
  }

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        buildSceneAndCheckConfigurations();
      }
    });
  }
}
jzy3d commented 2 years ago

Workaround : sun.awt.nopixfmt=true

Investigate WindowsWGLDrawable which seams to be what's backing GLCanvas. See WindowsWGLGraphicsConfigurationFactory.