Hello, I'm testing the new FBO-based offscreen Drawable mechanism. So far, I figured out that the GL id's of the draw and read framebuffers can be retrieved with GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer(). For certain applications, I'd also need to access the name of the texture used as the back color buffer, but I haven't found a way to do so. Any suggestions?
|
Administrator
|
On 10/20/2012 04:39 AM, ac [via jogamp] wrote:
> Hello, I'm testing the new FBO-based offscreen Drawable mechanism. So far, I > figured out that the GL id's of the draw and read framebuffers can be > retrieved with GLContext.getDefaultDrawFramebuffer() and > GLContext.getDefaultReadFramebuffer(). For certain applications, I'd also need > to access the name of the texture used as the back color buffer, but I haven't > found a way to do so. Any suggestions? Ofc .. looks at the unit tests, it's a GLFBO[Auto]Drawable what you receive w/ certain factory methods. This FBO specific drawable allows you to retrieve the FBObject, which discloses all the details to you. Details which are inspired by you :) ~Sven signature.asc (907 bytes) Download Attachment |
Hello Sven, thanks for your reply. All this new API to handle the FBOs looks great, but I'm still unsure how to properly integrate with my old code. I've been looking at TestFBOAutoDrawableFactoryNEWT.java, and I think I understand how the unit tests work. Based on that, I added the following code at the end of my JOGL initialization function (where I create the request capabilities, the canvas object, etc):
final GLDrawableFactory factory = GLDrawableFactory.getFactory(profile); GLOffscreenAutoDrawable.FBO glad = (GLOffscreenAutoDrawable.FBO) factory.createOffscreenAutoDrawable(null, capabilities, null, pg.width, pg.height, null); final FBObject fboBack = glad.getFBObject(GL.GL_BACK); final FBObject.TextureAttachment texAttachA = glad.getTextureBuffer(GL.GL_FRONT); final FBObject.TextureAttachment texAttachB = glad.getTextureBuffer(GL.GL_BACK); but the FBO and texture attachment objects are null. I imagine this is because the GL context is still not initialized at that point. In the unit test I see you force the initialization by calling glad.display(), if I insert that call right after GLOffscreenAutoDrawable.FBO glad = ... I get this error: Exception in thread "Animation Thread" java.lang.IllegalArgumentException: Cannot access GL_BACK buffer of MSAA FBO: ResizeableImpl[Initialized true, realized true, texUnit 0, samples 2, Factory jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory@564ac216, Handle 0x1001fb390, .... But shouldn't I be getting the GLOffscreenAutoDrawable.FBO in the display method of the GLEventListener itself? However all I have in GLEventListener.display() is the GLAutoDrawable object, which it seems I cannot cast or use to get the underlying GLOffscreenAutoDrawable.FBO... |
Administrator
|
On 10/20/2012 03:02 PM, ac [via jogamp] wrote:
> Hello Sven, thanks for your reply. All this new API to handle the FBOs looks > great, but I'm still unsure how to properly integrate with my old code. I've > been looking at TestFBOAutoDrawableFactoryNEWT.java, and I think I understand > how the unit tests work. Based on that, I added the following code at the end > of my JOGL initialization function (where I create the request capabilities, > the canvas object, etc): > > final GLDrawableFactory factory = GLDrawableFactory.getFactory(profile); > GLOffscreenAutoDrawable.FBO glad = (GLOffscreenAutoDrawable.FBO) > factory.createOffscreenAutoDrawable(null, capabilities, null, pg.width, > pg.height, null); > final FBObject fboBack = glad.getFBObject(GL.GL_BACK); > final FBObject.TextureAttachment texAttachA = glad.getTextureBuffer(GL.GL_FRONT); > final FBObject.TextureAttachment texAttachB = glad.getTextureBuffer(GL.GL_BACK); > > but the FBO and texture attachment objects are null. I imagine this is because > the GL context is still not initialized at that point. I agree .. maybe a bit hidden :) The unit test mentions the same. <http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/jogl/acore/TestFBOAutoDrawableFactoryNEWT.java;h=2dc547f39b55a2f0541a960a41bbb9437f78834c;hb=HEAD#l152> Maybe you can open a new bug entry for FBO enhancements, where we can mention all these weak points to have a chance to enhance it! > In the unit test I see > you force the initialization by calling glad.display(), if I insert that call > right after GLOffscreenAutoDrawable.FBO glad = ... I get this error: > > Exception in thread "Animation Thread" java.lang.IllegalArgumentException: > Cannot access GL_BACK buffer of MSAA FBO: ResizeableImpl[Initialized true, > realized true, texUnit 0, samples 2, > Factory > jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory@564ac216, > Handle 0x1001fb390, > .... <http://jogamp.org/deployment/archive/master/gluegen_600-joal_366-jogl_833-jocl_691-signed/javadoc/jogl/javadoc/javax/media/opengl/GLFBODrawable.html#getTextureBuffer%28int%29> "If MSAA is being used, only the GL.GL_FRONT buffer is accessible and an exception is being thrown if GL.GL_BACK is being requested." As you know, there is not readable BACK buffer w/ MSAA, i.e. the buffer we render into, only the sampled front buffer texture. The same GL error will happen if attempting to read an FBO BACK buffer, since it must be blitted. (You showed me that code sample once) Well, you can get the FBObject though. > > But shouldn't I be getting the GLOffscreenAutoDrawable.FBO in the display > method of the GLEventListener itself? However all I have in > GLEventListener.display() is the GLAutoDrawable object, which it seems I > cannot cast or use to get the underlying GLOffscreenAutoDrawable.FBO... Sure you can cast it, why not ? Well, we don't use the 'sophisticated' generics stuff here due to history and .. well, is it really that good looking ? :) But since you know what you have created you sure can cast, and/or use reflection/instanceof. You even can simply query a GLAutoDrawable's chosen Capabilities and if it says isFBO()==true .. you should be safe. However .. since this new API is now critical to JOGL due to it's usage in all core classes and especially on OSX, I love to see it being enhanced (See bug/enhancements above). ~Sven signature.asc (907 bytes) Download Attachment |
Ok, I think I'm on track now. If using AWT, then I can do:
protected class PGLListener implements GLEventListener { @Override public void display(GLAutoDrawable adrawable) { GLCanvas canvas = (GLCanvas)adrawable; GLFBODrawable drawable = (GLFBODrawable)canvas.getDelegatedDrawable(); ... and the name of the texture bound to the front FBO can be obtained with: FBObject.TextureAttachment texFront = drawable.getTextureBuffer(GL.GL_FRONT); System.out.println("front texture: " + texFront.getName()); Is this correct? But another route seems to be: FBObject fboFront = drawable.getFBObject(GL.GL_FRONT); System.out.println("number of color attachements: " + fboFront.getColorAttachmentCount()); (prints 1, as expected). But then, how can I get the texture name from here? FBObject has getDepthAttachment() and getStencilAttachment() methods, but not a getColorAttachement()... Should just I use GLFBODrawable.getTextureBuffer()? |
I found it, I only need to cast the color buffer object as a TextureAttachment:
FBObject fboFront = dr.getFBObject(GL.GL_FRONT); FBObject.Colorbuffer colorBuf = fboFront.getColorbuffer(0); FBObject.TextureAttachment texFront = (FBObject.TextureAttachment) colorBuf; System.out.println("front texture: " + texFront.getName()); which seems to be equivalent to FBObject.TextureAttachment texFront = drawable.getTextureBuffer(GL.GL_FRONT). Which method is preferred? Also, in terms of API, it seems to me that FBObject should have a getColorAttachment() method which returns a FBO.ColorAttachment. The texture name could be also queried from it, since it has a name property. Although this lead to three different ways of getting the name of the bound texture. Another question: what should I do if I need to blit the contents of the multisampled back buffer into the front buffer mid-render when using MSAA? Just call swapBuffers()? |
Administrator
|
On 10/20/2012 07:23 PM, ac [via jogamp] wrote:
> I found it, I only need to cast the color buffer object as a TextureAttachment: > > FBObject fboFront = dr.getFBObject(GL.GL_FRONT); > FBObject.Colorbuffer colorBuf = fboFront.getColorbuffer(0); > FBObject.TextureAttachment texFront = (FBObject.TextureAttachment) colorBuf; > System.out.println("front texture: " + texFront.getName()); > > which seems to be equivalent to FBObject.TextureAttachment texFront = > drawable.getTextureBuffer(GL.GL_FRONT). Which method is preferred? > > Also, in terms of API, it seems to me that FBObject should have a > getColorAttachment() method which returns a FBO.ColorAttachment. The texture > name could be also queried from it, since it has a name property. Although > this lead to three different ways of getting the name of the bound texture. > > Another question: what should I do if I need to blit the contents of the > multisampled back buffer into the front buffer mid-render when using MSAA? > Just call swapBuffers()? From the GLFBODrawable perspective yes ofc, it's completely transparent, and uses for OSX CALayer for example, see unit tests w/ auto GLFBODrawables: TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT <http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableGLWindowOnOffscrnCapsNEWT.java;h=da54567771d880daab83eb7fe2e903b21fdd78fa;hb=HEAD> TestGLAutoDrawableDelegateOnOffscrnCapsNEWT <http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLAutoDrawableDelegateOnOffscrnCapsNEWT.java;h=d9e9b2bf340ece3d9f4dd61a4ef2fd256d659fd8;hb=HEAD> Just select FBO in caps, done deal. Internally (GLFBODrawable) you will see that we intercept the swapBuffer signal and issue syncSamplingSink() <http://jogamp.org/deployment/archive/master/gluegen_600-joal_366-jogl_833-jocl_691-signed/javadoc/jogl/javadoc/com/jogamp/opengl/FBObject.html#syncSamplingSink%28javax.media.opengl.GL%29> besides buffer swapping (check the source). ~Sven signature.asc (907 bytes) Download Attachment |
Thanks. I'm trying to get the contents of the texture used as the sink of the MSAA rendering, but still having some issues (for example, rendering the texture results in garbage). My final goal consists in grabbing the contents of the screen at a specific time, and applying a post-processing shader to it.
The following is a simplified snippet of the display() function in my GLEventListener: public void display(GLAutoDrawable drawable) { GLCanvas canvas = (GLCanvas)drawable; GLContext context = drawable.getContext(); GL gl = context.getGL(); // Obtain the texture used a MSAA sink: GLFBODrawable fboDrawable = (GLFBODrawable)canvas.getDelegatedDrawable(); FBObject backFbo = fboDrawable.getFBObject(GL.GL_BACK); FBObject.TextureAttachment texAttach = fboBack.getSamplingSink(); // Draw geometry... * fboBack.syncSamplingSink(gl); fboBack.bind(gl); // Now texAttach should be up-to-date with the geometry rendered in (*) ... Do you see anything drastically wrong here? |
Administrator
|
On 10/24/2012 04:47 AM, ac [via jogamp] wrote:
> Thanks. I'm trying to get the contents of the texture used as the sink of the > MSAA rendering, but still having some issues (for example, rendering the > texture results in garbage). My final goal consists in grabbing the contents > of the screen at a specific time, and applying a post-processing shader to it. > > The following is a simplified snippet of the display() function in my > GLEventListener: > Do you see anything drastically wrong here? Why don't you simply use the FRONT texture/FBO after rendering content and sync the FBO ? Again, the BACK of an MSAA FBO only has a multisampled [unusable] colorbuffer not a texture and cannot be used (due to the OpenGL framebuffer spec). After sampling w/ syncSamplingSink() you can use the FRONT texture. Also be aware that the GLFBOAutoDrawable's intent is to handle swap-buffer and hence deliver the final image. Ofc you can circumvent this by disabling auto-swap buffer. Below I mention a manual swap-buffer step. It would be more clear if you can produce a small complete unit test stating your goals. There is for example a unit test which mixes 2 GLFBODrawable's: TestFBOMix2DemosES2NEWT/FBOMix2DemosES2. The 'inner' offscreen mix source drawables are FBObject and could be GLFBODrawables ofc. The outer drawable is an auto drawable (FBO or onscreen, doesn't matter). However .. I try to comment a bit on your code snippet, maybe it helps: > public void display(GLAutoDrawable drawable) { > GLCanvas canvas = (GLCanvas)drawable; > GLContext context = drawable.getContext(); > GL gl = context.getGL(); > > // Obtain the texture used a MSAA sink: > GLFBODrawable fboDrawable = (GLFBODrawable)canvas.getDelegatedDrawable(); > FBObject backFbo = fboDrawable.getFBObject(GL.GL_BACK); backFbo is the sampling sink, you want FRONT ! Note, FRONT is the last frame's content ! > FBObject.TextureAttachment texAttach = fboBack.getSamplingSink(); > > // Draw geometry... * > > fboBack.syncSamplingSink(gl); > fboBack.bind(gl); > > // Now texAttach should be up-to-date with the geometry rendered in (*) > > ... If you don't want to use the last frames content (see snippet below), but this frames .. you simply need to swap 'one more time' which also will sample the content. This is only required if both rendering contents shall be sampled, otherwise I would use another drawable target! public void display(GLAutoDrawable drawable) { GLContext context = drawable.getContext(); GL gl = context.getGL(); // Draw some stuff 1 // This will do the BACK -> FRONT swap // including MSAA sampling (sync). // Now we can use the FRONT buffer. drawable.swapBuffer(); // Obtain the texture used a MSAA sink: // getDelegatedDrawable() is specified in GLAutoDrawable! final GLFBODrawable fboDrawable = (GLFBODrawable)drawable.getDelegatedDrawable(); final TextureAttachment texAttach = fboDrawable.getTextureBuffer (GL.GL_FRONT); gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit); // DO THAT IF USING MULTI TEX UNITS .. gl.glBindTexture(GL.GL_TEXTURE_2D, texAttach.getName()); // use it .. gl.glEnable(GL.GL_TEXTURE_2D); // if not using ES2 or GLSL!! // now texUnit / texAttach is being used for texturing // use prev. frame texture .. // Draw some stuff 2 } The swapBuffer() will be issued within the current context and (w/ _latest_ JOGL code) will not issue a recursive call w/ GLDrawableHelper but use a direct call of the drawable.swapBuffer(). +++ Let's try a simple use case, where you want to reuse the FRONT buffer of the prev. frame while rendering the current frame. This way you could to some motion blur or whatever .. It is important to understand the 'timing' detail, i.e. front/back buffers and when what get synced/swapped! public void display(GLAutoDrawable drawable) { GLContext context = drawable.getContext(); GL gl = context.getGL(); // Draw some stuff 1 // Obtain the texture used a MSAA sink: // getDelegatedDrawable() is specified in GLAutoDrawable! final GLFBODrawable fboDrawable = (GLFBODrawable)drawable.getDelegatedDrawable(); final TextureAttachment texAttach = fboDrawable.getTextureBuffer (GL.GL_FRONT); gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit); // DO THAT IF USING MULTI TEX UNITS .. gl.glBindTexture(GL.GL_TEXTURE_2D, texAttach.getName()); // use it .. gl.glEnable(GL.GL_TEXTURE_2D); // if not using ES2 or GLSL!! // now texUnit / texAttach is being used for texturing // use prev. frame texture .. // Draw some stuff 2 } +++ Hope this helps a bit. ~Sven signature.asc (907 bytes) Download Attachment |
Free forum by Nabble | Edit this page |