aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/classes
diff options
context:
space:
mode:
Diffstat (limited to 'src/jogl/classes')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java83
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java105
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java178
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java110
4 files changed, 275 insertions, 201 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
index 0fba1170d..4fcf0b6cc 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/RandomTileRenderer.java
@@ -29,12 +29,14 @@ package com.jogamp.opengl.util;
import javax.media.opengl.GL2ES3;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
/**
* Variation of {@link TileRenderer} w/o using fixed tiles but arbitrary rectangular regions.
+ * <p>
+ * See {@link TileRendererBase} for details.
+ * </p>
*/
public class RandomTileRenderer extends TileRendererBase {
private boolean tileRectSet = false;
@@ -47,8 +49,8 @@ public class RandomTileRenderer extends TileRendererBase {
}
@Override
- public final int getParam(int param) {
- switch (param) {
+ public final int getParam(int pname) {
+ switch (pname) {
case TR_IMAGE_WIDTH:
return imageSize.getWidth();
case TR_IMAGE_HEIGHT:
@@ -62,7 +64,7 @@ public class RandomTileRenderer extends TileRendererBase {
case TR_CURRENT_TILE_HEIGHT:
return currentTileHeight;
default:
- throw new IllegalArgumentException("Invalid enumerant as argument");
+ throw new IllegalArgumentException("Invalid pname: "+pname);
}
}
@@ -94,15 +96,14 @@ public class RandomTileRenderer extends TileRendererBase {
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( !tileRectSet ) {
throw new IllegalStateException("tileRect has not been set");
}
gl.glViewport( 0, 0, currentTileWidth, currentTileHeight );
- pmvMatrixCB.reshapePMVMatrix(gl, currentTileXPos, currentTileYPos, currentTileWidth, currentTileHeight, imageSize.getWidth(), imageSize.getHeight());
+ // Do not forget to issue:
+ // reshape( 0, 0, tW, tH );
+ // which shall reflect tile renderer fileds: currentTileXPos, currentTileYPos and imageSize
beginCalled = true;
}
@@ -178,75 +179,11 @@ public class RandomTileRenderer extends TileRendererBase {
/**
* Rendering one tile, by simply calling {@link GLAutoDrawable#display()}.
*
- * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachToAutoDrawable(GLAutoDrawable, int) attached}
+ * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachToAutoDrawable(GLAutoDrawable) attached}
* or imageSize is not set
*/
public void display(int tX, int tY, int tWidth, int tHeight) throws IllegalStateException {
setTileRect(tX, tY, tWidth, tHeight);
display();
}
-
- protected final GLEventListener getTiledGLEL() { return tiledGLEL; }
- private final GLEventListener tiledGLEL = new GLEventListener() {
- @Override
- public void init(GLAutoDrawable drawable) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.init(drawable);
- }
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- final GLEventListener l = listeners[i];
- l.init(drawable);
- listenersInit[i] = true;
- }
- if( null != glEventListenerPost ) {
- glEventListenerPost.init(drawable);
- }
- }
- @Override
- public void dispose(GLAutoDrawable drawable) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.dispose(drawable);
- }
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- listeners[i].dispose(drawable);
- }
- if( null != glEventListenerPost ) {
- glEventListenerPost.dispose(drawable);
- }
- }
- @Override
- public void display(GLAutoDrawable drawable) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.display(drawable);
- }
- final GL2ES3 gl = drawable.getGL().getGL2ES3();
-
- beginTile(gl);
-
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- listeners[i].display(drawable);
- }
-
- endTile(gl);
- if( null != glEventListenerPost ) {
- glEventListenerPost.display(drawable);
- }
- }
- @Override
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.reshape(drawable, x, y, width, height);
- }
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- listeners[i].reshape(drawable, x, y, width, height);
- }
- if( null != glEventListenerPost ) {
- glEventListenerPost.reshape(drawable, x, y, width, height);
- }
- }
- };
} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
index a63694207..3bb9dc169 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/TileRenderer.java
@@ -39,7 +39,6 @@ package com.jogamp.opengl.util;
import javax.media.nativewindow.util.Dimension;
import javax.media.opengl.GL2ES3;
import javax.media.opengl.GLAutoDrawable;
-import javax.media.opengl.GLEventListener;
import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
@@ -56,48 +55,51 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
* <p>
* Enhanced for {@link GL2ES3}.
* </p>
+ * <p>
+ * See {@link TileRendererBase} for details.
+ * </p>
*
* @author ryanm, sgothel
*/
public class TileRenderer extends TileRendererBase {
/**
- * The width of a tile
+ * The width of a tile. See {@link #getParam(int)}.
*/
public static final int TR_TILE_WIDTH = 7;
/**
- * The height of a tile
+ * The height of a tile. See {@link #getParam(int)}.
*/
public static final int TR_TILE_HEIGHT = 8;
/**
- * The width of the border around the tiles
+ * The width of the border around the tiles. See {@link #getParam(int)}.
*/
public static final int TR_TILE_BORDER = 9;
/**
- * The number of rows of tiles
+ * The number of rows of tiles. See {@link #getParam(int)}.
*/
public static final int TR_ROWS = 10;
/**
- * The number of columns of tiles
+ * The number of columns of tiles. See {@link #getParam(int)}.
*/
public static final int TR_COLUMNS = 11;
/**
- * The current row number
+ * The current row number. See {@link #getParam(int)}.
*/
public static final int TR_CURRENT_ROW = 12;
/**
- * The current column number
+ * The current column number. See {@link #getParam(int)}.
*/
public static final int TR_CURRENT_COLUMN = 13;
/**
- * The order that the rows are traversed
+ * The order that the rows are traversed. See {@link #getParam(int)}.
*/
public static final int TR_ROW_ORDER = 14;
/**
- * Indicates we are traversing rows from the top to the bottom
+ * Indicates we are traversing rows from the top to the bottom. See {@link #getParam(int)}.
*/
public static final int TR_TOP_TO_BOTTOM = 15;
/**
- * Indicates we are traversing rows from the bottom to the top
+ * Indicates we are traversing rows from the bottom to the top. See {@link #getParam(int)}.
*/
public static final int TR_BOTTOM_TO_TOP = 16;
@@ -180,8 +182,8 @@ public class TileRenderer extends TileRendererBase {
public final boolean eot() { return 0 > currentTile; }
@Override
- public final int getParam(int param) {
- switch (param) {
+ public final int getParam(int pname) {
+ switch (pname) {
case TR_TILE_WIDTH:
return tileSize.getWidth();
case TR_TILE_HEIGHT:
@@ -219,7 +221,7 @@ public class TileRenderer extends TileRendererBase {
case TR_ROW_ORDER:
return rowOrder;
default:
- throw new IllegalArgumentException("Invalid enumerant as argument");
+ throw new IllegalArgumentException("Invalid pname: "+pname);
}
}
@@ -243,9 +245,6 @@ public class TileRenderer extends TileRendererBase {
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 (currentTile <= 0) {
setup();
}
@@ -297,7 +296,9 @@ public class TileRenderer extends TileRendererBase {
}
gl.glViewport( 0, 0, tW, tH );
- pmvMatrixCB.reshapePMVMatrix(gl, currentTileXPos, currentTileYPos, tW, tH, imageSize.getWidth(), imageSize.getHeight());
+ // Do not forget to issue:
+ // reshape( 0, 0, tW, tH );
+ // which shall reflect tile renderer fileds: currentTileXPos, currentTileYPos and imageSize
beginCalled = true;
}
@@ -385,72 +386,8 @@ public class TileRenderer extends TileRendererBase {
* </p>
*/
@Override
- public void attachToAutoDrawable(GLAutoDrawable glad, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException {
- super.attachToAutoDrawable(glad, pmvMatrixCB);
+ public void attachToAutoDrawable(GLAutoDrawable glad) throws IllegalStateException {
+ super.attachToAutoDrawable(glad);
setTileSize(glad.getWidth(), glad.getHeight(), 0);
}
-
- protected final GLEventListener getTiledGLEL() { return tiledGLEL; }
- private final GLEventListener tiledGLEL = new GLEventListener() {
- @Override
- public void init(GLAutoDrawable drawable) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.init(drawable);
- }
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- final GLEventListener l = listeners[i];
- l.init(drawable);
- listenersInit[i] = true;
- }
- if( null != glEventListenerPost ) {
- glEventListenerPost.init(drawable);
- }
- }
- @Override
- public void dispose(GLAutoDrawable drawable) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.dispose(drawable);
- }
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- listeners[i].dispose(drawable);
- }
- if( null != glEventListenerPost ) {
- glEventListenerPost.dispose(drawable);
- }
- }
- @Override
- public void display(GLAutoDrawable drawable) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.display(drawable);
- }
- final GL2ES3 gl = drawable.getGL().getGL2ES3();
-
- beginTile(gl);
-
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- listeners[i].display(drawable);
- }
-
- endTile(gl);
- if( null != glEventListenerPost ) {
- glEventListenerPost.display(drawable);
- }
- }
- @Override
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- if( null != glEventListenerPre ) {
- glEventListenerPre.reshape(drawable, x, y, width, height);
- }
- final int aSz = listenersInit.length;
- for(int i=0; i<aSz; i++) {
- listeners[i].reshape(drawable, x, y, width, height);
- }
- if( null != glEventListenerPost ) {
- glEventListenerPost.reshape(drawable, x, y, width, height);
- }
- }
- };
} \ No newline at end of file
diff --git a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
index 3aa6ea786..8779fa59f 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/TileRendererBase.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;
@@ -55,32 +54,43 @@ import javax.media.opengl.GLEventListener;
* <p>
* Enhanced for {@link GL2ES3}, abstracted to suit {@link TileRenderer} and {@link RandomTileRenderer}.
* </p>
+ * <a name="pmvmatrix"><h5>PMV Matrix Considerations</h5></a>
+ * <p>
+ * The PMV matrix needs to be reshaped in user code
+ * after calling {@link #beginTile(GL2ES3)}, See {@link #beginTile(GL2ES3)}.
+ * </p>
+ * <p>
+ * 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)}.
+ * </p>
*
* @author ryanm, sgothel
*/
public abstract class TileRendererBase {
/**
- * The width of the final image
+ * The width of the final image. See {@link #getParam(int)}.
*/
public static final int TR_IMAGE_WIDTH = 1;
/**
- * The height of the final image
+ * The height of the final image. See {@link #getParam(int)}.
*/
public static final int TR_IMAGE_HEIGHT = 2;
/**
- * The width of the current tile
+ * The width of the current tile. See {@link #getParam(int)}.
*/
public static final int TR_CURRENT_TILE_X_POS = 3;
/**
- * The height of the current tile
+ * The height of the current tile. See {@link #getParam(int)}.
*/
public static final int TR_CURRENT_TILE_Y_POS = 4;
/**
- * The width of the current tile
+ * The width of the current tile. See {@link #getParam(int)}.
*/
public static final int TR_CURRENT_TILE_WIDTH = 5;
/**
- * The height of the current tile
+ * The height of the current tile. See {@link #getParam(int)}.
*/
public static final int TR_CURRENT_TILE_HEIGHT = 6;
@@ -88,7 +98,6 @@ public abstract class TileRendererBase {
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;
@@ -100,34 +109,19 @@ public abstract class TileRendererBase {
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
+ * @param pname The parameter name that is to be retrieved
* @return the value of the parameter
- * @throws IllegalArgumentException if <code>param</code> is not handled
+ * @throws IllegalArgumentException if <code>pname</code> is not handled
*/
- public abstract int getParam(int param) throws IllegalArgumentException;
+ public abstract int getParam(int pname) 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.
@@ -170,13 +164,26 @@ public abstract class TileRendererBase {
/**
* 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)}!
+ * 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)}!
* </p>
- * <p>
- * The projection matrix stack should be
- * left alone after calling this method!
+ * <p>
+ * The <a href="#pmvmatrix">PMV Matrix</a>
+ * must be reshaped after this call using:
+ * <ul>
+ * <li>Current Viewport
+ * <ul>
+ * <li>x 0</li>
+ * <li>y 0</li>
+ * <li>{@link #TR_CURRENT_TILE_WIDTH tile width}</li>
+ * <li>{@link #TR_CURRENT_TILE_HEIGHT tile height}</li>
+ * </ul></li>
+ * <li>{@link #TR_CURRENT_TILE_X_POS tile x-pos}</li>
+ * <li>{@link #TR_CURRENT_TILE_Y_POS tile y-pos}</li>
+ * <li>{@link #TR_IMAGE_WIDTH image width}</li>
+ * <li>{@link #TR_IMAGE_HEIGHT image height}</li>
+ * </ul>
* </p>
* <p>
* Use shall render the scene afterwards, concluded with a call to
@@ -200,23 +207,46 @@ public abstract class TileRendererBase {
/**
* Attaches this renderer to the {@link GLAutoDrawable}.
* <p>
- * The {@link GLAutoDrawable}'s {@link GLEventListener} are removed first and stored locally.
+ * The {@link GLAutoDrawable}'s original {@link GLEventListener} are moved to local storage.
* This renderer {@link GLEventListener} is then added to handle the tile rendering
- * for the original {@link GLEventListener}.
+ * for the original {@link GLEventListener}, i.e. it's {@link GLEventListener#display(GLAutoDrawable) display} issues:
+ * <ul>
+ * <li>Optional {@link #setGLEventListener(GLEventListener, GLEventListener) pre-glel}.{@link GLEventListener#display(GLAutoDrawable) display(..)}</li>
+ * <li>{@link #beginTile(GL2ES3)}</li>
+ * <li>for all original {@link GLEventListener}:
+ * <ul>
+ * <li>{@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape(0, 0, tile-width, tile-height)}</li>
+ * <li>{@link GLEventListener#display(GLAutoDrawable) display(autoDrawable)}</li>
+ * </ul></li>
+ * <li>{@link #endTile(GL2ES3)}</li>
+ * <li>Optional {@link #setGLEventListener(GLEventListener, GLEventListener) post-glel}.{@link GLEventListener#display(GLAutoDrawable) display(..)}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Consider using {@link #setGLEventListener(GLEventListener, GLEventListener)} to add pre- and post
+ * hooks to be performed on this renderer {@link GLEventListener}.<br>
+ * The pre-hook is able to allocate memory and setup parameters, since it's called before {@link #beginTile(GL2ES3)}.<br>
+ * The post-hook is able to use the rendering result and can even shutdown tile-rendering,
+ * since it's called after {@link #endTile(GL2ES3)}.
* </p>
* <p>
* Call {@link #detachFromAutoDrawable()} to remove this renderer from the {@link GLAutoDrawable}
* and to restore it's original {@link GLEventListener}.
* </p>
+ * <p>
+ * The <a href="#pmvmatrix">PMV Matrix</a> shall be reshaped in the
+ * original {@link GLEventListener}'s {@link GLEventListener#reshape(GLAutoDrawable, int, int, int, int) reshape}
+ * method. The latter is called for each tile w/ the current viewport.
+ * The tile's position and image size can be utilized. See details in {@link #beginTile(GL2ES3)}.
+ * </p>
* @param glad
* @throws IllegalStateException if an {@link GLAutoDrawable} is already attached
*/
- public void attachToAutoDrawable(GLAutoDrawable glad, PMVMatrixCallback pmvMatrixCB) throws IllegalStateException {
+ public void attachToAutoDrawable(GLAutoDrawable glad) 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];
@@ -226,18 +256,18 @@ public abstract class TileRendererBase {
listenersInit[i] = glad.getGLEventListenerInitState(l);
listeners[i] = glad.removeGLEventListener( l );
}
- glad.addGLEventListener(getTiledGLEL());
+ glad.addGLEventListener(tiledGLEL);
}
/**
* Detaches this renderer from the {@link GLAutoDrawable}.
* <p>
- * See {@link #attachToAutoDrawable(GLAutoDrawable, PMVMatrixCallback)}.
+ * See {@link #attachToAutoDrawable(GLAutoDrawable)}.
* </p>
*/
public void detachFromAutoDrawable() {
if( null != glad ) {
- glad.removeGLEventListener(getTiledGLEL());
+ glad.removeGLEventListener(tiledGLEL);
final int aSz = listenersInit.length;
for(int i=0; i<aSz; i++) {
final GLEventListener l = listeners[i];
@@ -247,13 +277,9 @@ public abstract class TileRendererBase {
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)}
@@ -269,7 +295,7 @@ public abstract class TileRendererBase {
/**
* Rendering one tile, by simply calling {@link GLAutoDrawable#display()}.
*
- * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachToAutoDrawable(GLAutoDrawable, int) attached}
+ * @throws IllegalStateException if no {@link GLAutoDrawable} is {@link #attachToAutoDrawable(GLAutoDrawable) attached}
* or imageSize is not set
*/
public void display() throws IllegalStateException {
@@ -278,4 +304,68 @@ public abstract class TileRendererBase {
}
glad.display();
}
+
+ private final GLEventListener tiledGLEL = new GLEventListener() {
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ if( null != glEventListenerPre ) {
+ glEventListenerPre.init(drawable);
+ }
+ final int aSz = listenersInit.length;
+ for(int i=0; i<aSz; i++) {
+ final GLEventListener l = listeners[i];
+ l.init(drawable);
+ listenersInit[i] = true;
+ }
+ if( null != glEventListenerPost ) {
+ glEventListenerPost.init(drawable);
+ }
+ }
+ @Override
+ public void dispose(GLAutoDrawable drawable) {
+ if( null != glEventListenerPre ) {
+ glEventListenerPre.dispose(drawable);
+ }
+ final int aSz = listenersInit.length;
+ for(int i=0; i<aSz; i++) {
+ listeners[i].dispose(drawable);
+ }
+ if( null != glEventListenerPost ) {
+ glEventListenerPost.dispose(drawable);
+ }
+ }
+ @Override
+ public void display(GLAutoDrawable drawable) {
+ if( null != glEventListenerPre ) {
+ glEventListenerPre.display(drawable);
+ }
+ final GL2ES3 gl = drawable.getGL().getGL2ES3();
+
+ beginTile(gl);
+
+ final int aSz = listenersInit.length;
+ for(int i=0; i<aSz; i++) {
+ listeners[i].reshape(drawable, 0, 0, currentTileWidth, currentTileHeight);
+ listeners[i].display(drawable);
+ }
+
+ endTile(gl);
+ if( null != glEventListenerPost ) {
+ glEventListenerPost.display(drawable);
+ }
+ }
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ if( null != glEventListenerPre ) {
+ glEventListenerPre.reshape(drawable, x, y, width, height);
+ }
+ final int aSz = listenersInit.length;
+ for(int i=0; i<aSz; i++) {
+ listeners[i].reshape(drawable, x, y, width, height);
+ }
+ if( null != glEventListenerPost ) {
+ glEventListenerPost.reshape(drawable, x, y, width, height);
+ }
+ }
+ };
} \ No newline at end of file
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index b7a24a777..e04051cc0 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -52,10 +52,14 @@ import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
+import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBufferInt;
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -95,6 +99,11 @@ import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol;
import com.jogamp.nativewindow.awt.JAWTWindow;
import com.jogamp.opengl.JoglVersion;
+import com.jogamp.opengl.util.GLPixelBuffer;
+import com.jogamp.opengl.util.RandomTileRenderer;
+import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes;
+import com.jogamp.opengl.util.awt.AWTGLPixelBuffer;
+import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.SingleAWTGLPixelBufferProvider;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
@@ -719,6 +728,107 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
paint(g);
}
+ private static SingleAWTGLPixelBufferProvider singleAWTGLPixelBufferProvider = null;
+ private static synchronized SingleAWTGLPixelBufferProvider getSingleAWTGLPixelBufferProvider() {
+ if( null == singleAWTGLPixelBufferProvider ) {
+ singleAWTGLPixelBufferProvider = new SingleAWTGLPixelBufferProvider( true /* allowRowStride */ );
+ }
+ return singleAWTGLPixelBufferProvider;
+ }
+ private boolean animatorPaused = false;
+ private RandomTileRenderer tileRenderer;
+ private SingleAWTGLPixelBufferProvider printBufferProvider;
+ private IntBuffer cpuVFlipIntBbuffer;
+
+ public void setupPrint(final int printWidth, final int printHeight, RandomTileRenderer.PMVMatrixCallback pmvMatrixCB) {
+ final GLAnimatorControl animator = helper.getAnimator();
+ if( animator.isAnimating() ) {
+ animator.pause();
+ animatorPaused = true;
+ }
+ printBufferProvider = getSingleAWTGLPixelBufferProvider();
+ tileRenderer = new RandomTileRenderer();
+ tileRenderer.setImageSize(printWidth, printHeight);
+ tileRenderer.attachToAutoDrawable(this);
+ final GLEventListener preTileGLEL = new GLEventListener() {
+ @Override
+ public void init(GLAutoDrawable drawable) {
+ final GL gl = drawable.getGL();
+ GLPixelAttributes pixelAttribs = printBufferProvider.getAttributes(gl, 3);
+ GLPixelBuffer pixelBuffer = printBufferProvider.allocate(gl, pixelAttribs, drawable.getWidth(), drawable.getHeight(), 1, true, 0);
+ tileRenderer.setTileBuffer(pixelBuffer);
+ }
+ @Override
+ public void dispose(GLAutoDrawable drawable) {}
+ @Override
+ public void display(GLAutoDrawable drawable) {}
+ @Override
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {}
+ };
+ tileRenderer.setGLEventListener(preTileGLEL, null);
+ }
+ public void releasePrint() {
+ tileRenderer.detachFromAutoDrawable();
+ tileRenderer = null;
+ printBufferProvider = null;
+ singleAWTGLPixelBufferProvider = null;
+ final GLAnimatorControl animator = animatorPaused ? helper.getAnimator() : null;
+ if( null != animator ) {
+ animator.resume();
+ }
+ animatorPaused = false;
+ }
+
+ @Override
+ public void print(Graphics graphics) {
+ if( null != tileRenderer ) {
+ final Rectangle clip = graphics.getClipBounds();
+ System.err.println("AWT print clip: "+clip);
+ tileRenderer.setTileRect(clip.x, clip.y, clip.width, clip.height);
+ }
+ super.print(graphics);
+ }
+ private void print(GL gl) {
+ final int componentCount;
+ if( isOpaque() ) {
+ // w/o alpha
+ componentCount = 3;
+ } else {
+ // with alpha
+ componentCount = 4;
+ }
+ final GLPixelAttributes pixelAttribs = printBufferProvider.getAttributes(gl, componentCount);
+ final int imageWidth = tileRenderer.getImageSize().getWidth();
+ final int imageHeight = tileRenderer.getImageSize().getHeight();
+ AWTGLPixelBuffer pixelBuffer = printBufferProvider.getSingleBuffer(pixelAttribs);
+ if( null != pixelBuffer && pixelBuffer.requiresNewBuffer(gl, imageWidth, imageHeight, 0) ) {
+ pixelBuffer.dispose();
+ pixelBuffer = null;
+ }
+ if ( null == pixelBuffer ) {
+ pixelBuffer = printBufferProvider.allocate(gl, pixelAttribs, imageWidth, imageHeight, 1, true, 0);
+ }
+ if( null == cpuVFlipIntBbuffer || pixelBuffer.width * pixelBuffer.height > cpuVFlipIntBbuffer.remaining() ) {
+ cpuVFlipIntBbuffer = IntBuffer.allocate(pixelBuffer.width * pixelBuffer.height);
+ }
+
+ tileRenderer.setImageBuffer(pixelBuffer);
+
+ // Copy temporary data into raster of BufferedImage for faster
+ // blitting Note that we could avoid this copy in the cases
+ // where !offscreenDrawable.isGLOriented(),
+ // but that's the software rendering path which is very slow anyway.
+ final BufferedImage image = pixelBuffer.image;
+ final int[] src = cpuVFlipIntBbuffer.array();
+ final int[] dest = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
+ final int incr = pixelBuffer.width;
+ int srcPos = 0;
+ int destPos = (imageHeight - 1) * pixelBuffer.width;
+ for (; destPos >= 0; srcPos += incr, destPos -= incr) {
+ System.arraycopy(src, srcPos, dest, destPos, incr);
+ }
+ }
+
@Override
public void addGLEventListener(GLEventListener listener) {
helper.addGLEventListener(listener);