GL_FRAMEBUFFER_SRGB and GLJPanel

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

GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
I just upgraded from jogl version 2.0 (2.0-b58-20120620) to version 2.1 (2.1-b1111-20131010) and experienced an issue with using glEnable(GL_FRAMEBUFFER_SRGB) on both Mac and Windows. GLJPanel used to respect this setting and no longer does (though GLCanvas does respect it in both versions).

*** Example program below ***

import java.awt.Dimension;
import javax.media.opengl.GL;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.BoxLayout;
import javax.swing.JFrame;

// Demonstration program to show that GL_FRAMEBUFFER_SRGB is not
// respected by GLJPanel in JOGL 2.1. The two displayed boxes should
// be the same brightness. The one on the right is wrongly too dark.
public class SrgbDemo extends JFrame implements GLEventListener
{
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new SrgbDemo();
            }
        });
    }
   
        public SrgbDemo() {
        GLCanvas glPanel1 = new GLCanvas(); // correct pale brightness
        GLJPanel glPanel2 = new GLJPanel(); // wrong dark brightness
        glPanel1.setPreferredSize(new Dimension(200, 200));
        glPanel2.setPreferredSize(new Dimension(200, 200));
        getContentPane().setLayout(new BoxLayout(
        getContentPane(), BoxLayout.LINE_AXIS));
        getContentPane().add(glPanel1);
        getContentPane().add(glPanel2);
        glPanel1.addGLEventListener(this);
        glPanel2.addGLEventListener(this);
        pack();
        setVisible(true);
        }

        @Override
        public void display(GLAutoDrawable gad) {
                GL gl = gad.getGL();
                gl.glClear(GL.GL_COLOR_BUFFER_BIT);
        }

        @Override
        public void dispose(GLAutoDrawable arg0) {}

        @Override
        public void init(GLAutoDrawable gad) {
                GL2GL3 gl2gl3 = gad.getGL().getGL2GL3();
                // This next line should raise the brightness of the image
                gl2gl3.glEnable(GL2GL3.GL_FRAMEBUFFER_SRGB);
                gl2gl3.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        }

        @Override
        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
                        int arg4) {}
}


*****
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

Sven Gothel
Administrator
On 10/22/2013 10:24 PM, Christopher Bruns [via jogamp] wrote:
> I just upgraded from jogl version 2.0 (2.0-b58-20120620) to version 2.1
> (2.1-b1111-20131010) and experienced an issue with using
> glEnable(GL_FRAMEBUFFER_SRGB) on both Mac and Windows. GLJPanel used to
> respect this setting and no longer does (though GLCanvas does respect it in
> both versions).

Have a look at 'Warning' remark:
  <https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/awt/GLJPanel.html#fboGLSLVerticalFlip>

You need to enable/disable states at GLEventListener display
to not influence the FBO composition impl. in GLJPanel,
which is 'special'.

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
Thank you for your response Sven. I tried moving the glEnable(GL_FRAMEBUFFER_SRGB) call from the init() method to the display() method, but the unwanted darkness remains. Perhaps I have misunderstood the meaning of your comment?

Christopher
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

Sven Gothel
Administrator
On 10/23/2013 04:59 PM, Christopher Bruns [via jogamp] wrote:
> Thank you for your response Sven. I tried moving the
> glEnable(GL_FRAMEBUFFER_SRGB) call from the init() method to the display()
> method, but the unwanted darkness remains.

.. also add 'glDisable(GL_FRAMEBUFFER_SRGB)'
at the _end_ for your display - so the state change is local
and not impacting GLJPanel's FBO usage ..

That shall shed some light in the pipeline :)

> Perhaps I have misunderstood the
> meaning of your comment?

You just missed a little part of it ..

~Sven




signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
Sorry I'm still having trouble understanding how to do this correctly. I now have both glEnable and glDisable statements in my test program, and the GLJPanel still appears dark. Can you please suggest what might be wrong with my modified test program below?

*******************
import java.awt.Dimension;
import javax.media.opengl.GL;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.BoxLayout;
import javax.swing.JFrame;

