glReadBuffer() behavior on MAC

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

glReadBuffer() behavior on MAC

stepasite
Hi,

after migration to JOGL2, I have problem when getting/setting value for read buffer on MAC OS X (no problems on Windows).

The code:

   int[] glReadBufferValue = new int[1];
   gl.glGetIntegerv(GL2.GL_READ_BUFFER, glReadBufferValue, 0);

sets GL.GL_COLOR_ATTACHMENT0 value into glReadBufferValue[0]. Strange as I do not use FBOs at all.

Furthermore, when trying set:

gl.getGL2().glReadBuffer(GL.GL_FRONT);

or

gl.getGL2().glReadBuffer(GL.GL_BACK);

I get GL_INVALID_OPERATION error.

Why does this happen? Is FBO used by JOGL2 internally for rendering? Is it possible that GL_FRONT, GL_BACK, etc. constants are not valid for some OpenGL implementations?

Any help would be much appreciated.

Thanks in advance,
Pavel

ps: os OS X 10.7.5, renderer: Intel GMA 950 OpenGL Engine

 
Reply | Threaded
Open this post in threaded view
|

Re: glReadBuffer() behavior on MAC

gouessej
Administrator
Hi

JOGL 2.0 uses FBOs internally in GLJPanel.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: glReadBuffer() behavior on MAC

stepasite
Hi,

thanks for the reply. My app uses javax.media.opengl.awt.GLCanvas for rendering, there is no GLJPanel at all.

Thanks in advance,
Pavel
Reply | Threaded
Open this post in threaded view
|

Re: glReadBuffer() behavior on MAC

gouessej
Administrator
AWT GLCanvas uses CALayer under Mac OS X 10.7, not under Windows. Maybe Sven can confirm whether or not it can cause some troubles with FBOs.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: glReadBuffer() behavior on MAC

Sven Gothel
Administrator
On 01/29/2013 03:33 PM, gouessej [via jogamp] wrote:
> AWT GLCanvas uses CALayer under Mac OS X 10.7, not under Windows. Maybe Sven
> can confirm whether or not it can cause some troubles with FBOs.

Yes, if you must select the read buffer manually via glReadBuffer(..) [GL2, GL3, ..]
you need to use a valid buffer name - which is different in case of FBO usage.

FBO usage can be queried via the chosenGLCapabilities() of the GL[Auto]Drawable.

Here is a copy/paste of GLBase's getDefaultReadBuffer() method 'helper'
you may like to utilize:

   /**
    * Returns the default color buffer within the current bound
    * {@link #getDefaultReadFramebuffer()}, i.e. GL_READ_FRAMEBUFFER,
    * which will be used as the source for pixel reading commands,
    * like {@link GL#glReadPixels(int, int, int, int, int, int, java.nio.Buffer)} etc.
    * <p>
    * For offscreen framebuffer objects this is {@link GL#GL_COLOR_ATTACHMENT0},
    * otherwise this is {@link GL#GL_FRONT} for single buffer configurations
    * and {@link GL#GL_BACK} for double buffer configurations.
    * </p>
    */
   public int getDefaultReadBuffer();

~Sven



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

Re: glReadBuffer() behavior on MAC

stepasite
Hi Sven,

thanks for the reply, I wasn't aware of getDefaultReadBuffer() method. Anyway, I always want to read data from front buffer (from the screen). Is it possible with FBO rendering enabled?

I think it should as:

 glCanvas.getChosenGLCapabilities().getDoubleBuffered();

returns true when:

 glCanvas.getChosenGLCapabilities().isFBO();

returns true.

But I am not sure whether GL_COLOR_ATTACHMENT0 is considered as front or back buffer (in the case that such terminology is meaningful with FBO rendering).


Thanks in advance,
Pavel
Reply | Threaded
Open this post in threaded view
|

Re: glReadBuffer() behavior on MAC

Sven Gothel
Administrator
On 01/29/2013 04:23 PM, stepasite [via jogamp] wrote:
> Hi Sven,
>
> thanks for the reply, I wasn't aware of getDefaultReadBuffer() method. Anyway,
> I always want to read data from front buffer (from the screen). Is it possible
> with FBO rendering enabled?
Of course - all our unit tests creating snapshots via UITestCase.SnapshotGLEventListener
read from the FBO buffer. However to select the buffer, you would need to have it bound.

