summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java431
1 files changed, 262 insertions, 169 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index cc0af29a9..ca9e3d370 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -28,7 +28,6 @@
package com.jogamp.opengl;
-import java.util.ArrayList;
import java.util.Arrays;
import javax.media.opengl.GL;
@@ -119,7 +118,7 @@ public class FBObject {
case GL.GL_DEPTH24_STENCIL8:
return Type.DEPTH_STENCIL;
default:
- throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ throw new IllegalArgumentException("format invalid: "+toHexString(format));
}
}
};
@@ -151,9 +150,11 @@ public class FBObject {
final int _format;
switch(format) {
case GL.GL_RGBA:
+ case 4:
_format = rgba8Avail ? GL.GL_RGBA8 : GL.GL_RGBA4;
break;
case GL.GL_RGB:
+ case 3:
_format = rgba8Avail ? GL.GL_RGB8 : GL.GL_RGB565;
break;
default:
@@ -213,7 +214,7 @@ public class FBObject {
caps.setStencilBits(8);
break;
default:
- throw new IllegalArgumentException("format invalid: 0x"+Integer.toHexString(format));
+ throw new IllegalArgumentException("format invalid: "+toHexString(format));
}
}
@@ -291,8 +292,8 @@ public class FBObject {
int objectHashCode() { return super.hashCode(); }
public String toString() {
- return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", "+width+"x"+height+
- ", name 0x"+Integer.toHexString(name)+", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+ 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) {
@@ -305,7 +306,7 @@ public class FBObject {
case GL.GL_STENCIL_ATTACHMENT:
return Type.STENCIL;
default:
- throw new IllegalArgumentException("Invalid attachment point 0x"+Integer.toHexString(attachmentPoint));
+ throw new IllegalArgumentException("Invalid attachment point "+toHexString(attachmentPoint));
}
}
}
@@ -390,7 +391,7 @@ public class FBObject {
if(GL.GL_NO_ERROR != glerr) {
gl.glDeleteRenderbuffers(1, name, 0);
setName(0);
- throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ throw new GLException("GL Error "+toHexString(glerr)+" while creating "+this);
}
if(DEBUG) {
System.err.println("Attachment.init: "+this);
@@ -404,16 +405,16 @@ public class FBObject {
final int[] name = new int[] { getName() };
if( 0 != name[0] ) {
gl.glDeleteRenderbuffers(1, name, 0);
- setName(0);
if(DEBUG) {
System.err.println("Attachment.free: "+this);
}
+ setName(0);
}
}
public String toString() {
- return getClass().getSimpleName()+"[type "+type+", format 0x"+Integer.toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
- ", name 0x"+Integer.toHexString(getName())+", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+ return getClass().getSimpleName()+"[type "+type+", format "+toHexString(format)+", samples "+samples+", "+getWidth()+"x"+getHeight()+
+ ", name "+toHexString(getName())+", obj "+toHexString(objectHashCode())+"]";
}
}
@@ -482,7 +483,6 @@ public class FBObject {
setName(name[0]);
gl.glBindTexture(GL.GL_TEXTURE_2D, name[0]);
- gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
if( 0 < magFilter ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, magFilter);
}
@@ -494,12 +494,18 @@ public class FBObject {
}
if( 0 < wrapT ) {
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, wrapT);
- }
+ }
+ boolean preTexImage2D = true;
glerr = gl.glGetError();
+ if(GL.GL_NO_ERROR == glerr) {
+ preTexImage2D = false;
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, format, getWidth(), getHeight(), 0, dataFormat, dataType, null);
+ glerr = gl.glGetError();
+ }
if(GL.GL_NO_ERROR != glerr) {
gl.glDeleteTextures(1, name, 0);
setName(0);
- throw new GLException("GL Error 0x"+Integer.toHexString(glerr)+" while creating "+this);
+ throw new GLException("GL Error "+toHexString(glerr)+" while creating (pre TexImage2D "+preTexImage2D+") "+this);
}
if(DEBUG) {
System.err.println("Attachment.init: "+this);
@@ -513,12 +519,23 @@ public class FBObject {
final int[] name = new int[] { getName() };
if( 0 != name[0] ) {
gl.glDeleteTextures(1, name, 0);
- setName(0);
if(DEBUG) {
System.err.println("Attachment.free: "+this);
}
+ setName(0);
}
}
+ 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)+
+ ", dataType "+toHexString(dataType)+
+ "; 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);
}
/**
@@ -560,6 +577,8 @@ public class FBObject {
textureDataType = GL.GL_UNSIGNED_BYTE;
} else {
textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+ // textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ // textureInternalFormat = alpha ? 4 : 3;
textureDataFormat = alpha ? GL.GL_BGRA : GL.GL_RGB;
textureDataType = alpha ? GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV : GL.GL_UNSIGNED_BYTE;
}
@@ -637,14 +656,14 @@ public class FBObject {
throw new InternalError("maxColorAttachments "+maxColorAttachments+", array.lenght "+colorAttachmentPoints);
}
if(0 > point || point >= maxColorAttachments) {
- throw new IllegalArgumentException("attachment point out of range: "+point+", should be within [0.."+(maxColorAttachments-1)+"]");
+ 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]);
+ throw new IllegalArgumentException("Cannot attach "+ca+", attachment point already in use by "+colorAttachmentPoints[point]+", "+this);
}
}
@@ -786,20 +805,15 @@ public class FBObject {
int val[] = new int[1];
- int glerr = checkPreGLError(gl);
+ checkPreGLError(gl);
int realMaxColorAttachments = 1;
maxColorAttachments = 1;
if( null != samplesSink && fullFBOSupport || NV_fbo_color_attachments ) {
try {
gl.glGetIntegerv(GL2GL3.GL_MAX_COLOR_ATTACHMENTS, val, 0);
- glerr = gl.glGetError();
- if(GL.GL_NO_ERROR == glerr) {
- realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
- } else if(DEBUG) {
- System.err.println("FBObject.init-GL_MAX_COLOR_ATTACHMENTS query GL Error 0x"+Integer.toHexString(glerr));
- }
- } catch (GLException gle) {}
+ realMaxColorAttachments = 1 <= val[0] ? val[0] : 1; // cap minimum to 1
+ } catch (GLException gle) { gle.printStackTrace(); }
}
maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8; // cap to limit array size
@@ -817,10 +831,7 @@ public class FBObject {
maxRenderbufferSize = 2048;
}
- glerr = gl.glGetError();
- if(DEBUG && GL.GL_NO_ERROR != glerr) {
- System.err.println("Info: FBObject.init: pre-existing GL error 0x"+Integer.toHexString(glerr));
- }
+ checkPreGLError(gl);
this.width = width;
this.height = height;
@@ -873,7 +884,7 @@ public class FBObject {
samplesSinkDirty = true;
initialized = true;
- updateStatus(gl);
+ vStatus = GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; // always incomplete w/o attachments!
if(DEBUG) {
System.err.println("FBObject.init(): "+this);
}
@@ -1014,31 +1025,31 @@ public class FBObject {
return "OK";
case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
- return("GL FBO: incomplete, incomplete attachment\n");
+ return("FBO incomplete attachment\n");
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
- return("GL FBO: incomplete, missing attachment");
+ return("FBO missing attachment");
case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
- return("GL FBO: incomplete, attached images must have same dimensions");
+ return("FBO attached images must have same dimensions");
case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
- return("GL FBO: incomplete, attached images must have same format");
+ return("FBO attached images must have same format");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
- return("GL FBO: incomplete, missing draw buffer");
+ return("FBO missing draw buffer");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
- return("GL FBO: incomplete, missing read buffer");
+ return("FBO missing read buffer");
case GL2GL3.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
- return("GL FBO: incomplete, missing multisample buffer");
+ return("FBO missing multisample buffer");
case GL3.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
- return("GL FBO: incomplete, layer targets");
+ return("FBO missing layer targets");
case GL.GL_FRAMEBUFFER_UNSUPPORTED:
- return("GL FBO: Unsupported framebuffer format");
+ return("Unsupported FBO format");
case GL2GL3.GL_FRAMEBUFFER_UNDEFINED:
- return("GL FBO: framebuffer undefined");
+ return("FBO undefined");
case 0:
- return("GL FBO: incomplete, implementation fault");
+ return("FBO implementation fault");
default:
- return("GL FBO: incomplete, implementation ERROR 0x"+Integer.toHexString(fbStatus));
+ return("FBO incomplete, implementation ERROR "+toHexString(fbStatus));
}
}
@@ -1069,7 +1080,7 @@ public class FBObject {
case 0:
default:
- System.out.println("Framebuffer " + fbName + " is incomplete: status = 0x" + Integer.toHexString(vStatus) +
+ System.out.println("Framebuffer " + fbName + " is incomplete: status = " + toHexString(vStatus) +
" : " + getStatusString(vStatus));
return false;
}
@@ -1078,7 +1089,7 @@ public class FBObject {
private static int checkPreGLError(GL gl) {
int glerr = gl.glGetError();
if(DEBUG && GL.GL_NO_ERROR != glerr) {
- System.err.println("Pre-existing GL error: 0x"+Integer.toHexString(glerr));
+ System.err.println("Pre-existing GL error: "+toHexString(glerr));
Thread.dumpStack();
}
return glerr;
@@ -1090,7 +1101,7 @@ public class FBObject {
destroy(gl);
}
if(null != exceptionMessage) {
- throw new GLException(exceptionMessage+" GL Error 0x"+Integer.toHexString(err));
+ throw new GLException(exceptionMessage+" GL Error "+toHexString(err));
}
return false;
}
@@ -1218,7 +1229,7 @@ public class FBObject {
public final ColorAttachment attachColorbuffer(GL gl, int attachmentPoint, int internalFormat) throws GLException, IllegalArgumentException {
final Attachment.Type atype = Attachment.Type.determine(internalFormat);
if( Attachment.Type.COLOR != atype ) {
- throw new IllegalArgumentException("colorformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new IllegalArgumentException("colorformat invalid: "+toHexString(internalFormat)+", "+this);
}
return (ColorAttachment) attachColorbuffer(gl, attachmentPoint, new ColorAttachment(internalFormat, samples, width, height, 0));
@@ -1244,13 +1255,16 @@ public class FBObject {
* @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);
+ return attachColorbufferImpl(gl, attachmentPoint, colbuf);
+ }
+
+ private final Colorbuffer attachColorbufferImpl(GL gl, int attachmentPoint, Colorbuffer colbuf) throws GLException {
validateAddColorAttachment(attachmentPoint, colbuf);
final boolean initializedColorbuf = colbuf.initialize(gl);
addColorAttachment(attachmentPoint, colbuf);
- bind(gl);
-
if(colbuf instanceof TextureAttachment) {
final TextureAttachment texA = (TextureAttachment) colbuf;
@@ -1410,18 +1424,20 @@ public class FBObject {
public final void attachRenderbuffer(GL gl, int internalFormat) throws GLException, IllegalArgumentException {
final Attachment.Type atype = Attachment.Type.determine(internalFormat);
if( Attachment.Type.DEPTH != atype && Attachment.Type.STENCIL != atype && Attachment.Type.DEPTH_STENCIL != atype ) {
- throw new IllegalArgumentException("renderformat invalid: 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new IllegalArgumentException("renderformat invalid: "+toHexString(internalFormat)+", "+this);
}
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+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+ 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+", 0x"+Integer.toHexString(internalFormat)+", "+this);
+ throw new GLException("FBO stencil buffer already attached (rb "+stencil+"), type is "+atype+", "+toHexString(internalFormat)+", "+this);
}
+ bind(gl);
+
attachRenderbufferImpl2(gl, atype, internalFormat);
}
@@ -1460,8 +1476,6 @@ public class FBObject {
stencil.initialize(gl);
}
- bind(gl);
-
// Attach the buffer
if( Attachment.Type.DEPTH == atype ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, depth.getName());
@@ -1496,6 +1510,8 @@ public class FBObject {
* @throws IllegalArgumentException
*/
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);
@@ -1513,8 +1529,6 @@ public class FBObject {
return null;
}
- bind(gl);
-
removeColorAttachment(attachmentPoint, colbuf);
if(colbuf instanceof TextureAttachment) {
@@ -1524,23 +1538,23 @@ public class FBObject {
GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
GL.GL_TEXTURE_2D, 0, 0);
gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ texA.free(gl);
+ break;
+ default:
+ }
}
- switch(detachAction) {
- case DISPOSE:
- texA.free(gl);
- break;
- case RECREATE:
- texA.free(gl);
- if(samples == 0) {
- // stay non MSAA
- texA.setSize(width, height);
- } else {
- // switch to MSAA
- colbuf = createColorAttachment(hasAlpha(texA.format));
- }
- attachColorbuffer(gl, attachmentPoint, colbuf);
- break;
- default:
+ if(DetachAction.RECREATE == detachAction) {
+ if(samples == 0) {
+ // stay non MSAA
+ texA.setSize(width, height);
+ } else {
+ // switch to MSAA
+ colbuf = createColorAttachment(hasAlpha(texA.format));
+ }
+ attachColorbufferImpl(gl, attachmentPoint, colbuf);
}
} else if(colbuf instanceof ColorAttachment) {
final ColorAttachment colA = (ColorAttachment) colbuf;
@@ -1548,36 +1562,63 @@ public class FBObject {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ colA.free(gl);
+ break;
+ default:
+ }
}
- switch(detachAction) {
- case DISPOSE:
- colA.free(gl);
- break;
- case RECREATE:
- colA.free(gl);
- if(samples > 0) {
- // stay MSAA
- colA.setSize(width, height);
- colA.setSamples(samples);
+ if(DetachAction.RECREATE == detachAction) {
+ if(samples > 0) {
+ // stay MSAA
+ colA.setSize(width, height);
+ colA.setSamples(samples);
+ } else {
+ // switch to non MSAA
+ if(null != samplesSinkTexture) {
+ colbuf = createColorTextureAttachment(samplesSinkTexture.format, width, height,
+ samplesSinkTexture.dataFormat, samplesSinkTexture.dataType,
+ samplesSinkTexture.magFilter, samplesSinkTexture.minFilter,
+ samplesSinkTexture.wrapS, samplesSinkTexture.wrapT);
} else {
- // switch to non MSAA
- if(null != samplesSinkTexture) {
- colbuf = createColorTextureAttachment(samplesSinkTexture.format, width, height,
- samplesSinkTexture.dataFormat, samplesSinkTexture.dataType,
- samplesSinkTexture.magFilter, samplesSinkTexture.minFilter,
- samplesSinkTexture.wrapS, samplesSinkTexture.wrapT);
- } else {
- colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
- }
+ colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
}
- attachColorbuffer(gl, attachmentPoint, colbuf);
- break;
- default:
+ }
+ attachColorbuffer(gl, attachmentPoint, colbuf);
}
}
return colbuf;
}
+ private final void freeColorbufferImpl(GL gl, int attachmentPoint) {
+ Colorbuffer colbuf = colorAttachmentPoints[attachmentPoint]; // shortcut, don't validate here
+
+ if(null == colbuf) {
+ return;
+ }
+
+ if(colbuf instanceof TextureAttachment) {
+ final TextureAttachment texA = (TextureAttachment) colbuf;
+ if( 0 != texA.getName() ) {
+ gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
+ GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
+ GL.GL_TEXTURE_2D, 0, 0);
+ gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
+ }
+ texA.free(gl);
+ } 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.GL_RENDERBUFFER, 0);
+ }
+ colA.free(gl);
+ }
+ }
+
/**
*
* @param gl
@@ -1585,6 +1626,7 @@ public class FBObject {
* @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);
detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
if(DEBUG) {
System.err.println("FBObject.detachRenderbuffer: [attachmentType "+atype+", dispose "+dispose+"]: "+this);
@@ -1612,99 +1654,119 @@ public class FBObject {
if( null == depth && null == stencil ) {
return ; // nop
}
- // reduction of possible combinations, create unique atype command(s)
- final ArrayList<Attachment.Type> actions = new ArrayList<Attachment.Type>(2);
- if( isDepthStencilPackedFormat() ) {
+ final boolean packed = isDepthStencilPackedFormat();
+ if( packed ) {
// packed
- actions.add(Attachment.Type.DEPTH_STENCIL);
- } else {
- // individual
- switch ( atype ) {
- case DEPTH:
- if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
- break;
- case STENCIL:
- if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
- break;
- case DEPTH_STENCIL:
- if( null != depth ) { actions.add(Attachment.Type.DEPTH); }
- if( null != stencil ) { actions.add(Attachment.Type.STENCIL); }
- break;
- default: // handled
- }
+ atype = Attachment.Type.DEPTH_STENCIL;
}
-
- bind(gl);
-
- for(int i = 0; i < actions.size(); i++) {
- final int format;
-
- Attachment.Type action = actions.get(i);
- switch ( action ) {
- case DEPTH:
- format = depth.format;
+ switch ( atype ) {
+ case DEPTH:
+ if( null != depth ) {
+ final int format = depth.format;
if( 0 != depth.getName() ) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ depth.free(gl);
+ break;
+ default:
+ }
}
- switch(detachAction) {
- case DISPOSE:
- case RECREATE:
- depth.free(gl);
- break;
- default:
- }
- if(DetachAction.RECREATE != detachAction) {
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, atype, format);
+ } else {
depth = null;
}
- break;
- case STENCIL:
- format = stencil.format;
+ }
+ break;
+ case STENCIL:
+ if( null != stencil ) {
+ final int format = stencil.format;
if(0 != stencil.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ stencil.free(gl);
+ break;
+ default:
+ }
}
- switch(detachAction) {
- case DISPOSE:
- case RECREATE:
- stencil.free(gl);
- break;
- default:
- }
- if(DetachAction.RECREATE != detachAction) {
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, atype, format);
+ } else {
stencil = null;
}
- break;
- case DEPTH_STENCIL:
- format = depth.format;
+ }
+ break;
+ case DEPTH_STENCIL:
+ if( null != depth ) {
+ final int format = depth.format;
if(0 != depth.getName()) {
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
- gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
- }
- switch(detachAction) {
- case DISPOSE:
- case RECREATE:
- depth.free(gl);
- stencil.free(gl);
- break;
- default:
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ depth.free(gl);
+ break;
+ default:
+ }
}
- if(DetachAction.RECREATE != detachAction) {
+ if(DetachAction.RECREATE == detachAction) {
+ attachRenderbufferImpl2(gl, Attachment.Type.DEPTH, format);
+ } else if(!packed) {
depth = null;
+ }
+ }
+ if( null != stencil ) {
+ final int format = stencil.format;
+ if(0 != stencil.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ switch(detachAction) {
+ case DISPOSE:
+ case RECREATE:
+ stencil.free(gl);
+ break;
+ default:
+ }
+ }
+ if(DetachAction.RECREATE == detachAction) {
+ if(packed) {
+ // packed
+ attachRenderbufferImpl2(gl, Attachment.Type.DEPTH_STENCIL, format);
+ } else {
+ // single
+ attachRenderbufferImpl2(gl, Attachment.Type.STENCIL, format);
+ }
+ } else {
stencil = null;
}
- break;
- default:
- throw new InternalError("XXX");
- }
- if(DetachAction.RECREATE == detachAction) {
- attachRenderbufferImpl2(gl, action, format);
- }
+ }
+ break;
+ default: // handled
}
}
+ private final void freeAllRenderbufferImpl(GL gl) throws IllegalArgumentException {
+ if( null != depth ) {
+ if(0 != depth.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ depth.free(gl);
+ }
+ }
+ if( null != stencil ) {
+ if(0 != stencil.getName()) {
+ gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
+ stencil.free(gl);
+ }
+ }
+ }
+
/**
* Detaches all {@link ColorAttachment}s, {@link TextureAttachment}s and {@link RenderAttachment}s
* and disposes them.
- * <p>Leaves the FBO bound!</p>
+ * <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
* </p>
@@ -1720,7 +1782,7 @@ public class FBObject {
/**
* Detaches all {@link ColorAttachment}s and {@link TextureAttachment}s
* and disposes them.
- * <p>Leaves the FBO bound!</p>
+ * <p>Leaves the FBO bound, if initialized!</p>
* <p>
* An attached sampling sink texture will be detached as well, see {@link #getSamplingSink()}.
* </p>
@@ -1734,17 +1796,21 @@ public class FBObject {
}
/**
- * Detaches all {@link TextureAttachment}s and disposes them.
- * <p>Leaves the FBO bound!</p>
+ * 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>
* @param gl the current GL context
*/
public final void detachAllTexturebuffer(GL gl) {
+ if( !isInitialized() ) {
+ return;
+ }
if(null != samplesSink) {
samplesSink.detachAllTexturebuffer(gl);
}
+ bind(gl);
for(int i=0; i<maxColorAttachments; i++) {
if(colorAttachmentPoints[i] instanceof TextureAttachment) {
detachColorbufferImpl(gl, i, DetachAction.DISPOSE);
@@ -1756,15 +1822,34 @@ public class FBObject {
}
public final void detachAllRenderbuffer(GL gl) {
+ if( !isInitialized() ) {
+ return;
+ }
if(null != samplesSink) {
samplesSink.detachAllRenderbuffer(gl);
}
+ bind(gl);
detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, DetachAction.DISPOSE);
}
+ static final boolean FBOResizeQuirk = false;
+
private final void detachAllImpl(GL gl, boolean detachNonColorbuffer, boolean recreate) {
+ if( !isInitialized() ) {
+ return;
+ }
ignoreStatus = recreate; // ignore status on single calls only if recreate -> reset
try {
+ bind(gl);
+ if(FBOResizeQuirk) {
+ if(detachNonColorbuffer && recreate) {
+ // free all colorbuffer & renderbuffer 1st
+ for(int i=0; i<maxColorAttachments; i++) {
+ freeColorbufferImpl(gl, i);
+ }
+ freeAllRenderbufferImpl(gl);
+ }
+ }
for(int i=0; i<maxColorAttachments; i++) {
detachColorbufferImpl(gl, i, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
}
@@ -1793,7 +1878,14 @@ public class FBObject {
* @param gl the current GL context
*/
public final void destroy(GL gl) {
- if(null != samplesSink) {
+ if(!initialized) {
+ return;
+ }
+ if(DEBUG) {
+ System.err.println("FBObject.destroy.0: "+this);
+ // Thread.dumpStack();
+ }
+ if( null != samplesSink && samplesSink.isInitialized() ) {
samplesSink.destroy(gl);
}
@@ -1812,7 +1904,7 @@ public class FBObject {
initialized = false;
bound = false;
if(DEBUG) {
- System.err.println("FBObject.destroy: "+this);
+ System.err.println("FBObject.destroy.X: "+this);
}
}
@@ -2155,10 +2247,11 @@ public class FBObject {
public final String toString() {
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+
+ 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 "+samplesSinkTexture+", isSamplesSink "+(null == samplesSink)+
- ", obj 0x"+Integer.toHexString(objectHashCode())+"]";
+ ", state "+getStatusString()+", obj "+toHexString(objectHashCode())+"]";
}
private final void updateStatus(GL gl) {