Selecting the highest possible GL profile at runtime.

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

Selecting the highest possible GL profile at runtime.

Martin
Hi,

I usually work with GLProfile.get(GLProfile.GL2) but now I want to get the highest possible profile with GLProfile.getMaximum(true).

Most of my code base is made for GL2, so I often invoke gl.getGL2().glSomething(...). I understood that getGL2() will return either a GL2, GL3bc or GL4bc instance depending on the selected profile, and that all three can execute OpenGL method that refer to OpenGL version 1 or 2.

However, when I call gl.getGL2().glSomething(...) with GLProfile.getMaximum(true) that returns a GL4bcImpl on my mac :

Caused by: com.jogamp.opengl.GLException: Not a GL2 implementation
        at jogamp.opengl.gl4.GL4bcImpl.getGL2(GL4bcImpl.java:40488

Did I misunderstood the version mecanism?

I use MacOS 10.12.6 and JOGL 2.3.2

Thanks
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
Rather use getMaxFixedFunc(true) in your case.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
In reply to this post by Martin
Maybe relax the constraint by calling getMaxFixedFunc(false).
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
In reply to this post by gouessej
Thanks. But this

GLCapabilities caps = new GLCapabilities(GLProfile.getMaxFixedFunc(true));
System.out.println("Select profile " + caps.getGLProfile());

returns
GLProfile[GL2/GL2.hw]

which does not help me go on a GL3 or 4 profile.




Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
It's strange, you seem to get a forward compatible profile when calling getMaximum(true) but you talked about GL4bc which is backward compatible. What about getMaximum(false)?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
In reply to this post by gouessej
Relaxing the constraint with false does not yield to a higher profile than GL2.
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
I'll look at the generated source code in GL4bc. Do isGL2() and getGL2ES1() work in your case?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
Sorry, I missed your last question.

I can do the following for application started with GLProfile.get(GLProfile.GL2);

GL2 gl2 = gl.getGL2();
gl2.isGL2(); // true
gl2.isGL2ES1(); // true
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
There is one additional thing to note : when I order a GL2 profile, I got the below info. I output all isGLxx() output and found that above GL2 returns true despite my Mac seams limited to OpenGL 2.1 (10.12.6 from 2013).

GL2    : true
GL2GL3 : true
GL3    : true
GL3bc  : false
GL4    : true
GL4ES3 : true


Capabilities  : GLCaps[rgba 8/8/8/8, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL2/GL2.hw], offscr[fbo]]
GL_VENDOR     : NVIDIA Corporation
GL_RENDERER   : NVIDIA GeForce GT 650M OpenGL Engine
GL_VERSION    : 2.1 NVIDIA-10.17.5 355.10.05.45f01

Which I got with : gl.glGetString(GL.GL_VERSION)

Reading this page lead me to think that the OpenGL version supported by mac Mac is OpenGL 4.1. I am a bit lost who I should believe :D

Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
Please try -Djogl.disable.openglcore=true
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
Thank you Julien! When using -Djogl.disable.openglcore=true, I got a GL_VERSION that is now relevant with the requested GL profile.

So to summarize
- Add VM args -Djogl.disable.openglcore=true
- Choose a profile for the canvas with GLCapabilities caps = new GLCapabilities(GLProfile.getMaximum(true)); or GLCapabilities caps = new GLCapabilities(GLProfile.get(GLProfile.GL4));
- Call gl.glGetString(GL.GL_VERSION)

Then I properly get

GL_VERSION : 4.1 NVIDIA-10.17.5 355.10.05.45f01


The sad thing is that even if the selected profile is backward compatible (I get a GL4bc), it can't invoke GL2 functions :

Caused by: com.jogamp.opengl.GLException: Not a GL2 implementation
        at jogamp.opengl.gl4.GL4bcImpl.getGL2(GL4bcImpl.java:40488)
        at org.jzy3d.painters.NativeDesktopPainter.configureGL(NativeDesktopPainter.java:141)
        at org.jzy3d.plot3d.rendering.view.View.initQuality(View.java:910)
        at org.jzy3d.plot3d.rendering.view.View.init(View.java:882)
        at org.jzy3d.plot3d.rendering.view.Renderer3d.init(Renderer3d.java:75)
        at jogamp.opengl.GLDrawableHelper.reshape(GLDrawableHelper.java:749)
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
What happens when you invoke GL2 methods without calling getGL2()? Actually, as GL4bc implements GL2, you can call yourGl4bcInstance.glColor4iv​() for example.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
Hi Julien,

When

GL gl = drawable.getContext().getGL();
gl.getGL4bc().glClear(0);

Then I got

com.jogamp.opengl.GLException: Not a GL4bc implementation
        at jogamp.opengl.gl4.GL4bcImpl.getGL4bc(GL4bcImpl.java:40456)
        at org.jzy3d.demos.debugGL.GetOpenGLVersion_JOGL.main(GetOpenGLVersion_JOGL.java:65)


Despite the following output (see below the complete source code allowing to reproduce the issue)

GL INSTANCE : jogamp.opengl.gl4.GL4bcImpl

