aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes/com/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2014-05-26 19:15:42 +0200
committerSven Gothel <[email protected]>2014-05-26 19:15:42 +0200
commitd354cf767182c27f44ad4c00d2e975f8d689daa8 (patch)
treee3e0164592c040045ddadf91d8b7c0ddbc220407 /src/jogl/classes/com/jogamp
parent2790c756d5b88448d14cc302036581a57f3ffd53 (diff)
Bug 1009: Make FBObject's sampling sink format compatible w/ sampling source if possible (ES3 spec requirement)
Make FBObject's sampling sink format compatible w/ sampling source if possible, i.e. for all GL profiles but ES1 and ES2. This is an ES3 spec requirement: For ES3, sampling-sink colorbuffer format must be equal w/ the sampling-source Colorbuffer. ES3 BlitFramebuffer Requirements: OpenGL ES 3.0.2 p194: 4.3.2 Copying Pixels: If SAMPLE_BUFFERS for the read framebuffer is greater than zero, no copy is performed and an INVALID_OPERATION error is generated if the formats of the read and draw framebuffers are not identical or if the source and destination rectangles are not defined with the same (X0, Y 0) and (X1, Y 1) bounds. Texture and Renderbuffer format details: ES2 Base iFormat: OpenGL ES 2.0.24 p66: 3.7.1 Texture Image Specification, Table 3.8 - ALPHA, LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA ES3 Base iFormat: OpenGL ES 3.0.2 p125: 3.8.3 Texture Image Specification, Table 3.11 - ALPHA, LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA DEPTH_COMPONENT, STENCIL_COMPONENT, RED, RG ES3 Required Texture and Renderbuffer iFormat: OpenGL ES 3.0.2 p126: 3.8.3 Texture Image Specification - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I, RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and RGB5_A1. - RGB8 and RGB565. - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI. - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI. +++ Our implementation shall attempt to use the same format for the sampling-source and -sink wherever possible, e.g. GL2ES3 (excluding ES1 and ES2)!
Diffstat (limited to 'src/jogl/classes/com/jogamp')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/FBObject.java114
1 files changed, 97 insertions, 17 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/FBObject.java b/src/jogl/classes/com/jogamp/opengl/FBObject.java
index 33751eab9..a9b54097f 100644
--- a/src/jogl/classes/com/jogamp/opengl/FBObject.java
+++ b/src/jogl/classes/com/jogamp/opengl/FBObject.java
@@ -550,21 +550,52 @@ public class FBObject {
*
* <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 gl the used {@link GLContext}'s {@link GL} object
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
* @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);
+ public static final TextureAttachment createColorTextureAttachment(GL gl, boolean alpha, int width, int height) {
+ return createColorTextureAttachment(gl, 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},
* selecting the texture data type and format automatically.
+ * <p>
+ * For GLES3, sampling-sink format <b>must be equal</b> w/ the sampling-source {@link Colorbuffer},
+ * see details below. Implementation aligns w/ {@link #createColorAttachment(boolean)}
+ * and is enforced via {@link #sampleSinkFormatMismatch(GL)}.
+ * </p>
+ * <p>
+ * ES3 BlitFramebuffer Requirements: OpenGL ES 3.0.2 p194: 4.3.2 Copying Pixels
+ * <pre>
+ * If SAMPLE_BUFFERS for the read framebuffer is greater than zero, no copy
+ * is performed and an INVALID_OPERATION error is generated if the formats of
+ * the read and draw framebuffers are not identical or if the source and destination
+ * rectangles are not defined with the same (X0, Y 0) and (X1, Y 1) bounds.
+ * </pre>
+ * Texture and Renderbuffer format details:
+ * <pre>
+ * ES2 Base iFormat: OpenGL ES 2.0.24 p66: 3.7.1 Texture Image Specification, Table 3.8
+ * ALPHA, LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA
+ *
+ * ES3 Base iFormat: OpenGL ES 3.0.2 p125: 3.8.3 Texture Image Specification, Table 3.11
+ * ALPHA, LUMINANCE, LUMINANCE_ALPHA, RGB, RGBA
+ * DEPTH_COMPONENT, STENCIL_COMPONENT, RED, RG
*
- * @param glp the chosen {@link GLProfile}
+ * ES3 Required Texture and Renderbuffer iFormat: OpenGL ES 3.0.2 p126: 3.8.3 Texture Image Specification
+ * - RGBA32I, RGBA32UI, RGBA16I, RGBA16UI, RGBA8, RGBA8I,
+ * RGBA8UI, SRGB8_ALPHA8, RGB10_A2, RGB10_A2UI, RGBA4, and
+ * RGB5_A1.
+ * - RGB8 and RGB565.
+ * - RG32I, RG32UI, RG16I, RG16UI, RG8, RG8I, and RG8UI.
+ * - R32I, R32UI, R16I, R16UI, R8, R8I, and R8UI.
+ * </pre>
+ * </p>
+ *
+ * @param gl the used {@link GLContext}'s {@link GL} object
* @param alpha set to <code>true</code> if you request alpha channel, otherwise <code>false</code>;
* @param width texture width
* @param height texture height
@@ -574,10 +605,14 @@ public class FBObject {
* @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(GL gl, boolean alpha, int width, int height,
int magFilter, int minFilter, int wrapS, int wrapT) {
final int textureInternalFormat, textureDataFormat, textureDataType;
- if(glp.isGLES()) {
+ if(gl.isGLES3()) {
+ textureInternalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8;
+ textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
+ textureDataType = GL.GL_UNSIGNED_BYTE;
+ } else if(gl.isGLES()) {
textureInternalFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
textureDataFormat = alpha ? GL.GL_RGBA : GL.GL_RGB;
textureDataType = GL.GL_UNSIGNED_BYTE;
@@ -744,6 +779,26 @@ public class FBObject {
}
/**
+ * Returns true if any attached {@link Colorbuffer} uses alpha,
+ * otherwise false.
+ */
+ public final boolean hasAttachmentUsingAlpha() {
+ final int caCount = getColorAttachmentCount();
+ boolean hasAlpha = false;
+ for(int i=0; i<caCount; i++) {
+ final Attachment ca = (Attachment)getColorbuffer(i);
+ if( null == ca ) {
+ break;
+ }
+ if( hasAlpha(ca.format) ) {
+ hasAlpha = true;
+ break;
+ }
+ }
+ return hasAlpha;
+ }
+
+ /**
* Creates an uninitialized FBObject instance.
* <p>
* Call {@link #init(GL, int, int, int)} .. etc to use it.
@@ -1142,7 +1197,7 @@ public class FBObject {
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha) throws GLException {
return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
- createColorTextureAttachment(gl.getGLProfile(), alpha, width, height));
+ createColorTextureAttachment(gl, alpha, width, height));
}
/**
@@ -1164,7 +1219,7 @@ public class FBObject {
*/
public final TextureAttachment attachTexture2D(GL gl, int attachmentPoint, boolean alpha, int magFilter, int minFilter, int wrapS, int wrapT) throws GLException {
return (TextureAttachment)attachColorbuffer(gl, attachmentPoint,
- createColorTextureAttachment(gl.getGLProfile(), alpha, width, height, magFilter, minFilter, wrapS, wrapT));
+ createColorTextureAttachment(gl, alpha, width, height, magFilter, minFilter, wrapS, wrapT));
}
/**
@@ -1194,12 +1249,18 @@ public class FBObject {
/**
* Creates a {@link ColorAttachment}, selecting the format automatically.
+ * <p>
+ * For GLES3, sampling-sink {@link Colorbuffer} format <b>must be equal</b> w/ the sampling-source {@link Colorbuffer}.
+ * Implementation aligns w/ {@link #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int)}
+ * and is enforced via {@link #sampleSinkFormatMismatch(GL)}.
+ * </p>
*
* @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
*/
public final ColorAttachment createColorAttachment(boolean alpha) {
final int internalFormat;
+
if( rgba8Avail ) {
internalFormat = alpha ? GL.GL_RGBA8 : GL.GL_RGB8 ;
} else {
@@ -1591,7 +1652,7 @@ public class FBObject {
samplingSinkTexture.magFilter, samplingSinkTexture.minFilter,
samplingSinkTexture.wrapS, samplingSinkTexture.wrapT);
} else {
- colbuf = createColorTextureAttachment(gl.getGLProfile(), true, width, height);
+ colbuf = createColorTextureAttachment(gl, true, width, height);
}
}
attachColorbuffer(gl, attachmentPoint, colbuf);
@@ -1944,6 +2005,19 @@ public class FBObject {
return depthMismatch || stencilMismatch;
}
+ /**
+ * For GLES3, sampling-sink {@link Colorbuffer} format <b>must be equal</b> w/ the sampling-source {@link Colorbuffer}.
+ * Implementation aligns w/ {@link #createColorTextureAttachment(GLProfile, boolean, int, int, int, int, int, int)}
+ * and {@link #createColorAttachment(boolean)}.
+ */
+ private final boolean sampleSinkFormatMismatch(final GL gl) {
+ if( null != samplingSinkTexture && getColorAttachmentCount() > 0 && gl.isGL2ES3() ) {
+ final Attachment ca = (Attachment)getColorbuffer(0); // should be at attachment-point 0
+ return ( null != ca && ca.format != samplingSinkTexture.format ) ||
+ hasAlpha(samplingSinkTexture.format) != hasAttachmentUsingAlpha();
+ }
+ return false;
+ }
/**
* Manually reset the MSAA sampling sink, if used.
@@ -1980,16 +2054,17 @@ public class FBObject {
samplingSink.init(gl, width, height, 0);
}
+ boolean sampleSinkFormatMismatch = sampleSinkFormatMismatch(gl);
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);
+ "\n\t format "+sampleSinkFormatMismatch+", size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
} */
- if(!sampleSinkSizeMismatch && !sampleSinkTexMismatch && !sampleSinkDepthStencilMismatch) {
+ if(!sampleSinkFormatMismatch && !sampleSinkSizeMismatch && !sampleSinkTexMismatch && !sampleSinkDepthStencilMismatch) {
// all properties match ..
return;
}
@@ -1998,19 +2073,23 @@ public class FBObject {
if(DEBUG) {
System.err.println("FBObject.resetSamplingSink: BEGIN\n\tTHIS "+this+",\n\tSINK "+samplingSink+
- "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+ "\n\t format "+sampleSinkFormatMismatch+", size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
if( sampleSinkDepthStencilMismatch ) {
samplingSink.detachAllRenderbuffer(gl);
}
- if( sampleSinkSizeMismatch ) {
+ if( sampleSinkFormatMismatch ) {
+ samplingSink.detachAllColorbuffer(gl);
+ samplingSinkTexture = null;
+ } else if( sampleSinkSizeMismatch ) {
samplingSink.reset(gl, width, height);
}
if(null == samplingSinkTexture) {
- samplingSinkTexture = samplingSink.attachTexture2D(gl, 0, true);
+ boolean hasAlpha = hasAttachmentUsingAlpha();
+ samplingSinkTexture = samplingSink.attachTexture2D(gl, 0, hasAlpha);
} else if( 0 == samplingSinkTexture.getName() ) {
samplingSinkTexture.setSize(width, height);
samplingSink.attachColorbuffer(gl, 0, samplingSinkTexture);
@@ -2023,17 +2102,18 @@ public class FBObject {
}
}
+ sampleSinkFormatMismatch = sampleSinkFormatMismatch(gl);
sampleSinkSizeMismatch = sampleSinkSizeMismatch();
sampleSinkTexMismatch = sampleSinkTexMismatch();
sampleSinkDepthStencilMismatch = sampleSinkDepthStencilMismatch();
- if(sampleSinkSizeMismatch || sampleSinkTexMismatch || sampleSinkDepthStencilMismatch) {
+ if(sampleSinkFormatMismatch || sampleSinkSizeMismatch || sampleSinkTexMismatch || sampleSinkDepthStencilMismatch) {
throw new InternalError("Samples sink mismatch after reset: \n\tTHIS "+this+",\n\t SINK "+samplingSink+
- "\n\t size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
+ "\n\t format "+sampleSinkFormatMismatch+", 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);
+ "\n\t format "+sampleSinkFormatMismatch+", size "+sampleSinkSizeMismatch +", tex "+sampleSinkTexMismatch +", depthStencil "+sampleSinkDepthStencilMismatch);
}
}