// Demonstration program to show that GL_FRAMEBUFFER_SRGB is not
// respected by GLJPanel in JOGL 2.1. The two displayed boxes should
// be the same brightness. The one on the right is wrongly too dark.
@SuppressWarnings("serial")
public class SrgbDemo extends JFrame implements GLEventListener
{
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new SrgbDemo();
            }
        });
    }
   
    public SrgbDemo() {
        GLCanvas glPanel1 = new GLCanvas(); // correct pale brightness
        GLJPanel glPanel2 = new GLJPanel(); // wrong dark brightness
        glPanel1.setPreferredSize(new Dimension(200, 200));
        glPanel2.setPreferredSize(new Dimension(200, 200));
        getContentPane().setLayout(new BoxLayout(
        getContentPane(), BoxLayout.LINE_AXIS));
        getContentPane().add(glPanel1);
        getContentPane().add(glPanel2);
        glPanel1.addGLEventListener(this);
        glPanel2.addGLEventListener(this);
        pack();
        setVisible(true);
    }

        @Override
        public void display(GLAutoDrawable gad) {
                GL gl = gad.getGL();
                GL2GL3 gl2gl3 = gl.getGL2GL3();
                // This next line should raise the brightness of the image
                gl2gl3.glEnable(GL2GL3.GL_FRAMEBUFFER_SRGB);
                gl.glClear(GL.GL_COLOR_BUFFER_BIT);
                gl2gl3.glDisable(GL2GL3.GL_FRAMEBUFFER_SRGB);
        }

        @Override
        public void dispose(GLAutoDrawable arg0) {}

        @Override
        public void init(GLAutoDrawable gad) {
                GL gl = gad.getGL();
                gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
        }

        @Override
        public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3, int arg4)
        {}
}

*******************
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

Sven Gothel
Administrator
On 10/24/2013 09:03 PM, Christopher Bruns [via jogamp] wrote:

> Sorry I'm still having trouble understanding how to do this correctly. I now
> have both glEnable and glDisable statements in my test program, and the
> GLJPanel still appears dark. Can you please suggest what might be wrong with
> my modified test program below?
>
>         @Override
>         public void display(GLAutoDrawable gad) {
>                 GL gl = gad.getGL();
>                 GL2GL3 gl2gl3 = gl.getGL2GL3();
>                 // This next line should raise the brightness of the image
>                 gl2gl3.glEnable(GL2GL3.GL_FRAMEBUFFER_SRGB);
The enable/disable is good.

>                 gl.glClear(GL.GL_COLOR_BUFFER_BIT);

You perform nothing here ?

I was expecting you would at least render something into an FBO
and use it's texture..

So all what happens is .. glClear(..)

>                 gl2gl3.glDisable(GL2GL3.GL_FRAMEBUFFER_SRGB);
>         }
>


signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
Yes, for this test program glClear() is all that is needed to demonstrate the problem, because the glClearColor is a midtone that is strongly affected by the GL_FRAMEBUFFER_SRGB setting. Even if rendering other things would respect the GL_FRAMEBUFFER_SRGB setting, the failure to respect it in glClear() would still represent a problem for me.

Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

Sven Gothel
Administrator
On 10/24/2013 09:17 PM, Christopher Bruns [via jogamp] wrote:
> Yes, for this test program glClear() is all that is needed to demonstrate the
> problem, because the glClearColor is a midtone that is strongly affected by
> the GL_FRAMEBUFFER_SRGB setting. Even if rendering other things would respect
> the GL_FRAMEBUFFER_SRGB setting, the failure to respect it in glClear() would
> still represent a problem for me.
>

In this case, we have a problem w/:

> Have a look at 'Warning' remark:
>   <https://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/awt/GLJPanel.html#fboGLSLVerticalFlip>

.. i.e. the FRAMEBUFFER state ..

If you have a proposal to fix this issue (git patch),
i.e.
  - save this state before we use our GLSL flip FBO
  - disable it
  - GLSL flip
  - re-enable it

you are more than welcome ..

We might should have a GL[234]State (?) class to properly
outline the code, similar to GLTextureState.

Or .. disable GLSL flipping for these [special] cases.

See GLJPanel code ..

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
OK. I might take on this challenge.

Could you please suggest the 1) git branch I should clone to get started, and 2) the location of your issue tracker so I can file this as a formal issue I might address?