GL2    : true
GL2GL3 : true
GL3    : true
GL3bc  : false
GL4    : true
GL4ES3 : true
GL4bc  : false


Additionnaly,  when I explicitely ask for GLProfile.get(GLProfile.GL4bc), I got

Exception in thread "main" com.jogamp.opengl.GLException: Profile GL4bc is not available on null, but: [GLProfile[GL2ES1/GL2.hw], GLProfile[GL4ES3/GL4.hw], GLProfile[GL2ES2/GL4.hw], GLProfile[GL2/GL2.hw], GLProfile[GL2/GL2.hw], GLProfile[GL4/GL4.hw], GLProfile[GL3/GL4.hw], GLProfile[GL2GL3/GL4.hw]]
        at com.jogamp.opengl.GLProfile.get(GLProfile.java:991)
        at com.jogamp.opengl.GLProfile.get(GLProfile.java:1004)
        at org.jzy3d.demos.debugGL.GetOpenGLVersion_JOGL.main(GetOpenGLVersion_JOGL.java:24)

Whereas when I ask for GLProfile glp = GLProfile.getMaximum(true); - like in the example, I got a jogamp.opengl.gl4.GL4bcImpl


---------------------------------------

import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLDrawableFactory;
import com.jogamp.opengl.GLProfile;

/**
 * This shows how to switch OpenGL version with JOGL.
 *
 * It requires to invoke the JVM with -Djogl.disable.openglcore=true to work.
 *
 * @see https://forum.jogamp.org/Selecting-the-highest-possible-GL-profile-at-runtime-td4041302.html
 */
public class GetOpenGLVersion_JOGL {

  public static void main(String[] args) throws Exception {
   
    // ------------------------------------------------------
    // Profile & capabilities
   
    //GLProfile glp = GLProfile.getDefault();
    //GLProfile glp = GLProfile.get(GLProfile.GL4bc);
    GLProfile glp = GLProfile.getMaximum(true);

    GLCapabilities caps = new GLCapabilities(glp);
    caps.setOnscreen(false);

    // ------------------------------------------------------
    // Drawable to get a GL context

    GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
    GLAutoDrawable drawable =
        factory.createOffscreenAutoDrawable(factory.getDefaultDevice(), caps, null, 100, 100);
    drawable.display();
    drawable.getContext().makeCurrent();

    GL gl = drawable.getContext().getGL();


    // ------------------------------------------------------
    // Report
   
    System.out.println("PROFILE       : " + glp);
    System.out.println("CAPS (query)  : " + caps);
    System.out.println("CAPS (found)  : " + drawable.getChosenGLCapabilities());
   
    System.out.println(getDebugInfo(gl));
   
    System.out.println("GL2    : " + GLProfile.isAvailable(GLProfile.GL2));
    System.out.println("GL2GL3 : " + GLProfile.isAvailable(GLProfile.GL2GL3));
    System.out.println("GL3    : " + GLProfile.isAvailable(GLProfile.GL3));
    System.out.println("GL3bc  : " + GLProfile.isAvailable(GLProfile.GL3bc));
    System.out.println("GL4    : " + GLProfile.isAvailable(GLProfile.GL4));
    System.out.println("GL4ES3 : " + GLProfile.isAvailable(GLProfile.GL4ES3));
    System.out.println("GL4bc  : " + GLProfile.isAvailable(GLProfile.GL4bc));

    // ------------------------------------------------------
    // Try invoking something

   
    //gl.getGL2().glClear(0);
   
    gl.getGL4bc().glClear(0);
   

    // ------------------------------------------------------
    // We are done, release context for further work
   
    drawable.getContext().release();
  }

  public static String getDebugInfo(GL gl) {
    StringBuffer sb = new StringBuffer();
    sb.append("GL_VENDOR     : " + gl.glGetString(GL.GL_VENDOR) + "\n");
    sb.append("GL_RENDERER   : " + gl.glGetString(GL.GL_RENDERER) + "\n");
    sb.append("GL_VERSION    : " + gl.glGetString(GL.GL_VERSION) + "\n");
   
    String ext = gl.glGetString(GL.GL_EXTENSIONS);

    if(ext!=null) {
      sb.append("GL_EXTENSIONS : " + "\n");
      for(String e: ext.split(" ")) {
        sb.append("\t" + e + "\n");
      }
    }
    else {
      sb.append("GL_EXTENSIONS : null\n");      
    }
   
    sb.append("GL INSTANCE : " + gl.getClass().getName() + "\n");
   
    return sb.toString();
  }
 
}
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
I'll try to reproduce your bug when I have some spare time.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
Another interesting thing to share about GL version detection and JOGL profile : when running on a Microsoft VM in Github CI and asking a GL2 profile, I got this

PROFILE       : GLProfile[GL2/GL2.sw]
CAPS (query)  : GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL2/GL2.sw], offscr[auto-cfg]]
CAPS (found)  : GLCaps[wgl vid 14 gdi: rgba 8/8/8/0, opaque, accum-rgba 16/16/16/0, dp/st/ms 16/8/0, one, mono  , sw, GLProfile[GL2/GL2.sw], offscr[bitmap]]
GL_VENDOR     : Microsoft Corporation
GL_RENDERER   : GDI Generic
GL_VERSION    : 1.1.0
GL_EXTENSIONS :
        GL_WIN_swap_hint
        GL_EXT_bgra
        GL_EXT_paletted_texture