Our GLFBODrawableImpl reads:

    int getDefaultDrawFramebuffer() { return initialized ? fbos[fboIBack].getWriteFramebuffer() : 0; }
    int getDefaultReadFramebuffer() { return initialized ? fbos[fboIFront].getReadFramebuffer() : 0; }
    int getDefaultReadBuffer(GL gl) { return initialized ? fbos[fboIFront].getDefaultReadBuffer() : GL.GL_COLOR_ATTACHMENT0 ; }

Note-1: You cannot use the back buffer in MSAA mode!

Note-2: We separate front/back buffer via a full FBO object, not by the attachment.
        Hence we always use GL.GL_COLOR_ATTACHMENT0 as the read buffer name.
        Hence you would need to bind the right FBO name to select front/back.
 
FBOObject reads:
    gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
    gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);

This leads to:
    gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, getDefaultDrawFramebuffer());
    gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, getDefaultReadFramebuffer());

This results reading from the front buffer, and draw to the back buffer by default,
as recommended in the GL spec. The latter discourages you to read from the
current draw buffer.

>
> I think it should as:
>
>  glCanvas.getChosenGLCapabilities().getDoubleBuffered();
>
> returns true when:
>
>  glCanvas.getChosenGLCapabilities().isFBO();
>
> returns true.
You can use both queries, yes.
FBO doesn't necessarily imply double buffering, but w/ MSAA enabled.
However, since the default GLCaps has double buffering enabled ..

>
> But I am not sure whether GL_COLOR_ATTACHMENT0 is considered as front or back
> buffer (in the case that such terminology is meaningful with FBO rendering).

See Note-2 above - using [our] FBO, makes it easy to use the front buffer (default)
and hard to use the back buffer - since you need to either switch the FBO
or change the point in time you read the buffer.

You will notice that in our unit tests w/ UITestCase.SnapshotGLEventListener using ReadBufferUtil
we simply don't do anything but call glReadPixels .. hence using the complete front buffer.

Hope it helps.

>
>
> Thanks in advance,
> Pavel
>


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

Re: glReadBuffer() behavior on MAC

stepasite
Sven,

thanks for a thorough description of the problem.

Given your reply I understand that when reading a buffer (when FBO rendering enabled) I always get front buffer data. Reading back buffer would be difficult (maybe impossible) as I don't have access to your FBO objects so I cannot bind the right one. Am I right?

But I think reading pixels just from front buffer is Okay for me as I need to get pixel data once the scene is rendered (and glSwapBuffers() called).

Thanks for your help and clarification!
Pavel

 
Reply | Threaded
Open this post in threaded view
|

Re: glReadBuffer() behavior on MAC

Sven Gothel
Administrator
On 01/29/2013 09:38 PM, stepasite [via jogamp] wrote:
> Sven,
>
> thanks for a thorough description of the problem.
>
> Given your reply I understand that when reading a buffer (when FBO rendering
> enabled) I always get front buffer data. Reading back buffer would be
> difficult (maybe impossible) as I don't have access to your FBO objects so I
> cannot bind the right one. Am I right?

Sort of, yes.

However, you can have access to the FBObject for each framebuffer name (front, back, ..).
GLFBODrawable interface is public:

GLFBODrawable -> GLDrawable
GLOffscreenAutoDrawable.FBO -> GLOffscreenAutoDrawable, GLFBODrawable

So if true == glCaps.isFBO() then you may cast the GLAutoDrawable
instance to GLOffscreenAutoDrawable.FBO and can access the FBO via
  FBObject fbo = ((GLOffscreenAutoDrawable.FBO)autoDrawable).getFBObject(bufferName);
or
  FBObject fbo = ((GLFBODrawable)drawable).getFBObject(bufferName);

So no detail is hidden, all transparent.

>
> But I think reading pixels just from front buffer is Okay for me as I need to
> get pixel data once the scene is rendered (and glSwapBuffers() called).
>
yup


> Thanks for your help and clarification!
> Pavel

~Sven



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

Re: glReadBuffer() behavior on MAC

stepasite
Hi Sven,

got it.

Thanks again,
Pavel