diff options
6 files changed, 389 insertions, 393 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java index ac420da3d..0fba1170d 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java @@ -27,8 +27,6 @@ */ 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.GLAutoDrawable; import javax.media.opengl.GLEventListener; @@ -38,128 +36,80 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; /** * Variation of {@link TileRenderer} w/o using fixed tiles but arbitrary rectangular regions. */ -public class RandomTileRenderer { - private final Dimension imageSize = new Dimension(0, 0); - private final GLPixelStorageModes psm = new GLPixelStorageModes(); - - private GLPixelBuffer imageBuffer; - private GLPixelBuffer tileBuffer; - private PMVMatrixCallback pmvMatrixCB = null; - private int tX = 0; - private int tY = 0; - private int tWidth = 0; - private int tHeight = 0; - - private GLAutoDrawable glad; - private GLEventListener[] listeners; - private boolean[] listenersInit; - private GLEventListener glEventListenerPre = null; - private GLEventListener glEventListenerPost = null; +public class RandomTileRenderer extends TileRendererBase { + private boolean tileRectSet = false; - public static interface PMVMatrixCallback { - void reshapePMVMatrix(GL gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight); - } - /** * Creates a new TileRenderer object */ public RandomTileRenderer() { + super(); } - public final void setPMVMatrixCallback(PMVMatrixCallback pmvMatrixCB) { - assert ( null != pmvMatrixCB ); - this.pmvMatrixCB = pmvMatrixCB; - } - - /** - * Specify a buffer the tiles to be copied to. This is not - * necessary for the creation of the final image, but useful if you - * want to inspect each tile in turn. - * - * @param buffer The buffer itself. Must be large enough to contain a random tile - */ - public final void setTileBuffer(GLPixelBuffer buffer) { - tileBuffer = buffer; - } - - /** @see #setTileBuffer(GLPixelBuffer) */ - public final GLPixelBuffer getTileBuffer() { return tileBuffer; } - - /** - * Sets the desired size of the final image - * - * @param width - * The width of the final image - * @param height - * The height of the final image - */ - public final void setImageSize(int width, int height) { - imageSize.setWidth(width); - imageSize.setHeight(height); + @Override + public final int getParam(int param) { + switch (param) { + case TR_IMAGE_WIDTH: + return imageSize.getWidth(); + case TR_IMAGE_HEIGHT: + return imageSize.getHeight(); + case TR_CURRENT_TILE_X_POS: + return currentTileXPos; + case TR_CURRENT_TILE_Y_POS: + return currentTileYPos; + case TR_CURRENT_TILE_WIDTH: + return currentTileWidth; + case TR_CURRENT_TILE_HEIGHT: + return currentTileHeight; + default: + throw new IllegalArgumentException("Invalid enumerant as argument"); + } } - - /** @see #setImageSize(int, int) */ - public final Dimension getImageSize() { return imageSize; } /** - * Sets the buffer in which to store the final image + * Set the tile rectangle for the subsequent rendering calls. * - * @param buffer the buffer itself, must be large enough to hold the final image + * @throws IllegalArgumentException is tile x/y are < 0 or tile size is <= 0x0 */ - public final void setImageBuffer(GLPixelBuffer buffer) { - imageBuffer = buffer; + public void setTileRect(int tX, int tY, int tWidth, int tHeight) throws IllegalStateException, IllegalArgumentException { + if( 0 > tX || 0 > tX ) { + throw new IllegalArgumentException("Tile pos must be >= 0/0"); + } + if( 0 >= tWidth || 0 >= tHeight ) { + throw new IllegalArgumentException("Tile size must be > 0x0"); + } + this.currentTileXPos = tX; + this.currentTileYPos = tY; + this.currentTileWidth = tWidth; + this.currentTileHeight = tHeight; + tileRectSet = true; } - - /** @see #setImageBuffer(GLPixelBuffer) */ - public final GLPixelBuffer getImageBuffer() { return imageBuffer; } /** - * Begins rendering a tile. - * <p> - * Methods modifies the viewport, hence user shall reset the viewport when finishing tile rendering. - * </p> - * <p> - * The projection matrix stack should be - * left alone after calling this method! - * </p> - * - * @param gl The gl context - * @throws IllegalStateException - * @throws IllegalArgumentException + * {@inheritDoc} + * @throws IllegalStateException if image-size, pmvMatrixCB or tileRect has not been set */ - public final void beginTile(GL2ES3 gl, int tX, int tY, int tWidth, int tHeight) throws IllegalStateException, IllegalArgumentException { + @Override + public final void beginTile(GL2ES3 gl) throws IllegalStateException { if( 0 >= imageSize.getWidth() || 0 >= imageSize.getHeight() ) { throw new IllegalStateException("Image size has not been set"); } if( null == this.pmvMatrixCB ) { throw new IllegalStateException("pmvMatrixCB has not been set"); } - if( 0 > tX || 0 > tX ) { - throw new IllegalArgumentException("Tile pos must be >= 0/0"); - } - if( 0 >= tWidth || 0 >= tHeight ) { - throw new IllegalArgumentException("Tile size must be > 0x0"); + if( !tileRectSet ) { + throw new IllegalStateException("tileRect has not been set"); } - gl.glViewport( 0, 0, tWidth, tHeight ); - pmvMatrixCB.reshapePMVMatrix(gl, tX, tY, tWidth, tHeight, imageSize.getWidth(), imageSize.getHeight()); + gl.glViewport( 0, 0, currentTileWidth, currentTileHeight ); + pmvMatrixCB.reshapePMVMatrix(gl, currentTileXPos, currentTileYPos, currentTileWidth, currentTileHeight, imageSize.getWidth(), imageSize.getHeight()); - this.tX = tX; - this.tY = tY; - this.tWidth = tWidth; - this.tHeight = tHeight; + beginCalled = true; } - - /** - * Must be called after rendering the scene - * - * @param gl - * the gl context - * @return true if there are more tiles to be rendered, false if - * the final image is complete - */ - public void endTile( GL2ES3 gl ) { - if( 0 >= tWidth || 0 >= tHeight ) { + + @Override + public void endTile( GL2ES3 gl ) throws IllegalStateException { + if( !beginCalled ) { throw new IllegalStateException("beginTile(..) has not been called"); } @@ -175,8 +125,8 @@ public class RandomTileRenderer { final GLPixelAttributes pixelAttribs = tileBuffer.pixelAttributes; final int srcX = 0; final int srcY = 0; - final int srcWidth = tWidth; - final int srcHeight = tHeight; + final int srcWidth = currentTileWidth; + final int srcHeight = currentTileHeight; final int readPixelSize = GLBuffers.sizeof(gl, tmp, pixelAttribs.bytesPerPixel, srcWidth, srcHeight, 1, true); tileBuffer.clear(); if( tileBuffer.requiresNewBuffer(gl, srcWidth, srcHeight, readPixelSize) ) { @@ -193,8 +143,8 @@ public class RandomTileRenderer { final GLPixelAttributes pixelAttribs = imageBuffer.pixelAttributes; final int srcX = 0; final int srcY = 0; - final int srcWidth = tWidth; - final int srcHeight = tHeight; + final int srcWidth = currentTileWidth; + final int srcHeight = currentTileHeight; /* setup pixel store for glReadPixels */ final int rowLength = imageSize.getWidth(); @@ -204,7 +154,7 @@ public class RandomTileRenderer { /* read the tile into the final image */ final int readPixelSize = GLBuffers.sizeof(gl, tmp, pixelAttribs.bytesPerPixel, srcWidth, srcHeight, 1, true); - final int ibPos = ( tX + ( tY * rowLength ) ) * pixelAttribs.bytesPerPixel; // skipPixels + skipRows + final int ibPos = ( currentTileXPos + ( currentTileYPos * rowLength ) ) * pixelAttribs.bytesPerPixel; // skipPixels + skipRows final int ibLim = ibPos + readPixelSize; imageBuffer.clear(); if( imageBuffer.requiresNewBuffer(gl, srcWidth, srcHeight, readPixelSize) ) { @@ -221,87 +171,22 @@ public class RandomTileRenderer { /* restore previous glPixelStore values */ psm.restore(gl); - - this.tX = 0; - this.tY = 0; - this.tWidth = 0; - this.tHeight = 0; - } - - /** - * - * <p> - * Sets the size of the tiles to use in rendering. The actual - * effective size of the tile depends on the border size, ie ( - * width - 2*border ) * ( height - 2 * border ) - * </p> - * @param glad - * @throws IllegalStateException if an {@link GLAutoDrawable} is already attached - */ - public void attachAutoDrawable(GLAutoDrawable glad, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException { - if( null != this.glad ) { - throw new IllegalStateException("GLAutoDrawable already attached"); - } - this.glad = glad; - setPMVMatrixCallback(pmvMatrixCB); - final int aSz = glad.getGLEventListenerCount(); - listeners = new GLEventListener[aSz]; - listenersInit = new boolean[aSz]; - for(int i=0; i<aSz; i++) { - final GLEventListener l = glad.getGLEventListener(0); - listenersInit[i] = glad.getGLEventListenerInitState(l); - listeners[i] = glad.removeGLEventListener( l ); - } - glad.addGLEventListener(tiledGLEL); - } - - public void detachAutoDrawable() { - if( null != glad ) { - glad.removeGLEventListener(tiledGLEL); - final int aSz = listenersInit.length; - for(int i=0; i<aSz; i++) { - final GLEventListener l = listeners[i]; - glad.addGLEventListener(l); - glad.setGLEventListenerInitState(l, listenersInit[i]); - } - listeners = null; - listenersInit = null; - glad = null; - pmvMatrixCB = null; - } - } - - /** - * Set {@link GLEventListener} for pre- and post operations when used w/ - * {@link #attachAutoDrawable(GLAutoDrawable, int, PMVMatrixCallback)} - * for each {@link GLEventListener} callback. - * @param preTile the pre operations - * @param postTile the post operations - */ - public void setGLEventListener(GLEventListener preTile, GLEventListener postTile) { - glEventListenerPre = preTile; - glEventListenerPost = postTile; + beginCalled = false; } /** * Rendering one tile, by simply calling {@link GLAutoDrawable#display()}. * - * @return true if there are more tiles to be rendered, false if the final image is complete - * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachAutoDrawable(GLAutoDrawable, int) attached} + * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachToAutoDrawable(GLAutoDrawable, int) attached} * or imageSize is not set */ public void display(int tX, int tY, int tWidth, int tHeight) throws IllegalStateException { - if( null == glad ) { - throw new IllegalStateException("No GLAutoDrawable attached"); - } - this.tX = tX; - this.tY = tY; - this.tWidth = tWidth; - this.tHeight = tHeight; - glad.display(); + setTileRect(tX, tY, tWidth, tHeight); + display(); } + protected final GLEventListener getTiledGLEL() { return tiledGLEL; } private final GLEventListener tiledGLEL = new GLEventListener() { @Override public void init(GLAutoDrawable drawable) { @@ -338,7 +223,7 @@ public class RandomTileRenderer { } final GL2ES3 gl = drawable.getGL().getGL2ES3(); - beginTile(gl, tX, tY, tWidth, tHeight); + beginTile(gl); final int aSz = listenersInit.length; for(int i=0; i<aSz; i++) { diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java index c7c94c8da..a63694207 100644 --- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java @@ -37,7 +37,6 @@ 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.GLAutoDrawable; import javax.media.opengl.GLEventListener; @@ -60,103 +59,69 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; * * @author ryanm, sgothel */ -public class TileRenderer { +public class TileRenderer extends TileRendererBase { /** * The width of a tile */ - public static final int TR_TILE_WIDTH = 0; + public static final int TR_TILE_WIDTH = 7; /** * The height of a tile */ - public static final int TR_TILE_HEIGHT = 1; + public static final int TR_TILE_HEIGHT = 8; /** * The width of the border around the tiles */ - public static final int TR_TILE_BORDER = 2; - /** - * The width of the final image - */ - public static final int TR_IMAGE_WIDTH = 3; - /** - * The height of the final image - */ - public static final int TR_IMAGE_HEIGHT = 4; + public static final int TR_TILE_BORDER = 9; /** * The number of rows of tiles */ - public static final int TR_ROWS = 5; + public static final int TR_ROWS = 10; /** * The number of columns of tiles */ - public static final int TR_COLUMNS = 6; + public static final int TR_COLUMNS = 11; /** * The current row number */ - public static final int TR_CURRENT_ROW = 7; + public static final int TR_CURRENT_ROW = 12; /** * The current column number */ - public static final int TR_CURRENT_COLUMN = 8; - /** - * The width of the current tile - */ - public static final int TR_CURRENT_TILE_WIDTH = 9; - /** - * The height of the current tile - */ - public static final int TR_CURRENT_TILE_HEIGHT = 10; + public static final int TR_CURRENT_COLUMN = 13; /** * The order that the rows are traversed */ - public static final int TR_ROW_ORDER = 11; + public static final int TR_ROW_ORDER = 14; /** * Indicates we are traversing rows from the top to the bottom */ - public static final int TR_TOP_TO_BOTTOM = 1; + public static final int TR_TOP_TO_BOTTOM = 15; /** * Indicates we are traversing rows from the bottom to the top */ - public static final int TR_BOTTOM_TO_TOP = 2; + public static final int TR_BOTTOM_TO_TOP = 16; private static final boolean DEBUG = true; private static final int DEFAULT_TILE_WIDTH = 256; private static final int DEFAULT_TILE_HEIGHT = 256; private static final int DEFAULT_TILE_BORDER = 0; - private final Dimension imageSize = new Dimension(0, 0); private final Dimension tileSize = new Dimension(DEFAULT_TILE_WIDTH, DEFAULT_TILE_HEIGHT); private final Dimension tileSizeNB = new Dimension(DEFAULT_TILE_WIDTH - 2 * DEFAULT_TILE_BORDER, DEFAULT_TILE_HEIGHT - 2 * DEFAULT_TILE_BORDER); - private final int[] userViewport = new int[ 4 ]; - private final GLPixelStorageModes psm = new GLPixelStorageModes(); private int tileBorder = DEFAULT_TILE_BORDER; - private GLPixelBuffer imageBuffer; - private GLPixelBuffer tileBuffer; private int rowOrder = TR_BOTTOM_TO_TOP; private int rows; private int columns; private int currentTile = -1; - private int currentTileWidth; - private int currentTileHeight; private int currentRow; private int currentColumn; - private PMVMatrixCallback pmvMatrixCB = null; - private boolean beginCalled = false; - - private GLAutoDrawable glad; - private GLEventListener[] listeners; - private boolean[] listenersInit; - private GLEventListener glEventListenerPre = null; - private GLEventListener glEventListenerPost = null; - - public static interface PMVMatrixCallback { - void reshapePMVMatrix(GL gl, int tileNum, int tileColumn, int tileRow, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight); - } /** * Creates a new TileRenderer object */ public TileRenderer() { + super(); } /** @@ -190,11 +155,6 @@ public class TileRenderer { setup(); } - public final void setPMVMatrixCallback(PMVMatrixCallback pmvMatrixCB) { - assert ( null != pmvMatrixCB ); - this.pmvMatrixCB = pmvMatrixCB; - } - /** * Sets up the number of rows and columns needed */ @@ -202,6 +162,8 @@ public class TileRenderer { columns = ( imageSize.getWidth() + tileSizeNB.getWidth() - 1 ) / tileSizeNB.getWidth(); rows = ( imageSize.getHeight() + tileSizeNB.getHeight() - 1 ) / tileSizeNB.getHeight(); currentTile = 0; + currentTileXPos = 0; + currentTileYPos = 0; currentTileWidth = 0; currentTileHeight = 0; currentRow = 0; @@ -217,56 +179,7 @@ public class TileRenderer { */ public final boolean eot() { return 0 > currentTile; } - /** - * Specify a buffer the tiles to be copied to. This is not - * necessary for the creation of the final image, but useful if you - * want to inspect each tile in turn. - * - * @param buffer The buffer itself. Must be large enough to contain a tile, minus any borders - */ - public final void setTileBuffer(GLPixelBuffer buffer) { - tileBuffer = buffer; - } - - /** @see #setTileBuffer(GLPixelBuffer) */ - public final GLPixelBuffer getTileBuffer() { return tileBuffer; } - - /** - * Sets the desired size of the final image - * - * @param width - * The width of the final image - * @param height - * The height of the final image - */ - public final void setImageSize(int width, int height) { - imageSize.setWidth(width); - imageSize.setHeight(height); - setup(); - } - - /** @see #setImageSize(int, int) */ - public final Dimension getImageSize() { return imageSize; } - - /** - * Sets the buffer in which to store the final image - * - * @param image the buffer itself, must be large enough to hold the final image - */ - public final void setImageBuffer(GLPixelBuffer buffer) { - imageBuffer = buffer; - } - - /** @see #setImageBuffer(GLPixelBuffer) */ - public final GLPixelBuffer getImageBuffer() { return imageBuffer; } - - /** - * Gets the parameters of this TileRenderer object - * - * @param param - * The parameter that is to be retrieved - * @return the value of the parameter - */ + @Override public final int getParam(int param) { switch (param) { case TR_TILE_WIDTH: @@ -284,15 +197,21 @@ public class TileRenderer { case TR_COLUMNS: return columns; case TR_CURRENT_ROW: - if( currentTile < 0 ) + if( currentTile < 0 ) { return -1; - else + } else { return currentRow; + } case TR_CURRENT_COLUMN: - if( currentTile < 0 ) + if( currentTile < 0 ) { return -1; - else + } else { return currentColumn; + } + case TR_CURRENT_TILE_X_POS: + return currentTileXPos; + case TR_CURRENT_TILE_Y_POS: + return currentTileYPos; case TR_CURRENT_TILE_WIDTH: return currentTileWidth; case TR_CURRENT_TILE_HEIGHT: @@ -319,16 +238,7 @@ public class TileRenderer { } } - /** - * Begins rendering a tile. - * <p> - * The projection matrix stack should be - * left alone after calling this method! - * </p> - * - * @param gl The gl context - * @throws IllegalStateException - */ + @Override public final void beginTile( GL2ES3 gl ) throws IllegalStateException { if( 0 >= imageSize.getWidth() || 0 >= imageSize.getHeight() ) { throw new IllegalStateException("Image size has not been set"); @@ -338,11 +248,6 @@ public class TileRenderer { } if (currentTile <= 0) { setup(); - /* - * Save user's viewport, will be restored after last tile - * rendered - */ - gl.glGetIntegerv( GL.GL_VIEWPORT, userViewport, 0 ); } final int preRow = currentRow; @@ -376,8 +281,8 @@ public class TileRenderer { tW = imageSize.getWidth() - ( columns - 1 ) * ( tileSizeNB.getWidth() ) + 2 * border; } - final int tX = currentColumn * tileSizeNB.getWidth(); - final int tY = currentRow * tileSizeNB.getHeight(); + currentTileXPos = currentColumn * tileSizeNB.getWidth(); + currentTileYPos = currentRow * tileSizeNB.getHeight(); final int preTileWidth = currentTileWidth; final int preTileHeight = currentTileHeight; @@ -388,24 +293,16 @@ public class TileRenderer { if( DEBUG ) { System.err.println("Tile["+currentTile+"]: ["+preColumn+"]["+preRow+"] "+preTileWidth+"x"+preTileHeight+ - " -> ["+currentColumn+"]["+currentRow+"] "+tX+"/"+tY+", "+tW+"x"+tH+", image "+imageSize.getWidth()+"x"+imageSize.getHeight()); + " -> ["+currentColumn+"]["+currentRow+"] "+currentTileXPos+"/"+currentTileYPos+", "+tW+"x"+tH+", image "+imageSize.getWidth()+"x"+imageSize.getHeight()); } gl.glViewport( 0, 0, tW, tH ); - pmvMatrixCB.reshapePMVMatrix(gl, currentTile, currentColumn, currentRow, tX, tY, tW, tH, imageSize.getWidth(), imageSize.getHeight()); + pmvMatrixCB.reshapePMVMatrix(gl, currentTileXPos, currentTileYPos, tW, tH, imageSize.getWidth(), imageSize.getHeight()); beginCalled = true; } - /** - * Must be called after rendering the scene - * - * @param gl - * the gl context - * @return true if there are more tiles to be rendered, false if - * the final image is complete - * @throws IllegalStateException - */ - public boolean endTile( GL2ES3 gl ) throws IllegalStateException { + @Override + public void endTile( GL2ES3 gl ) throws IllegalStateException { if( !beginCalled ) { throw new IllegalStateException("beginTile(..) has not been called"); } @@ -476,91 +373,24 @@ public class TileRenderer { /* increment tile counter, return 1 if more tiles left to render */ currentTile++; if( currentTile >= rows * columns ) { - /* restore user's viewport */ - gl.glViewport( userViewport[ 0 ], userViewport[ 1 ], userViewport[ 2 ], userViewport[ 3 ] ); currentTile = -1; /* all done */ - return false; - } else { - return true; } } /** - * + * {@inheritDoc} * <p> - * Sets the size of the tiles to use in rendering. The actual - * effective size of the tile depends on the border size, ie ( - * width - 2*border ) * ( height - 2 * border ) + * Sets the tile size of this renderer to the given {@link GLAutoDrawable} size + * with zero tile border. * </p> - * @param glad - * @param border - * The width of the borders on each tile. This is needed - * to avoid artifacts when rendering lines or points with - * thickness > 1. - * @throws IllegalStateException if an {@link GLAutoDrawable} is already attached */ - public void attachAutoDrawable(GLAutoDrawable glad, int border, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException { - if( null != this.glad ) { - throw new IllegalStateException("GLAutoDrawable already attached"); - } - this.glad = glad; - setTileSize(glad.getWidth(), glad.getHeight(), border); - setPMVMatrixCallback(pmvMatrixCB); - - final int aSz = glad.getGLEventListenerCount(); - listeners = new GLEventListener[aSz]; - listenersInit = new boolean[aSz]; - for(int i=0; i<aSz; i++) { - final GLEventListener l = glad.getGLEventListener(0); - listenersInit[i] = glad.getGLEventListenerInitState(l); - listeners[i] = glad.removeGLEventListener( l ); - } - glad.addGLEventListener(tiledGLEL); - } - - public void detachAutoDrawable() { - if( null != glad ) { - glad.removeGLEventListener(tiledGLEL); - final int aSz = listenersInit.length; - for(int i=0; i<aSz; i++) { - final GLEventListener l = listeners[i]; - glad.addGLEventListener(l); - glad.setGLEventListenerInitState(l, listenersInit[i]); - } - listeners = null; - listenersInit = null; - glad = null; - pmvMatrixCB = null; - } - } - - /** - * Set {@link GLEventListener} for pre- and post operations when used w/ - * {@link #attachAutoDrawable(GLAutoDrawable, int, PMVMatrixCallback)} - * for each {@link GLEventListener} callback. - * @param preTile the pre operations - * @param postTile the post operations - */ - public void setGLEventListener(GLEventListener preTile, GLEventListener postTile) { - glEventListenerPre = preTile; - glEventListenerPost = postTile; + @Override + public void attachToAutoDrawable(GLAutoDrawable glad, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException { + super.attachToAutoDrawable(glad, pmvMatrixCB); + setTileSize(glad.getWidth(), glad.getHeight(), 0); } - /** - * Rendering one tile, by simply calling {@link GLAutoDrawable#display()}. - * - * @return true if there are more tiles to be rendered, false if the final image is complete - * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachAutoDrawable(GLAutoDrawable, int) attached} - * or imageSize is not set - */ - public boolean display() throws IllegalStateException { - if( null == glad ) { - throw new IllegalStateException("No GLAutoDrawable attached"); - } - glad.display(); - return !eot(); - } - + protected final GLEventListener getTiledGLEL() { return tiledGLEL; } private final GLEventListener tiledGLEL = new GLEventListener() { @Override public void init(GLAutoDrawable drawable) { diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java new file mode 100644 index 000000000..3aa6ea786 --- /dev/null +++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java @@ -0,0 +1,281 @@ +/** + * Copyright 2013 JogAmp Community. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of JogAmp Community. + * + * --------------------- + * + * Based on Brian Paul's tile rendering library, found + * at <a href = "http://www.mesa3d.org/brianp/TR.html">http://www.mesa3d.org/brianp/TR.html</a>. + * + * Copyright (C) 1997-2005 Brian Paul. + * Licensed under BSD-compatible terms with permission of the author. + * See LICENSE.txt for license information. + */ +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.GLAutoDrawable; +import javax.media.opengl.GLEventListener; + +/** + * A fairly direct port of Brian Paul's tile rendering library, found + * at <a href = "http://www.mesa3d.org/brianp/TR.html"> + * http://www.mesa3d.org/brianp/TR.html </a> . I've java-fied it, but + * the functionality is the same. + * <p> + * Original code Copyright (C) 1997-2005 Brian Paul. Licensed under + * BSD-compatible terms with permission of the author. See LICENSE.txt + * for license information. + * </p> + * <p> + * Enhanced for {@link GL2ES3}, abstracted to suit {@link TileRenderer} and {@link RandomTileRenderer}. + * </p> + * + * @author ryanm, sgothel + */ +public abstract class TileRendererBase { + /** + * The width of the final image + */ + public static final int TR_IMAGE_WIDTH = 1; + /** + * The height of the final image + */ + public static final int TR_IMAGE_HEIGHT = 2; + /** + * The width of the current tile + */ + public static final int TR_CURRENT_TILE_X_POS = 3; + /** + * The height of the current tile + */ + public static final int TR_CURRENT_TILE_Y_POS = 4; + /** + * The width of the current tile + */ + public static final int TR_CURRENT_TILE_WIDTH = 5; + /** + * The height of the current tile + */ + public static final int TR_CURRENT_TILE_HEIGHT = 6; + + protected final Dimension imageSize = new Dimension(0, 0); + protected final GLPixelStorageModes psm = new GLPixelStorageModes(); + protected GLPixelBuffer imageBuffer; + protected GLPixelBuffer tileBuffer; + protected PMVMatrixCallback pmvMatrixCB = null; + protected boolean beginCalled = false; + protected int currentTileXPos; + protected int currentTileYPos; + protected int currentTileWidth; + protected int currentTileHeight; + protected GLAutoDrawable glad; + protected GLEventListener[] listeners; + protected boolean[] listenersInit; + protected GLEventListener glEventListenerPre = null; + protected GLEventListener glEventListenerPost = null; + + public static interface PMVMatrixCallback { + void reshapePMVMatrix(GL gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight); + } + + protected TileRendererBase() { + } + + /** + * Gets the parameters of this TileRenderer object + * + * @param param The parameter that is to be retrieved + * @return the value of the parameter + * @throws IllegalArgumentException if <code>param</code> is not handled + */ + public abstract int getParam(int param) throws IllegalArgumentException; + + /** + * @param pmvMatrixCB + * @throws IllegalArgumentException if <code>pmvMatrixCB</code> is null + */ + public final void setPMVMatrixCallback(PMVMatrixCallback pmvMatrixCB) throws IllegalArgumentException { + if( null == pmvMatrixCB ) { + throw new IllegalArgumentException("pmvMatrixCB is null"); + } + this.pmvMatrixCB = pmvMatrixCB; + } + + /** + * Specify a buffer the tiles to be copied to. This is not + * necessary for the creation of the final image, but useful if you + * want to inspect each tile in turn. + * + * @param buffer The buffer itself. Must be large enough to contain a random tile + */ + public final void setTileBuffer(GLPixelBuffer buffer) { + tileBuffer = buffer; + } + + /** @see #setTileBuffer(GLPixelBuffer) */ + public final GLPixelBuffer getTileBuffer() { return tileBuffer; } + + /** + * Sets the desired size of the final image + * + * @param width The width of the final image + * @param height The height of the final image + */ + public final void setImageSize(int width, int height) { + imageSize.setWidth(width); + imageSize.setHeight(height); + } + + /** @see #setImageSize(int, int) */ + public final Dimension getImageSize() { return imageSize; } + + /** + * Sets the buffer in which to store the final image + * + * @param buffer the buffer itself, must be large enough to hold the final image + */ + public final void setImageBuffer(GLPixelBuffer buffer) { + imageBuffer = buffer; + } + + /** @see #setImageBuffer(GLPixelBuffer) */ + public final GLPixelBuffer getImageBuffer() { return imageBuffer; } + + /** + * Begins rendering a tile. + * <p> + * Methods modifies the viewport. + * User shall reset the viewport when finishing tile rendering, + * i.e. after last call of {@link #endTile(GL2ES3)}! + * </p> + * <p> + * The projection matrix stack should be + * left alone after calling this method! + * </p> + * <p> + * Use shall render the scene afterwards, concluded with a call to + * this renderer {@link #endTile(GL2ES3)}. + * </p> + * + * @param gl The gl context + * @throws IllegalStateException if image-size or pmvMatrixCB has not been set + */ + public abstract void beginTile(GL2ES3 gl) throws IllegalStateException; + + /** + * Must be called after rendering the scene, + * see {@link #beginTile(GL2ES3)}. + * + * @param gl the gl context + * @throws IllegalStateException if beginTile(gl) has not been called + */ + public abstract void endTile( GL2ES3 gl ) throws IllegalStateException; + + /** + * Attaches this renderer to the {@link GLAutoDrawable}. + * <p> + * The {@link GLAutoDrawable}'s {@link GLEventListener} are removed first and stored locally. + * This renderer {@link GLEventListener} is then added to handle the tile rendering + * for the original {@link GLEventListener}. + * </p> + * <p> + * Call {@link #detachFromAutoDrawable()} to remove this renderer from the {@link GLAutoDrawable} + * and to restore it's original {@link GLEventListener}. + * </p> + * @param glad + * @throws IllegalStateException if an {@link GLAutoDrawable} is already attached + */ + public void attachToAutoDrawable(GLAutoDrawable glad, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException { + if( null != this.glad ) { + throw new IllegalStateException("GLAutoDrawable already attached"); + } + this.glad = glad; + setPMVMatrixCallback(pmvMatrixCB); + + final int aSz = glad.getGLEventListenerCount(); + listeners = new GLEventListener[aSz]; + listenersInit = new boolean[aSz]; + for(int i=0; i<aSz; i++) { + final GLEventListener l = glad.getGLEventListener(0); + listenersInit[i] = glad.getGLEventListenerInitState(l); + listeners[i] = glad.removeGLEventListener( l ); + } + glad.addGLEventListener(getTiledGLEL()); + } + + /** + * Detaches this renderer from the {@link GLAutoDrawable}. + * <p> + * See {@link #attachToAutoDrawable(GLAutoDrawable, PMVMatrixCallback)}. + * </p> + */ + public void detachFromAutoDrawable() { + if( null != glad ) { + glad.removeGLEventListener(getTiledGLEL()); + final int aSz = listenersInit.length; + for(int i=0; i<aSz; i++) { + final GLEventListener l = listeners[i]; + glad.addGLEventListener(l); + glad.setGLEventListenerInitState(l, listenersInit[i]); + } + listeners = null; + listenersInit = null; + glad = null; + pmvMatrixCB = null; + } + } + + /** Return this rendere {@link GLEventListener} implementation. */ + protected abstract GLEventListener getTiledGLEL(); + + /** + * Set {@link GLEventListener} for pre- and post operations when used w/ + * {@link #attachAutoDrawable(GLAutoDrawable, int, PMVMatrixCallback)} + * for each {@link GLEventListener} callback. + * @param preTile the pre operations + * @param postTile the post operations + */ + public void setGLEventListener(GLEventListener preTile, GLEventListener postTile) { + glEventListenerPre = preTile; + glEventListenerPost = postTile; + } + + /** + * Rendering one tile, by simply calling {@link GLAutoDrawable#display()}. + * + * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachToAutoDrawable(GLAutoDrawable, int) attached} + * or imageSize is not set + */ + public void display() throws IllegalStateException { + if( null == glad ) { + throw new IllegalStateException("No GLAutoDrawable attached"); + } + glad.display(); + } +}
\ No newline at end of file diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java index 1d917efb9..d1fabfa6b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestRandomTiledRendering2GL2.java @@ -90,7 +90,7 @@ public class TestRandomTiledRendering2GL2 extends UITestCase { gl.glMatrixMode(GL2.GL_MODELVIEW); } }; - renderer.attachAutoDrawable(glad, pmvMatrixCallback); + renderer.attachToAutoDrawable(glad, pmvMatrixCallback); renderer.setImageSize(imageWidth, imageHeight); final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride; @@ -101,9 +101,7 @@ public class TestRandomTiledRendering2GL2 extends UITestCase { public void init(GLAutoDrawable drawable) { final GL gl = drawable.getGL(); GLPixelAttributes pixelAttribs = pixelBufferProvider.getAttributes(gl, 3); - System.err.println("XXX: "+pixelAttribs+", gl2gl3 "+gl.isGL2GL3()+", "+gl.getContext().getGLVersion()); GLPixelBuffer pixelBuffer = pixelBufferProvider.allocate(gl, pixelAttribs, imageWidth, imageHeight, 1, true, 0); - System.err.println("XXX: "+pixelBuffer); renderer.setImageBuffer(pixelBuffer); if( drawable.isGLOriented() ) { flipVertically[0] = false; @@ -131,7 +129,7 @@ public class TestRandomTiledRendering2GL2 extends UITestCase { } } - renderer.detachAutoDrawable(); + renderer.detachFromAutoDrawable(); glad.destroy(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java index 7b1272993..5b628091b 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering1GL2.java @@ -52,7 +52,7 @@ public class TestTiledRendering1GL2 extends UITestCase { // Initialize the tile rendering library final TileRenderer renderer = new com.jogamp.opengl.util.TileRenderer(); final TileRenderer.PMVMatrixCallback pmvMatrixCallback = new TileRenderer.PMVMatrixCallback() { - public void reshapePMVMatrix(GL _gl, int tileNum, int tileColumn, int tileRow, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { + public void reshapePMVMatrix(GL _gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { final GL2 gl = _gl.getGL2(); gl.glMatrixMode( GL2.GL_PROJECTION ); gl.glLoadIdentity(); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java index 27198b149..d750ca853 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/tile/TestTiledRendering2GL2.java @@ -55,7 +55,7 @@ public class TestTiledRendering2GL2 extends UITestCase { // Initialize the tile rendering library final TileRenderer renderer = new TileRenderer(); final TileRenderer.PMVMatrixCallback pmvMatrixCallback = new TileRenderer.PMVMatrixCallback() { - public void reshapePMVMatrix(GL _gl, int tileNum, int tileColumn, int tileRow, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { + public void reshapePMVMatrix(GL _gl, int tileX, int tileY, int tileWidth, int tileHeight, int imageWidth, int imageHeight) { final GL2 gl = _gl.getGL2(); gl.glMatrixMode( GL2.GL_PROJECTION ); gl.glLoadIdentity(); @@ -91,7 +91,7 @@ public class TestTiledRendering2GL2 extends UITestCase { } }; - renderer.attachAutoDrawable(glad, 0, pmvMatrixCallback); + renderer.attachToAutoDrawable(glad, pmvMatrixCallback); renderer.setImageSize(imageWidth, imageHeight); final GLPixelBuffer.GLPixelBufferProvider pixelBufferProvider = GLPixelBuffer.defaultProviderWithRowStride; @@ -119,9 +119,11 @@ public class TestTiledRendering2GL2 extends UITestCase { }; renderer.setGLEventListener(preTileGLEL, null); - while ( renderer.display() ); + do { + renderer.display(); + } while ( !renderer.eot() ); - renderer.detachAutoDrawable(); + renderer.detachFromAutoDrawable(); glad.destroy(); |