summaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp/opengl/FBObject.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes/com/jogamp/opengl/FBObject.java')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java790
1 files changed, 397 insertions, 393 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 7060bb7d1..72041a389 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -46,7 +46,7 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
/**
* Core utility class simplifying usage of framebuffer objects (FBO)
- * with all {@link GLProfile}s.
+ * with all {@link GLProfile}s.
* <p>
* Supports on-the-fly reconfiguration of dimension and multisample buffers via {@link #reset(GL, int, int, int, boolean)}
* while preserving the {@link Attachment} references.
@@ -55,50 +55,50 @@ import com.jogamp.opengl.FBObject.Attachment.Type;
* Integrates default read/write framebuffers via {@link GLContext#getDefaultReadFramebuffer()} and {@link GLContext#getDefaultReadFramebuffer()},
* which is being hooked at {@link GL#glBindFramebuffer(int, int)} when the default (<code>zero</code>) framebuffer is selected.
* </p>
- *
+ *
* <p>FIXME: Implement support for {@link Type#DEPTH_TEXTURE}, {@link Type#STENCIL_TEXTURE} .</p>
*/
public class FBObject {
protected static final boolean DEBUG = Debug.debug("FBObject");
private static final boolean FBOResizeQuirk = false;
-
+
private static enum DetachAction { NONE, DISPOSE, RECREATE };
-
- /**
+
+ /**
* Marker interface, denotes a color buffer attachment.
* <p>Always an instance of {@link Attachment}.</p>
- * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b>
+ * <p>Either an instance of {@link ColorAttachment} or {@link TextureAttachment}.</b>
*/
- public static interface Colorbuffer {
- /**
+ public static interface Colorbuffer {
+ /**
* Initializes the color buffer and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
* @return <code>true</code> if newly initialized, otherwise <code>false</code>.
- * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ * @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;
-
- /**
+
+ /**
* Releases the color buffer if initialized, i.e. name is not <code>zero</code>.
- * @throws GLException if buffer release fails.
+ * @throws GLException if buffer release fails.
*/
public 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);
+ public void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail);
}
-
+
/** Common super class of all attachments */
public static abstract class Attachment {
- public enum Type {
+ public enum Type {
NONE, DEPTH, STENCIL, DEPTH_STENCIL, COLOR, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE;
-
- /**
+
+ /**
* Returns {@link #COLOR}, {@link #DEPTH}, {@link #STENCIL} or {@link #DEPTH_STENCIL}
- * @throws IllegalArgumentException if <code>format</code> cannot be handled.
+ * @throws IllegalArgumentException if <code>format</code> cannot be handled.
*/
public static Type determine(int format) throws IllegalArgumentException {
switch(format) {
@@ -120,20 +120,20 @@ public class FBObject {
return Type.DEPTH_STENCIL;
default:
throw new IllegalArgumentException("format invalid: "+toHexString(format));
- }
+ }
}
};
-
+
/** immutable type [{@link #COLOR}, {@link #DEPTH}, {@link #STENCIL}, {@link #COLOR_TEXTURE}, {@link #DEPTH_TEXTURE}, {@link #STENCIL_TEXTURE} ] */
public final Type type;
-
+
/** immutable the internal format */
public final int format;
-
+
private int width, height;
-
+
private int name;
-
+
protected Attachment(Type type, int iFormat, int width, int height, int name) {
this.type = type;
this.format = iFormat;
@@ -141,18 +141,18 @@ public class FBObject {
this.height = height;
this.name = name;
}
-
+
/**
* Writes the internal format to the given GLCapabilities object.
* @param caps the destination for format bits
* @param rgba8Avail whether rgba8 is available
*/
- public final void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail) {
+ public final void formatToGLCapabilities(GLCapabilities caps, boolean rgba8Avail) {
final int _format;
switch(format) {
case GL.GL_RGBA:
case 4:
- _format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;
+ _format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;
break;
case GL.GL_RGB:
case 3:
@@ -191,7 +191,7 @@ public class FBObject {
caps.setGreenBits(8);
caps.setBlueBits(8);
caps.setAlphaBits(8);
- break;
+ break;
case GL.GL_DEPTH_COMPONENT16:
caps.setDepthBits(16);
break;
@@ -218,18 +218,18 @@ public class FBObject {
throw new IllegalArgumentException("format invalid: "+toHexString(format));
}
}
-
+
/** width of attachment */
public final int getWidth() { return width; }
/** height of attachment */
public final int getHeight() { return height; }
/* pp */ final void setSize(int w, int h) { width = w; height = h; }
-
+
/** buffer name [1..max], maybe a texture or renderbuffer name, depending on type. */
- public final int getName() { return name; }
+ public final int getName() { return name; }
/* pp */ final void setName(int n) { name = n; }
-
- /**
+
+ /**
* Initializes the attachment and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
* <pre>
final boolean init = 0 == name;
@@ -239,11 +239,11 @@ public class FBObject {
return init;
* </pre>
* @return <code>true</code> if newly initialized, otherwise <code>false</code>.
- * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
+ * @throws GLException if buffer generation or setup fails. The just created buffer name will be deleted in this case.
*/
public abstract boolean initialize(GL gl) throws GLException;
-
- /**
+
+ /**
* Releases the attachment if initialized, i.e. name is not <code>zero</code>.
* <pre>
if(0 != name) {
@@ -251,10 +251,10 @@ public class FBObject {
name = 0;
}
* </pre>
- * @throws GLException if buffer release fails.
+ * @throws GLException if buffer release fails.
*/
public abstract void free(GL gl) throws GLException;
-
+
/**
* <p>
* Comparison by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}.
@@ -272,7 +272,7 @@ public class FBObject {
height== a.height &&
name == a.name ;
}
-
+
/**
* <p>
* Hashed by {@link #type}, {@link #format}, {@link #width}, {@link #height} and {@link #name}.
@@ -289,14 +289,15 @@ public class FBObject {
hash = ((hash << 5) - hash) + name;
return hash;
}
-
+
int objectHashCode() { return super.hashCode(); }
-
+
+ @Override
public String toString() {
return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", "+width+"x"+height+
"; name "+toHexString(name)+", obj "+toHexString(objectHashCode())+"]";
}
-
+
public static Type getType(int attachmentPoint, int maxColorAttachments) {
if( GL.GL_COLOR_ATTACHMENT0 <= attachmentPoint && attachmentPoint < GL.GL_COLOR_ATTACHMENT0+maxColorAttachments ) {
return Type.COLOR;
@@ -304,9 +305,9 @@ public class FBObject {
switch(attachmentPoint) {
case GL.GL_DEPTH_ATTACHMENT:
return Type.DEPTH;
- case GL.GL_STENCIL_ATTACHMENT:
+ case GL.GL_STENCIL_ATTACHMENT:
return Type.STENCIL;
- default:
+ default:
throw new IllegalArgumentException("Invalid attachment point "+toHexString(attachmentPoint));
}
}
@@ -315,7 +316,7 @@ public class FBObject {
/** Other renderbuffer attachment which maybe a colorbuffer, depth or stencil. */
public static class RenderAttachment extends Attachment {
private int samples;
-
+
/**
* @param type allowed types are {@link Type#DEPTH_STENCIL} {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#COLOR}
* @param iFormat
@@ -328,11 +329,11 @@ public class FBObject {
super(validateType(type), iFormat, width, height, name);
this.samples = samples;
}
-
+
/** number of samples, or zero for no multisampling */
public final int getSamples() { return samples; }
/* pp */ final void setSamples(int s) { samples = s; }
-
+
private static Type validateType(Type type) {
switch(type) {
case DEPTH_STENCIL:
@@ -340,11 +341,11 @@ public class FBObject {
case STENCIL:
case COLOR:
return type;
- default:
+ default:
throw new IllegalArgumentException("Invalid type: "+type);
}
}
-
+
/**
* <p>
* Comparison by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}.
@@ -358,7 +359,7 @@ public class FBObject {
return super.equals(o) &&
samples == ((RenderAttachment)o).samples;
}
-
+
/**
* <p>
* Hashed by {@link #type}, {@link #format}, {@link #samples}, {@link #width}, {@link #height} and {@link #name}.
@@ -378,14 +379,14 @@ public class FBObject {
final boolean init = 0 == getName();
if( init ) {
checkPreGLError(gl);
-
+
final int[] name = new int[] { -1 };
gl.glGenRenderbuffers(1, name, 0);
setName(name[0]);
-
+
gl.glBindRenderbuffer(GL.GL_RENDERBUFFER, getName());
if( samples > 0 ) {
- ((GL2GL3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight());
+ ((GL2GL3)gl).glRenderbufferStorageMultisample(GL.GL_RENDERBUFFER, samples, format, getWidth(), getHeight());
} else {
gl.glRenderbufferStorage(GL.GL_RENDERBUFFER, format, getWidth(), getHeight());
}
@@ -401,7 +402,7 @@ public class FBObject {
}
return init;
}
-
+
@Override
public void free(GL gl) {
final int[] name = new int[] { getName() };
@@ -413,20 +414,21 @@ public class FBObject {
setName(0);
}
}
-
+
+ @Override
public String toString() {
return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
", name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
}
}
-
+
/** Color render buffer attachment */
public static class ColorAttachment extends RenderAttachment implements Colorbuffer {
public ColorAttachment(int iFormat, int samples, int width, int height, int name) {
super(Type.COLOR, iFormat, samples, width, height, name);
- }
+ }
}
-
+
/** Texture attachment */
public static class TextureAttachment extends Attachment implements Colorbuffer {
/** details of the texture setup */
@@ -445,7 +447,7 @@ public class FBObject {
* @param wrapT
* @param name
*/
- public TextureAttachment(Type type, int iFormat, int width, int height, int dataFormat, int dataType,
+ public TextureAttachment(Type type, int iFormat, int width, int height, int dataFormat, int dataType,
int magFilter, int minFilter, int wrapS, int wrapT, int name) {
super(validateType(type), iFormat, width, height, name);
this.dataFormat = dataFormat;
@@ -455,35 +457,35 @@ public class FBObject {
this.wrapS = wrapS;
this.wrapT = wrapT;
}
-
+
private static Type validateType(Type type) {
switch(type) {
case COLOR_TEXTURE:
case DEPTH_TEXTURE:
case STENCIL_TEXTURE:
return type;
- default:
+ default:
throw new IllegalArgumentException("Invalid type: "+type);
}
}
-
- /**
+
+ /**
* Initializes the texture and set it's parameter, if uninitialized, i.e. name is <code>zero</code>.
- * @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case.
+ * @throws GLException if texture generation and setup fails. The just created texture name will be deleted in this case.
*/
@Override
public boolean initialize(GL gl) throws GLException {
final boolean init = 0 == getName();
if( init ) {
checkPreGLError(gl);
-
- final int[] name = new int[] { -1 };
+
+ final int[] name = new int[] { -1 };
gl.glGenTextures(1, name, 0);
if(0 == name[0]) {
throw new GLException("null texture, "+this);
}
setName(name[0]);
-
+
gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
if( 0 < magFilter ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
@@ -495,7 +497,7 @@ public class FBObject {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, wrapS);
}
if( 0 < wrapT ) {
- gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
+ gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
}
boolean preTexImage2D = true;
int glerr = gl.glGetError();
@@ -527,6 +529,7 @@ public class FBObject {
setName(0);
}
}
+ @Override
public String toString() {
return getClass().getSimpleName()+"[type "+type+", target GL_TEXTURE_2D, level 0, format "+toHexString(format)+
", "+getWidth()+"x"+getHeight()+", border 0, dataFormat "+toHexString(dataFormat)+
@@ -534,50 +537,50 @@ public class FBObject {
"; min/mag "+toHexString(minFilter)+"/"+toHexString(magFilter)+
", wrap S/T "+toHexString(wrapS)+"/"+toHexString(wrapT)+
"; name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
- }
+ }
}
static String toHexString(int v) {
return "0x"+Integer.toHexString(v);
}
-
+
/**
- * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
* selecting the texture data type and format automatically.
- *
+ *
* <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
- *
+ *
* @param glp the chosen {@link GLProfile}
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
- * @param width texture width
+ * @param width texture width
* @param height texture height
* @return the created and uninitialized color {@link TextureAttachment}
*/
public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height) {
return createColorTextureAttachment(glp, alpha, width, height, GL.GL_NEAREST, GL.GL_NEAREST, GL.GL_CLAMP_TO_EDGE, GL.GL_CLAMP_TO_EDGE);
}
-
+
/**
- * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE},
* selecting the texture data type and format automatically.
- *
+ *
* @param glp the chosen {@link GLProfile}
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
- * @param width texture width
+ * @param width texture width
* @param height texture height
* @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
- * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
* @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return the created and uninitialized color {@link TextureAttachment}
*/
- public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height,
+ public static final TextureAttachment createColorTextureAttachment(GLProfile glp, boolean alpha, int width, int height,
int magFilter, int minFilter, int wrapS, int wrapT) {
final int textureInternalFormat, textureDataFormat, textureDataType;
- if(glp.isGLES()) {
+ if(glp.isGLES()) {
textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
textureDataType = GL.GL_UNSIGNED_BYTE;
- } else {
+ } else {
textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
// textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
// textureInternalFormat = alpha ? 4 : 3;
@@ -586,27 +589,27 @@ public class FBObject {
}
return createColorTextureAttachment(textureInternalFormat, width, height, textureDataFormat, textureDataType, magFilter, minFilter, wrapS, wrapT);
}
-
+
/**
- * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}.
+ * Creates a color {@link TextureAttachment}, i.e. type {@link Type#COLOR_TEXTURE}.
*
* @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
- * @param width texture width
+ * @param width texture width
* @param height texture height
* @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
* @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
* @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
- * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
* @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return the created and uninitialized color {@link TextureAttachment}
*/
public static final TextureAttachment createColorTextureAttachment(int internalFormat, int width, int height, int dataFormat, int dataType,
int magFilter, int minFilter, int wrapS, int wrapT) {
- return new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
+ return new TextureAttachment(Type.COLOR_TEXTURE, internalFormat, width, height, dataFormat, dataType,
magFilter, minFilter, wrapS, wrapT, 0 /* name */);
}
-
+
private static boolean hasAlpha(int format) {
switch(format) {
case GL.GL_RGBA8:
@@ -619,7 +622,7 @@ public class FBObject {
return false;
}
}
-
+
private boolean initialized;
private boolean fullFBOSupport;
private boolean rgba8Avail;
@@ -629,7 +632,7 @@ public class FBObject {
private boolean stencil04Avail;
private boolean stencil08Avail;
private boolean stencil16Avail;
- private boolean packedDepthStencilAvail;
+ private boolean packedDepthStencilAvail;
private int maxColorAttachments, maxSamples, maxTextureSize, maxRenderbufferSize;
private int width, height, samples;
@@ -639,21 +642,21 @@ public class FBObject {
private boolean bound;
private int colorAttachmentCount;
- private Colorbuffer[] colorAttachmentPoints; // colorbuffer attachment points
+ private Colorbuffer[] colorAttachmentPoints; // 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 TextureAttachment samplingSinkTexture;
private boolean samplingSinkDirty;
//
// ColorAttachment helper ..
//
-
+
private final void validateColorAttachmentPointRange(int point) {
if(!initialized) {
throw new GLException("FBO not initialized");
- }
+ }
if(maxColorAttachments != colorAttachmentPoints.length) {
throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
}
@@ -661,14 +664,14 @@ public class FBObject {
throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"], "+this);
}
}
-
+
private final void validateAddColorAttachment(int point, Colorbuffer ca) {
validateColorAttachmentPointRange(point);
if( null != colorAttachmentPoints[point] ) {
throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]+", "+this);
- }
+ }
}
-
+
private final void addColorAttachment(int point, Colorbuffer ca) {
validateColorAttachmentPointRange(point);
final Colorbuffer c = colorAttachmentPoints[point];
@@ -678,7 +681,7 @@ public class FBObject {
colorAttachmentPoints[point] = ca;
colorAttachmentCount++;
}
-
+
private final void removeColorAttachment(int point, Colorbuffer ca) {
validateColorAttachmentPointRange(point);
final Colorbuffer c = colorAttachmentPoints[point];
@@ -688,20 +691,20 @@ public class FBObject {
colorAttachmentPoints[point] = null;
colorAttachmentCount--;
}
-
+
/**
* Return the {@link Colorbuffer} attachment at <code>attachmentPoint</code> if it is attached to this FBO, otherwise null.
- *
+ *
* @see #attachColorbuffer(GL, boolean)
* @see #attachColorbuffer(GL, boolean)
* @see #attachTexture2D(GL, int, boolean, int, int, int, int)
- * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
+ * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
*/
public final Colorbuffer getColorbuffer(int attachmentPoint) {
- validateColorAttachmentPointRange(attachmentPoint);
+ validateColorAttachmentPointRange(attachmentPoint);
return colorAttachmentPoints[attachmentPoint];
}
-
+
/**
* Finds the passed {@link Colorbuffer} within the valid range of attachment points
* using <i>reference</i> comparison only.
@@ -709,36 +712,36 @@ public class FBObject {
* Note: Slow. Implementation uses a logN array search to save resources, i.e. not using a HashMap.
* </p>
* @param ca the {@link Colorbuffer} to look for.
- * @return -1 if the {@link Colorbuffer} could not be found, otherwise [0..{@link #getMaxColorAttachments()}-1]
+ * @return -1 if the {@link Colorbuffer} could not be found, otherwise [0..{@link #getMaxColorAttachments()}-1]
*/
public final int getColorbufferAttachmentPoint(Colorbuffer ca) {
for(int i=0; i<colorAttachmentPoints.length; i++) {
if( colorAttachmentPoints[i] == ca ) {
- return i;
+ return i;
}
}
return -1;
}
-
+
/**
* Returns the passed {@link Colorbuffer} if it is attached to this FBO, otherwise null.
* Implementation compares the <i>reference</i> only.
- *
+ *
* <p>
* Note: Slow. Uses {@link #getColorbufferAttachmentPoint(Colorbuffer)} to determine it's attachment point
* to be used for {@link #getColorbuffer(int)}
* </p>
- *
+ *
* @see #attachColorbuffer(GL, boolean)
* @see #attachColorbuffer(GL, boolean)
* @see #attachTexture2D(GL, int, boolean, int, int, int, int)
- * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
+ * @see #attachTexture2D(GL, int, int, int, int, int, int, int, int)
*/
public final Colorbuffer getColorbuffer(Colorbuffer ca) {
final int p = getColorbufferAttachmentPoint(ca);
return p>=0 ? getColorbuffer(p) : null;
}
-
+
/**
* Creates an uninitialized FBObject instance.
* <p>
@@ -747,7 +750,7 @@ public class FBObject {
*/
public FBObject() {
this.initialized = false;
-
+
// TBD @ init
this.fullFBOSupport = false;
this.rgba8Avail = false;
@@ -762,7 +765,7 @@ public class FBObject {
this.maxSamples=-1;
this.maxTextureSize = 0;
this.maxRenderbufferSize = 0;
-
+
this.width = 0;
this.height = 0;
this.samples = 0;
@@ -770,17 +773,17 @@ public class FBObject {
this.ignoreStatus = false;
this.fbName = 0;
this.bound = false;
-
+
this.colorAttachmentPoints = null; // at init ..
this.colorAttachmentCount = 0;
this.depth = null;
- this.stencil = null;
-
+ this.stencil = null;
+
this.samplingSink = null;
this.samplingSinkTexture = null;
this.samplingSinkDirty = true;
}
-
+
private void init(GL gl, int width, int height, int samples) throws GLException {
if(initialized) {
throw new GLException("FBO already initialized");
@@ -788,8 +791,8 @@ public class FBObject {
if( !gl.hasBasicFBOSupport() ) {
throw new GLException("FBO not supported w/ context: "+gl.getContext()+", "+this);
}
- fullFBOSupport = gl.hasFullFBOSupport();
-
+ fullFBOSupport = gl.hasFullFBOSupport();
+
rgba8Avail = gl.isGL2GL3() || gl.isExtensionAvailable(GLExtensions.OES_rgb8_rgba8);
depth24Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth24);
depth32Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_depth32);
@@ -797,15 +800,15 @@ public class FBObject {
stencil04Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil4);
stencil08Avail = fullFBOSupport || gl.isExtensionAvailable(GLExtensions.OES_stencil8);
stencil16Avail = fullFBOSupport;
-
+
packedDepthStencilAvail = fullFBOSupport ||
gl.isExtensionAvailable(GLExtensions.OES_packed_depth_stencil) ||
gl.isExtensionAvailable(GLExtensions.EXT_packed_depth_stencil) ;
-
+
final boolean NV_fbo_color_attachments = gl.isExtensionAvailable(GLExtensions.NV_fbo_color_attachments);
-
+
int val[] = new int[1];
-
+
checkPreGLError(gl);
int realMaxColorAttachments = 1;
@@ -818,24 +821,24 @@ public class FBObject {
} catch (GLException gle) { gle.printStackTrace(); }
}
maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size
-
+
colorAttachmentPoints = new Colorbuffer[maxColorAttachments];
colorAttachmentCount = 0;
-
+
maxSamples = gl.getMaxRenderbufferSamples();
gl.glGetIntegerv(GL.GL_MAX_TEXTURE_SIZE, val, 0);
maxTextureSize = val[0];
gl.glGetIntegerv(GL.GL_MAX_RENDERBUFFER_SIZE, val, 0);
maxRenderbufferSize = val[0];
-
+
checkPreGLError(gl);
-
+
if( 0 >= width ) { width = 1; }
if( 0 >= height ) { height = 1; }
this.width = width;
this.height = height;
this.samples = samples <= maxSamples ? samples : maxSamples;
-
+
if(DEBUG) {
System.err.println("FBObject "+width+"x"+height+", "+samples+" -> "+this.samples+" samples");
System.err.println("fullFBOSupport: "+fullFBOSupport);
@@ -856,16 +859,16 @@ public class FBObject {
System.err.println(JoglVersion.getGLStrings(gl, null).toString());
System.err.println(gl.getContext());
}
-
+
checkNoError(null, gl.glGetError(), "FBObject Init.pre"); // throws GLException if error
-
+
if(width > 2 + maxTextureSize || height> 2 + maxTextureSize ||
width > maxRenderbufferSize || height> maxRenderbufferSize ) {
throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
}
resetSamplingSink(gl);
-
+
// generate fbo ..
gl.glGenFramebuffers(1, val, 0);
fbName = val[0];
@@ -874,15 +877,15 @@ public class FBObject {
}
// bind fbo ..
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbName);
- checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, fbName);
+ checkNoError(gl, gl.glGetError(), "FBObject Init.bindFB"); // throws GLException if error
if(!gl.glIsFramebuffer(fbName)) {
checkNoError(gl, GL.GL_INVALID_VALUE, "FBObject Init.isFB"); // throws GLException
}
bound = true;
samplingSinkDirty = true;
initialized = true;
-
+
vStatus = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // always incomplete w/o attachments!
if(DEBUG) {
System.err.println("FBObject.init(): "+this);
@@ -900,9 +903,9 @@ public class FBObject {
* Incompatibility and hence recreation is forced if
* the size or sample count doesn't match for subsequent calls.
* </p>
- *
+ *
* <p>Leaves the FBO bound state untouched</p>
- *
+ *
* @param gl the current GL context
* @param newWidth
* @param newHeight
@@ -911,7 +914,7 @@ public class FBObject {
public final void reset(GL gl, int newWidth, int newHeight) {
reset(gl, newWidth, newHeight, 0, false);
}
-
+
/**
* Initializes or resets this FBO's instance.
* <p>
@@ -920,21 +923,21 @@ public class FBObject {
* to match the new given parameters.
* </p>
* <p>
- * Currently incompatibility and hence recreation of the attachments will be performed
+ * Currently incompatibility and hence recreation of the attachments will be performed
* if the size or sample count doesn't match for subsequent calls.
* </p>
- *
+ *
* <p>Leaves the FBO bound state untouched</p>
- *
+ *
* @param gl the current GL context
* @param newWidth the new width, it's minimum is capped to 1
* @param newHeight the new height, it's minimum is capped to 1
* @param newSamples if > 0, MSAA will be used, otherwise no multisampling. Will be capped to {@link #getMaxSamples()}.
- * @param resetSamplingSink <code>true</code> calls {@link #resetSamplingSink(GL)} immediatly.
+ * @param resetSamplingSink <code>true</code> calls {@link #resetSamplingSink(GL)} immediatly.
* <code>false</code> postpones resetting the sampling sink until {@link #use(GL, TextureAttachment)} or {@link #syncSamplingSink(GL)},
- * allowing to use the samples sink's FBO and texture until then. The latter is useful to benefit
- * from implicit double buffering while resetting the sink just before it's being used, eg. at swap-buffer.
- *
+ * allowing to use the samples sink's FBO and texture until then. The latter is useful to benefit
+ * from implicit double buffering while resetting the sink just before it's being used, eg. at swap-buffer.
+ *
* @throws GLException in case of an error, i.e. size too big, etc ..
*/
public final void reset(GL gl, int newWidth, int newHeight, int newSamples, boolean resetSamplingSink) {
@@ -942,9 +945,9 @@ public class FBObject {
init(gl, newWidth, newHeight, newSamples);
return;
}
-
+
newSamples = newSamples <= maxSamples ? newSamples : maxSamples; // clamp
-
+
if( newWidth != width || newHeight != height || newSamples != samples ) {
if( 0 >= newWidth ) { newWidth = 1; }
if( 0 >= newHeight ) { newHeight = 1; }
@@ -952,39 +955,39 @@ public class FBObject {
newWidth > maxRenderbufferSize || newHeight > maxRenderbufferSize ) {
throw new GLException("size "+width+"x"+height+" exceeds on of the maxima [texture "+maxTextureSize+", renderbuffer "+maxRenderbufferSize+"]");
}
-
+
if(DEBUG) {
System.err.println("FBObject.reset - START - "+width+"x"+height+", "+samples+" -> "+newWidth+"x"+newHeight+", "+newSamples+"; "+this);
- }
-
+ }
+
final boolean wasBound = isBound();
-
+
width = newWidth;
height = newHeight;
samples = newSamples;
-
+
if(0 < samples && null == samplingSink ) {
// needs valid samplingSink for detach*() -> bind()
samplingSink = new FBObject();
samplingSink.init(gl, width, height, 0);
}
- detachAllImpl(gl, true , true);
+ detachAllImpl(gl, true , true);
if(resetSamplingSink) {
resetSamplingSink(gl);
}
-
+
samplingSinkDirty = true;
if(!wasBound) {
unbind(gl);
}
-
+
if(DEBUG) {
System.err.println("FBObject.reset - END - "+this);
}
- }
+ }
}
-
+
/**
* Writes the internal format of the attachments to the given GLCapabilities object.
* @param caps the destination for format bits
@@ -994,11 +997,11 @@ public class FBObject {
caps.setNumSamples(samples);
caps.setDepthBits(0);
caps.setStencilBits(0);
-
+
final Colorbuffer cb = samples > 0 ? getSamplingSink() : getColorbuffer(0);
if(null != cb) {
cb.formatToGLCapabilities(caps, rgba8Avail);
- }
+ }
if(null != depth) {
depth.formatToGLCapabilities(caps, rgba8Avail);
}
@@ -1006,11 +1009,11 @@ public class FBObject {
stencil.formatToGLCapabilities(caps, rgba8Avail);
}
}
-
- /**
+
+ /**
* Note that the status may reflect an incomplete state during transition of attachments.
* @return The FB status. {@link GL.GL_FRAMEBUFFER_COMPLETE} if ok, otherwise return GL FBO error state or -1
- * @see #validateStatus()
+ * @see #validateStatus()
*/
public final int getStatus() {
return vStatus;
@@ -1020,15 +1023,15 @@ public class FBObject {
public final String getStatusString() {
return getStatusString(vStatus);
}
-
+
public static final String getStatusString(int fbStatus) {
switch(fbStatus) {
case -1:
return "NOT A FBO";
-
+
case GL.GL_FRAMEBUFFER_COMPLETE:
return "OK";
-
+
case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
return("FBO incomplete attachment\n");
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
@@ -1043,21 +1046,21 @@ public class FBObject {
return("FBO missing read buffer");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
return("FBO missing multisample buffer");
- case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
+ case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
return("FBO missing layer targets");
-
+
case GL.GL_FRAMEBUFFER_UNSUPPORTED:
return("Unsupported FBO format");
case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
return("FBO undefined");
-
+
case 0:
return("FBO implementation fault");
default:
return("FBO incomplete, implementation ERROR "+toHexString(fbStatus));
}
}
-
+
/**
* The status may even be valid if incomplete during transition of attachments.
* @see #getStatus()
@@ -1066,7 +1069,7 @@ public class FBObject {
switch(vStatus) {
case GL.GL_FRAMEBUFFER_COMPLETE:
return true;
-
+
case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
@@ -1079,29 +1082,29 @@ public class FBObject {
// we are in transition
return true;
}
-
+
case GL.GL_FRAMEBUFFER_UNSUPPORTED:
case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
-
- case 0:
+
+ case 0:
default:
if(DEBUG) {
- System.err.println("Framebuffer " + fbName + " is incomplete, status = " + toHexString(vStatus) +
+ System.err.println("Framebuffer " + fbName + " is incomplete, status = " + toHexString(vStatus) +
" : " + getStatusString(vStatus));
}
return false;
}
}
-
+
private static int checkPreGLError(GL gl) {
int glerr = gl.glGetError();
if(DEBUG && GL.GL_NO_ERROR != glerr) {
System.err.println("Pre-existing GL error: "+toHexString(glerr));
Thread.dumpStack();
}
- return glerr;
+ return glerr;
}
-
+
private final boolean checkNoError(GL gl, int err, String exceptionMessage) throws GLException {
if(GL.GL_NO_ERROR != err) {
if(null != gl) {
@@ -1118,17 +1121,17 @@ public class FBObject {
private final void checkInitialized() throws GLException {
if(!initialized) {
throw new GLException("FBO not initialized, call init(GL) first.");
- }
+ }
}
-
+
/**
* Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
- *
+ *
* <p>Using default min/mag filter {@link GL#GL_NEAREST} and default wrapS/wrapT {@link GL#GL_CLAMP_TO_EDGE}.</p>
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl the current GL context
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
@@ -1140,18 +1143,18 @@ public class FBObject {
return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
createColorTextureAttachment(gl.getGLProfile(), alpha, width, height));
}
-
+
/**
* Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point,
* selecting the texture data type and format automatically.
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl the current GL context
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
* @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
- * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
* @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
@@ -1162,19 +1165,19 @@ public class FBObject {
return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
createColorTextureAttachment(gl.getGLProfile(), alpha, width, height, magFilter, minFilter, wrapS, wrapT));
}
-
+
/**
* Attaches a {@link Colorbuffer}, i.e. {@link TextureAttachment}, to this FBO's instance at the given attachment point.
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl the current GL context
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
* @param internalFormat internalFormat parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
* @param dataFormat format parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
* @param dataType type parameter to {@link GL#glTexImage2D(int, int, int, int, int, int, int, int, long)}
* @param magFilter if > 0 value for {@link GL#GL_TEXTURE_MAG_FILTER}
- * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
+ * @param minFilter if > 0 value for {@link GL#GL_TEXTURE_MIN_FILTER}
* @param wrapS if > 0 value for {@link GL#GL_TEXTURE_WRAP_S}
* @param wrapT if > 0 value for {@link GL#GL_TEXTURE_WRAP_T}
* @return TextureAttachment instance describing the new attached texture colorbuffer if bound and configured successfully, otherwise GLException is thrown
@@ -1187,10 +1190,10 @@ public class FBObject {
return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
createColorTextureAttachment(internalFormat, width, height, dataFormat, dataType, magFilter, minFilter, wrapS, wrapT));
}
-
+
/**
* Creates a {@link ColorAttachment}, selecting the format automatically.
- *
+ *
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
* @return uninitialized ColorAttachment instance describing the new attached colorbuffer
*/
@@ -1203,13 +1206,13 @@ public class FBObject {
}
return new ColorAttachment(internalFormat, samples, width, height, 0);
}
-
+
/**
* Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point,
* selecting the format automatically.
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl the current GL context
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
@@ -1220,15 +1223,15 @@ public class FBObject {
public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, boolean alpha) throws GLException {
return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, createColorAttachment(alpha));
}
-
+
/**
* Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment}, to this FBO's instance at the given attachment point.
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl the current GL context
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
- * @param internalFormat usually {@link GL#GL_RGBA4}, {@link GL#GL_RGB5_A1}, {@link GL#GL_RGB565}, {@link GL#GL_RGB8} or {@link GL#GL_RGBA8}
+ * @param internalFormat usually {@link GL#GL_RGBA4}, {@link GL#GL_RGB5_A1}, {@link GL#GL_RGB565}, {@link GL#GL_RGB8} or {@link GL#GL_RGBA8}
* @return ColorAttachment instance describing the new attached colorbuffer if bound and configured successfully, otherwise GLException is thrown
* @throws GLException in case the colorbuffer couldn't be allocated
* @throws IllegalArgumentException if <code>internalFormat</code> doesn't reflect a colorbuffer
@@ -1238,28 +1241,28 @@ public class FBObject {
if( Attachment.Type.COLOR != atype ) {
throw new IllegalArgumentException("colorformat invalid: "+toHexString(internalFormat)+", "+this);
}
-
+
return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
}
-
+
/**
- * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment},
+ * Attaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment},
* to this FBO's instance at the given attachment point.
- *
+ *
* <p>
* If {@link Colorbuffer} is a {@link TextureAttachment} and is uninitialized, i.e. it's texture name is <code>zero</code>,
* a new texture name is generated and setup w/ the texture parameter.<br/>
* Otherwise, i.e. texture name is not <code>zero</code>, the passed TextureAttachment <code>texA</code> is
- * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
+ * considered complete and assumed matching this FBO requirement. A GL error may occur is the latter is untrue.
* </p>
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl
* @param attachmentPoint the color attachment point ranging from [0..{@link #getMaxColorAttachments()}-1]
- * @param colbuf the to be attached {@link Colorbuffer}
+ * @param colbuf the to be attached {@link Colorbuffer}
* @return newly attached {@link Colorbuffer} instance if bound and configured successfully, otherwise GLException is thrown
- * @throws GLException in case the colorbuffer couldn't be allocated or MSAA has been chosen in case of a {@link TextureAttachment}
+ * @throws GLException in case the colorbuffer couldn't be allocated or MSAA has been chosen in case of a {@link TextureAttachment}
*/
public final Colorbuffer attachColorbuffer(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
bind(gl);
@@ -1268,13 +1271,13 @@ public class FBObject {
private final Colorbuffer attachColorbufferImpl(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
validateAddColorAttachment(attachmentPoint, colbuf);
-
+
final boolean initializedColorbuf = colbuf.initialize(gl);
addColorAttachment(attachmentPoint, colbuf);
-
+
if(colbuf instanceof TextureAttachment) {
final TextureAttachment texA = (TextureAttachment) colbuf;
-
+
if(samples>0) {
removeColorAttachment(attachmentPoint, texA);
if(initializedColorbuf) {
@@ -1282,14 +1285,14 @@ public class FBObject {
}
throw new GLException("Texture2D not supported w/ MSAA. If you have enabled MSAA with exisiting texture attachments, you may want to detach them via detachAllTexturebuffer(gl).");
}
-
+
// Set up the color buffer for use as a renderable texture:
gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
GL.GL_TEXTURE_2D, texA.getName(), 0);
-
+
if(!ignoreStatus) {
- updateStatus(gl);
+ updateStatus(gl);
if(!isStatusValid()) {
detachColorbuffer(gl, attachmentPoint, true);
throw new GLException("attachTexture2D "+texA+" at "+attachmentPoint+" failed "+getStatusString()+", "+this);
@@ -1297,12 +1300,12 @@ public class FBObject {
}
} else if(colbuf instanceof ColorAttachment) {
final ColorAttachment colA = (ColorAttachment) colbuf;
-
+
// Attach the color buffer
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
GL.GL_RENDERBUFFER, colA.getName());
-
+
if(!ignoreStatus) {
updateStatus(gl);
if(!isStatusValid()) {
@@ -1316,7 +1319,7 @@ public class FBObject {
}
return colbuf;
}
-
+
/**
* Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
* selecting the internalFormat automatically.
@@ -1325,30 +1328,30 @@ public class FBObject {
* </p>
* <p>
* In case the desired type or bit-number is not supported, the next available one is chosen.
- * </p>
+ * </p>
* <p>
* Use {@link #getDepthAttachment()} and/or {@link #getStencilAttachment()} to retrieve details
* about the attached buffer. The details cannot be returned, since it's possible 2 buffers
* are being created, depth and stencil.
* </p>
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl
- * @param atype either {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#DEPTH_STENCIL}
+ * @param atype either {@link Type#DEPTH}, {@link Type#STENCIL} or {@link Type#DEPTH_STENCIL}
* @param reqBits desired bits for depth or -1 for default (24 bits)
* @throws GLException in case the renderbuffer couldn't be allocated or one is already attached.
* @throws IllegalArgumentException
* @see #getDepthAttachment()
* @see #getStencilAttachment()
*/
- public final void attachRenderbuffer(GL gl, Attachment.Type atype, int reqBits) throws GLException, IllegalArgumentException {
+ public final void attachRenderbuffer(GL gl, Attachment.Type atype, int reqBits) throws GLException, IllegalArgumentException {
if( 0 > reqBits ) {
reqBits = 24;
- }
+ }
final int internalFormat;
int internalStencilFormat = -1;
-
+
switch ( atype ) {
case DEPTH:
if( 32 <= reqBits && depth32Avail ) {
@@ -1356,10 +1359,10 @@ public class FBObject {
} else if( 24 <= reqBits && depth24Avail ) {
internalFormat = GL.GL_DEPTH_COMPONENT24;
} else {
- internalFormat = GL.GL_DEPTH_COMPONENT16;
+ internalFormat = GL.GL_DEPTH_COMPONENT16;
}
break;
-
+
case STENCIL:
if( 16 <= reqBits && stencil16Avail ) {
internalFormat = GL2GL3.GL_STENCIL_INDEX16;
@@ -1370,10 +1373,10 @@ public class FBObject {
} else if( 1 <= reqBits && stencil01Avail ) {
internalFormat = GL.GL_STENCIL_INDEX1;
} else {
- throw new GLException("stencil buffer n/a");
+ throw new GLException("stencil buffer n/a");
}
break;
-
+
case DEPTH_STENCIL:
if( packedDepthStencilAvail ) {
internalFormat = GL.GL_DEPTH24_STENCIL8;
@@ -1381,7 +1384,7 @@ public class FBObject {
if( 24 <= reqBits && depth24Avail ) {
internalFormat = GL.GL_DEPTH_COMPONENT24;
} else {
- internalFormat = GL.GL_DEPTH_COMPONENT16;
+ internalFormat = GL.GL_DEPTH_COMPONENT16;
}
if( stencil08Avail ) {
internalStencilFormat = GL.GL_STENCIL_INDEX8;
@@ -1397,17 +1400,17 @@ public class FBObject {
default:
throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this);
}
-
+
attachRenderbufferImpl(gl, atype, internalFormat);
-
+
if(0<=internalStencilFormat) {
attachRenderbufferImpl(gl, Attachment.Type.STENCIL, internalStencilFormat);
}
}
-
+
/**
* Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,
- * depending on the <code>internalFormat</code>.
+ * depending on the <code>internalFormat</code>.
* <p>
* Stencil and depth buffer can be attached only once.
* </p>
@@ -1416,9 +1419,9 @@ public class FBObject {
* about the attached buffer. The details cannot be returned, since it's possible 2 buffers
* are being created, depth and stencil.
* </p>
- *
+ *
* <p>Leaves the FBO bound.</p>
- *
+ *
* @param gl the current GL context
* @param internalFormat {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24}, {@link GL#GL_DEPTH_COMPONENT32},
* {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8}
@@ -1435,19 +1438,19 @@ public class FBObject {
}
attachRenderbufferImpl(gl, atype, internalFormat);
}
-
+
protected final void attachRenderbufferImpl(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
if( null != depth && ( Attachment.Type.DEPTH == atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
throw new GLException("FBO depth buffer already attached (rb "+depth+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
- }
+ }
if( null != stencil && ( Attachment.Type.STENCIL== atype || Attachment.Type.DEPTH_STENCIL == atype ) ) {
throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
}
bind(gl);
-
+
attachRenderbufferImpl2(gl, atype, internalFormat);
}
-
+
private final void attachRenderbufferImpl2(GL gl, Attachment.Type atype, int internalFormat) throws GLException {
if( Attachment.Type.DEPTH == atype ) {
if(null == depth) {
@@ -1486,10 +1489,10 @@ public class FBObject {
} else if( Attachment.Type.STENCIL == atype ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
} else if( Attachment.Type.DEPTH_STENCIL == atype ) {
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, stencil.getName());
}
-
+
if(!ignoreStatus) {
updateStatus(gl);
if( !isStatusValid() ) {
@@ -1500,13 +1503,13 @@ public class FBObject {
if(DEBUG) {
System.err.println("FBObject.attachRenderbuffer.X: [attachmentType "+atype+", iformat "+toHexString(internalFormat)+"]: "+this);
- }
+ }
}
-
+
/**
- * Detaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}.
+ * Detaches a {@link Colorbuffer}, i.e. {@link ColorAttachment} or {@link TextureAttachment}.
* <p>Leaves the FBO bound!</p>
- *
+ *
* @param gl
* @param attachmentPoint
* @param dispose true if the Colorbuffer shall be disposed
@@ -1515,26 +1518,26 @@ public class FBObject {
*/
public final Colorbuffer detachColorbuffer(GL gl, int attachmentPoint, boolean dispose) throws IllegalArgumentException {
bind(gl);
-
+
final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
if(null == res) {
- throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);
+ throw new IllegalArgumentException("ColorAttachment at "+attachmentPoint+", not attached, "+this);
}
if(DEBUG) {
System.err.println("FBObject.detachColorbuffer.X: [attachmentPoint "+attachmentPoint+", dispose "+dispose+"]: "+res+", "+this);
}
return res;
}
-
+
private final Colorbuffer detachColorbufferImpl(GL gl, int attachmentPoint, DetachAction detachAction) {
Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
-
+
if(null == colbuf) {
return null;
}
-
+
removeColorAttachment(attachmentPoint, colbuf);
-
+
if(colbuf instanceof TextureAttachment) {
final TextureAttachment texA = (TextureAttachment) colbuf;
if( 0 != texA.getName() ) {
@@ -1553,7 +1556,7 @@ public class FBObject {
if(DetachAction.RECREATE == detachAction) {
if(samples == 0) {
// stay non MSAA
- texA.setSize(width, height);
+ texA.setSize(width, height);
} else {
// switch to MSAA
colbuf = createColorAttachment(hasAlpha(texA.format));
@@ -1563,8 +1566,8 @@ public class FBObject {
} else if(colbuf instanceof ColorAttachment) {
final ColorAttachment colA = (ColorAttachment) colbuf;
if( 0 != colA.getName() ) {
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
GL.GL_RENDERBUFFER, 0);
switch(detachAction) {
case DISPOSE:
@@ -1582,9 +1585,9 @@ public class FBObject {
} else {
// switch to non MSAA
if(null != samplingSinkTexture) {
- colbuf = createColorTextureAttachment(samplingSinkTexture.format, width, height,
- samplingSinkTexture.dataFormat, samplingSinkTexture.dataType,
- samplingSinkTexture.magFilter, samplingSinkTexture.minFilter,
+ colbuf = createColorTextureAttachment(samplingSinkTexture.format, width, height,
+ samplingSinkTexture.dataFormat, samplingSinkTexture.dataType,
+ samplingSinkTexture.magFilter, samplingSinkTexture.minFilter,
samplingSinkTexture.wrapS, samplingSinkTexture.wrapT);
} else {
colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
@@ -1595,15 +1598,15 @@ public class FBObject {
}
return colbuf;
}
-
+
private final void freeAllColorbufferImpl(GL gl) {
for(int i=0; i<maxColorAttachments; i++) {
final Colorbuffer colbuf = colorAttachmentPoints[i]; // shortcut, don't validate here
-
+
if(null == colbuf) {
return;
}
-
+
if(colbuf instanceof TextureAttachment) {
final TextureAttachment texA = (TextureAttachment) colbuf;
if( 0 != texA.getName() ) {
@@ -1616,29 +1619,29 @@ public class FBObject {
} else if(colbuf instanceof ColorAttachment) {
final ColorAttachment colA = (ColorAttachment) colbuf;
if( 0 != colA.getName() ) {
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
- GL.GL_COLOR_ATTACHMENT0 + i,
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + i,
GL.GL_RENDERBUFFER, 0);
}
colA.free(gl);
}
}
}
-
+
/**
- *
+ *
* @param gl
* @param dispose true if the Colorbuffer shall be disposed
- * @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL}
+ * @param reqAType {@link Type#DEPTH}, {@link Type#DEPTH} or {@link Type#DEPTH_STENCIL}
*/
public final void detachRenderbuffer(GL gl, Attachment.Type atype, boolean dispose) throws IllegalArgumentException {
- bind(gl);
+ bind(gl);
detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
if(DEBUG) {
System.err.println("FBObject.detachRenderbuffer.X: [attachmentType "+atype+", dispose "+dispose+"]: "+this);
- }
+ }
}
-
+
public final boolean isDepthStencilPackedFormat() {
final boolean res = null != depth && null != stencil &&
depth.format == stencil.format ;
@@ -1652,19 +1655,19 @@ public class FBObject {
}
return res;
}
-
+
private final void detachRenderbufferImpl(GL gl, Attachment.Type atype, DetachAction detachAction) throws IllegalArgumentException {
switch ( atype ) {
case DEPTH:
case STENCIL:
- case DEPTH_STENCIL:
+ case DEPTH_STENCIL:
break;
default:
throw new IllegalArgumentException("only depth/stencil types allowed, was "+atype+", "+this);
- }
+ }
if( null == depth && null == stencil ) {
return ; // nop
- }
+ }
final boolean packed = isDepthStencilPackedFormat();
if( packed ) {
// Note: DEPTH_STENCIL shares buffer w/ depth and stencil
@@ -1734,7 +1737,7 @@ public class FBObject {
if(packed) {
stencil = null;
}
- }
+ }
}
if( !packed && null != stencil ) {
final int format = stencil.format;
@@ -1756,17 +1759,17 @@ public class FBObject {
}
break;
default: // handled
- }
+ }
}
-
+
private final void freeAllRenderbufferImpl(GL gl) throws IllegalArgumentException {
// Note: DEPTH_STENCIL shares buffer w/ depth and stencil
final boolean packed = isDepthStencilPackedFormat();
- if( null != depth ) {
+ if( null != depth ) {
if(0 != depth.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
if(packed) {
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
}
depth.free(gl);
}
@@ -1774,49 +1777,49 @@ public class FBObject {
if( !packed && null != stencil ) {
if(0 != stencil.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
- stencil.free(gl);
+ stencil.free(gl);
}
}
}
-
- /**
+
+ /**
* Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s
* and disposes them.
* <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
- * </p>
+ * </p>
* @param gl the current GL context
*/
public final void detachAll(GL gl) {
if(null != samplingSink) {
samplingSink.detachAll(gl);
- }
+ }
detachAllImpl(gl, true/* detachNonColorbuffer */, false /* recreate */);
}
-
- /**
- * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s
+
+ /**
+ * Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s
* and disposes them.
* <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
- * </p>
+ * </p>
* @param gl the current GL context
*/
public final void detachAllColorbuffer(GL gl) {
if(null != samplingSink) {
samplingSink.detachAllColorbuffer(gl);
- }
+ }
detachAllImpl(gl, false/* detachNonColorbuffer */, false /* recreate */);
}
-
- /**
+
+ /**
* Detaches all {@link TextureAttachment}s and disposes them.
* <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
- * </p>
+ * </p>
* @param gl the current GL context
*/
public final void detachAllTexturebuffer(GL gl) {
@@ -1826,7 +1829,7 @@ public class FBObject {
if(null != samplingSink) {
samplingSink.detachAllTexturebuffer(gl);
}
- bind(gl);
+ bind(gl);
for(int i=0; i<maxColorAttachments; i++) {
if(colorAttachmentPoints[i] instanceof TextureAttachment) {
detachColorbufferImpl(gl, i, DetachAction.DISPOSE);
@@ -1836,7 +1839,7 @@ public class FBObject {
System.err.println("FBObject.detachAllTexturebuffer.X: "+this);
}
}
-
+
public final void detachAllRenderbuffer(GL gl) {
if( !isInitialized() ) {
return;
@@ -1844,10 +1847,10 @@ public class FBObject {
if(null != samplingSink) {
samplingSink.detachAllRenderbuffer(gl);
}
- bind(gl);
+ bind(gl);
detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, DetachAction.DISPOSE);
}
-
+
private final void detachAllImpl(GL gl, boolean detachNonColorbuffer, boolean recreate) {
if( !isInitialized() ) {
return;
@@ -1868,7 +1871,7 @@ public class FBObject {
if( !recreate && colorAttachmentCount>0 ) {
throw new InternalError("Non zero ColorAttachments "+this);
}
-
+
if(detachNonColorbuffer) {
detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
}
@@ -1888,7 +1891,7 @@ public class FBObject {
System.err.println("FBObject.detachAll.X: [resetNonColorbuffer "+detachNonColorbuffer+", recreate "+recreate+"]: "+this);
}
}
-
+
/**
* @param gl the current GL context
*/
@@ -1903,9 +1906,9 @@ public class FBObject {
if( null != samplingSink && samplingSink.isInitialized() ) {
samplingSink.destroy(gl);
}
-
+
detachAllImpl(gl, true /* detachNonColorbuffer */, false /* recreate */);
-
+
// cache FB names, preset exposed to zero,
// braking ties w/ GL/GLContext link to getReadFramebuffer()/getWriteFramebuffer()
final int fb_cache = fbName;
@@ -1915,7 +1918,7 @@ public class FBObject {
if(0!=fb_cache) {
name[0] = fb_cache;
gl.glDeleteFramebuffers(1, name, 0);
- }
+ }
initialized = false;
bound = false;
if(DEBUG) {
@@ -1933,14 +1936,14 @@ public class FBObject {
final boolean depthMismatch = ( null != depth && null == samplingSink.depth ) ||
( null != depth && null != samplingSink.depth &&
depth.format != samplingSink.depth.format );
-
+
final boolean stencilMismatch = ( null != stencil && null == samplingSink.stencil ) ||
( null != stencil && null != samplingSink.stencil &&
- stencil.format != samplingSink.stencil.format );
-
- return depthMismatch || stencilMismatch;
+ stencil.format != samplingSink.stencil.format );
+
+ return depthMismatch || stencilMismatch;
}
-
+
/**
* Manually reset the MSAA sampling sink, if used.
* <p>
@@ -1948,7 +1951,7 @@ public class FBObject {
* a new sampling sink is being created.
* </p>
* <p>
- * Automatically called by {@link #reset(GL, int, int, int, boolean)}
+ * Automatically called by {@link #reset(GL, int, int, int, boolean)}
* and {@link #syncSamplingSink(GL)}.
* </p>
* <p>
@@ -1967,58 +1970,58 @@ public class FBObject {
}
return;
}
-
+
if(null == samplingSink ) {
samplingSink = new FBObject();
}
-
+
if(!samplingSink.initialized) {
samplingSink.init(gl, width, height, 0);
}
-
+
boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
boolean sampleSinkTexMismatch = sampleSinkTexMismatch();
boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
-
+
/** if(DEBUG) {
System.err.println("FBObject.resetSamplingSink.0: \n\tTHIS "+this+",\n\tSINK "+samplesSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
} */
-
+
if(!sampleSinkSizeMismatch && !sampleSinkTexMismatch && !sampleSinkDepthStencilMismatch) {
- // all properties match ..
- return;
+ // all properties match ..
+ return;
}
-
+
unbind(gl);
-
+
if(DEBUG) {
System.err.println("FBObject.resetSamplingSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplingSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
-
+
if( sampleSinkDepthStencilMismatch ) {
samplingSink.detachAllRenderbuffer(gl);
}
-
+
if( sampleSinkSizeMismatch ) {
samplingSink.reset(gl, width, height);
}
-
+
if(null == samplingSinkTexture) {
samplingSinkTexture = samplingSink.attachTexture2D(gl, 0, true);
} else if( 0 == samplingSinkTexture.getName() ) {
samplingSinkTexture.setSize(width, height);
samplingSink.attachColorbuffer(gl, 0, samplingSinkTexture);
}
-
+
if( sampleSinkDepthStencilMismatch ) {
samplingSink.attachRenderbuffer(gl, depth.format);
if( null != stencil && !isDepthStencilPackedFormat() ) {
samplingSink.attachRenderbuffer(gl, stencil.format);
}
- }
-
+ }
+
sampleSinkSizeMismatch = sampleSinkSizeMismatch();
sampleSinkTexMismatch = sampleSinkTexMismatch();
sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
@@ -2026,21 +2029,21 @@ public class FBObject {
throw new InternalError("Samples sink mismatch after reset: \n\tTHIS "+this+",\n\t SINK "+samplingSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
-
+
if(DEBUG) {
System.err.println("FBObject.resetSamplingSink: END\n\tTHIS "+this+",\n\tSINK "+samplingSink+
"\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
}
-
+
/**
* Setting this FBO sampling sink.
* @param newSamplingSink the new FBO sampling sink to use, or null to remove current sampling sink
- * @return the previous sampling sink or null if none was attached
+ * @return the previous sampling sink or null if none was attached
* @throws GLException if this FBO doesn't use MSAA or the given sink uses MSAA itself
*/
public FBObject setSamplingSink(FBObject newSamplingSink) throws GLException {
- final FBObject prev = samplingSink;
+ final FBObject prev = samplingSink;
if( null == newSamplingSink) {
samplingSink = null;
samplingSinkTexture = null;
@@ -2056,14 +2059,14 @@ public class FBObject {
samplingSinkDirty = true;
return prev;
}
-
- /**
+
+ /**
* Bind this FBO, i.e. bind write framebuffer to {@link #getWriteFramebuffer()}.
- *
- * <p>If multisampling is used, it sets the read framebuffer to the sampling sink {@link #getWriteFramebuffer()},
+ *
+ * <p>If multisampling is used, it sets the read framebuffer to the sampling sink {@link #getWriteFramebuffer()},
* if full FBO is supported.</p>
- *
- * <p>
+ *
+ * <p>
* In case you have attached more than one color buffer,
* you may want to setup {@link GL2GL3#glDrawBuffers(int, int[], int)}.
* </p>
@@ -2079,7 +2082,7 @@ public class FBObject {
gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, getReadFramebuffer());
} else {
// one for all
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, getWriteFramebuffer());
}
bound = true;
@@ -2087,29 +2090,29 @@ public class FBObject {
}
}
- /**
+ /**
* Unbind this FBO, i.e. bind read and write framebuffer to default, see {@link GLBase#getDefaultDrawFramebuffer()}.
- *
- * <p>If full FBO is supported, sets the read and write framebuffer individually to default, hence not disturbing
+ *
+ * <p>If full FBO is supported, sets the read and write framebuffer individually to default, hence not disturbing
* an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}</p>
- *
+ *
* @param gl the current GL context
* @throws GLException
*/
public final void unbind(GL gl) throws GLException {
if(bound) {
if(fullFBOSupport) {
- // default read/draw buffers, may utilize GLContext/GLDrawable override of
+ // default read/draw buffers, may utilize GLContext/GLDrawable override of
// GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
} else {
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
}
bound = false;
}
}
-
+
/**
* Method simply marks this FBO unbound w/o interfering w/ the bound framebuffer as perfomed by {@link #unbind(GL)}.
* <p>
@@ -2121,22 +2124,22 @@ public class FBObject {
bound = false;
}
- /**
+ /**
* Returns <code>true</code> if framebuffer object is bound via {@link #bind(GL)}, otherwise <code>false</code>.
* <p>
* Method verifies the bound state via {@link GL#getBoundFramebuffer(int)}.
* </p>
* @param gl the current GL context
*/
- public final boolean isBound(GL gl) {
+ public final boolean isBound(GL gl) {
bound = bound && fbName != gl.getBoundFramebuffer(GL.GL_FRAMEBUFFER) ;
return bound;
}
-
+
/** Returns <code>true</code> if framebuffer object is bound via {@link #bind(GL)}, otherwise <code>false</code>. */
public final boolean isBound() { return bound; }
-
- /**
+
+ /**
* If multisampling is being used and flagged dirty by a previous call of {@link #bind(GL)} or after initialization,
* the msaa-buffers are sampled to it's sink {@link #getSamplingSink()}.
* <p>
@@ -2147,7 +2150,7 @@ public class FBObject {
* </p>
* <p>
* Method always resets the framebuffer binding to default in the end.
- * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
+ * If full FBO is supported, sets the read and write framebuffer individually to default after sampling, hence not disturbing
* an optional operating MSAA FBO, see {@link GLBase#getDefaultReadFramebuffer()} and {@link GLBase#getDefaultDrawFramebuffer()}
* </p>
* <p>
@@ -2155,10 +2158,10 @@ public class FBObject {
* you may want to call {@link GL#glBindFramebuffer(int, int) glBindFramebuffer}({@link GL2GL3#GL_READ_FRAMEBUFFER}, {@link #getReadFramebuffer()});
* </p>
* <p>Leaves the FBO unbound.</p>
- *
+ *
* @param gl the current GL context
* @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
- * @throws IllegalArgumentException
+ * @throws IllegalArgumentException
*/
public final void syncSamplingSink(GL gl) {
markUnbound();
@@ -2170,30 +2173,30 @@ public class FBObject {
gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, samplingSink.getWriteFramebuffer());
((GL2GL3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, // since MSAA is supported, casting to GL2GL3 is OK
GL.GL_COLOR_BUFFER_BIT, GL.GL_NEAREST);
- checkNoError(null, gl.glGetError(), "FBObject syncSampleSink"); // throws GLException if error
+ checkNoError(null, gl.glGetError(), "FBObject syncSampleSink"); // throws GLException if error
}
if(fullFBOSupport) {
- // default read/draw buffers, may utilize GLContext/GLDrawable override of
+ // default read/draw buffers, may utilize GLContext/GLDrawable override of
// GLContext.getDefaultDrawFramebuffer() and GLContext.getDefaultReadFramebuffer()
gl.glBindFramebuffer(GL2GL3.GL_DRAW_FRAMEBUFFER, 0);
gl.glBindFramebuffer(GL2GL3.GL_READ_FRAMEBUFFER, 0);
} else {
- gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
+ gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); // default draw buffer
}
}
-
- /**
+
+ /**
* Bind the given texture colorbuffer.
- *
+ *
* <p>If using multiple texture units, ensure you call {@link GL#glActiveTexture(int)} first!</p>
- *
+ *
* <p>{@link #syncSamplingSink(GL)} is being called</p>
- *
+ *
* <p>Leaves the FBO unbound!</p>
- *
+ *
* @param gl the current GL context
* @param ta {@link TextureAttachment} to use, prev. attached w/ {@link #attachTexture2D(GL, int, boolean, int, int, int, int) attachTexture2D(..)}
- * @throws IllegalArgumentException
+ * @throws IllegalArgumentException
*/
public final void use(GL gl, TextureAttachment ta) throws IllegalArgumentException {
if(null == ta) { throw new IllegalArgumentException("Null TextureAttachment, this: "+toString()); }
@@ -2201,26 +2204,26 @@ public class FBObject {
gl.glBindTexture(GL.GL_TEXTURE_2D, ta.getName()); // use it ..
}
- /**
+ /**
* Unbind texture, ie bind 'non' texture 0
- *
+ *
* <p>Leaves the FBO unbound.</p>
- */
+ */
public final void unuse(GL gl) {
unbind(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0); // don't use it
}
- /** @see GL#hasFullFBOSupport() */
+ /** @see GL#hasFullFBOSupport() */
public final boolean hasFullFBOSupport() throws GLException { checkInitialized(); return this.fullFBOSupport; }
-
- /**
+
+ /**
* Returns <code>true</code> if renderbuffer accepts internal format {@link GL#GL_RGB8} and {@link GL#GL_RGBA8}, otherwise <code>false</code>.
* @throws GLException if {@link #init(GL)} hasn't been called.
*/
public final boolean supportsRGBA8() throws GLException { checkInitialized(); return rgba8Avail; }
-
- /**
+
+ /**
* Returns <code>true</code> if {@link GL#GL_DEPTH_COMPONENT16}, {@link GL#GL_DEPTH_COMPONENT24} or {@link GL#GL_DEPTH_COMPONENT32} is supported, otherwise <code>false</code>.
* @param bits 16, 24 or 32 bits
* @throws GLException if {@link #init(GL)} hasn't been called.
@@ -2228,14 +2231,14 @@ public class FBObject {
public final boolean supportsDepth(int bits) throws GLException {
checkInitialized();
switch(bits) {
- case 16: return true;
+ case 16: return true;
case 24: return depth24Avail;
case 32: return depth32Avail;
- default: return false;
+ default: return false;
}
}
-
- /**
+
+ /**
* Returns <code>true</code> if {@link GL#GL_STENCIL_INDEX1}, {@link GL#GL_STENCIL_INDEX4}, {@link GL#GL_STENCIL_INDEX8} or {@link GL2GL3#GL_STENCIL_INDEX16} is supported, otherwise <code>false</code>.
* @param bits 1, 4, 8 or 16 bits
* @throws GLException if {@link #init(GL)} hasn't been called.
@@ -2243,34 +2246,34 @@ public class FBObject {
public final boolean supportsStencil(int bits) throws GLException {
checkInitialized();
switch(bits) {
- case 1: return stencil01Avail;
+ case 1: return stencil01Avail;
case 4: return stencil04Avail;
case 8: return stencil08Avail;
case 16: return stencil16Avail;
- default: return false;
+ default: return false;
}
}
-
- /**
+
+ /**
* Returns <code>true</code> if {@link GL#GL_DEPTH24_STENCIL8} is supported, otherwise <code>false</code>.
* @throws GLException if {@link #init(GL)} hasn't been called.
*/
public final boolean supportsPackedDepthStencil() throws GLException { checkInitialized(); return packedDepthStencilAvail; }
-
+
/**
* Returns the maximum number of colorbuffer attachments.
* @throws GLException if {@link #init(GL)} hasn't been called.
*/
public final int getMaxColorAttachments() throws GLException { checkInitialized(); return maxColorAttachments; }
-
+
public final int getMaxTextureSize() throws GLException { checkInitialized(); return this.maxTextureSize; }
public final int getMaxRenderbufferSize() throws GLException { checkInitialized(); return this.maxRenderbufferSize; }
-
+
/** @see GL#getMaxRenderbufferSamples() */
public final int getMaxSamples() throws GLException { checkInitialized(); return this.maxSamples; }
-
+
/**
- * Returns <code>true</code> if this instance has been initialized with {@link #reset(GL, int, int)}
+ * Returns <code>true</code> if this instance has been initialized with {@link #reset(GL, int, int)}
* or {@link #reset(GL, int, int, int, boolean)}, otherwise <code>false</code>
*/
public final boolean isInitialized() { return initialized; }
@@ -2283,43 +2286,44 @@ public class FBObject {
/** Returns the framebuffer name to render to. */
public final int getWriteFramebuffer() { return fbName; }
/** 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; }
+ 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 stencil {@link RenderAttachment} attachment, if exist. Maybe share the same {@link Attachment#getName()} as {@link #getDepthAttachment()}, if packed depth-stencil is being used. */
+ /** 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. */
+ /** Return the depth {@link RenderAttachment} attachment. Maybe share the same {@link Attachment#getName()} as {@link #getStencilAttachment()}, if packed depth-stencil is being used. */
public final RenderAttachment getDepthAttachment() { return depth; }
-
- /** Return the complete multisampling {@link FBObject} sink, if using multisampling. */
+
+ /** 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. */
+
+ /** Return the multisampling {@link TextureAttachment} sink, if using multisampling. */
public final TextureAttachment getSamplingSink() { return samplingSinkTexture; }
- /**
- * Returns <code>true</code> if the multisampling colorbuffer (msaa-buffer)
+ /**
+ * Returns <code>true</code> if the multisampling colorbuffer (msaa-buffer)
* has been flagged dirty by a previous call of {@link #bind(GL)},
* otherwise <code>false</code>.
*/
public final boolean isSamplingBufferDirty() { return samplingSinkDirty; }
-
+
int objectHashCode() { return super.hashCode(); }
-
+
+ @Override
public final String toString() {
- final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).toString() : null ;
+ final String caps = null != colorAttachmentPoints ? Arrays.asList(colorAttachmentPoints).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-sink "+samplingSinkTexture+", hasSamplesSink "+(null != samplingSink)+
", state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]";
}
-
+
private final void updateStatus(GL gl) {
if( 0 == fbName ) {
vStatus = -1;
} else {
vStatus = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
}
- }
+ }
}