GL INSTANCE : jogamp.opengl.gl4.GL4bcImpl

GL2    : true
GL2GL3 : true
GL3    : false
GL3bc  : false
GL4    : false
GL4ES3 : false
GL4bc  : false

Knowing Julien a bit, I know we won't discuss problems involving Github+Microsoft VM in detail :D but I mainly discuss the topic of JOGL profile & version selection.
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
In reply to this post by gouessej
I have been a bit further on trying to tunderstanding why I can't call gl.getGL2() when gl is a GL4bc.

 When using :
GLProfile glp = GLProfile.getMaxProgrammable(true);
-Djogl.disable.openglcore=true

Then

drawable.getContext().isGLCompatibilityProfile(); returns false, which shouldn't be.

I looked at gl.getGL2(), which will check context.isGL2() before throwing the exception "not a GL2 implementation", and I see

public final boolean isGL2() {
      return 0 != ( ctxOptions & CTX_PROFILE_COMPAT ) && ctxVersion.getMajor()>=1 ;
}

with ctxOptions : 0x4C45 (which is ...0101)
and CTX_PROFILE_COMPAT : 0x2 (which is 10)

so I presume the problem comes from this ctxOptions value. I could not locate exactly where it is set, seamingly somewhere around GLContextImpl.createContextARB

The complete GLContext is

MacOSXCGLContext [Version 4.1 (Core profile, arb, compat[ES2, ES3], FBO, hardware) - 4.1 Metal - 71.6.4 [GL 4.1.0, vendor 71.6.4 (Metal - 71.6.4)], options 0x4c05, this 0x68bbe345, handle 0x122d1d180, isShared false, jogamp.opengl.gl4.GL4bcImpl@26aa12dd,
         quirks: [NoOffscreenBitmap, GL4NeedsGL3Request, NeedSharedObjectSync],
        Drawable: ResizeableImpl[Initialized true, realized true, texUnit 0, samples 0,
        Factory   jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory@3fd7a715,
        Handle    0x0,
        Caps      GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[fbo]],
        fboI back 1, front 0, num 2,
        FBO front read 1, FBO[name r/w 1/1, init true, bound false, size 100x100, samples 0/4, modified false/false, depth RenderAttachment[type DEPTH, format 0x81a5, samples 0, 100x100, name 0x1, obj 0x51cdd8a], stencil null, colorbuffer attachments: 1/8, with 1 textures: [TextureAttachment[type COLOR_TEXTURE, target GL_TEXTURE_2D, level 0, format 0x8051, 100x100, border 0, dataFormat 0x1907, dataType 0x1401; min/mag 0x2600/0x2600, wrap S/T 0x812f/0x812f; name 0x1, obj 0x711f39f9], null, null, null, null, null, null, null], msaa[null, hasSink false, dirty true], state OK, obj 0xd44fc21],
        FBO back  write 2, FBO[name r/w 2/2, init true, bound true, size 100x100, samples 0/4, modified true/true, depth RenderAttachment[type DEPTH, format 0x81a5, samples 0, 100x100, name 0x2, obj 0x2d6eabae], stencil null, colorbuffer attachments: 1/8, with 1 textures: [TextureAttachment[type COLOR_TEXTURE, target GL_TEXTURE_2D, level 0, format 0x8051, 100x100, border 0, dataFormat 0x1907, dataType 0x1401; min/mag 0x2600/0x2600, wrap S/T 0x812f/0x812f; name 0x2, obj 0x23faf8f2], null, null, null, null, null, null, null], msaa[null, hasSink false, dirty true], state OK, obj 0x4e7dc304],
        Surface   WrappedSurface[ displayHandle 0x0
, surfaceHandle 0x0
, size 100x100
, UOB[ OWNS_SURFACE | OWNS_DEVICE | WINDOW_INVISIBLE | SURFACELESS ]
, MacOSXCGLGraphicsConfiguration[DefaultGraphicsScreen[MacOSXGraphicsDevice[type .macosx, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x64729b1e]], idx 0],
        chosen    GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[fbo]],
        requested GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4/GL4.hw], offscr[auto-cfg]]]
, surfaceLock <10bbd20a, 48503868>[count 1, qsz 0, owner <main>]
, GenericUpstreamSurfacelessHook[pixel 100x100]
, upstreamSurface false ]], mode NSOPENGL]


I am on MacOS BigSur + Silicon.
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
Thank you. Ok you claim that ctxOptions doesn't take the expected value, it would explain your problem.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

Martin
Well, I don't really know what should the value be, do you have hints about this?

Do you know which GL primitive is used to retrieve it and/or what piece of code retrieves?

I gather anything I can find about this in this ticket.
Reply | Threaded
Open this post in threaded view
|

Re: Selecting the highest possible GL profile at runtime.

gouessej
Administrator
It involves some native (C or Objective C) source code for sure.
Julien Gouesse | Personal blog | Website