It sounds like wrapping that flip code might be the most incisive approach.
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

Sven Gothel
Administrator
On 10/24/2013 09:58 PM, cmbruns [via jogamp] wrote:
> OK. I might take on this challenge.
>
> Could you please suggest the 1) git branch I should clone to get started, and
> 2) the location of your issue tracker so I can file this as a formal issue I
> might address?

Official JOGL repo:
  http://jogamp.org/git/?p=jogl.git;a=summary

If you like to use GitHub [for me to pull from]:
  https://github.com/sgothel/jogl

Both are 1:1 ..

Use the 'master' branch.

>
> It sounds like wrapping that flip code might be the most incisive approach.

This is coded that way already, sure, more encapsulation is always welcome.

Thank you very much!

~Sven



signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

gouessej
Administrator
In reply to this post by cmbruns
cmbruns wrote
2) the location of your issue tracker
https://jogamp.org/bugzilla/

Thank you for your help. I hope GLJPanel will become less painful to use, I don't like those "surprises", when it leaves the OpenGL state machine in an "undesirable" state.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
I entered a bug report at
  https://jogamp.org/bugzilla/show_bug.cgi?id=874

Sorry I spent one day trying to fix this issue myself and I failed to resolve the issue. I am unable to give this more attention in the near future, so I explained what I learned in that issue report, and hopefully someone can carry this further in the future.

In the meantime, I am working around this issue in my own applications by manually applying sRGB color correction as the very last step of my GLSL fragment shaders. Just as GL_FRAMEBUFFER_SRGB was expected to do automatically.

Christopher
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

cmbruns
Is it possible more me to modify the GLSL fragment shader that GLJPanel uses to blit the framebuffer, since this bug has been closed as WONTFIX, and I do not have a general workaround? This way I could insert srgb color correction into that shader. And that shader could thus apply the correction correctly to everything, including glClearColor(), which NEVER gets sRGB correction in recent versions of GLJPanel (jogl 2.1+).

The suggested workarounds do not work for this issue:

1) I tried wrapping my display method inside glEnable(GL_FRAMEBUFFER_SRGB)/glDisable(GL_FRAMEBUFFER_SRGB), but that did not seem to help.

2) I also tried setting the GLJPanel setSkipGLOrientationVerticalFlip(true). Sure, my scene is now rendered upside down, but the sRGB color correction remains unapplied.

3) I tried passing "-Djogl.gljpanel.noglsl" to the JVM, but that did not help.

Do I really need to allocate my own render buffer, render to it, and blit it to the screen myself with my own srgb shader, to get physically correct lighting in my scene? I feel like this puts me on the road toward writing my own replacement for GLJPanel. On Windows and Linux, I am able to kludge a non-broken GLCanvas into my Swing application, but on Mac, GLCanvas is unusable in a Swing container, so I must use GLJPanel. So Mac is the platform I most need a solution for.

Below is an updated version of my demonstration program, including the suggested workarounds. But the problem remains. Any other workaround suggestions?

*********************************

package org.janelia.it.FlyWorkstation.gui.opengl.demo;

import java.awt.Dimension;
import javax.media.opengl.GL;
import javax.media.opengl.GL2GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.BoxLayout;
import javax.swing.JFrame;

