From e96882ae569c681e1b28da6701bf547f6dd9eda8 Mon Sep 17 00:00:00 2001
From: Sven Gothel <sgothel@jausoft.com>
Date: Mon, 28 Jul 2014 15:29:59 +0200
Subject: Bug 1037 - FBObject/GLFBODrawable: Do not assume using a
 TextureAttachment for a Colorbuffer, also make DEPTH optional.

API Change

+++

In certain cases a TextureAttachment for the FBO's color buffer
is not desired, either for performance reasons where texture functionality
is not required or to avoid texture restrictions like size, etc.

+++

GLFBODrawable shall use TextureAttachment for the FBO's color buffer
and a DEPTH buffer per default.
However, the user shall be allowed to use a plain ColorAttachment (renderbuffer)
and also no DEPTH buffer.

+++

FBObject Details:
 - Colorbuffer interface exposes Attachment details
   like format, size, etc as well as it's implementation
   specifics, isTextureAttachment() and getTextureAttachment() allowing a clean cast and type query.

 - Allow ColorAttachment to be used for non MSAA

 - Make TextureAttachment optional for method 'use(GL, TextureAttachment)'

 - Only validate size against MAX_TEXTURESIZE if using a TextureAttachment

 - API Change:
   - rename: getColorAttachmentCount() -> getColorbufferCount()
   - add: getTextureAttachmentCount()
   - change 'TextureAttachment getSamplingSink()' -> 'Colorbuffer getSamplingSink()'
---
 .../classes/jogamp/opengl/GLFBODrawableImpl.java   | 87 ++++++++++++++++------
 1 file changed, 66 insertions(+), 21 deletions(-)

(limited to 'src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java')

diff --git a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
index 6046527d1..2d0f8f70b 100644
--- a/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLFBODrawableImpl.java
@@ -51,6 +51,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
     private GLCapabilitiesImmutable origParentChosenCaps;
 
     private boolean initialized;
+    private int fboModeBits;
     private int texUnit;
     private int samples;
     private boolean fboResetQuirk;
