diff options
author | Sven Gothel <[email protected]> | 2013-09-07 12:52:19 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-09-07 12:52:19 +0200 |
commit | 4b5e77961d1c660f3537f4041fc1a3ce47ef105c (patch) | |
tree | db6bd07357ce6a79d5cb6279b76fa58d99e7b508 /src/jogl | |
parent | 27c4a837580c7a68582e852d5ff64f733e669509 (diff) |
AWT/GL Printing WIP: Abstract AWT tile painting code out to AWTTilePainter, reused w/ GLCanvas and GLJPanel
Diffstat (limited to 'src/jogl')
-rw-r--r-- | src/jogl/classes/javax/media/opengl/awt/GLCanvas.java | 186 | ||||
-rw-r--r-- | src/jogl/classes/javax/media/opengl/awt/GLJPanel.java | 198 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java | 217 |
3 files changed, 300 insertions, 301 deletions
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java index 4ff25d0e6..5ada2d80f 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java @@ -53,13 +53,9 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; -import java.awt.Rectangle; import java.awt.RenderingHints; -import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; -import java.awt.image.BufferedImage; -import java.awt.image.DataBufferInt; import java.awt.EventQueue; import java.lang.reflect.InvocationTargetException; @@ -107,16 +103,13 @@ import com.jogamp.nativewindow.awt.AWTWindowClosingProtocol; import com.jogamp.nativewindow.awt.JAWTWindow; import com.jogamp.opengl.JoglVersion; import com.jogamp.opengl.util.GLDrawableUtil; -import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.TileRenderer; -import com.jogamp.opengl.util.TileRendererBase; -import com.jogamp.opengl.util.awt.AWTGLPixelBuffer; -import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider; import jogamp.opengl.Debug; import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableHelper; import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.awt.AWTTilePainter; // FIXME: Subclasses need to call resetGLFunctionAvailability() on their // context whenever the displayChanged() function is called on our @@ -738,12 +731,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing private static final int PRINT_TILE_SIZE = 512; private volatile boolean printActive = false; - private GLOffscreenAutoDrawable printGLAD = null; - private TileRenderer printRenderer = null; private GLAnimatorControl printAnimator = null; - private AWTGLPixelBuffer printBuffer = null; - private BufferedImage printVFlipImage = null; - private Graphics2D printGraphics = null; + private GLOffscreenAutoDrawable printGLAD = null; + private AWTTilePainter printAWTTiles = null; @Override public void setupPrint() { @@ -777,95 +767,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing printGLAD = factory.createOffscreenAutoDrawable(null, caps, null, PRINT_TILE_SIZE, PRINT_TILE_SIZE, null); GLDrawableUtil.swapGLContextAndAllGLEventListener(GLCanvas.this, printGLAD); destroyOnEDTAction.run(); - printRenderer = new TileRenderer(); - printRenderer.setRowOrder(TileRenderer.TR_TOP_TO_BOTTOM); + + final int componentCount = isOpaque() ? 3 : 4; + final TileRenderer printRenderer = new TileRenderer(); printRenderer.setTileSize(printGLAD.getWidth(), printGLAD.getHeight(), 0); printRenderer.attachToAutoDrawable(printGLAD); - - final GLEventListener preTileGLEL = new GLEventListener() { - @Override - public void init(GLAutoDrawable drawable) { - } - @Override - public void dispose(GLAutoDrawable drawable) {} - @Override - public void display(GLAutoDrawable drawable) { - final GL gl = drawable.getGL(); - if( null == printBuffer ) { - final int componentCount = isOpaque() ? 3 : 4; - final AWTGLPixelBufferProvider printBufferProvider = new AWTGLPixelBufferProvider( true /* allowRowStride */ ); - final GLPixelAttributes pixelAttribs = printBufferProvider.getAttributes(gl, componentCount); - printBuffer = printBufferProvider.allocate(gl, pixelAttribs, printGLAD.getWidth(), printGLAD.getHeight(), 1, true, 0); - printRenderer.setTileBuffer(printBuffer); - printVFlipImage = new BufferedImage(printBuffer.width, printBuffer.height, printBuffer.image.getType()); - } - System.err.println("XXX tile-pre "+printRenderer); // FIXME - } - @Override - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - }; - final GLEventListener postTileGLEL = new GLEventListener() { - int tTopRowHeight = 0; - @Override - public void init(GLAutoDrawable drawable) { - tTopRowHeight = 0; - } - @Override - public void dispose(GLAutoDrawable drawable) {} - @Override - public void display(GLAutoDrawable drawable) { - // 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 int tHeight = printRenderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT); - final int tWidth = printRenderer.getParam(TileRendererBase.TR_CURRENT_TILE_WIDTH); - // final BufferedImage dstImage = printBuffer.image; - final BufferedImage srcImage = printBuffer.image; - final BufferedImage dstImage = printVFlipImage; - final int[] src = ((DataBufferInt) srcImage.getRaster().getDataBuffer()).getData(); - final int[] dst = ((DataBufferInt) dstImage.getRaster().getDataBuffer()).getData(); - final int incr = printBuffer.width; - int srcPos = 0; - int destPos = (tHeight - 1) * printBuffer.width; - for (; destPos >= 0; srcPos += incr, destPos -= incr) { - System.arraycopy(src, srcPos, dst, destPos, incr); - } - // Draw resulting image in one shot - final int tRows = printRenderer.getParam(TileRenderer.TR_ROWS); - final int tRow = printRenderer.getParam(TileRenderer.TR_CURRENT_ROW); - final int pX = printRenderer.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS); - final int pYf; - if( tRow == tRows - 1 ) { - tTopRowHeight = tHeight; - pYf = 0; - } else if( tRow == tRows - 2 ){ - pYf = tTopRowHeight; - } else { - pYf = ( tRows - 2 - tRow ) * tHeight + tTopRowHeight; - } - final Shape oClip = printGraphics.getClip(); - printGraphics.clipRect(pX, pYf, tWidth, tHeight); - final Shape clip = printGraphics.getClip(); - printGraphics.drawImage(dstImage, pX, pYf, dstImage.getWidth(), dstImage.getHeight(), null); // Null ImageObserver since image data is ready. - printGraphics.setColor(Color.BLACK); - printGraphics.drawRect(pX, pYf, tWidth, tHeight); - { - final Rectangle r = oClip.getBounds(); - printGraphics.setColor(Color.YELLOW); - printGraphics.drawRect(r.x, r.y, r.width, r.height); - } - printGraphics.setClip(oClip); - System.err.println("XXX tile-post.X clip "+oClip+" -> "+clip); - System.err.println("XXX tile-post.X "+printRenderer); - System.err.println("XXX tile-post.X dst-img "+dstImage.getWidth()+"x"+dstImage.getHeight()+" -> "+pX+"/"+pYf); // +", "+dstImage); // FIXME - } - @Override - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - }; - printRenderer.setGLEventListener(preTileGLEL, postTileGLEL); - - System.err.println("AWT print.setup "+printRenderer); // FIXME + printAWTTiles = new AWTTilePainter(printRenderer, componentCount, DEBUG); + if( DEBUG ) { + System.err.println("AWT print.setup "+printAWTTiles); + } } }; @@ -882,26 +792,19 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing private final Runnable releasePrintOnEDT = new Runnable() { @Override public void run() { - printRenderer.detachFromAutoDrawable(); // tile-renderer -> printGLAD + if( DEBUG ) { + System.err.println("AWT print.release "+printAWTTiles); + } + printAWTTiles.dispose(); + printAWTTiles= null; createDrawableAndContext( false ); GLDrawableUtil.swapGLContextAndAllGLEventListener(printGLAD, GLCanvas.this); printGLAD.destroy(); + printGLAD = null; if( null != printAnimator ) { printAnimator.add(GLCanvas.this); + printAnimator = null; } - System.err.println("AWT print.release "+printRenderer); // FIXME - printGLAD = null; - printRenderer = null; - printAnimator = null; - if( null != printBuffer ) { - printBuffer.dispose(); - printBuffer = null; - } - if( null != printVFlipImage ) { - printVFlipImage.flush(); - printVFlipImage = null; - } - printGraphics = null; printActive = false; } }; @@ -916,40 +819,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing // we cannot dispatch print on AWT-EDT due to printing internal locking .. } sendReshape = false; // clear reshape flag - printGraphics = (Graphics2D)graphics; - System.err.println("AWT print.0: canvasSize "+getWidth()+"x"+getWidth()+", printAnimator "+printAnimator); - { - final RenderingHints rHints = printGraphics.getRenderingHints(); - final Set<Entry<Object, Object>> rEntries = rHints.entrySet(); - int count = 0; - for(Iterator<Entry<Object, Object>> rEntryIter = rEntries.iterator(); rEntryIter.hasNext(); count++) { - final Entry<Object, Object> rEntry = rEntryIter.next(); - System.err.println("Hint["+count+"]: "+rEntry.getKey()+" -> "+rEntry.getValue()); + final Graphics2D printGraphics = (Graphics2D)graphics; + if( DEBUG ) { + System.err.println("AWT print.0: canvasSize "+getWidth()+"x"+getWidth()+", printAnimator "+printAnimator); + { + final RenderingHints rHints = printGraphics.getRenderingHints(); + final Set<Entry<Object, Object>> rEntries = rHints.entrySet(); + int count = 0; + for(Iterator<Entry<Object, Object>> rEntryIter = rEntries.iterator(); rEntryIter.hasNext(); count++) { + final Entry<Object, Object> rEntry = rEntryIter.next(); + System.err.println("Hint["+count+"]: "+rEntry.getKey()+" -> "+rEntry.getValue()); + } } + final AffineTransform aTrans = printGraphics.getTransform(); + System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY()); + System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY()); + } + printAWTTiles.updateGraphics2DAndClipBounds(printGraphics); + final TileRenderer tileRenderer = printAWTTiles.getTileRenderer(); + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); } - // final GraphicsConfiguration gc = printGraphics.getDeviceConfiguration(); - final AffineTransform aTrans = printGraphics.getTransform(); - System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY()); - System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY()); - - final Rectangle gClipOrig = printGraphics.getClipBounds(); - final Rectangle gClip = new Rectangle(gClipOrig); - if( 0 > gClip.x ) { - gClip.width += gClip.x; - gClip.x = 0; - } - if( 0 > gClip.y ) { - gClip.height += gClip.y; - gClip.y = 0; - } - printRenderer.setImageSize(gClip.width, gClip.height); - printRenderer.setTileOffset(gClip.x, gClip.y); - System.err.println("AWT print.0: "+gClipOrig+" -> "+gClip); - System.err.println("AWT print.0: "+printRenderer); do { - printRenderer.display(); - } while ( !printRenderer.eot() ); - System.err.println("AWT print.X: "+printRenderer); + tileRenderer.display(); + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.X: "+tileRenderer); + } } @Override diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java index 84663cb3a..1f9e65a7d 100644 --- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java +++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java @@ -49,7 +49,6 @@ import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.RenderingHints; -import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; @@ -90,6 +89,7 @@ import jogamp.opengl.GLContextImpl; import jogamp.opengl.GLDrawableFactoryImpl; import jogamp.opengl.GLDrawableHelper; import jogamp.opengl.GLDrawableImpl; +import jogamp.opengl.awt.AWTTilePainter; import jogamp.opengl.awt.Java2D; import jogamp.opengl.util.glsl.GLSLTextureRaster; @@ -100,7 +100,6 @@ import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; import com.jogamp.opengl.util.GLPixelBuffer.SingletonGLPixelBufferProvider; import com.jogamp.opengl.util.GLPixelStorageModes; import com.jogamp.opengl.util.TileRenderer; -import com.jogamp.opengl.util.TileRendererBase; import com.jogamp.opengl.util.awt.AWTGLPixelBuffer; import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider; import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.SingleAWTGLPixelBufferProvider; @@ -502,11 +501,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } private volatile boolean printActive = false; - private TileRenderer printRenderer = null; private GLAnimatorControl printAnimator = null; - private AWTGLPixelBuffer printBuffer = null; - private BufferedImage printVFlipImage = null; - private Graphics2D printGraphics = null; + private AWTTilePainter printAWTTiles = null; @Override public void setupPrint() { @@ -535,102 +531,15 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing printAnimator = helper.getAnimator(); if( null != printAnimator ) { printAnimator.remove(GLJPanel.this); - } - final int tileWidth = getWidth(); - final int tileHeight = getHeight(); - - // FIXME final OffscreenBackend offscrBacken = (OffscreenBackend)backend; - final GLCapabilities caps = (GLCapabilities)getChosenGLCapabilities().cloneMutable(); - caps.setOnscreen(false); - printRenderer = new TileRenderer(); - printRenderer.setRowOrder(TileRenderer.TR_TOP_TO_BOTTOM); - printRenderer.setTileSize(tileWidth, tileHeight, 0); + } + final int componentCount = isOpaque() ? 3 : 4; + final TileRenderer printRenderer = new TileRenderer(); + printRenderer.setTileSize(getWidth(), getHeight(), 0); printRenderer.attachToAutoDrawable(GLJPanel.this); - - final GLEventListener preTileGLEL = new GLEventListener() { - @Override - public void init(GLAutoDrawable drawable) { - } - @Override - public void dispose(GLAutoDrawable drawable) {} - @Override - public void display(GLAutoDrawable drawable) { - final GL gl = drawable.getGL(); - if( null == printBuffer ) { - final int componentCount = isOpaque() ? 3 : 4; - final AWTGLPixelBufferProvider printBufferProvider = new AWTGLPixelBufferProvider( true /* allowRowStride */ ); - final GLPixelAttributes pixelAttribs = printBufferProvider.getAttributes(gl, componentCount); - printBuffer = printBufferProvider.allocate(gl, pixelAttribs, tileWidth, tileHeight, 1, true, 0); - printRenderer.setTileBuffer(printBuffer); - printVFlipImage = new BufferedImage(printBuffer.width, printBuffer.height, printBuffer.image.getType()); - } - System.err.println("XXX tile-pre "+printRenderer); // FIXME - } - @Override - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - }; - final GLEventListener postTileGLEL = new GLEventListener() { - int tTopRowHeight = 0; - @Override - public void init(GLAutoDrawable drawable) { - tTopRowHeight = 0; - } - @Override - public void dispose(GLAutoDrawable drawable) {} - @Override - public void display(GLAutoDrawable drawable) { - // 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 int tHeight = printRenderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT); - final int tWidth = printRenderer.getParam(TileRendererBase.TR_CURRENT_TILE_WIDTH); - // final BufferedImage dstImage = printBuffer.image; - final BufferedImage srcImage = printBuffer.image; - final BufferedImage dstImage = printVFlipImage; - final int[] src = ((DataBufferInt) srcImage.getRaster().getDataBuffer()).getData(); - final int[] dst = ((DataBufferInt) dstImage.getRaster().getDataBuffer()).getData(); - final int incr = printBuffer.width; - int srcPos = 0; - int destPos = (tHeight - 1) * printBuffer.width; - for (; destPos >= 0; srcPos += incr, destPos -= incr) { - System.arraycopy(src, srcPos, dst, destPos, incr); - } - // Draw resulting image in one shot - final int tRows = printRenderer.getParam(TileRenderer.TR_ROWS); - final int tRow = printRenderer.getParam(TileRenderer.TR_CURRENT_ROW); - final int pX = printRenderer.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS); - final int pYf; - if( tRow == tRows - 1 ) { - tTopRowHeight = tHeight; - pYf = 0; - } else if( tRow == tRows - 2 ){ - pYf = tTopRowHeight; - } else { - pYf = ( tRows - 2 - tRow ) * tHeight + tTopRowHeight; - } - final Shape oClip = printGraphics.getClip(); - printGraphics.clipRect(pX, pYf, tWidth, tHeight); - final Shape clip = printGraphics.getClip(); - printGraphics.drawImage(dstImage, pX, pYf, dstImage.getWidth(), dstImage.getHeight(), null); // Null ImageObserver since image data is ready. - printGraphics.setColor(Color.BLACK); - printGraphics.drawRect(pX, pYf, tWidth, tHeight); - { - final Rectangle r = oClip.getBounds(); - printGraphics.setColor(Color.YELLOW); - printGraphics.drawRect(r.x, r.y, r.width, r.height); - } - printGraphics.setClip(oClip); - System.err.println("XXX tile-post.X clip "+oClip+" -> "+clip); - System.err.println("XXX tile-post.X "+printRenderer); - System.err.println("XXX tile-post.X dst-img "+dstImage.getWidth()+"x"+dstImage.getHeight()+" -> "+pX+"/"+pYf); // +", "+dstImage); // FIXME - } - @Override - public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} - }; - printRenderer.setGLEventListener(preTileGLEL, postTileGLEL); - - System.err.println("AWT print.setup "+printRenderer); // FIXME + printAWTTiles = new AWTTilePainter(printRenderer, componentCount, DEBUG); + if( DEBUG ) { + System.err.println("AWT print.setup "+printAWTTiles); + } } }; @@ -649,22 +558,15 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing private final Runnable releasePrintOnEDT = new Runnable() { @Override public void run() { - printRenderer.detachFromAutoDrawable(); // tile-renderer -> printGLAD + if( DEBUG ) { + System.err.println("AWT print.release "+printAWTTiles); + } + printAWTTiles.dispose(); + printAWTTiles= null; if( null != printAnimator ) { printAnimator.add(GLJPanel.this); + printAnimator = null; } - System.err.println("AWT print.release "+printRenderer); // FIXME - printRenderer = null; - printAnimator = null; - if( null != printBuffer ) { - printBuffer.dispose(); - printBuffer = null; - } - if( null != printVFlipImage ) { - printVFlipImage.flush(); - printVFlipImage = null; - } - printGraphics = null; printActive = false; } }; @@ -680,45 +582,40 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing } sendReshape = false; // clear reshape flag handleReshape = false; // ditto - printGraphics = (Graphics2D)graphics; - System.err.println("AWT print.0: canvasSize "+getWidth()+"x"+getWidth()+", printAnimator "+printAnimator); - { - final RenderingHints rHints = printGraphics.getRenderingHints(); - final Set<Entry<Object, Object>> rEntries = rHints.entrySet(); - int count = 0; - for(Iterator<Entry<Object, Object>> rEntryIter = rEntries.iterator(); rEntryIter.hasNext(); count++) { - final Entry<Object, Object> rEntry = rEntryIter.next(); - System.err.println("Hint["+count+"]: "+rEntry.getKey()+" -> "+rEntry.getValue()); + final Graphics2D printGraphics = (Graphics2D)graphics; + if( DEBUG ) { + System.err.println("AWT print.0: canvasSize "+getWidth()+"x"+getWidth()+", printAnimator "+printAnimator); + { + final RenderingHints rHints = printGraphics.getRenderingHints(); + final Set<Entry<Object, Object>> rEntries = rHints.entrySet(); + int count = 0; + for(Iterator<Entry<Object, Object>> rEntryIter = rEntries.iterator(); rEntryIter.hasNext(); count++) { + final Entry<Object, Object> rEntry = rEntryIter.next(); + System.err.println("Hint["+count+"]: "+rEntry.getKey()+" -> "+rEntry.getValue()); + } } + final AffineTransform aTrans = printGraphics.getTransform(); + System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY()); + System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY()); + } + printAWTTiles.updateGraphics2DAndClipBounds(printGraphics); + final TileRenderer tileRenderer = printAWTTiles.getTileRenderer(); + if( DEBUG ) { + System.err.println("AWT print.0: "+tileRenderer); } - // final GraphicsConfiguration gc = printGraphics.getDeviceConfiguration(); - final AffineTransform aTrans = printGraphics.getTransform(); - System.err.println(" scale "+aTrans.getScaleX()+" x "+aTrans.getScaleY()); - System.err.println(" move "+aTrans.getTranslateX()+" x "+aTrans.getTranslateY()); - - final Rectangle gClipOrig = printGraphics.getClipBounds(); - final Rectangle gClip = new Rectangle(gClipOrig); - if( 0 > gClip.x ) { - gClip.width += gClip.x; - gClip.x = 0; - } - if( 0 > gClip.y ) { - gClip.height += gClip.y; - gClip.y = 0; - } - printRenderer.setImageSize(gClip.width, gClip.height); - printRenderer.setTileOffset(gClip.x, gClip.y); - System.err.println("AWT print.0: "+gClipOrig+" -> "+gClip); - System.err.println("AWT print.0: "+printRenderer); do { // printRenderer.display(); backend.doPlainPaint(); - } while ( !printRenderer.eot() ); - System.err.println("AWT print.X: "+printRenderer); + } while ( !tileRenderer.eot() ); + if( DEBUG ) { + System.err.println("AWT print.X: "+tileRenderer); + } } @Override protected void printComponent(Graphics g) { - System.err.println("AWT printComponent.X: "+printRenderer); + if( DEBUG ) { + System.err.println("AWT printComponent.X: "+printAWTTiles); + } print(g); } @@ -1578,17 +1475,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing @Override public boolean handleReshape() { - /** FIXME: Shall we utilize such resize optimization (snippet kept alive from removed pbuffer backend) ? - // Use factor larger than 2 during shrinks for some hysteresis - float shrinkFactor = 2.5f; - if ( (panelWidth > readBackWidthInPixels) || (panelHeight > readBackHeightInPixels) || - (panelWidth < (readBackWidthInPixels / shrinkFactor)) || (panelHeight < (readBackHeightInPixels / shrinkFactor))) { - if (DEBUG) { - System.err.println(getThreadName()+": Resizing offscreen from (" + readBackWidthInPixels + ", " + readBackHeightInPixels + ") " + - " to fit (" + panelWidth + ", " + panelHeight + ")"); - } - } */ - GLDrawableImpl _drawable = offscreenDrawable; { final GLDrawableImpl _drawableNew = GLDrawableHelper.resizeOffscreenDrawable(_drawable, offscreenContext, panelWidth, panelHeight); diff --git a/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java new file mode 100644 index 000000000..7493a19c5 --- /dev/null +++ b/src/jogl/classes/jogamp/opengl/awt/AWTTilePainter.java @@ -0,0 +1,217 @@ +/** + * 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. + */ +package jogamp.opengl.awt; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; + +import javax.media.opengl.GL; +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLEventListener; + +import com.jogamp.opengl.util.TileRenderer; +import com.jogamp.opengl.util.TileRendererBase; +import com.jogamp.opengl.util.GLPixelBuffer.GLPixelAttributes; +import com.jogamp.opengl.util.awt.AWTGLPixelBuffer; +import com.jogamp.opengl.util.awt.AWTGLPixelBuffer.AWTGLPixelBufferProvider; + +/** + * Implementing AWT {@link Graphics2D} based {@link TileRenderer} <i>painter</i>. + * <p> + * Maybe utilized for AWT printing. + * </p> + */ +public class AWTTilePainter { + final private TileRenderer renderer; + final private int componentCount; + final private boolean verbose; + + private AWTGLPixelBuffer tBuffer = null; + private BufferedImage vFlipImage = null; + private Graphics2D g2d = null; + + /** + * Assumes a configured {@link TileRenderer}, i.e. + * an {@link TileRenderer#attachToAutoDrawable(GLAutoDrawable) attached} + * {@link GLAutoDrawable} with {@link TileRenderer#setTileSize(int, int, int) set tile size}. + * <p> + * Sets the renderer to {@link TileRenderer#TR_TOP_TO_BOTTOM} row order. + * </p> + * <p> + * <code>componentCount</code> reflects opaque, i.e. 4 if non opaque. + * </p> + */ + public AWTTilePainter(TileRenderer renderer, int componentCount, boolean verbose) { + this.renderer = renderer; + this.renderer.setGLEventListener(preTileGLEL, postTileGLEL); + this.componentCount = componentCount; + this.verbose = verbose; + this.renderer.setRowOrder(TileRenderer.TR_TOP_TO_BOTTOM); + } + + public String toString() { return renderer.toString(); } + + public TileRenderer getTileRenderer() { return renderer; } + + /** + * Caches the {@link Graphics2D} instance for rendering. + * <p> + * Sets the {@link TileRenderer}'s {@link TileRenderer#setImageSize(int, int) image size} + * and {@link TileRenderer#setTileOffset(int, int) tile offset} according the + * the {@link Graphics2D#getClipBounds() graphics clip bounds}. + * </p> + * @param g2d + */ + public void updateGraphics2DAndClipBounds(Graphics2D g2d) { + this.g2d = g2d; + final Rectangle gClipOrig = g2d.getClipBounds(); + final Rectangle gClip = new Rectangle(gClipOrig); + if( 0 > gClip.x ) { + gClip.width += gClip.x; + gClip.x = 0; + } + if( 0 > gClip.y ) { + gClip.height += gClip.y; + gClip.y = 0; + } + if( verbose ) { + System.err.println("AWT print.0: "+gClipOrig+" -> "+gClip); + } + renderer.setImageSize(gClip.width, gClip.height); + renderer.setTileOffset(gClip.x, gClip.y); + } + + /** + * Disposes resources and {@link TileRenderer#detachFromAutoDrawable() detaches} + * the {@link TileRenderer}'s {@link GLAutoDrawable}. + */ + public void dispose() { + renderer.detachFromAutoDrawable(); // tile-renderer -> printGLAD + g2d = null; + if( null != tBuffer ) { + tBuffer.dispose(); + tBuffer = null; + } + if( null != vFlipImage ) { + vFlipImage.flush(); + vFlipImage = null; + } + } + + final GLEventListener preTileGLEL = new GLEventListener() { + @Override + public void init(GLAutoDrawable drawable) { + } + @Override + public void dispose(GLAutoDrawable drawable) {} + @Override + public void display(GLAutoDrawable drawable) { + final GL gl = drawable.getGL(); + if( null == tBuffer ) { + final int tWidth = renderer.getParam(TileRenderer.TR_TILE_WIDTH); + final int tHeight = renderer.getParam(TileRenderer.TR_TILE_HEIGHT); + final AWTGLPixelBufferProvider printBufferProvider = new AWTGLPixelBufferProvider( true /* allowRowStride */ ); + final GLPixelAttributes pixelAttribs = printBufferProvider.getAttributes(gl, componentCount); + tBuffer = printBufferProvider.allocate(gl, pixelAttribs, tWidth, tHeight, 1, true, 0); + renderer.setTileBuffer(tBuffer); + vFlipImage = new BufferedImage(tBuffer.width, tBuffer.height, tBuffer.image.getType()); + } + if( verbose ) { + System.err.println("XXX tile-pre "+renderer); + } + } + @Override + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + }; + final GLEventListener postTileGLEL = new GLEventListener() { + int tTopRowHeight = 0; + @Override + public void init(GLAutoDrawable drawable) { + tTopRowHeight = 0; + } + @Override + public void dispose(GLAutoDrawable drawable) {} + @Override + public void display(GLAutoDrawable drawable) { + // 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 int tWidth = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_WIDTH); + final int tHeight = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_HEIGHT); + // final BufferedImage dstImage = printBuffer.image; + final BufferedImage srcImage = tBuffer.image; + final BufferedImage dstImage = vFlipImage; + final int[] src = ((DataBufferInt) srcImage.getRaster().getDataBuffer()).getData(); + final int[] dst = ((DataBufferInt) dstImage.getRaster().getDataBuffer()).getData(); + final int incr = tBuffer.width; + int srcPos = 0; + int destPos = (tHeight - 1) * tBuffer.width; + for (; destPos >= 0; srcPos += incr, destPos -= incr) { + System.arraycopy(src, srcPos, dst, destPos, incr); + } + // Draw resulting image in one shot + final int tRows = renderer.getParam(TileRenderer.TR_ROWS); + final int tRow = renderer.getParam(TileRenderer.TR_CURRENT_ROW); + final int pX = renderer.getParam(TileRendererBase.TR_CURRENT_TILE_X_POS); + final int pYf; + if( tRow == tRows - 1 ) { + tTopRowHeight = tHeight; + pYf = 0; + } else if( tRow == tRows - 2 ){ + pYf = tTopRowHeight; + } else { + pYf = ( tRows - 2 - tRow ) * tHeight + tTopRowHeight; + } + final Shape oClip = g2d.getClip(); + g2d.clipRect(pX, pYf, tWidth, tHeight); + final Shape clip = g2d.getClip(); + g2d.drawImage(dstImage, pX, pYf, dstImage.getWidth(), dstImage.getHeight(), null); // Null ImageObserver since image data is ready. + g2d.setColor(Color.BLACK); + g2d.drawRect(pX, pYf, tWidth, tHeight); + { + final Rectangle r = oClip.getBounds(); + g2d.setColor(Color.YELLOW); + g2d.drawRect(r.x, r.y, r.width, r.height); + } + g2d.setClip(oClip); + if( verbose ) { + System.err.println("XXX tile-post.X clip "+oClip+" -> "+clip); + System.err.println("XXX tile-post.X "+renderer); + System.err.println("XXX tile-post.X dst-img "+dstImage.getWidth()+"x"+dstImage.getHeight()+" -> "+pX+"/"+pYf); + } + } + @Override + public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {} + }; + +} |