// Demonstration program to show that GL_FRAMEBUFFER_SRGB is not
// respected by GLJPanel in JOGL 2.1. The two displayed boxes should
// be the same brightness. The one on the right is wrongly too dark.
// (GL_FRAMEBUFFER_SRGB behavior was correct in JOGL 2.0)
//
// Suggested solution of passing "-Djogl.gljpanel.noglsl" to the JVM does NOT
// resolve the problem.
public class TestSrgbFramebuffer extends JFrame implements GLEventListener
{
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TestSrgbFramebuffer();
            }
        });
    }

    public TestSrgbFramebuffer() {
        // left GLCanvas demonstrates correct paler brightness
        GLCanvas glPanel1 = new GLCanvas();
        // right GLJPanel demonstrates wrong darker brightness
        GLJPanel glPanel2 = new GLJPanel();
       
        // setSkipGLOrientationVerticalFlip(true) does NOT resolve the problem
        glPanel2.setSkipGLOrientationVerticalFlip(true);
       
        glPanel1.setPreferredSize(new Dimension(200, 200));
        glPanel2.setPreferredSize(new Dimension(200, 200));
        getContentPane().setLayout(new BoxLayout(
                getContentPane(), BoxLayout.LINE_AXIS));
        getContentPane().add(glPanel1);
        getContentPane().add(glPanel2);
        glPanel1.addGLEventListener(this);
        glPanel2.addGLEventListener(this);
        pack();
        setVisible(true);
    }

    @Override
    public void display(GLAutoDrawable gad) {
        GL gl = gad.getGL();
       
        // This line should raise the brightness of the image
        gl.glEnable(GL2GL3.GL_FRAMEBUFFER_SRGB);

        // Solid midtone clear color demonstrates the sRGB effect,
        // or lack thereof
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
       
        // glDisable(GL2GL3.GL_FRAMEBUFFER_SRGB) does NOT resolve the problem
        gl.glDisable(GL2GL3.GL_FRAMEBUFFER_SRGB);
    }

    @Override
    public void dispose(GLAutoDrawable arg0) {}

    @Override
    public void init(GLAutoDrawable gad) {
        GL2GL3 gl2gl3 = gad.getGL().getGL2GL3();
       
        // This next line should raise the brightness of the image
        // (moved to display() method, to show futility of one proposed solution)
        // gl2gl3.glEnable(GL2GL3.GL_FRAMEBUFFER_SRGB);
       
        // midtone gray color clearly shows effect of sRGB correction
        // (when it works!)
        gl2gl3.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    }

    @Override
    public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,
            int arg4) {}
}

Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

gouessej
Administrator
Either reopen this bug or create another one (request for enhancement). I understand your position as the workaround has failed in your case.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: GL_FRAMEBUFFER_SRGB and GLJPanel

Sven Gothel
Administrator
In reply to this post by cmbruns
On 02/12/2014 02:40 PM, cmbruns [via jogamp] wrote:

4)
> Is it possible more me to modify the GLSL fragment shader that GLJPanel uses
> to blit the framebuffer,

This would be a possible solution,
i.e. allow the user to pass a custom fragment shader.

> since this bug has been closed as WONTFIX, and I do
> not have a general workaround? This way I could insert srgb color correction
> into that shader. And that shader could thus apply the correction correctly to
> everything, including glClearColor(), which NEVER gets sRGB correction in
> recent versions of GLJPanel (jogl 2.1+).

The bug reflects the GL states .. not the custom pixel format
which is not compatible w/ AWT.

Pls create a new specific bug report focusing on this issue.

>
> The suggested workarounds do not work for this issue:
>
> 1) I tried wrapping my display method inside
> glEnable(GL_FRAMEBUFFER_SRGB)/glDisable(GL_FRAMEBUFFER_SRGB), but that did not
> seem to help.
>
> 2) I also tried setting the GLJPanel setSkipGLOrientationVerticalFlip(true).
> Sure, my scene is now rendered upside down, but the sRGB color correction
> remains unapplied.
This is the _best_ solution IMHO ..

The sRGB color conversion must be performed by your own GLEventListener,
since AWT does not handle such.

>
> 3) I tried passing "-Djogl.gljpanel.noglsl" to the JVM, but that did not help.

Same as above ..

>
> Do I really need to allocate my own render buffer, render to it, and blit it
> to the screen myself with my own srgb shader, to get physically correct
> lighting in my scene?

This is more an AWT restriction than a JOGL one.

> I feel like this puts me on the road toward writing my
> own replacement for GLJPanel. On Windows and Linux, I am able to kludge a
> non-broken GLCanvas into my Swing application, but on Mac, GLCanvas is
> unusable in a Swing container, so I must use GLJPanel. So Mac is the platform
> I most need a solution for.

Even though I don't like using GLJPanel and AWT at all
it surely is a valid use case.

Your suggested solution (4) seems most desirable IMHO
and easy to implement.

Pls note this in your bugreport
and attach your test code as well.

Maybe you can even add (4), i.e. the custom fragment shader hook
to GLJPanel and give us a git pull request / patch.

Thank you!

~Sven




signature.asc (894 bytes) Download Attachment