@@ -89,6 +90,7 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
                                 final GLCapabilitiesImmutable fboCaps, final int textureUnit) {
         super(factory, surface, fboCaps, false);
         this.initialized = false;
+        this.fboModeBits = FBOMODE_USE_TEXTURE | FBOMODE_USE_DEPTH;
 
         this.parent = parent;
         this.origParentChosenCaps = getChosenGLCapabilities(); // just to avoid null, will be reset at initialize(..)
@@ -138,25 +140,56 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
             fboIBack = 0;                // head
             fboIFront = fbos.length - 1; // tail
 
+            final boolean useTexture = 0 != ( FBOMODE_USE_TEXTURE & fboModeBits );
+            final boolean useDepth   = 0 != ( FBOMODE_USE_DEPTH   & fboModeBits );
+            final boolean useStencil = chosenFBOCaps.getStencilBits() > 0;
+            final boolean useAlpha = chosenFBOCaps.getAlphaBits() > 0;
+            final int width = getSurfaceWidth();
+            final int height = getSurfaceHeight();
+
             for(int i=0; i<fbosN; i++) {
                 fbos[i] = new FBObject();
-                fbos[i].reset(gl, getSurfaceWidth(), getSurfaceHeight(), samples, false);
+                fbos[i].reset(gl, width, height, samples, false);
                 if(fbos[i].getNumSamples() != samples) {
                     throw new InternalError("Sample number mismatch: "+samples+", fbos["+i+"] "+fbos[i]);
                 }
-                if(samples > 0) {
-                    fbos[i].attachColorbuffer(gl, 0, chosenFBOCaps.getAlphaBits()>0);
+                if(samples > 0 || !useTexture) {
+                    fbos[i].attachColorbuffer(gl, 0, useAlpha);
                 } else {
-                    fbos[i].attachTexture2D(gl, 0, chosenFBOCaps.getAlphaBits()>0);
+                    fbos[i].attachTexture2D(gl, 0, useAlpha);
                 }
-                if( chosenFBOCaps.getStencilBits() > 0 ) {
-                    fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
-                } else {
+                if( useStencil ) {
+                    if( useDepth ) {
+                        fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+                    } else {
+                        fbos[i].attachRenderbuffer(gl, Attachment.Type.STENCIL, 24);
+                    }
+                } else if( useDepth ) {
                     fbos[i].attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
                 }
+                if(samples > 0) {
+                    final FBObject ssink = new FBObject();
+                    {
+                        ssink.reset(gl, width, height);
+                        if( !useTexture ) {
+                            ssink.attachColorbuffer(gl, 0, useAlpha);
+                        } else {
+                            ssink.attachTexture2D(gl, 0, useAlpha);
+                        }
+                        if( useStencil ) {
+                            if( useDepth ) {
+                                ssink.attachRenderbuffer(gl, Attachment.Type.DEPTH_STENCIL, 24);
+                            } else {
+                                ssink.attachRenderbuffer(gl, Attachment.Type.STENCIL, 24);
+                            }
+                        } else if( useDepth ) {
+                            ssink.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24);
+                        }
+                    }
+                    fbos[i].setSamplingSink(ssink);
+                    fbos[i].resetSamplingSink(gl); // validate
+                }
             }
-            fbos[fboIFront].resetSamplingSink(gl);
-
             fbos[0].formatToGLCapabilities(chosenFBOCaps);
             chosenFBOCaps.setDoubleBuffered( chosenFBOCaps.getDoubleBuffered() || samples > 0 );
         } else {
@@ -414,17 +447,16 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
         fboIBack  = ( fboIBack  + 1 ) % fbos.length;
 
         final Colorbuffer colorbuffer = samples > 0 ? fbos[fboIFront].getSamplingSink() : fbos[fboIFront].getColorbuffer(0);
+        if(null == colorbuffer) {
+            throw new GLException("Front colorbuffer is null: samples "+samples+", "+this);
+        }
         final TextureAttachment texAttachment;
-        if(colorbuffer instanceof TextureAttachment) {
-            texAttachment = (TextureAttachment) colorbuffer;
+        if( colorbuffer.isTextureAttachment() ) {
+            texAttachment = colorbuffer.getTextureAttachment();
+            gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
         } else {
-            if(null == colorbuffer) {
-                throw new GLException("Front colorbuffer is null: samples "+samples+", "+this);
-            } else {
-                throw new GLException("Front colorbuffer is not a texture: "+colorbuffer.getClass().getName()+": samples "+samples+", "+colorbuffer+", "+this);
-            }
+            texAttachment = null;
         }
-        gl.glActiveTexture(GL.GL_TEXTURE0 + texUnit);
         fbos[fboIFront].use(gl, texAttachment);
 
         /* Included in above use command:
@@ -446,6 +478,19 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
         return initialized;
     }
 
+    @Override
+    public final void setFBOMode(final int modeBits) throws IllegalStateException {
+        if( isInitialized() ) {
+            throw new IllegalStateException("Already initialized: "+this);
+        }
+        this.fboModeBits = modeBits;
+    }
+
+    @Override
+    public final int getFBOMode() {
+        return fboModeBits;
+    }
+
     @Override
     public final void resetSize(final GL gl) throws GLException {
         reset(gl, samples);
@@ -519,24 +564,24 @@ public class GLFBODrawableImpl extends GLDrawableImpl implements GLFBODrawable {
     }
 
     @Override
-    public final TextureAttachment getTextureBuffer(final int bufferName) throws IllegalArgumentException {
+    public final Colorbuffer getColorbuffer(final int bufferName) throws IllegalArgumentException {
         if(!initialized) {
             return null;
         }
-        final TextureAttachment res;
+        final Colorbuffer res;
         switch(bufferName) {
             case GL.GL_FRONT:
                 if( samples > 0 ) {
                     res = fbos[0].getSamplingSink();
                 } else {
-                    res = (TextureAttachment) fbos[fboIFront].getColorbuffer(0);
+                    res = fbos[fboIFront].getColorbuffer(0);
                 }
                 break;
             case GL.GL_BACK:
                 if( samples > 0 ) {
                     throw new IllegalArgumentException("Cannot access GL_BACK buffer of MSAA FBO: "+this);
                 } else {
-                    res = (TextureAttachment) fbos[fboIBack].getColorbuffer(0);
+                    res = fbos[fboIBack].getColorbuffer(0);
                 }
                 break;
             default:
-- 
cgit v1.2.3