From e96882ae569c681e1b28da6701bf547f6dd9eda8 Mon Sep 17 00:00:00 2001
From: Sven Gothel Always an instance of {@link Attachment}. Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.
*/
public static interface Colorbuffer {
/**
@@ -76,23 +75,55 @@ public class FBObject {
* @return
+ * For GLES3, sampling-sink {@link Colorbuffer} format must be equal w/ the sampling-source {@link Colorbuffer}.
+ * Implementation aligns w/ {@link #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int)}
+ * and is enforced via {@link #sampleSinkFormatMismatch(GL)}.
+ *
- * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingTextureSink()}.
* Leaves the FBO bound, if initialized!
- * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingTextureSink()}.
* Leaves the FBO bound, if initialized!
- * An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
+ * An attached sampling sink texture will be detached as well, see {@link #getSamplingTextureSink()}.
*
* Method also resets the sampling sink configuration via {@link #resetSamplingSink(GL)} if used and required.
* If using multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first! If using a {@link TextureAttachment} and multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first! {@link #syncSamplingSink(GL)} is being called Leaves the FBO unbound!true
if newly initialized, otherwise false
.
* @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
*/
- public boolean initialize(GL gl) throws GLException;
+ boolean initialize(GL gl) throws GLException;
/**
* Releases the color buffer if initialized, i.e. name is not zero
.
* @throws GLException if buffer release fails.
*/
- public void free(GL gl) throws GLException;
+ void free(GL gl) throws GLException;
/**
* Writes the internal format to the given GLCapabilities object.
* @param caps the destination for format bits
* @param rgba8Avail whether rgba8 is available
*/
- public void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);
+ void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);
+
+ /**
+ * Returns true
if instance is of type {@link TextureAttachment}
+ * and false
if instance is of type {@link ColorAttachment}.
+ */
+ boolean isTextureAttachment();
+
+ /**
+ * Casts this object to a {@link TextureAttachment} reference, see {@link #isTextureAttachment()}.
+ * @throws GLException if this object is not of type {@link TextureAttachment}
+ * @see #isTextureAttachment()
+ */
+ TextureAttachment getTextureAttachment();
+
+ /**
+ * Casts this object to a {@link ColorAttachment} reference, see {@link #isTextureAttachment()}.
+ * @throws GLException if this object is not of type {@link ColorAttachment}
+ * @see #isTextureAttachment()
+ */
+ ColorAttachment getColorAttachment();
+
+ /** internal format of colorbuffer */
+ int getFormat();
+
+ /** width of colorbuffer */
+ int getWidth();
+
+ /** height of colorbuffer */
+ int getHeight();
+
+ /** colorbuffer name [1..max] */
+ int getName();
}
- /** Common super class of all attachments */
+ /** Common super class of all FBO attachments */
public static abstract class Attachment {
public enum Type {
NONE, DEPTH, STENCIL, DEPTH_STENCIL, COLOR, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE;
@@ -220,6 +251,9 @@ public class FBObject {
}
}
+ /** immutable internal format of attachment */
+ public final int getFormat() { return format; }
+
/** width of attachment */
public final int getWidth() { return width; }
/** height of attachment */
@@ -423,14 +457,21 @@ public class FBObject {
}
}
- /** Color render buffer attachment */
+ /** Color render buffer FBO attachment */
public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
public ColorAttachment(final int iFormat, final int samples, final int width, final int height, final int name) {
super(Type.COLOR, iFormat, samples, width, height, name);
}
+ @Override
+ public final boolean isTextureAttachment() { return false; }
+ @Override
+ public final TextureAttachment getTextureAttachment() { throw new GLException("Not a TextureAttachment, but ColorAttachment"); }
+ @Override
+ public final ColorAttachment getColorAttachment() { return this; }
+
}
- /** Texture attachment */
+ /** Texture FBO attachment */
public static class TextureAttachment extends Attachment implements Colorbuffer {
/** details of the texture setup */
public final int dataFormat, dataType, magFilter, minFilter, wrapS, wrapT;
@@ -530,6 +571,14 @@ public class FBObject {
setName(0);
}
}
+
+ @Override
+ public final boolean isTextureAttachment() { return true; }
+ @Override
+ public final TextureAttachment getTextureAttachment() { return this; }
+ @Override
+ public final ColorAttachment getColorAttachment() { throw new GLException("Not a ColorAttachment, but TextureAttachment"); }
+
@Override
public String toString() {
return getClass().getSimpleName()+"[type "+type+", target GL_TEXTURE_2D, level 0, format "+toHexString(format)+
@@ -677,12 +726,13 @@ public class FBObject {
private int fbName;
private boolean bound;
- private int colorAttachmentCount;
- private Colorbuffer[] colorAttachmentPoints; // colorbuffer attachment points
+ private int colorbufferCount;
+ private int textureAttachmentCount;
+ private Colorbuffer[] colorbufferAttachments; // colorbuffer attachment points
private RenderAttachment depth, stencil; // depth and stencil maybe equal in case of packed-depth-stencil
private FBObject samplingSink; // MSAA sink
- private TextureAttachment samplingSinkTexture;
+ private Colorbuffer samplingColorSink;
private boolean samplingSinkDirty;
//
@@ -693,8 +743,8 @@ public class FBObject {
if(!initialized) {
throw new GLException("FBO not initialized");
}
- if(maxColorAttachments != colorAttachmentPoints.length) {
- throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.length "+colorAttachmentPoints.length);
+ if(maxColorAttachments != colorbufferAttachments.length) {
+ throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.length "+colorbufferAttachments.length);
}
if(0 > point || point >= maxColorAttachments) {
throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"], "+this);
@@ -703,29 +753,35 @@ public class FBObject {
private final void validateAddColorAttachment(final int point, final Colorbuffer ca) {
validateColorAttachmentPointRange(point);
- if( null != colorAttachmentPoints[point] ) {
- throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]+", "+this);
+ if( null != colorbufferAttachments[point] ) {
+ throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorbufferAttachments[point]+", "+this);
}
}
private final void addColorAttachment(final int point, final Colorbuffer ca) {
validateColorAttachmentPointRange(point);
- final Colorbuffer c = colorAttachmentPoints[point];
+ final Colorbuffer c = colorbufferAttachments[point];
if( null != c && c != ca ) {
throw new IllegalArgumentException("Add failed: requested to add "+ca+" at "+point+", but slot is holding "+c+"; "+this);
}
- colorAttachmentPoints[point] = ca;
- colorAttachmentCount++;
+ colorbufferAttachments[point] = ca;
+ colorbufferCount++;
+ if( ca.isTextureAttachment() ) {
+ textureAttachmentCount++;
+ }
}
private final void removeColorAttachment(final int point, final Colorbuffer ca) {
validateColorAttachmentPointRange(point);
- final Colorbuffer c = colorAttachmentPoints[point];
+ final Colorbuffer c = colorbufferAttachments[point];
if( null != c && c != ca ) {
throw new IllegalArgumentException("Remove failed: requested to removed "+ca+" at "+point+", but slot is holding "+c+"; "+this);
}
- colorAttachmentPoints[point] = null;
- colorAttachmentCount--;
+ colorbufferAttachments[point] = null;
+ colorbufferCount--;
+ if( ca.isTextureAttachment() ) {
+ textureAttachmentCount--;
+ }
}
/**
@@ -738,7 +794,7 @@ public class FBObject {
*/
public final Colorbuffer getColorbuffer(final int attachmentPoint) {
validateColorAttachmentPointRange(attachmentPoint);
- return colorAttachmentPoints[attachmentPoint];
+ return colorbufferAttachments[attachmentPoint];
}
/**
@@ -751,8 +807,8 @@ public class FBObject {
* @return -1 if the {@link Colorbuffer} could not be found, otherwise [0..{@link #getMaxColorAttachments()}-1]
*/
public final int getColorbufferAttachmentPoint(final Colorbuffer ca) {
- for(int i=0; itrue
if you request alpha channel, otherwise false
;
+ * @return uninitialized ColorAttachment instance describing the new attached colorbuffer
+ */
+ public static final ColorAttachment createColorAttachment(final int internalFormat, final int samples, final int width, final int height) {
+ return new ColorAttachment(internalFormat, samples, width, height, 0 /* name not yet determined */);
+ }
+
+ public static final RenderAttachment createRenderAttachment(final Type type, final int internalFormat, final int samples, final int width, final int height) {
+ return new RenderAttachment(type, internalFormat, samples, width, height, 0 /* name not yet determined */);
}
/**
@@ -1283,7 +1373,7 @@ public class FBObject {
* @see #createColorAttachment(boolean)
*/
public final ColorAttachment attachColorbuffer(final GL gl, final int attachmentPoint, final boolean alpha) throws GLException {
- return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha));
+ return attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha)).getColorAttachment();
}
/**
@@ -1304,7 +1394,7 @@ public class FBObject {
throw new IllegalArgumentException("colorformat invalid: "+toHexString(internalFormat)+", "+this);
}
- return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
+ return attachColorbuffer(gl, attachmentPoint, createColorAttachment(internalFormat, samples, width, height)).getColorAttachment();
}
/**
@@ -1337,10 +1427,9 @@ public class FBObject {
final boolean initializedColorbuf = colbuf.initialize(gl);
addColorAttachment(attachmentPoint, colbuf);
- if(colbuf instanceof TextureAttachment) {
- final TextureAttachment texA = (TextureAttachment) colbuf;
-
- if(samples>0) {
+ if( colbuf.isTextureAttachment() ) {
+ final TextureAttachment texA = colbuf.getTextureAttachment();
+ if( samples > 0 ) {
removeColorAttachment(attachmentPoint, texA);
if(initializedColorbuf) {
texA.free(gl);
@@ -1360,8 +1449,8 @@ public class FBObject {
throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
}
}
- } else if(colbuf instanceof ColorAttachment) {
- final ColorAttachment colA = (ColorAttachment) colbuf;
+ } else {
+ final ColorAttachment colA = colbuf.getColorAttachment();
// Attach the color buffer
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
@@ -1516,7 +1605,7 @@ public class FBObject {
private final void attachRenderbufferImpl2(final GL gl, final Attachment.Type atype, final int internalFormat) throws GLException {
if( Attachment.Type.DEPTH == atype ) {
if(null == depth) {
- depth = new RenderAttachment(Type.DEPTH, internalFormat, samples, width, height, 0);
+ depth = createRenderAttachment(Type.DEPTH, internalFormat, samples, width, height);
} else {
depth.setSize(width, height);
depth.setSamples(samples);
@@ -1524,7 +1613,7 @@ public class FBObject {
depth.initialize(gl);
} else if( Attachment.Type.STENCIL == atype ) {
if(null == stencil) {
- stencil = new RenderAttachment(Type.STENCIL, internalFormat, samples, width, height, 0);
+ stencil = createRenderAttachment(Type.STENCIL, internalFormat, samples, width, height);
} else {
stencil.setSize(width, height);
stencil.setSamples(samples);
@@ -1535,7 +1624,7 @@ public class FBObject {
if(null != stencil) {
throw new InternalError("XXX: DEPTH_STENCIL, depth was null, stencil not: "+this.toString());
}
- depth = new RenderAttachment(Type.DEPTH_STENCIL, internalFormat, samples, width, height, 0);
+ depth = createRenderAttachment(Type.DEPTH_STENCIL, internalFormat, samples, width, height);
} else {
depth.setSize(width, height);
depth.setSamples(samples);
@@ -1581,7 +1670,7 @@ public class FBObject {
public final Colorbuffer detachColorbuffer(final GL gl, final int attachmentPoint, final boolean dispose) throws IllegalArgumentException {
bind(gl);
- final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
+ final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE, 0);
if(null == res) {
throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);
}
@@ -1591,8 +1680,8 @@ public class FBObject {
return res;
}
- private final Colorbuffer detachColorbufferImpl(final GL gl, final int attachmentPoint, final DetachAction detachAction) {
- Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+ private final Colorbuffer detachColorbufferImpl(final GL gl, final int attachmentPoint, final DetachAction detachAction, final int sampleCountChange) {
+ Colorbuffer colbuf = colorbufferAttachments[attachmentPoint]; // shortcut, don't validate here
if(null == colbuf) {
return null;
@@ -1600,8 +1689,8 @@ public class FBObject {
removeColorAttachment(attachmentPoint, colbuf);
- if(colbuf instanceof TextureAttachment) {
- final TextureAttachment texA = (TextureAttachment) colbuf;
+ if( colbuf.isTextureAttachment() ) {
+ final TextureAttachment texA = colbuf.getTextureAttachment();
if( 0 != texA.getName() ) {
gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
@@ -1616,17 +1705,17 @@ public class FBObject {
}
}
if(DetachAction.RECREATE == detachAction) {
- if(samples == 0) {
- // stay non MSAA
- texA.setSize(width, height);
- } else {
- // switch to MSAA
+ if( 0 < sampleCountChange ) {
+ // switch to MSAA: TextureAttachment -> ColorAttachment
colbuf = createColorAttachment(hasAlpha(texA.format));
+ } else {
+ // keep MSAA settings
+ texA.setSize(width, height);
}
attachColorbufferImpl(gl, attachmentPoint, colbuf);
}
- } else if(colbuf instanceof ColorAttachment) {
- final ColorAttachment colA = (ColorAttachment) colbuf;
+ } else {
+ final ColorAttachment colA = colbuf.getColorAttachment();
if( 0 != colA.getName() ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
@@ -1640,19 +1729,22 @@ public class FBObject {
}
}
if(DetachAction.RECREATE == detachAction) {
- if(samples > 0) {
- // stay MSAA
+ if( 0 <= sampleCountChange || null == samplingColorSink ) {
+ // keep ColorAttachment,
+ // including 'switch to non-MSAA' if no samplingColorSink is available
+ // to determine whether a TextureAttachment or ColorAttachment is desired!
colA.setSize(width, height);
colA.setSamples(samples);
} else {
// switch to non MSAA
- if(null != samplingSinkTexture) {
- colbuf = createColorTextureAttachment(samplingSinkTexture.format, width, height,
- samplingSinkTexture.dataFormat, samplingSinkTexture.dataType,
- samplingSinkTexture.magFilter, samplingSinkTexture.minFilter,
- samplingSinkTexture.wrapS, samplingSinkTexture.wrapT);
+ if( samplingColorSink.isTextureAttachment() ) {
+ final TextureAttachment samplingTextureSink = samplingColorSink.getTextureAttachment();
+ colbuf = createColorTextureAttachment(samplingTextureSink.format, width, height,
+ samplingTextureSink.dataFormat, samplingTextureSink.dataType,
+ samplingTextureSink.magFilter, samplingTextureSink.minFilter,
+ samplingTextureSink.wrapS, samplingTextureSink.wrapT);
} else {
- colbuf = createColorTextureAttachment(gl, true, width, height);
+ colbuf = createColorAttachment(samplingColorSink.getFormat(), 0, width, height);
}
}
attachColorbuffer(gl, attachmentPoint, colbuf);
@@ -1663,14 +1755,14 @@ public class FBObject {
private final void freeAllColorbufferImpl(final GL gl) {
for(int i=0; inull
.
*
- * null
in case no {@link TextureAttachment} is used.
* @throws IllegalArgumentException
*/
public final void use(final GL gl, final TextureAttachment ta) throws IllegalArgumentException {
- if(null == ta) { throw new IllegalArgumentException("Null TextureAttachment, this: "+toString()); }
syncSamplingSink(gl);
- gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
+ if( null != ta ) {
+ gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
+ }
}
/**
@@ -2369,8 +2479,10 @@ public class FBObject {
/** Returns the framebuffer name to read from. Depending on multisampling, this may be a different framebuffer. */
public final int getReadFramebuffer() { return ( samples > 0 ) ? samplingSink.getReadFramebuffer() : fbName; }
public final int getDefaultReadBuffer() { return GL.GL_COLOR_ATTACHMENT0; }
- /** Return the number of color/texture attachments */
- public final int getColorAttachmentCount() { return colorAttachmentCount; }
+ /** Return the number of attached {@link Colorbuffer}s */
+ public final int getColorbufferCount() { return colorbufferCount; }
+ /** Return the number of attached {@link TextureAttachment}s */
+ public final int getTextureAttachmentCount() { return textureAttachmentCount; }
/** Return the stencil {@link RenderAttachment} attachment, if exist. Maybe share the same {@link Attachment#getName()} as {@link #getDepthAttachment()}, if packed depth-stencil is being used. */
public final RenderAttachment getStencilAttachment() { return stencil; }
/** Return the depth {@link RenderAttachment} attachment. Maybe share the same {@link Attachment#getName()} as {@link #getStencilAttachment()}, if packed depth-stencil is being used. */
@@ -2379,8 +2491,9 @@ public class FBObject {
/** Return the complete multisampling {@link FBObject} sink, if using multisampling. */
public final FBObject getSamplingSinkFBO() { return samplingSink; }
- /** Return the multisampling {@link TextureAttachment} sink, if using multisampling. */
- public final TextureAttachment getSamplingSink() { return samplingSinkTexture; }
+ /** Return the multisampling {@link Colorbuffer} sink, if using multisampling. */
+ public final Colorbuffer getSamplingSink() { return samplingColorSink; }
+
/**
* Returns true
if the multisampling colorbuffer (msaa-buffer)
* has been flagged dirty by a previous call of {@link #bind(GL)},
@@ -2392,11 +2505,11 @@ public class FBObject {
@Override
public final String toString() {
- final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ;
+ final String caps = null != colorbufferAttachments ? Arrays.asList(colorbufferAttachments).toString() : null ;
return "FBO[name r/w "+fbName+"/"+getReadFramebuffer()+", init "+initialized+", bound "+bound+", size "+width+"x"+height+
", samples "+samples+"/"+maxSamples+", depth "+depth+", stencil "+stencil+
- ", color attachments: "+colorAttachmentCount+"/"+maxColorAttachments+
- ": "+caps+", msaa["+samplingSinkTexture+", hasSink "+(null != samplingSink)+
+ ", colorbuffer attachments: "+colorbufferCount+"/"+maxColorAttachments+", with "+textureAttachmentCount+" textures"+
+ ": "+caps+", msaa["+samplingColorSink+", hasSink "+(null != samplingSink)+
", dirty "+samplingSinkDirty+"], state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]";
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoClientRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoClientRenderer.java
index 0801b65fa..c9445b74f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoClientRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/stereo/StereoClientRenderer.java
@@ -105,7 +105,7 @@ public class StereoClientRenderer implements GLEventListener {
}
fbos[i].setSamplingSink(ssink);
fbos[i].resetSamplingSink(gl); // validate
- fboTexs[i] = fbos[i].getSamplingSink();
+ fboTexs[i] = fbos[i].getSamplingSink().getTextureAttachment();
} else {
fboTexs[i] = fbos[i].attachTexture2D(gl, 0, false, magFilter, minFilter, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
fbos[i].attachRenderbuffer(gl, Type.DEPTH, 24);
@@ -125,9 +125,9 @@ public class StereoClientRenderer implements GLEventListener {
}
numSamples = fbos[i].getNumSamples();
if(numSamples>0) {
- fboTexs[i] = fbos[i].getSamplingSink();
+ fboTexs[i] = fbos[i].getSamplingSink().getTextureAttachment();
} else {
- fboTexs[i] = (TextureAttachment) fbos[i].getColorbuffer(0);
+ fboTexs[i] = fbos[i].getColorbuffer(0).getTextureAttachment();
}
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
index a34fca0fa..f423e0ee4 100644
--- a/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLFBODrawable.java
@@ -31,6 +31,8 @@ package javax.media.opengl;
import javax.media.nativewindow.NativeWindowException;
import com.jogamp.opengl.FBObject;
+import com.jogamp.opengl.FBObject.Colorbuffer;
+import com.jogamp.opengl.FBObject.ColorAttachment;
import com.jogamp.opengl.FBObject.TextureAttachment;
/**
@@ -62,12 +64,12 @@ import com.jogamp.opengl.FBObject.TextureAttachment;
*
* It would be possible to implement double buffering simply using - * {@link TextureAttachment}s with one {@link FBObject framebuffer}. + * {@link Colorbuffer}s with one {@link FBObject framebuffer}. * This would require mode selection and hence complicate the API. Besides, it would * not support differentiation of read and write framebuffer and hence not be spec compliant. *
*- * Actual swapping of the {@link TextureAttachment texture}s and/or {@link FBObject framebuffer} + * Actual swapping of the {@link Colorbuffer}s and/or {@link FBObject framebuffer} * is performed either in the {@link jogamp.opengl.GLContextImpl#contextMadeCurrent(boolean) context current hook} * or when {@link jogamp.opengl.GLDrawableImpl#swapBuffersImpl(boolean) swapping buffers}, whatever comes first. *
@@ -75,11 +77,35 @@ import com.jogamp.opengl.FBObject.TextureAttachment; public interface GLFBODrawable extends GLDrawable { // public enum DoubleBufferMode { NONE, TEXTURE, FBO }; // TODO: Add or remove TEXTURE (only) DoubleBufferMode support + /** FBO Mode Bit: Use a {@link TextureAttachment} for the {@link #getColorbuffer(int) render colorbuffer} ({@link #FBOMODE_DEFAULT default}), see {@link #setFBOMode(int)}. */ + public static final int FBOMODE_USE_TEXTURE = 1 << 0; + /** FBO Mode Bit: Use a depth renderbuffer ({@link #FBOMODE_DEFAULT default}), see {@link #setFBOMode(int)}. */ + public static final int FBOMODE_USE_DEPTH = 1 << 1; + + /** FBO Default Mode Bit: {@link #FBOMODE_USE_TEXTURE} | {@link #FBOMODE_USE_DEPTH}. */ + public static final int FBOMODE_DEFAULT = FBOMODE_USE_TEXTURE | FBOMODE_USE_DEPTH; + /** * @returntrue
if initialized, i.e. a {@link GLContext} is bound and made current once, otherwise false
.
*/
public boolean isInitialized();
+ /**
+ * Set the FBO mode bits used for FBO creation.
+ * + * See {@link #FBOMODE_DEFAULT} values. + *
+ * + * @param modeBits custom FBO mode bits like {@link #FBOMODE_USE_TEXTURE} and {@link #FBOMODE_USE_DEPTH}. + * @throws IllegalStateException if the underlying FBO is already {@link #isInitialized()}. + */ + void setFBOMode(final int modeBits) throws IllegalStateException; + + /** + * @return the used FBO mode bits, mutable via {@link #setFBOMode(int)} + */ + int getFBOMode(); + /** * Notify this instance about upstream size change * to reconfigure the {@link FBObject}. @@ -87,7 +113,7 @@ public interface GLFBODrawable extends GLDrawable { * A prev. current context will be make current after operation. * @throws GLException if resize operation failed */ - void resetSize(GL gl) throws GLException; + void resetSize(final GL gl) throws GLException; /** * @return the used texture unit @@ -98,7 +124,7 @@ public interface GLFBODrawable extends GLDrawable { * * @param unit the texture unit to be used */ - void setTextureUnit(int unit); + void setTextureUnit(final int unit); /** * Set the number of sample buffers if using MSAA @@ -108,7 +134,7 @@ public interface GLFBODrawable extends GLDrawable { * @param newSamples new sample size * @throws GLException if resetting the FBO failed */ - void setNumSamples(GL gl, int newSamples) throws GLException; + void setNumSamples(final GL gl, final int newSamples) throws GLException; /** * @return the number of sample buffers if using MSAA, otherwise 0 @@ -126,7 +152,7 @@ public interface GLFBODrawable extends GLDrawable { * @return the new number of buffers (FBO) used, maybe different than the requestedbufferCount
(see above)
* @throws GLException if already initialized, see {@link #isInitialized()}.
*/
- int setNumBuffers(int bufferCount) throws GLException;
+ int setNumBuffers(final int bufferCount) throws GLException;
/**
* @return the number of buffers (FBO) being used. 1 if not using {@link GLCapabilities#getDoubleBuffered() double buffering},
@@ -162,19 +188,24 @@ public interface GLFBODrawable extends GLDrawable {
* @return the named {@link FBObject}
* @throws IllegalArgumentException if an illegal buffer name is being used
*/
- FBObject getFBObject(int bufferName) throws IllegalArgumentException;
+ FBObject getFBObject(final int bufferName) throws IllegalArgumentException;
/**
- * Returns the named texture buffer.
+ * Returns the named {@link Colorbuffer} instance.
* * If MSAA is being used, only the {@link GL#GL_FRONT} buffer is accessible * and an exception is being thrown if {@link GL#GL_BACK} is being requested. *
+ *+ * Depending on the {@link #setFBOMode(int) fbo mode} the resulting {@link Colorbuffer} + * is either a {@link TextureAttachment} ({@link #FBOMODE_DEFAULT default}) or a {@link ColorAttachment}, + * see {@link Colorbuffer#isTextureAttachment()}. + *
* @param bufferName {@link GL#GL_FRONT} and {@link GL#GL_BACK} are valid buffer names - * @return the named {@link TextureAttachment} + * @return the named {@link Colorbuffer} * @throws IllegalArgumentException if using MSAA and {@link GL#GL_BACK} is requested or an illegal buffer name is being used */ - FBObject.TextureAttachment getTextureBuffer(int bufferName) throws IllegalArgumentException; + Colorbuffer getColorbuffer(final int bufferName) throws IllegalArgumentException; /** Resizeable {@link GLFBODrawable} specialization */ public interface Resizeable extends GLFBODrawable { diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index f0ba08c3e..40fc1001f 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -1812,7 +1812,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing // perform vert-flipping via OpenGL/FBO final GLFBODrawable fboDrawable = (GLFBODrawable)offscreenDrawable; - final FBObject.TextureAttachment fboTex = fboDrawable.getTextureBuffer(GL.GL_FRONT); + final FBObject.TextureAttachment fboTex = fboDrawable.getColorbuffer(GL.GL_FRONT).getTextureAttachment(); fboFlipped.bind(gl); diff --git a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java index fa81e2a3f..ca50b5d2d 100644 --- a/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java +++ b/src/jogl/classes/jogamp/graph/curve/opengl/VBORegion2PMSAAES2.java @@ -427,7 +427,7 @@ public class VBORegion2PMSAAES2 extends GLRegion { gl.glActiveTexture(GL.GL_TEXTURE0 + gcu_FboTexUnit.intValue()); - fbo.use(gl, fbo.getSamplingSink()); + fbo.use(gl, fbo.getSamplingSink().getTextureAttachment()); gca_FboVerticesAttr.enableBuffer(gl, true); gca_FboTexCoordsAttr.enableBuffer(gl, true); indicesFbo.bindBuffer(gl, true); // keeps VBO binding @@ -457,7 +457,10 @@ public class VBORegion2PMSAAES2 extends GLRegion { fbo.reset(gl, fboWidth, fboHeight, sampleCount[0], false); sampleCount[0] = fbo.getNumSamples(); fbo.attachColorbuffer(gl, 0, true); - fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + if( !blendingEnabled ) { + // no depth-buffer w/ blending + fbo.attachRenderbuffer(gl, Attachment.Type.DEPTH, 24); + } final FBObject ssink = new FBObject(); { ssink.reset(gl, fboWidth, fboHeight); 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