29package com.jogamp.opengl;
31import java.util.Arrays;
33import com.jogamp.common.ExceptionUtils;
34import com.jogamp.common.util.PropertyAccess;
35import com.jogamp.opengl.FBObject.Attachment.Type;
37import jogamp.opengl.Debug;
54 protected static final boolean DEBUG;
55 private static final int USER_MAX_TEXTURE_SIZE;
56 private static final boolean FBOResizeQuirk =
false;
59 Debug.initSingleton();
60 DEBUG = Debug.debug(
"FBObject");
61 USER_MAX_TEXTURE_SIZE = PropertyAccess.getIntProperty(
"jogl.debug.FBObject.MaxTextureSize",
true, 0);
64 private static enum DetachAction { NONE, DISPOSE, RECREATE };
127 NONE, DEPTH, STENCIL, DEPTH_STENCIL,
COLOR, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE;
152 throw new IllegalArgumentException(
"format invalid: "+toHexString(
format));
189 private int width, height;
196 protected Attachment(
final Type type,
final int iFormat,
final int width,
final int height,
final int name) {
198 this.format = iFormat;
200 this.height = height;
225 _format = rgba8Avail ? GL.GL_RGBA8 :
GL.
GL_RGBA4;
288 throw new IllegalArgumentException(
"format invalid: "+toHexString(
format));
299 final void setSize(
final int w,
final int h) { width = w; height = h; }
303 final void setName(
final int n) { name = n; }
339 if(
this == o )
return true;
340 if( ! ( o instanceof
Attachment ) )
return false;
342 return type == a.type &&
358 int hash = 31 +
type.ordinal();
359 hash = ((hash << 5) - hash) +
format;
360 hash = ((hash << 5) - hash) + width;
361 hash = ((hash << 5) - hash) + height;
362 hash = ((hash << 5) - hash) + name;
366 int objectHashCode() {
return super.hashCode(); }
370 return getClass().getSimpleName()+
"[type "+
type+
", format "+toHexString(
format)+
", "+width+
"x"+height+
371 "; name "+toHexString(name)+
", obj "+toHexString(objectHashCode())+
"]";
374 public static Type getType(
final int attachmentPoint,
final int maxColorAttachments) {
378 switch(attachmentPoint) {
384 throw new IllegalArgumentException(
"Invalid attachment point "+toHexString(attachmentPoint));
401 public RenderAttachment(
final Type type,
final int iFormat,
final int samples,
final int width,
final int height,
final int name) {
402 super(validateType(
type), iFormat, width, height, name);
404 this.samples = samples;
409 final void setSamples(
final int s) { samples = s; }
419 throw new IllegalArgumentException(
"Invalid type: "+
type);
431 if(
this == o )
return true;
433 return super.equals(o) &&
446 int hash = super.hashCode();
447 hash = ((hash << 5) - hash) + samples;
459 final int[] name =
new int[] { -1 };
460 gl.glGenRenderbuffers(1, name, 0);
466 final int glerr = gl.glGetError();
468 gl.glDeleteRenderbuffers(1, name, 0);
470 throw new GLException(
"GL Error "+toHexString(glerr)+
" while creating "+
this);
474 System.err.println(
"Attachment.init.X: "+
this);
479 private final StorageDefinition defStorageDefinition =
new StorageDefinition() {
492 final int[] name =
new int[] {
getName() };
495 System.err.println(
"Attachment.free.0: "+
this);
504 return getClass().getSimpleName()+
"[type "+
type+
", format "+toHexString(
format)+
", samples "+samples+
", "+
getWidth()+
"x"+
getHeight()+
505 ", name "+toHexString(
getName())+
", obj "+toHexString(objectHashCode())+
"]";
511 public ColorAttachment(
final int iFormat,
final int samples,
final int width,
final int height,
final int name) {
512 super(
Type.
COLOR, iFormat, samples, width, height, name);
542 super(validateType(
type), iFormat, width, height, name);
556 case STENCIL_TEXTURE:
559 throw new IllegalArgumentException(
"Invalid type: "+
type);
575 final int[] name =
new int[] { -1 };
596 boolean preTexImage2D =
true;
599 preTexImage2D =
false;
606 throw new GLException(
"GL Error "+toHexString(glerr)+
" while creating (pre TexImage2D "+preTexImage2D+
") "+
this);
612 System.err.println(
"Attachment.init.X: "+
this);
617 private final StorageDefinition defStorageDefinition =
new StorageDefinition() {
626 final int[] name =
new int[] {
getName() };
629 System.err.println(
"Attachment.free.0: "+
this);
645 return getClass().getSimpleName()+
"[type "+
type+
", target GL_TEXTURE_2D, level 0, format "+toHexString(
format)+
647 ", dataType "+toHexString(
dataType)+
649 ", wrap S/T "+toHexString(
wrapS)+
"/"+toHexString(
wrapT)+
650 "; name "+toHexString(
getName())+
", obj "+toHexString(objectHashCode())+
"]";
653 static String toHexString(
final int v) {
654 return "0x"+Integer.toHexString(v);
719 final int magFilter,
final int minFilter,
final int wrapS,
final int wrapT) {
720 final int internalFormat, dataFormat, dataType;
722 internalFormat = alpha ? GL.GL_RGBA8 :
GL.
GL_RGB8;
723 dataFormat = alpha ? GL.GL_RGBA :
GL.
GL_RGB;
726 internalFormat = alpha ? GL.GL_RGBA :
GL.
GL_RGB;
727 dataFormat = alpha ? GL.GL_RGBA :
GL.
GL_RGB;
730 internalFormat = alpha ? GL.GL_RGBA8 :
GL.
GL_RGB8;
733 dataFormat = alpha ? GL.GL_BGRA :
GL.
GL_RGB;
740 final int magFilter,
final int minFilter,
final int wrapS,
final int wrapT) {
741 final int dataFormat, dataType;
742 final boolean alpha = hasAlpha(internalFormat);
744 dataFormat = alpha ? GL.GL_RGBA :
GL.
GL_RGB;
747 dataFormat = alpha ? GL.GL_BGRA :
GL.
GL_RGB;
768 final int magFilter,
final int minFilter,
final int wrapS,
final int wrapT) {
770 magFilter, minFilter, wrapS, wrapT, 0 );
773 private static boolean hasAlpha(
final int format) {
786 private boolean initialized;
787 private boolean fullFBOSupport;
788 private boolean rgba8Avail;
789 private boolean depth24Avail;
790 private boolean depth32Avail;
791 private boolean stencil01Avail;
792 private boolean stencil04Avail;
793 private boolean stencil08Avail;
794 private boolean stencil16Avail;
795 private boolean packedDepthStencilAvail;
796 private int maxColorAttachments, maxSamples, maxTextureSize, maxRenderbufferSize;
798 private int width, height, samples;
800 private boolean ignoreStatus;
802 private boolean bound;
804 private int colorbufferCount;
805 private int textureAttachmentCount;
806 private Colorbuffer[] colorbufferAttachments;
807 private RenderAttachment depth, stencil;
808 private boolean modified;
811 private Colorbuffer samplingColorSink;
812 private boolean samplingSinkDirty;
818 private final void validateColorAttachmentPointRange(
final int point) {
820 throw new GLException(
"FBO not initialized");
822 if(maxColorAttachments != colorbufferAttachments.length) {
823 throw new InternalError(String.format(
"maxColorAttachments %d, array.length %d",
824 maxColorAttachments, colorbufferAttachments.length) );
826 if(0 > point || point >= maxColorAttachments) {
827 throw new IllegalArgumentException(String.format(
"attachment point out of range: %d, should be within [0..%d], %s",
828 point, maxColorAttachments-1,
this.toString() ) );
832 private final void validateAddColorAttachment(
final int point,
final Colorbuffer ca) {
833 validateColorAttachmentPointRange(point);
834 if(
null != colorbufferAttachments[point] ) {
835 throw new IllegalStateException(String.format(
"Cannot attach %s at %d, attachment point already in use by %s, %s",
836 ca.toString(), point, colorbufferAttachments[point].toString(),
this.toString() ) );
840 private final void addColorAttachment(
final int point,
final Colorbuffer ca,
final boolean validate) {
841 final Colorbuffer c = colorbufferAttachments[point];
843 validateColorAttachmentPointRange(point);
845 throw new IllegalArgumentException(
"Colorbuffer is null");
848 throw new IllegalStateException(String.format(
"Cannot attach %s at %d, attachment point already in use by %s, %s",
849 ca.toString(), point, c.toString(),
this.toString() ) );
852 colorbufferAttachments[point] = ca;
854 if( ca.isTextureAttachment() ) {
855 textureAttachmentCount++;
860 private final void removeColorAttachment(
final int point,
final Colorbuffer ca) {
861 validateColorAttachmentPointRange(point);
863 throw new IllegalArgumentException(
"Colorbuffer is null");
865 final Colorbuffer c = colorbufferAttachments[point];
867 throw new IllegalStateException(String.format(
"Cannot detach %s at %d, slot is holding other: %s, %s",
868 ca.toString(), point, c.toString(),
this.toString() ) );
870 colorbufferAttachments[point] =
null;
872 if( ca.isTextureAttachment() ) {
873 textureAttachmentCount--;
887 validateColorAttachmentPointRange(attachmentPoint);
888 return colorbufferAttachments[attachmentPoint];
901 for(
int i=0; i<colorbufferAttachments.length; i++) {
902 if( colorbufferAttachments[i] == ca ) {
934 boolean hasAlpha =
false;
935 for(
int i=0; i<caCount; i++) {
940 if( hasAlpha(ca.
format) ) {
955 this.initialized =
false;
958 this.fullFBOSupport =
false;
959 this.rgba8Avail =
false;
960 this.depth24Avail =
false;
961 this.depth32Avail =
false;
962 this.stencil01Avail =
false;
963 this.stencil04Avail =
false;
964 this.stencil08Avail =
false;
965 this.stencil16Avail =
false;
966 this.packedDepthStencilAvail =
false;
967 this.maxColorAttachments=-1;
969 this.maxTextureSize = 0;
970 this.maxRenderbufferSize = 0;
976 this.ignoreStatus =
false;
980 this.colorbufferAttachments =
null;
981 this.colorbufferCount = 0;
982 this.textureAttachmentCount = 0;
985 this.modified =
true;
987 this.samplingSink =
null;
988 this.samplingColorSink =
null;
989 this.samplingSinkDirty =
true;
1008 public void init(
final GL gl,
final int newWidth,
final int newHeight,
final int newSamples)
throws IllegalStateException,
GLException {
1010 throw new IllegalStateException(
"FBO already initialized");
1023 stencil16Avail = fullFBOSupport;
1025 packedDepthStencilAvail = fullFBOSupport ||
1031 final int val[] =
new int[1];
1033 checkPreGLError(gl);
1035 int realMaxColorAttachments = 1;
1036 maxColorAttachments = 1;
1037 if( fullFBOSupport || NV_fbo_color_attachments ) {
1041 realMaxColorAttachments = 1 <= val[0] ? val[0] : 1;
1042 }
catch (
final GLException gle) { gle.printStackTrace(); }
1044 maxColorAttachments = realMaxColorAttachments <= 8 ? realMaxColorAttachments : 8;
1046 colorbufferAttachments =
new Colorbuffer[maxColorAttachments];
1047 colorbufferCount = 0;
1048 textureAttachmentCount = 0;
1052 final int _maxTextureSize = val[0];
1053 if( 0 < USER_MAX_TEXTURE_SIZE ) {
1054 maxTextureSize = USER_MAX_TEXTURE_SIZE;
1056 maxTextureSize = _maxTextureSize;
1059 maxRenderbufferSize = val[0];
1061 this.width = 0 < newWidth ? newWidth : 1;
1062 this.height = 0 < newHeight ? newHeight : 1;
1063 this.samples = newSamples <= maxSamples ? newSamples : maxSamples;
1066 System.err.println(
"FBObject.init() START: "+width+
"x"+height+
", "+newSamples+
" -> "+this.samples+
" samples");
1067 System.err.println(
"fullFBOSupport: "+fullFBOSupport);
1068 System.err.println(
"maxColorAttachments: "+maxColorAttachments+
"/"+realMaxColorAttachments+
" [capped/real]");
1069 System.err.println(
"maxSamples: "+maxSamples);
1070 System.err.println(
"maxTextureSize: "+_maxTextureSize+
" -> "+maxTextureSize);
1071 System.err.println(
"maxRenderbufferSize: "+maxRenderbufferSize);
1072 System.err.println(
"rgba8: "+rgba8Avail);
1073 System.err.println(
"depth24: "+depth24Avail);
1074 System.err.println(
"depth32: "+depth32Avail);
1075 System.err.println(
"stencil01: "+stencil01Avail);
1076 System.err.println(
"stencil04: "+stencil04Avail);
1077 System.err.println(
"stencil08: "+stencil08Avail);
1078 System.err.println(
"stencil16: "+stencil16Avail);
1079 System.err.println(
"packedDepthStencil: "+packedDepthStencilAvail);
1080 System.err.println(
"NV_fbo_color_attachments: "+NV_fbo_color_attachments);
1085 checkPreGLError(gl);
1087 if( width > maxRenderbufferSize || height > maxRenderbufferSize ) {
1088 throw new GLException(
"Size "+width+
"x"+height+
" exceeds on of the maxima renderbuffer size "+maxRenderbufferSize+
": \n\t"+
this);
1092 samplingSinkDirty =
true;
1103 checkNoError(gl, gl.
glGetError(),
"FBObject Init.bindFB");
1112 System.err.println(
"FBObject.init() END: "+
this);
1113 ExceptionUtils.dumpStack(System.err);
1140 public final boolean reset(
final GL gl,
int newWidth,
int newHeight,
int newSamples)
throws GLException, IllegalStateException {
1141 if( !initialized ) {
1142 throw new IllegalStateException(
"FBO not initialized");
1145 newSamples = newSamples <= maxSamples ? newSamples : maxSamples;
1147 if( newWidth != width || newHeight != height || newSamples != samples ) {
1148 if( 0 >= newWidth ) { newWidth = 1; }
1149 if( 0 >= newHeight ) { newHeight = 1; }
1150 if( textureAttachmentCount > 0 && ( newWidth > 2 + maxTextureSize || newHeight > 2 + maxTextureSize ) ) {
1151 throw new GLException(
"Size "+newWidth+
"x"+newHeight+
" exceeds on of the maximum texture size "+maxTextureSize+
": \n\t"+
this);
1153 if( newWidth > maxRenderbufferSize || newHeight > maxRenderbufferSize ) {
1154 throw new GLException(
"Size "+newWidth+
"x"+newHeight+
" exceeds on of the maxima renderbuffer size "+maxRenderbufferSize+
": \n\t"+
this);
1158 System.err.println(
"FBObject.reset - START - "+width+
"x"+height+
", "+samples+
" -> "+newWidth+
"x"+newHeight+
", "+newSamples+
"; "+
this);
1161 final boolean wasBound =
isBound();
1163 final int sampleCountChange;
1164 if( 0 < samples && 0 < newSamples || 0 == samples && 0 == newSamples ) {
1165 sampleCountChange = 0;
1166 }
else if( 0 == samples && 0 < newSamples ) {
1167 sampleCountChange = 1;
1168 }
else if( 0 < samples && 0 == newSamples ) {
1169 sampleCountChange = -1;
1171 throw new IllegalArgumentException(
"Error in sampleCount change: "+samples+
" -> "+newSamples);
1175 samples = newSamples;
1178 samplingSinkDirty =
true;
1180 detachAllImpl(gl,
true,
true, sampleCountChange);
1188 System.err.println(
"FBObject.reset - END - wasBound, "+wasBound+
", "+
this);
1205 private final void resetSizeImpl(
final GL gl,
final int newWidth,
final int newHeight) {
1207 System.err.println(
"FBObject.resetSize - START - "+width+
"x"+height+
", "+samples+
" -> "+newWidth+
"x"+newHeight);
1210 final int sampleCountChange = 0;
1215 samplingSinkDirty =
true;
1217 detachAllImpl(gl,
true,
true, sampleCountChange);
1220 System.err.println(
"FBObject.resetSize - END - "+
this);
1224 private void validateAttachmentSize(
final Attachment a) {
1225 final int aWidth = a.getWidth();
1226 final int aHeight = a.getHeight();
1228 if( a instanceof TextureAttachment && ( aWidth > 2 + maxTextureSize || aHeight > 2 + maxTextureSize ) ) {
1229 throw new GLException(
"Size "+aWidth+
"x"+aHeight+
" of "+a+
" exceeds on of the maximum texture size "+maxTextureSize+
": \n\t"+
this);
1231 if( aWidth > maxRenderbufferSize || aHeight > maxRenderbufferSize ) {
1232 throw new GLException(
"Size "+aWidth+
"x"+aHeight+
" of "+a+
" exceeds on of the maxima renderbuffer size "+maxRenderbufferSize+
": \n\t"+
this);
1251 depth.formatToGLCapabilities(caps, rgba8Avail);
1253 if(
null != stencil && stencil != depth) {
1254 stencil.formatToGLCapabilities(caps, rgba8Avail);
1281 return(
"FBO incomplete attachment\n");
1283 return(
"FBO missing attachment");
1285 return(
"FBO attached images must have same dimensions");
1287 return(
"FBO attached images must have same format");
1289 return(
"FBO missing draw buffer");
1291 return(
"FBO missing read buffer");
1293 return(
"FBO missing multisample buffer");
1295 return(
"FBO missing layer targets");
1298 return(
"Unsupported FBO format");
1300 return(
"FBO undefined");
1303 return(
"FBO implementation fault");
1305 return(
"FBO incomplete, implementation ERROR "+toHexString(fbStatus));
1326 if(0 == colorbufferCount ||
null == depth) {
1337 System.err.println(
"Framebuffer " + fbName +
" is incomplete, status = " + toHexString(vStatus) +
1344 private static int checkPreGLError(
final GL gl) {
1347 System.err.println(
"Pre-existing GL error: "+toHexString(glerr));
1348 ExceptionUtils.dumpStack(System.err);
1353 private final boolean checkNoError(
final GL gl,
final int err,
final String exceptionMessage)
throws GLException {
1354 if(GL.GL_NO_ERROR != err) {
1358 if(
null != exceptionMessage) {
1359 throw new GLException(exceptionMessage+
" GL Error "+toHexString(err)+
" of "+this.
toString());
1366 private final void checkInitialized() throws GLException {
1368 throw new GLException(
"FBO not initialized, call init(GL) first.");
1433 final int internalFormat,
final int dataFormat,
final int dataType,
1434 final int magFilter,
final int minFilter,
final int wrapS,
final int wrapT)
throws GLException {
1451 final int internalFormat;
1454 internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
1456 internalFormat = alpha ? GL.GL_RGBA4 :
GL.
GL_RGB565;
1473 return new ColorAttachment(internalFormat, samples, width, height, 0 );
1477 return new RenderAttachment(type, internalFormat, samples, width, height, 0 );
1519 throw new IllegalArgumentException(
"colorformat invalid: "+toHexString(internalFormat)+
", "+
this);
1548 return attachColorbufferImpl(gl, attachmentPoint, colbuf);
1552 validateAddColorAttachment(attachmentPoint, colbuf);
1553 validateAttachmentSize((Attachment)colbuf);
1555 final boolean initializedColorbuf = colbuf.initialize(gl);
1556 addColorAttachment(attachmentPoint, colbuf,
false);
1558 if( colbuf.isTextureAttachment() ) {
1561 removeColorAttachment(attachmentPoint, texA);
1562 if( initializedColorbuf ) {
1565 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).");
1570 GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
1571 GL.GL_TEXTURE_2D, texA.
getName(), 0);
1577 throw new GLException(
"attachTexture2D "+texA+
" at "+attachmentPoint+
" failed: "+
getStatusString()+
", "+
this);
1581 final ColorAttachment colA = colbuf.getColorAttachment();
1585 GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
1586 GL.GL_RENDERBUFFER, colA.getName());
1592 throw new GLException(
"attachColorbuffer "+colA+
" at "+attachmentPoint+
" failed: "+
getStatusString()+
", "+
this);
1597 System.err.println(
"FBObject.attachColorbuffer.X: [attachmentPoint "+attachmentPoint+
", colbuf "+colbuf+
"]: "+
this);
1602 private final int getDepthIFormat(
final int reqBits) {
1603 if( 32 <= reqBits && depth32Avail ) {
1604 return GL.GL_DEPTH_COMPONENT32;
1605 }
else if( 24 <= reqBits && ( depth24Avail || depth32Avail ) ) {
1606 if( depth24Avail ) {
1607 return GL.GL_DEPTH_COMPONENT24;
1609 return GL.GL_DEPTH_COMPONENT32;
1612 return GL.GL_DEPTH_COMPONENT16;
1615 private final int getStencilIFormat(
final int reqBits) {
1616 if( 16 <= reqBits && stencil16Avail ) {
1617 return GL2GL3.GL_STENCIL_INDEX16;
1618 }
else if( 8 <= reqBits && ( stencil08Avail || stencil16Avail ) ) {
1619 if( stencil08Avail ) {
1620 return GL.GL_STENCIL_INDEX8;
1622 return GL2GL3.GL_STENCIL_INDEX16;
1624 }
else if( 4 <= reqBits && ( stencil04Avail || stencil08Avail || stencil16Avail ) ) {
1625 if( stencil04Avail ) {
1626 return GL.GL_STENCIL_INDEX4;
1627 }
else if( stencil08Avail ) {
1628 return GL.GL_STENCIL_INDEX8;
1630 return GL2GL3.GL_STENCIL_INDEX16;
1632 }
else if( 1 <= reqBits && ( stencil01Avail || stencil04Avail || stencil08Avail || stencil16Avail ) ) {
1633 if( stencil01Avail ) {
1634 return GL.GL_STENCIL_INDEX1;
1635 }
else if( stencil04Avail ) {
1636 return GL.GL_STENCIL_INDEX4;
1637 }
else if( stencil08Avail ) {
1638 return GL.GL_STENCIL_INDEX8;
1640 return GL2GL3.GL_STENCIL_INDEX16;
1643 throw new GLException(
"stencil buffer n/a");
1692 final int reqDepth, reqStencil;
1694 throw new IllegalArgumentException(
"reqBits out of range, shall be >= "+
MAXIMUM_BITS);
1711 reqStencil = reqBits;
1713 final int internalFormat;
1714 int internalStencilFormat = -1;
1718 internalFormat = getDepthIFormat(reqDepth);
1722 internalFormat = getStencilIFormat(reqStencil);
1726 if( packedDepthStencilAvail ) {
1729 internalFormat = getDepthIFormat(reqDepth);
1730 internalStencilFormat = getStencilIFormat(reqStencil);
1734 throw new IllegalArgumentException(
"only depth/stencil types allowed, was "+atype+
", "+
this);
1738 if(0<=internalStencilFormat) {
1769 throw new IllegalArgumentException(
"renderformat invalid: "+toHexString(internalFormat)+
", "+
this);
1776 throw new GLException(
"FBO depth buffer already attached (rb "+depth+
"), type is "+atype+
", "+toHexString(internalFormat)+
", "+
this);
1779 throw new GLException(
"FBO stencil buffer already attached (rb "+stencil+
"), type is "+atype+
", "+toHexString(internalFormat)+
", "+
this);
1783 attachRenderbufferImpl2(gl, atype, internalFormat);
1786 private final void attachRenderbufferImpl2(
final GL gl,
final Attachment.Type atype,
final int internalFormat)
throws GLException {
1788 if( Attachment.Type.DEPTH == atype ) {
1792 depth.setSize(width, height);
1793 depth.setSamples(samples);
1795 validateAttachmentSize(depth);
1796 depth.initialize(gl);
1797 }
else if( Attachment.Type.STENCIL == atype ) {
1798 if(
null == stencil) {
1801 stencil.setSize(width, height);
1802 stencil.setSamples(samples);
1804 validateAttachmentSize(stencil);
1805 stencil.initialize(gl);
1806 }
else if( Attachment.Type.DEPTH_STENCIL == atype ) {
1808 if(
null != stencil) {
1809 throw new InternalError(
"XXX: DEPTH_STENCIL, depth was null, stencil not: "+this.
toString());
1813 depth.setSize(width, height);
1814 depth.setSamples(samples);
1816 validateAttachmentSize(depth);
1817 depth.initialize(gl);
1823 if( Attachment.Type.DEPTH == atype ) {
1825 }
else if( Attachment.Type.STENCIL == atype ) {
1827 }
else if( Attachment.Type.DEPTH_STENCIL == atype ) {
1838 throw new GLException(
"renderbuffer [attachmentType "+atype+
", iformat "+toHexString(internalFormat)+
"] failed: "+this.
getStatusString()+
", "+this.
toString());
1843 System.err.println(
"FBObject.attachRenderbuffer.X: [attachmentType "+atype+
", iformat "+toHexString(internalFormat)+
"]: "+
this);
1860 final Colorbuffer res = detachColorbufferImpl(gl, attachmentPoint, dispose ? DetachAction.DISPOSE : DetachAction.NONE, 0);
1862 throw new IllegalArgumentException(
"ColorAttachment at "+attachmentPoint+
", not attached, "+
this);
1865 System.err.println(
"FBObject.detachColorbuffer.X: [attachmentPoint "+attachmentPoint+
", dispose "+dispose+
"]: "+res+
", "+
this);
1870 private final Colorbuffer detachColorbufferImpl(
final GL gl,
final int attachmentPoint,
final DetachAction detachAction,
final int sampleCountChange) {
1871 final Colorbuffer colbufOld = colorbufferAttachments[attachmentPoint];
1873 if(
null == colbufOld) {
1877 removeColorAttachment(attachmentPoint, colbufOld);
1881 if( 0 != texA.getName() ) {
1883 GL.GL_COLOR_ATTACHMENT0 + attachmentPoint,
1884 GL.GL_TEXTURE_2D, 0, 0);
1886 switch(detachAction) {
1894 if(DetachAction.RECREATE == detachAction) {
1895 final Colorbuffer colbufNew;
1896 if( 0 < sampleCountChange ) {
1901 texA.setSize(width, height);
1904 attachColorbufferImpl(gl, attachmentPoint, colbufNew);
1908 if( 0 != colA.getName() ) {
1910 GL.GL_COLOR_ATTACHMENT0+attachmentPoint,
1911 GL.GL_RENDERBUFFER, 0);
1912 switch(detachAction) {
1920 if(DetachAction.RECREATE == detachAction) {
1921 final Colorbuffer colbufNew;
1922 if( 0 <= sampleCountChange ||
null == samplingColorSink ) {
1926 colA.setSize(width, height);
1927 colA.setSamples(samples);
1931 if( samplingColorSink.isTextureAttachment() ) {
1932 final TextureAttachment samplingTextureSink = samplingColorSink.getTextureAttachment();
1934 samplingTextureSink.dataFormat, samplingTextureSink.dataType,
1935 samplingTextureSink.magFilter, samplingTextureSink.minFilter,
1936 samplingTextureSink.wrapS, samplingTextureSink.wrapT);
1947 private final void freeAllColorbufferImpl(
final GL gl) {
1948 for(
int i=0; i<maxColorAttachments; i++) {
1949 final Colorbuffer colbuf = colorbufferAttachments[i];
1951 if(
null == colbuf) {
1955 if( colbuf.isTextureAttachment() ) {
1957 if( 0 != texA.getName() ) {
1958 gl.glFramebufferTexture2D(GL.GL_FRAMEBUFFER,
1959 GL.GL_COLOR_ATTACHMENT0 + i,
1960 GL.GL_TEXTURE_2D, 0, 0);
1961 gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
1965 final ColorAttachment colA = colbuf.getColorAttachment();
1966 if( 0 != colA.getName() ) {
1967 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
1968 GL.GL_COLOR_ATTACHMENT0 + i,
1969 GL.GL_RENDERBUFFER, 0);
1984 final RenderAttachment res = detachRenderbufferImpl(gl, atype, dispose ? DetachAction.DISPOSE : DetachAction.NONE);
1986 throw new IllegalArgumentException(
"RenderAttachment type "+atype+
", not attached, "+
this);
1989 System.err.println(
"FBObject.detachRenderbuffer.X: [attachmentType "+atype+
", dispose "+dispose+
"]: "+
this);
1994 final boolean res =
null != depth &&
null != stencil &&
1995 depth.format == stencil.format ;
1997 if(depth.getName() != stencil.getName() ) {
1998 throw new InternalError(
"depth/stencil packed format not sharing: depth "+depth+
", stencil "+stencil);
2000 if(depth != stencil) {
2001 throw new InternalError(
"depth/stencil packed format not a shared reference: depth "+depth+
", stencil "+stencil);
2007 private final RenderAttachment detachRenderbufferImpl(
final GL gl, Attachment.Type atype,
final DetachAction detachAction)
throws IllegalArgumentException {
2014 throw new IllegalArgumentException(
"only depth/stencil types allowed, was "+atype+
", "+
this);
2016 if(
null == depth &&
null == stencil ) {
2022 atype = Attachment.Type.DEPTH_STENCIL;
2024 final RenderAttachment renderOld;
2028 if(
null != renderOld ) {
2029 final int format = renderOld.format;
2030 if( 0 != renderOld.getName() ) {
2031 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2032 switch(detachAction) {
2040 if(DetachAction.RECREATE == detachAction) {
2041 attachRenderbufferImpl2(gl, atype, format);
2048 renderOld = stencil;
2049 if(
null != renderOld ) {
2050 final int format = renderOld.format;
2051 if(0 != renderOld.getName()) {
2052 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2053 switch(detachAction) {
2061 if(DetachAction.RECREATE == detachAction) {
2062 attachRenderbufferImpl2(gl, atype, format);
2070 if(
null != renderOld ) {
2071 final int format = renderOld.format;
2072 if(0 != renderOld.getName()) {
2073 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2075 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2077 switch(detachAction) {
2085 if(DetachAction.RECREATE == detachAction) {
2086 attachRenderbufferImpl2(gl, packed ? Attachment.Type.DEPTH_STENCIL : Attachment.Type.DEPTH, format);
2094 if( !packed &&
null != stencil ) {
2095 final int format = stencil.format;
2096 if(0 != stencil.getName()) {
2097 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2098 switch(detachAction) {
2106 if(DetachAction.RECREATE == detachAction) {
2107 attachRenderbufferImpl2(gl, Attachment.Type.STENCIL, format);
2114 throw new InternalError(
"XXX");
2120 private final void freeAllRenderbufferImpl(
final GL gl)
throws IllegalArgumentException {
2123 if(
null != depth ) {
2124 if(0 != depth.getName()) {
2125 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_DEPTH_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2127 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2132 if( !packed &&
null != stencil ) {
2133 if(0 != stencil.getName()) {
2134 gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER, GL.GL_STENCIL_ATTACHMENT, GL.GL_RENDERBUFFER, 0);
2150 if(
null != samplingSink) {
2151 samplingSink.detachAll(gl);
2153 detachAllImpl(gl,
true,
false , 0);
2166 if(
null != samplingSink) {
2167 samplingSink.detachAllColorbuffer(gl);
2169 detachAllImpl(gl,
false,
false , 0);
2184 if(
null != samplingSink) {
2185 samplingSink.detachAllTexturebuffer(gl);
2188 for(
int i=0; i<maxColorAttachments; i++) {
2189 if( colorbufferAttachments[i].isTextureAttachment() ) {
2190 detachColorbufferImpl(gl, i, DetachAction.DISPOSE, 0);
2194 System.err.println(
"FBObject.detachAllTexturebuffer.X: "+
this);
2202 if(
null != samplingSink) {
2203 samplingSink.detachAllRenderbuffer(gl);
2209 private final void detachAllImpl(
final GL gl,
final boolean detachNonColorbuffer,
final boolean recreate,
final int sampleCountChange) {
2213 ignoreStatus = recreate;
2216 if(FBOResizeQuirk) {
2217 if(detachNonColorbuffer && recreate) {
2219 freeAllColorbufferImpl(gl);
2220 freeAllRenderbufferImpl(gl);
2223 for(
int i=0; i<maxColorAttachments; i++) {
2224 detachColorbufferImpl(gl, i, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE, sampleCountChange);
2226 if( !recreate && colorbufferCount>0 ) {
2227 throw new InternalError(
"Non zero ColorAttachments "+
this);
2230 if(detachNonColorbuffer) {
2231 detachRenderbufferImpl(gl, Attachment.Type.DEPTH_STENCIL, recreate ? DetachAction.RECREATE : DetachAction.DISPOSE);
2239 throw new GLException(
"detachAllImpl failed: "+
getStatusString()+
", "+
this);
2243 ignoreStatus =
false;
2246 System.err.println(
"FBObject.detachAll.X: [resetNonColorbuffer "+detachNonColorbuffer+
", recreate "+recreate+
"]: "+
this);
2258 System.err.println(
"FBObject.destroy.0: "+
this);
2261 if(
null != samplingSink && samplingSink.isInitialized() ) {
2262 samplingSink.destroy(gl);
2265 detachAllImpl(gl,
true ,
false , 0);
2269 final int fb_cache = fbName;
2272 final int name[] =
new int[1];
2277 initialized =
false;
2280 System.err.println(
"FBObject.destroy.X: "+
this);
2284 private final boolean sampleSinkSizeMismatch() {
2285 return samplingSink.getWidth() != width || samplingSink.getHeight() != height ;
2287 private final boolean sampleSinkDepthStencilMismatch() {
2288 if ( (
null != depth && (
null == samplingSink.depth || depth.format != samplingSink.depth.format ) )
2290 (
null == depth &&
null != samplingSink.depth )
2295 if ( (
null != stencil && (
null == samplingSink.stencil || stencil.format != samplingSink.stencil.format ) )
2297 (
null == stencil &&
null != samplingSink.stencil )
2309 private final boolean sampleSinkExFormatMismatch(
final GL gl) {
2315 return null != ca && ca.format != samplingColorSink.
getFormat();
2347 System.err.println(
"FBObject.resetSamplingSink.0");
2348 ExceptionUtils.dumpStack(System.err);
2351 if( 0 == samples ) {
2352 final boolean modifiedInstance;
2354 if(
null != samplingSink ) {
2356 if( samplingSink.initialized ) {
2357 samplingSink.detachAll(gl);
2359 samplingSink =
null;
2360 samplingColorSink =
null;
2361 modifiedInstance =
true;
2363 modifiedInstance =
false;
2365 this.modified =
false;
2367 System.err.println(
"FBObject.resetSamplingSink.X1: zero samples, mod "+modifiedInstance+
"\n\tTHIS "+
this);
2369 return modifiedInstance;
2372 boolean modifiedInstance =
false;
2374 if(
null == samplingSink ) {
2376 samplingSink.init(gl, width, height, 0);
2377 samplingColorSink =
null;
2378 modifiedInstance =
true;
2379 }
else if( !samplingSink.initialized ) {
2380 throw new InternalError(
"InitState Mismatch: samplingSink set, but not initialized "+samplingSink);
2381 }
else if(
null == samplingColorSink || 0 == samplingColorSink.getName() ) {
2382 throw new InternalError(
"InitState Mismatch: samplingColorSink set, but not initialized "+samplingColorSink+
", "+samplingSink);
2386 System.err.println(
"FBObject.resetSamplingSink.1: mod "+modifiedInstance+
"\n\tTHIS "+
this+
",\n\tSINK "+samplingSink);
2388 boolean sampleSinkExFormatMismatch = sampleSinkExFormatMismatch(gl);
2389 boolean sampleSinkSizeMismatch = sampleSinkSizeMismatch();
2390 boolean sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
2392 if( modifiedInstance ) {
2395 if( sampleSinkExFormatMismatch || sampleSinkSizeMismatch ) {
2396 throw new InternalError(
"InitState Mismatch: Matching exFormat "+!sampleSinkExFormatMismatch+
2397 ", size "+!sampleSinkSizeMismatch +
", "+
this);
2401 if(!sampleSinkExFormatMismatch && !sampleSinkSizeMismatch && !sampleSinkDepthStencilMismatch) {
2403 System.err.println(
"FBObject.resetSamplingSink.X2: Matching: exFormat "+!sampleSinkExFormatMismatch+
2404 ", size "+!sampleSinkSizeMismatch +
", depthStencil "+!sampleSinkDepthStencilMismatch+
2405 ", mod "+modifiedInstance);
2408 samplingSink.modified =
false;
2409 this.modified =
false;
2410 return modifiedInstance;
2414 final boolean wasBound;
2423 System.err.println(
"FBObject.resetSamplingSink.2: wasBound "+wasBound+
", matching: exFormat "+!sampleSinkExFormatMismatch+
2424 ", size "+!sampleSinkSizeMismatch +
", depthStencil "+!sampleSinkDepthStencilMismatch);
2427 modifiedInstance =
true;
2429 if( sampleSinkDepthStencilMismatch ) {
2430 samplingSink.detachAllRenderbuffer(gl);
2433 final boolean samplingColorSinkShallBeTA =
null == samplingColorSink || samplingColorSink.isTextureAttachment();
2435 if( sampleSinkExFormatMismatch ) {
2436 samplingSink.detachAllColorbuffer(gl);
2437 samplingColorSink =
null;
2438 }
else if( sampleSinkSizeMismatch ) {
2439 samplingSink.resetSizeImpl(gl, width, height);
2440 samplingColorSink = samplingSink.getColorbuffer(0);
2443 if(
null == samplingColorSink ) {
2447 if( samplingColorSinkShallBeTA ) {
2454 samplingSink.attachColorbuffer(gl, 0, samplingColorSink);
2458 if( samplingColorSinkShallBeTA ) {
2459 samplingColorSink = samplingSink.attachTexture2D(gl, 0, hasAlpha);
2461 samplingColorSink = samplingSink.attachColorbuffer(gl, 0, hasAlpha);
2466 if( sampleSinkDepthStencilMismatch ) {
2467 samplingSink.attachRenderbuffer(gl, depth.format);
2469 samplingSink.attachRenderbuffer(gl, stencil.format);
2473 sampleSinkExFormatMismatch = sampleSinkExFormatMismatch(gl);
2474 sampleSinkSizeMismatch = sampleSinkSizeMismatch();
2475 sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
2476 if(sampleSinkExFormatMismatch || sampleSinkSizeMismatch || sampleSinkDepthStencilMismatch) {
2477 throw new InternalError(
"Samples sink mismatch after reset: \n\tTHIS "+
this+
",\n\t SINK "+samplingSink+
2478 "\n\t Mismatch. Matching: exFormat "+!sampleSinkExFormatMismatch+
2479 ", size "+!sampleSinkSizeMismatch +
", depthStencil "+!sampleSinkDepthStencilMismatch);
2482 samplingSink.modified =
false;
2483 samplingSink.unbind(gl);
2484 this.modified =
false;
2491 System.err.println(
"FBObject.resetSamplingSink.XX: END mod "+modifiedInstance+
"\n\tTHIS "+
this+
",\n\tSINK "+samplingSink+
2492 "\n\t Matching: exFormat "+!sampleSinkExFormatMismatch+
2493 ", size "+!sampleSinkSizeMismatch +
", depthStencil "+!sampleSinkDepthStencilMismatch);
2495 return modifiedInstance;
2506 final FBObject prev = samplingSink;
2507 if(
null == newSamplingSink) {
2508 samplingSink =
null;
2509 samplingColorSink =
null;
2510 }
else if( samples > 0 ) {
2511 if( !newSamplingSink.isInitialized() ) {
2512 throw new IllegalStateException(
"SamplingSink not initialized: "+newSamplingSink);
2514 if( newSamplingSink.getNumSamples() > 0 ) {
2515 throw new GLException(
"SamplingSink FBO cannot use MSAA itself: "+newSamplingSink);
2517 samplingSink = newSamplingSink;
2518 samplingColorSink = newSamplingSink.getColorbuffer(0);
2520 throw new GLException(
"Setting SamplingSink for non MSAA FBO not allowed: "+
this);
2523 samplingSinkDirty =
true;
2543 if( fullFBOSupport ) {
2550 samplingSinkDirty =
true;
2565 if(fullFBOSupport) {
2629 if(samples>0 && samplingSinkDirty) {
2630 samplingSinkDirty =
false;
2636 checkPreGLError(gl);
2640 ((
GL2ES3)gl).glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
2643 checkNoError(
null, gl.
glGetError(),
"FBObject syncSampleSink");
2648 if(fullFBOSupport) {
2706 case 16:
return true;
2707 case 24:
return depth24Avail;
2708 case 32:
return depth32Avail;
2709 default:
return false;
2721 case 1:
return stencil01Avail;
2722 case 4:
return stencil04Avail;
2723 case 8:
return stencil08Avail;
2724 case 16:
return stencil16Avail;
2725 default:
return false;
2762 return 0 < samples ? (
null != samplingSink ? samplingSink.getReadFramebuffer() : 0 ) : fbName;
2800 public final boolean isModified() {
return modified || (
null != samplingSink && samplingSink.modified ); }
2802 int objectHashCode() {
return super.hashCode(); }
2806 final String caps =
null != colorbufferAttachments ? Arrays.asList(colorbufferAttachments).toString() : null ;
2807 return "FBO[name r/w "+fbName+
"/"+
getReadFramebuffer()+
", init "+initialized+
", bound "+bound+
", size "+width+
"x"+height+
2808 ", samples "+samples+
"/"+maxSamples+
", modified "+modified+
"/"+
isModified()+
", depth "+depth+
", stencil "+stencil+
2809 ", colorbuffer attachments: "+colorbufferCount+
"/"+maxColorAttachments+
", with "+textureAttachmentCount+
" textures"+
2810 ": "+caps+
", msaa["+samplingColorSink+
", hasSink "+(
null != samplingSink)+
2811 ", dirty "+samplingSinkDirty+
"], state "+
getStatusString()+
", obj "+toHexString(objectHashCode())+
"]";
2814 private final void updateStatus(
final GL gl) {
void setRedBits(final int redBits)
Sets the number of bits requested for the color buffer's red component.
void setGreenBits(final int greenBits)
Sets the number of bits requested for the color buffer's green component.
void setBlueBits(final int blueBits)
Sets the number of bits requested for the color buffer's blue component.
void setAlphaBits(final int alphaBits)
Sets the number of bits requested for the color buffer's alpha component.
Common super class of all FBO attachments.
final int format
immutable the internal format
abstract boolean initialize(final GL gl)
Initializes the attachment and set it's parameter, if uninitialized, i.e.
final void setStorage(final GL gl)
Accessor to call StorageDefinition#setStorage(GL, Attachment) within initialize(GL) for implementatio...
final void formatToGLCapabilities(final GLCapabilities caps, final boolean rgba8Avail)
Writes the internal format to the given GLCapabilities object.
void setStorageDefinition(final StorageDefinition sd)
Override implementation default StorageDefinition.
final int getName()
buffer name [1..max], maybe a texture or renderbuffer name, depending on type.
final Type type
immutable type [COLOR, DEPTH, STENCIL, COLOR_TEXTURE, DEPTH_TEXTURE, STENCIL_TEXTURE ]
final int getFormat()
immutable internal format of attachment
static Type getType(final int attachmentPoint, final int maxColorAttachments)
Attachment(final Type type, final int iFormat, final int width, final int height, final int name)
abstract void free(final GL gl)
Releases the attachment if initialized, i.e.
final int getHeight()
height of attachment
final int getWidth()
width of attachment
boolean equals(final Object o)
Color render buffer FBO attachment
ColorAttachment(final int iFormat, final int samples, final int width, final int height, final int name)
final ColorAttachment getColorAttachment()
Casts this object to a ColorAttachment reference, see isTextureAttachment().
final TextureAttachment getTextureAttachment()
Casts this object to a TextureAttachment reference, see isTextureAttachment().
final boolean isTextureAttachment()
Returns true if instance is of type TextureAttachment and false if instance is of type ColorAttachmen...
Other renderbuffer attachment which maybe a colorbuffer, depth or stencil.
boolean initialize(final GL gl)
Initializes the attachment and set it's parameter, if uninitialized, i.e.
final int getSamples()
number of samples, or zero for no multisampling
void free(final GL gl)
Releases the attachment if initialized, i.e.
boolean equals(final Object o)
RenderAttachment(final Type type, final int iFormat, final int samples, final int width, final int height, final int name)
TextureAttachment(final Type type, final int iFormat, final int width, final int height, final int dataFormat, final int dataType, final int magFilter, final int minFilter, final int wrapS, final int wrapT, final int name)
final ColorAttachment getColorAttachment()
Casts this object to a ColorAttachment reference, see isTextureAttachment().
final boolean isTextureAttachment()
Returns true if instance is of type TextureAttachment and false if instance is of type ColorAttachmen...
final TextureAttachment getTextureAttachment()
Casts this object to a TextureAttachment reference, see isTextureAttachment().
void free(final GL gl)
Releases the color buffer if initialized, i.e.
boolean initialize(final GL gl)
Initializes the texture and set it's parameter, if uninitialized, i.e.
final int dataFormat
details of the texture setup
Core utility class simplifying usage of framebuffer objects (FBO) with all GLProfiles.
final void attachRenderbufferImpl(final GL gl, final Attachment.Type atype, final int internalFormat)
final boolean isInitialized()
Returns true if this instance has been initialized with reset(GL, int, int) or reset(GL,...
final void detachAllRenderbuffer(final GL gl)
static final TextureAttachment createColorTextureAttachment(final int internalFormat, final int width, final int height, final int dataFormat, final int dataType, final int magFilter, final int minFilter, final int wrapS, final int wrapT)
Creates a color TextureAttachment, i.e.
static final String getStatusString(final int fbStatus)
final void attachRenderbuffer(final GL gl, final Attachment.Type atype, final int reqBits)
Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,...
final void bind(final GL gl)
Bind this FBO, i.e.
final TextureAttachment attachTexture2D(final GL gl, final int attachmentPoint, final boolean alpha)
Attaches a Colorbuffer, i.e.
final int getReadFramebuffer()
Returns the framebuffer name to read from.
static final TextureAttachment createColorTextureAttachment(final GL gl, final boolean alpha, final int width, final int height, final int magFilter, final int minFilter, final int wrapS, final int wrapT)
Creates a color TextureAttachment, i.e.
final int getWriteFramebuffer()
Returns the framebuffer name to render to.
static final int REQUESTED_BITS
Request current context drawable's requested depth- or stencil-bits; value {@value}.
final boolean supportsStencil(final int bits)
Returns true if GL#GL_STENCIL_INDEX1, GL#GL_STENCIL_INDEX4, GL#GL_STENCIL_INDEX8 or GL2GL3#GL_STENCIL...
final Colorbuffer attachColorbuffer(final GL gl, final int attachmentPoint, final Colorbuffer colbuf)
Attaches a Colorbuffer at the given attachment point and initializes it, if not done yet.
final boolean supportsRGBA8()
Returns true if renderbuffer accepts internal format GL#GL_RGB8 and GL#GL_RGBA8, otherwise false.
static final boolean DEBUG
static final TextureAttachment createColorTextureAttachment(final GL gl, final int internalFormat, final int width, final int height, final int magFilter, final int minFilter, final int wrapS, final int wrapT)
final void formatToGLCapabilities(final GLCapabilities caps)
Writes the internal format of the attachments to the given GLCapabilities object.
static final TextureAttachment createColorTextureAttachment(final GL gl, final boolean alpha, final int width, final int height)
Creates a color TextureAttachment, i.e.
final int getMaxTextureSize()
final String getStatusString()
return the getStatus() as a string.
final int getNumSamples()
Returns the number of samples for multisampling (MSAA).
final boolean hasAttachmentUsingAlpha()
Returns true if any attached Colorbuffer uses alpha, otherwise false.
final RenderAttachment getDepthAttachment()
Return the depth RenderAttachment attachment.
final TextureAttachment attachTexture2D(final GL gl, final int attachmentPoint, final boolean alpha, final int magFilter, final int minFilter, final int wrapS, final int wrapT)
Attaches a Colorbuffer, i.e.
static final int MAXIMUM_BITS
Request maximum bit count for depth- or stencil buffer (depth 32 bits, stencil 16 bits),...
final int getWidth()
Returns the width.
final void detachAllColorbuffer(final GL gl)
Detaches all ColorAttachments and TextureAttachments and disposes them.
FBObject setSamplingSink(final FBObject newSamplingSink)
Setting this FBO sampling sink.
final boolean isStatusValid()
The status may even be valid if incomplete during transition of attachments.
static final RenderAttachment createRenderAttachment(final Type type, final int internalFormat, final int samples, final int width, final int height)
final boolean supportsPackedDepthStencil()
Returns true if GL#GL_DEPTH24_STENCIL8 is supported, otherwise false.
final int getDefaultReadBuffer()
final boolean isModified()
Returns true if size, sample-count or any attachment of this instance or its sampling-sink has been m...
final ColorAttachment createColorAttachment(final boolean alpha)
Creates a ColorAttachment, selecting the format automatically.
final void destroy(final GL gl)
final Colorbuffer detachColorbuffer(final GL gl, final int attachmentPoint, final boolean dispose)
Detaches a Colorbuffer, i.e.
final int getMaxColorAttachments()
Returns the maximum number of colorbuffer attachments.
final void attachRenderbuffer(final GL gl, final int internalFormat)
Attaches one depth, stencil or packed-depth-stencil buffer to this FBO's instance,...
final int getHeight()
Returns the height.
final int getMaxSamples()
final RenderAttachment getStencilAttachment()
Return the stencil RenderAttachment attachment, if exist.
final int getDefaultDrawBuffer()
final void syncSamplingSink(final GL gl)
If multisampling is being used and flagged dirty by a previous call of bind(GL) or after initializati...
final boolean isSamplingBufferDirty()
Returns true if the multisampling colorbuffer (msaa-buffer) has been flagged dirty by a previous call...
final boolean isDepthStencilPackedFormat()
final void unuse(final GL gl)
Unbind texture, ie bind 'non' texture 0.
final void use(final GL gl, final TextureAttachment ta)
Synchronize the sampling sink and bind the given TextureAttachment, if not null.
final void markUnbound()
Method simply marks this FBO unbound w/o interfering w/ the bound framebuffer as perfomed by unbind(G...
final TextureAttachment attachTexture2D(final GL gl, final int attachmentPoint, final int internalFormat, final int dataFormat, final int dataType, final int magFilter, final int minFilter, final int wrapS, final int wrapT)
Attaches a Colorbuffer, i.e.
final void detachRenderbuffer(final GL gl, final Attachment.Type atype, final boolean dispose)
final Colorbuffer getSamplingSink()
Return the multisampling Colorbuffer sink, if using multisampling.
static final int DEFAULT_BITS
Request default bit count for depth- or stencil buffer (depth 24 bits, stencil 8 bits),...
static final ColorAttachment createColorAttachment(final int internalFormat, final int samples, final int width, final int height)
Creates a ColorAttachment, selecting the format automatically.
final boolean hasFullFBOSupport()
final boolean resetSamplingSink(final GL gl)
Manually validates the MSAA sampling sink, if used.
final ColorAttachment attachColorbuffer(final GL gl, final int attachmentPoint, final boolean alpha)
Attaches a newly created and initialized Colorbuffer, i.e.
final Colorbuffer getColorbuffer(final Colorbuffer ca)
Returns the passed Colorbuffer if it is attached to this FBO, otherwise null.
final boolean supportsDepth(final int bits)
Returns true if GL#GL_DEPTH_COMPONENT16, GL#GL_DEPTH_COMPONENT24 or GL#GL_DEPTH_COMPONENT32 is suppor...
FBObject()
Creates an uninitialized FBObject instance.
final boolean isBound(final GL gl)
Returns true if framebuffer object is bound via bind(GL), otherwise false.
final void detachAll(final GL gl)
Detaches all ColorAttachments, TextureAttachments and RenderAttachments and disposes them.
final int getColorbufferAttachmentPoint(final Colorbuffer ca)
Finds the passed Colorbuffer within the valid range of attachment points using reference comparison o...
final int getTextureAttachmentCount()
Return the number of attached TextureAttachments.
final int getColorbufferCount()
Return the number of attached Colorbuffers.
final ColorAttachment attachColorbuffer(final GL gl, final int attachmentPoint, final int internalFormat)
Attaches a newly created and initialized Colorbuffer, i.e.
final void unbind(final GL gl)
Unbind this FBO, i.e.
final boolean isBound()
Returns true if framebuffer object is bound via bind(GL), otherwise false.
final boolean reset(final GL gl, int newWidth, int newHeight, int newSamples)
Resets this FBO's instance.
final int getMaxRenderbufferSize()
static final int CHOSEN_BITS
Request current context drawable's chosen depth- or stencil-bits; value {@value}.
final int getStatus()
Note that the status may reflect an incomplete state during transition of attachments.
void init(final GL gl, final int newWidth, final int newHeight, final int newSamples)
Initializes this FBO's instance.
final FBObject getSamplingSinkFBO()
Return the complete multisampling FBObject sink, if using multisampling.
final Colorbuffer getColorbuffer(final int attachmentPoint)
Return the Colorbuffer attachment at attachmentPoint if it is attached to this FBO,...
final void detachAllTexturebuffer(final GL gl)
Detaches all TextureAttachments and disposes them.
Specifies a set of OpenGL capabilities.
void setStencilBits(final int stencilBits)
Sets the number of bits requested for the stencil buffer.
void setNumSamples(final int numSamples)
If sample buffers are enabled, indicates the number of buffers to be allocated.
void setSampleBuffers(final boolean enable)
Defaults to false.
void setDepthBits(final int depthBits)
Sets the number of bits requested for the depth buffer.
Abstraction for an OpenGL rendering context.
abstract GLDrawable getGLDrawable()
Returns the write-drawable this context uses for framebuffer operations.
static final boolean DEBUG_GL
Reflects property jogl.debug.DebugGL.
final String getGLVersion()
Returns a valid OpenGL version string, ie
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Class holding OpenGL extension strings, commonly used by JOGL's implementation.
static final String NV_fbo_color_attachments
static final String OES_stencil8
static final String OES_depth24
static final String OES_depth32
static final String EXT_packed_depth_stencil
static final String OES_packed_depth_stencil
static final String OES_stencil4
static final String OES_stencil1
static final String OES_rgb8_rgba8
static StringBuilder getGLStrings(final GL gl, final StringBuilder sb)
static Type determine(final int format)
Returns COLOR, DEPTH, STENCIL or DEPTH_STENCIL.
Interface abstraction to allow custom definitions of Attachment's storage.
void setStorage(final GL gl, final Attachment a)
Set or create the Attachment's storage after generating its name and binding it to the target.
Generic color buffer FBO attachment, either of type ColorAttachment or TextureAttachment.
int getFormat()
internal format of colorbuffer
int getWidth()
width of colorbuffer
boolean initialize(final GL gl)
Initializes the color buffer and set it's parameter, if uninitialized, i.e.
TextureAttachment getTextureAttachment()
Casts this object to a TextureAttachment reference, see isTextureAttachment().
void formatToGLCapabilities(final GLCapabilities caps, final boolean rgba8Avail)
Writes the internal format to the given GLCapabilities object.
void free(final GL gl)
Releases the color buffer if initialized, i.e.
int getHeight()
height of colorbuffer
boolean isTextureAttachment()
Returns true if instance is of type TextureAttachment and false if instance is of type ColorAttachmen...
int getName()
colorbuffer name [1..max]
ColorAttachment getColorAttachment()
Casts this object to a ColorAttachment reference, see isTextureAttachment().
static final int GL_MAX_COLOR_ATTACHMENTS
GL_ES_VERSION_3_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_draw_buffers,...
static final int GL_FRAMEBUFFER_UNDEFINED
GL_ES_VERSION_3_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_OES_surfaceless_context Alias for: G...
static final int GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object Alias for: GL_FRAMEBUFFER_INCOMP...
static final int GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object Alias for: GL_FRAMEBUFFER_INCOMP...
static final int GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS
GL_ES_VERSION_3_2, GL_VERSION_3_2, GL_NV_geometry_program4, GL_EXT_geometry_shader4,...
boolean hasBasicFBOSupport()
Returns true if basic FBO support is available, otherwise false.
boolean isGLES()
Indicates whether this GL object conforms to one of the OpenGL ES profiles, see isGLES1(),...
int getMaxRenderbufferSamples()
Returns the maximum number of FBO RENDERBUFFER samples if full FBO is supported, otherwise false.
int getBoundFramebuffer(int target)
Return the framebuffer name bound to this context, see GL#glBindFramebuffer(int, int).
boolean isGL2ES3()
Indicates whether this GL object conforms to a either a GL2GL3 or GL3ES3 compatible profile.
boolean isExtensionAvailable(String glExtensionName)
Returns true if the specified OpenGL extension can be used successfully through this GL instance give...
GLContext getContext()
Returns the GLContext associated which this GL object.
boolean isGLES3()
Indicates whether this GL object conforms to the OpenGL ES ≥ 3.0 profile.
boolean hasFullFBOSupport()
Returns true if full FBO support is available, otherwise false.
Specifies an immutable set of OpenGL capabilities.
int getDepthBits()
Returns the number of depth buffer bits.
int getStencilBits()
Returns the number of stencil buffer bits.
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
GLCapabilitiesImmutable getRequestedGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the user requested OpenGL capabilities (pixel fo...
void glFramebufferTexture2D(int target, int attachment, int textarget, int texture, int level)
Entry point to C language function: void {@native glFramebufferTexture2D}(GLenum target,...
static final int GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
static final int GL_TEXTURE_MAG_FILTER
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_MAG_FILTER" w...
static final int GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_OES_framebuffer_object,...
static final int GL_READ_FRAMEBUFFER
GL_ES_VERSION_3_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_blit,...
static final int GL_RGBA4
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_EXT_texture, GL_OES_framebuffer_object, GL_OES_required_interna...
void glGetIntegerv(int pname, IntBuffer data)
Entry point to C language function: void {@native glGetIntegerv}(GLenum pname, GLint * data) Part ...
static final int GL_RGB8
GL_ES_VERSION_3_0, GL_VERSION_1_1, GL_EXT_texture, GL_OES_rgb8_rgba8, GL_OES_required_internalformat ...
static final int GL_BGRA
GL_VERSION_1_2, GL_IMG_read_format, GL_APPLE_texture_format_BGRA8888, GL_EXT_texture_format_BGRA8888,...
static final int GL_INVALID_VALUE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_INVALID_VALUE" with e...
static final int GL_RGB
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_RGB" with expression ...
static final int GL_TEXTURE_2D
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_2D" with expr...
static final int GL_TEXTURE_WRAP_S
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_WRAP_S" with ...
void glDeleteTextures(int n, IntBuffer textures)
Entry point to C language function: void {@native glDeleteTextures}(GLsizei n, const GLuint * textur...
void glBindTexture(int target, int texture)
Entry point to C language function: void {@native glBindTexture}(GLenum target, GLuint texture) Pa...
void glGenTextures(int n, IntBuffer textures)
Entry point to C language function: void {@native glGenTextures}(GLsizei n, GLuint * textures) Par...
int glCheckFramebufferStatus(int target)
Entry point to C language function: GLenum {@native glCheckFramebufferStatus}(GLenum target) Part ...
static final int GL_STENCIL_INDEX8
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
static final int GL_RGB565
GL_ARB_ES2_compatibility, GL_ES_VERSION_2_0, GL_VERSION_4_1, GL_OES_framebuffer_object,...
void glDeleteRenderbuffers(int n, IntBuffer renderbuffers)
Entry point to C language function: void {@native glDeleteRenderbuffers}(GLsizei n,...
void glRenderbufferStorage(int target, int internalformat, int width, int height)
Entry point to C language function: void {@native glRenderbufferStorage}(GLenum target,...
static final int GL_NO_ERROR
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_NO_ERROR" with expres...
static final int GL_MAX_RENDERBUFFER_SIZE
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_OES_framebuffer_object,...
int glGetError()
Entry point to C language function: GLenum {@native glGetError}() Part of GL_ES_VERSION_2_0,...
void glGenFramebuffers(int n, IntBuffer framebuffers)
Entry point to C language function: void {@native glGenFramebuffers}(GLsizei n, GLuint * framebuffer...
static final int GL_STENCIL_INDEX4
GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object, GL_OES_stencil4 Alias for: GL_S...
static final int GL_RENDERBUFFER
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
void glDeleteFramebuffers(int n, IntBuffer framebuffers)
Entry point to C language function: void {@native glDeleteFramebuffers}(GLsizei n,...
static final int GL_TEXTURE_MIN_FILTER
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_MIN_FILTER" w...
static final int GL_COLOR_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_COLOR_BUFFER_BIT" wit...
static final int GL_RGBA8
GL_ES_VERSION_3_0, GL_VERSION_1_1, GL_OES_rgb8_rgba8, GL_OES_required_internalformat,...
boolean glIsFramebuffer(int framebuffer)
Entry point to C language function: GLboolean {@native glIsFramebuffer}(GLuint framebuffer) Part o...
void glFramebufferRenderbuffer(int target, int attachment, int renderbuffertarget, int renderbuffer)
Entry point to C language function: void {@native glFramebufferRenderbuffer}(GLenum target,...
static final int GL_DEPTH_COMPONENT32
GL_VERSION_1_4, GL_ARB_depth_texture, GL_SGIX_depth_texture, GL_OES_depth32 Alias for: GL_DEPTH_COMPO...
static final int GL_COLOR_ATTACHMENT0
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_NV_draw_buffers, GL_OES_framebuffer_...
static final int GL_TEXTURE_WRAP_T
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_TEXTURE_WRAP_T" with ...
void glTexParameteri(int target, int pname, int param)
Entry point to C language function: void {@native glTexParameteri}(GLenum target,...
static final int GL_FRAMEBUFFER_COMPLETE
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
static final int GL_FRAMEBUFFER_INCOMPLETE_FORMATS
Part of GL_EXT_framebuffer_object; GL_ES_VERSION_2_0; GL_OES_framebuffer_object
static final int GL_STENCIL_INDEX1
GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object, GL_OES_stencil1 Alias for: GL_S...
void glBindFramebuffer(int target, int framebuffer)
Entry point to C language function: void {@native glBindFramebuffer}(GLenum target,...
static final int GL_NEAREST
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_NEAREST" with express...
static final int GL_DEPTH_COMPONENT16
GL_ES_VERSION_2_0, GL_VERSION_1_4, GL_ARB_depth_texture, GL_OES_framebuffer_object,...
static final int GL_RGBA
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_RGBA" with expression...
static final int GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
GL_ES_VERSION_2_0, GL_EXT_framebuffer_object, GL_OES_framebuffer_object Alias for: GL_FRAMEBUFFER_INC...
static final int GL_FRAMEBUFFER_UNSUPPORTED
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
static final int GL_MAX_TEXTURE_SIZE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_MAX_TEXTURE_SIZE" wit...
void glRenderbufferStorageMultisample(int target, int samples, int internalformat, int width, int height)
Entry point to C language function: void {@native glRenderbufferStorageMultisample}(GLenum target,...
void glTexImage2D(int target, int level, int internalformat, int width, int height, int border, int format, int type, Buffer pixels)
Entry point to C language function: void {@native glTexImage2D}(GLenum target, GLint level,...
static final int GL_DRAW_FRAMEBUFFER
GL_ES_VERSION_3_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_NV_framebuffer_blit,...
static final int GL_DEPTH_COMPONENT24
GL_ES_VERSION_3_0, GL_VERSION_1_4, GL_ARB_depth_texture, GL_OES_depth24, GL_SGIX_depth_texture Alias ...
static final int GL_CLAMP_TO_EDGE
GL_ES_VERSION_2_0, GL_VERSION_1_2, GL_VERSION_ES_1_0, GL_SGIS_texture_edge_clamp Alias for: GL_CLAMP_...
static final int GL_DEPTH_ATTACHMENT
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
static final int GL_UNSIGNED_BYTE
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_UNSIGNED_BYTE" with e...
static final int GL_DEPTH24_STENCIL8
GL_ES_VERSION_3_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_packed_depth_stencil,...
static final int GL_STENCIL_ATTACHMENT
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_EXT_framebuffer_object,...
static final int GL_FRAMEBUFFER
GL_ES_VERSION_2_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_OES_framebuffer_object,...
static final int GL_RGB5_A1
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_OES_framebuffer_object, GL_OES_required_internalformat,...
static final int GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
GL_ES_VERSION_3_0, GL_ARB_framebuffer_object, GL_VERSION_3_0, GL_IMG_multisampled_render_to_texture,...