From 6fe3e99dab9721294a3bf72eaea77af33afc9481 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 7 Sep 2013 16:57:47 +0200 Subject: Fix TileRenderer*: Allow general usage w/ any GL profile, only image-buffer requires >= GL2ES3; Always set pack-alignment, Set glReadBuffer(..) >= GL2ES3 - Allow general usage w/ any GL profile, only image-buffer requires >= GL2ES3 Due to GL2ES3.GL_PACK_ROW_LENGTH and image-width != tile-width - Always set pack-alignment Forgot for tile-buffer - Set glReadBuffer(..) >= GL2ES3 Required if using FBO offscreen, i.e. MSAA mode. --- .../com/jogamp/opengl/util/RandomTileRenderer.java | 19 +++++-- .../com/jogamp/opengl/util/TileRenderer.java | 23 ++++++--- .../com/jogamp/opengl/util/TileRendererBase.java | 60 ++++++++++++++++------ 3 files changed, 77 insertions(+), 25 deletions(-) (limited to 'src/jogl/classes/com/jogamp/opengl') diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java index 4fcf0b6cc..2b698d2f5 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java @@ -27,8 +27,10 @@ */ package com.jogamp.opengl.util; +import javax.media.opengl.GL; import javax.media.opengl.GL2ES3; import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLException; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; @@ -92,13 +94,14 @@ public class RandomTileRenderer extends TileRendererBase { * @throws IllegalStateException if image-size, pmvMatrixCB or tileRect has not been set */ @Override - public final void beginTile(GL2ES3 gl) throws IllegalStateException { + public final void beginTile(GL gl) throws IllegalStateException, GLException { if( 0 >= imageSize.getWidth() || 0 >= imageSize.getHeight() ) { throw new IllegalStateException("Image size has not been set"); } if( !tileRectSet ) { throw new IllegalStateException("tileRect has not been set"); } + validateGL(gl); gl.glViewport( 0, 0, currentTileWidth, currentTileHeight ); // Do not forget to issue: @@ -109,16 +112,25 @@ public class RandomTileRenderer extends TileRendererBase { } @Override - public void endTile( GL2ES3 gl ) throws IllegalStateException { + public void endTile( GL gl ) throws IllegalStateException, GLException { if( !beginCalled ) { throw new IllegalStateException("beginTile(..) has not been called"); } + validateGL(gl); // be sure OpenGL rendering is finished gl.glFlush(); // save current glPixelStore values psm.save(gl); + psm.setPackAlignment(gl, 1); + final GL2ES3 gl2es3; + if( gl.isGL2ES3() ) { + gl2es3 = gl.getGL2ES3(); + gl2es3.glReadBuffer(gl2es3.getDefaultReadBuffer()); + } else { + gl2es3 = null; + } final int tmp[] = new int[1]; @@ -149,8 +161,7 @@ public class RandomTileRenderer extends TileRendererBase { /* setup pixel store for glReadPixels */ final int rowLength = imageSize.getWidth(); - psm.setPackRowLength(gl, rowLength); - psm.setPackAlignment(gl, 1); + psm.setPackRowLength(gl2es3, rowLength); /* read the tile into the final image */ final int readPixelSize = GLBuffers.sizeof(gl, tmp, pixelAttribs.bytesPerPixel, srcWidth, srcHeight, 1, true); diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java index 695e2d93d..46a1e2452 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java @@ -37,7 +37,9 @@ package com.jogamp.opengl.util; import javax.media.nativewindow.util.Dimension; +import javax.media.opengl.GL; import javax.media.opengl.GL2ES3; +import javax.media.opengl.GLException; import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; @@ -248,10 +250,11 @@ public class TileRenderer extends TileRendererBase { } @Override - public final void beginTile( GL2ES3 gl ) throws IllegalStateException { + public final void beginTile( GL gl ) throws IllegalStateException, GLException { if( 0 >= imageSize.getWidth() || 0 >= imageSize.getHeight() ) { throw new IllegalStateException("Image size has not been set"); } + validateGL(gl); if (currentTile <= 0) { setup(); } @@ -311,19 +314,28 @@ public class TileRenderer extends TileRendererBase { } @Override - public void endTile( GL2ES3 gl ) throws IllegalStateException { + public void endTile( GL gl ) throws IllegalStateException, GLException { if( !beginCalled ) { throw new IllegalStateException("beginTile(..) has not been called"); } + validateGL(gl); // be sure OpenGL rendering is finished gl.glFlush(); // save current glPixelStore values psm.save(gl); - + psm.setPackAlignment(gl, 1); + final GL2ES3 gl2es3; + if( gl.isGL2ES3() ) { + gl2es3 = gl.getGL2ES3(); + gl2es3.glReadBuffer(gl2es3.getDefaultReadBuffer()); + } else { + gl2es3 = null; + } + final int tmp[] = new int[1]; - + if( tileBuffer != null ) { final GLPixelAttributes pixelAttribs = tileBuffer.pixelAttributes; final int srcX = tileBorder; @@ -351,8 +363,7 @@ public class TileRenderer extends TileRendererBase { /* setup pixel store for glReadPixels */ final int rowLength = imageSize.getWidth(); - psm.setPackRowLength(gl, rowLength); - psm.setPackAlignment(gl, 1); + psm.setPackRowLength(gl2es3, rowLength); /* read the tile into the final image */ final int readPixelSize = GLBuffers.sizeof(gl, tmp, pixelAttribs.bytesPerPixel, srcWidth, srcHeight, 1, true); diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java index 5baa1e4a5..e7296ab0a 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java @@ -38,9 +38,11 @@ package com.jogamp.opengl.util; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.DimensionImmutable; +import javax.media.opengl.GL; import javax.media.opengl.GL2ES3; import javax.media.opengl.GLAutoDrawable; import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; /** * A fairly direct port of Brian Paul's tile rendering library, found @@ -53,18 +55,32 @@ import javax.media.opengl.GLEventListener; * for license information. *

*

- * Enhanced for {@link GL2ES3}, abstracted to suit {@link TileRenderer} and {@link RandomTileRenderer}. + * Enhanced for {@link GL} and {@link GL2ES3}, abstracted to suit {@link TileRenderer} and {@link RandomTileRenderer}. *

*
PMV Matrix Considerations
*

* The PMV matrix needs to be reshaped in user code - * after calling {@link #beginTile(GL2ES3)}, See {@link #beginTile(GL2ES3)}. + * after calling {@link #beginTile(GL)}, See {@link #beginTile(GL)}. *

*

* If {@link #attachToAutoDrawable(GLAutoDrawable) attaching to} an {@link GLAutoDrawable}, * the {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int)} method - * is being called after {@link #beginTile(GL2ES3)}. - * It's implementation shall reshape the PMV matrix according to {@link #beginTile(GL2ES3)}. + * is being called after {@link #beginTile(GL)}. + * It's implementation shall reshape the PMV matrix according to {@link #beginTile(GL)}. + *

+ *
GL Profile Requirement
+ *

+ * Note that {@link #setImageBuffer(GLPixelBuffer) image buffer} can only be used + * in conjunction w/ a {@link GL} instance ≥ {@link GL2ES3} passed to {@link #beginTile(GL)} and {@link #endTile(GL)}.
+ * This is due to setting up the {@link GL2ES3#GL_PACK_ROW_LENGTH pack row length} + * for an {@link #setImageSize(int, int) image width} != tile-width, which usually is the case.
+ * Hence a {@link GLException} is thrown in both methods, + * if using an {@link #setImageBuffer(GLPixelBuffer) image buffer} + * and passing a {@link GL} instance < {@link GL2ES3}. + *

+ *

+ * Further more, reading back of MSAA buffers is only supported since {@link GL2ES3} + * since it requires to set the {@link GL2ES3#glReadBuffer(int) read-buffer}. *

* * @author ryanm, sgothel @@ -195,12 +211,18 @@ public abstract class TileRendererBase { /** @see #setImageBuffer(GLPixelBuffer) */ public final GLPixelBuffer getImageBuffer() { return imageBuffer; } + /* pp */ final void validateGL(GL gl) throws GLException { + if( imageBuffer != null && !gl.isGL2ES3()) { + throw new GLException("Using image-buffer w/ inssufficient GL context: "+gl.getContext().getGLVersion()+", "+gl.getGLProfile()); + } + } + /** * Begins rendering a tile. *

* Methods modifies the viewport, see below. * User shall reset the viewport when finishing all tile rendering, - * i.e. after very last call of {@link #endTile(GL2ES3)}! + * i.e. after very last call of {@link #endTile(GL)}! *

*

* The PMV Matrix @@ -221,22 +243,30 @@ public abstract class TileRendererBase { *

*

* Use shall render the scene afterwards, concluded with a call to - * this renderer {@link #endTile(GL2ES3)}. + * this renderer {@link #endTile(GL)}. + *

+ *

+ * User has to comply with the GL profile requirement. *

* * @param gl The gl context * @throws IllegalStateException if image-size or pmvMatrixCB has not been set + * @throws GLException if {@link #setImageBuffer(GLPixelBuffer) image buffer} is used but gl instance is < {@link GL2ES3} */ - public abstract void beginTile(GL2ES3 gl) throws IllegalStateException; + public abstract void beginTile(GL gl) throws IllegalStateException, GLException; /** * Must be called after rendering the scene, - * see {@link #beginTile(GL2ES3)}. + * see {@link #beginTile(GL)}. + *

+ * User has to comply with the GL profile requirement. + *

* * @param gl the gl context * @throws IllegalStateException if beginTile(gl) has not been called + * @throws GLException if {@link #setImageBuffer(GLPixelBuffer) image buffer} is used but gl instance is < {@link GL2ES3} */ - public abstract void endTile( GL2ES3 gl ) throws IllegalStateException; + public abstract void endTile( GL gl ) throws IllegalStateException, GLException; /** * Attaches this renderer to the {@link GLAutoDrawable}. @@ -251,13 +281,13 @@ public abstract class TileRendererBase { * for the original {@link GLEventListener}, i.e. it's {@link GLEventListener#display(GLAutoDrawable) display} issues: * *

@@ -267,16 +297,16 @@ public abstract class TileRendererBase { * according to the tile-position, -size and image-size
* The {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape} method is called for each tile * w/ the current viewport of tile-size, where the tile-position and image-size can be retrieved by this tile renderer, - * see details in {@link #beginTile(GL2ES3)}.
+ * see details in {@link #beginTile(GL)}.
* The original {@link GLEventListener} implementing {@link TileRendererNotify} is aware of this * tile renderer instance. *

*

* Consider using {@link #setGLEventListener(GLEventListener, GLEventListener)} to add pre- and post * hooks to be performed on this renderer {@link GLEventListener}.
- * The pre-hook is able to allocate memory and setup parameters, since it's called before {@link #beginTile(GL2ES3)}.
+ * The pre-hook is able to allocate memory and setup parameters, since it's called before {@link #beginTile(GL)}.
* The post-hook is able to use the rendering result and can even shutdown tile-rendering, - * since it's called after {@link #endTile(GL2ES3)}. + * since it's called after {@link #endTile(GL)}. *

*

* Call {@link #detachFromAutoDrawable()} to remove this renderer from the {@link GLAutoDrawable} @@ -393,7 +423,7 @@ public abstract class TileRendererBase { if( null != glEventListenerPre ) { glEventListenerPre.display(drawable); } - final GL2ES3 gl = drawable.getGL().getGL2ES3(); + final GL gl = drawable.getGL(); beginTile(gl); -- cgit v1.2.3